[C28-33][@ant] feat: срок «в срок до» и фонд списания в СЗ 2010 + инвариант механики оплаты — пайщику только аванс под отчёт, организации только прямая оплата (форма/бэкенд/контракт); фикс 422 на пустом recipient организации
Typecheck / desktop (pull_request) Failing after 8m28s
Typecheck / controller (pull_request) Failing after 8m1s

This commit is contained in:
coopops
2026-06-11 20:28:35 +00:00
parent dfe73601e8
commit 61038a6f8c
15 changed files with 187 additions and 18 deletions
@@ -91,6 +91,22 @@ void expense::createexp(name coopname, name username,
"Неизвестная mechanics item (0 = ADVANCE, 1 = DIRECT)");
eosio::check(it.recipient_type <= static_cast<uint8_t>(D::RecipientType::ORG),
"Неизвестный recipient_type item");
// Инвариант: пайщик (SELF/MEMBER) получает только аванс под отчёт на личные
// реквизиты (расходом станет после его отчёта чеком); организация — только
// прямую оплату по выставленным реквизитам, аванс ей не выдаётся.
if (it.recipient_type == static_cast<uint8_t>(D::RecipientType::ORG)) {
eosio::check(it.mechanics == static_cast<uint8_t>(D::Mechanics::DIRECT),
"Организации доступна только прямая оплата (DIRECT)");
} else {
eosio::check(it.mechanics == static_cast<uint8_t>(D::Mechanics::ADVANCE),
"Пайщику средства выдаются только авансом под отчёт (ADVANCE)");
eosio::check(it.recipient != name(),
"recipient обязателен для получателя-пайщика");
eosio::check(is_account(it.recipient),
"Аккаунт получателя-пайщика не существует");
}
it.status = static_cast<uint8_t>(D::ItemStatus::APPROVED);
it.actual_amount = zero_like(it.planned_amount);
}
@@ -77,6 +77,19 @@ class ExpenseProposalHeaderInputDTO implements HeaderAction {
@Field({ description: 'Кошелёк-источник' })
@IsString()
source_wallet!: string;
@Field({ description: 'Срок исполнения («в срок до»), формат DD.MM.YYYY', nullable: true })
@IsOptional()
@IsString()
deadline?: string;
@Field({
description: 'Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно',
nullable: true,
})
@IsOptional()
@IsString()
fund_name?: string;
}
@InputType('BaseExpenseProposalStatementMetaDocumentInput')
@@ -58,6 +58,7 @@ export class ProgramExpensesManagementService {
itemHash: it.item_hash,
recipient: it.recipient,
isOrganization: it.recipient_type === ExpenseRecipientType.ORG,
mechanics: it.mechanics === ExpenseMechanics.DIRECT ? 'DIRECT' : 'ADVANCE',
paymentMethodId: it.payment_method_id,
requisites: it.requisites,
}));
@@ -1,5 +1,5 @@
import { Field, InputType } from '@nestjs/graphql';
import { IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { IsEnum, IsNotEmpty, IsOptional, IsString, ValidateIf } from 'class-validator';
import { ExpenseMechanics } from '../../domain/enums/expense-mechanics.enum';
import { ExpenseRecipientType } from '../../domain/enums/expense-recipient-type.enum';
@@ -18,7 +18,10 @@ export class ExpenseItemInputDTO {
@IsEnum(ExpenseRecipientType)
recipient_type!: ExpenseRecipientType;
@Field(() => String, { description: 'Получатель (username / eosio::name организации).' })
@Field(() => String, {
description: 'Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет).',
})
@ValidateIf((o) => o.recipient_type !== ExpenseRecipientType.ORG)
@IsNotEmpty()
@IsString()
recipient!: string;
@@ -55,6 +55,20 @@ export class ExpenseRequisiteSnapshotsService {
): Promise<ExpenseRequisiteSnapshotTypeormEntity[]> {
return Promise.all(
items.map(async (it) => {
// Инвариант шасси: пайщику — только аванс под отчёт (средства на личные
// реквизиты, расходом станут после отчёта чеком); организации — только
// прямая оплата по выставленным реквизитам.
if (it.isOrganization && it.mechanics !== 'DIRECT') {
throw new BadRequestException(
'Организации доступна только прямая оплата по реквизитам (DIRECT) — аванс под отчёт ей не выдаётся'
)
}
if (!it.isOrganization && it.mechanics !== 'ADVANCE') {
throw new BadRequestException(
`Пайщику ${it.recipient} средства передаются только авансом под отчёт (ADVANCE) — прямая оплата доступна только организации`
)
}
const snapshot = this.repository.create({
coopname,
proposal_hash: it.proposalHash.toLowerCase(),
@@ -19,6 +19,7 @@ import {
} from '../../domain/interfaces/expenses-blockchain.port'
import { ExpenseMechanics } from '../../domain/enums/expense-mechanics.enum'
import { ExpenseRecipientType } from '../../domain/enums/expense-recipient-type.enum'
import { EXPENSES_CHASSIS_CONFIG } from '../../domain/expenses-chassis.config'
import { ExpenseRequisiteSnapshotsService } from './expense-requisite-snapshots.service'
/**
@@ -44,6 +45,9 @@ export class ExpensesMutationsService {
): Promise<DocumentDomainEntity> {
data.registry_id = Cooperative.Registry.ExpenseProposalStatement.registry_id
// Фонд списания — параметр шасси, фронт его не передаёт
data.proposal = { ...data.proposal, fund_name: EXPENSES_CHASSIS_CONFIG.fundNameDative }
// Полные реквизиты получателей подставляет сервер: фронт оперирует только
// идентификатором платёжного метода (и видит лишь сокращённое представление).
// Служебные поля (payment_method_id / recipient_username) в meta документа
@@ -177,6 +181,7 @@ function toRequisiteItems(proposalHash: string, items: ExpenseItemInputDTO[]): I
itemHash: it.item_hash,
recipient: it.recipient,
isOrganization: it.recipient_type === ExpenseRecipientType.ORG,
mechanics: it.mechanics === ExpenseMechanics.DIRECT ? 'DIRECT' : 'ADVANCE',
paymentMethodId: it.payment_method_id,
requisites: it.requisites,
}))
@@ -0,0 +1,12 @@
/**
* Параметры шасси расходов.
*
* `fundNameDative` — фонд, по которому совет согласует списание затрат
* (строка в служебной записке 2010: «списание затрат по …»). Хранится
* в дательном падеже, т.к. подставляется после предлога «по». Дефолт —
* фонд хозяйственной деятельности; другой фонд (развития кооперации,
* материальной помощи и т.п.) задаётся через env EXPENSES_FUND_NAME.
*/
export const EXPENSES_CHASSIS_CONFIG = {
fundNameDative: process.env.EXPENSES_FUND_NAME ?? 'Фонду хозяйственной деятельности',
};
+21 -5
View File
@@ -5284,7 +5284,7 @@ export type ValueTypes = {
payment_method_id?: string | undefined | null | Variable<any, string>,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string | Variable<any, string>,
/** Получатель (username / eosio::name организации). */
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
recipient: string | Variable<any, string>,
/** Тип получателя. */
recipient_type: ValueTypes["ExpenseRecipientType"] | Variable<any, string>,
@@ -5394,8 +5394,12 @@ export type ValueTypes = {
requisites?: string | undefined | null | Variable<any, string>
};
["ExpenseProposalHeaderInput"]: {
/** Срок исполнения («в срок до»), формат DD.MM.YYYY */
deadline?: string | undefined | null | Variable<any, string>,
/** Описание цели расходов */
description: string | Variable<any, string>,
/** Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно */
fund_name?: string | undefined | null | Variable<any, string>,
/** Количество позиций */
items_count: number | Variable<any, string>,
/** Кошелёк-источник */
@@ -14310,7 +14314,7 @@ export type ResolverInputTypes = {
payment_method_id?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель (username / eosio::name организации). */
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
recipient: string,
/** Тип получателя. */
recipient_type: ResolverInputTypes["ExpenseRecipientType"],
@@ -14419,8 +14423,12 @@ export type ResolverInputTypes = {
requisites?: string | undefined | null
};
["ExpenseProposalHeaderInput"]: {
/** Срок исполнения («в срок до»), формат DD.MM.YYYY */
deadline?: string | undefined | null,
/** Описание цели расходов */
description: string,
/** Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно */
fund_name?: string | undefined | null,
/** Количество позиций */
items_count: number,
/** Кошелёк-источник */
@@ -23077,7 +23085,7 @@ export type ModelTypes = {
payment_method_id?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель (username / eosio::name организации). */
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
recipient: string,
/** Тип получателя. */
recipient_type: ModelTypes["ExpenseRecipientType"],
@@ -23183,8 +23191,12 @@ export type ModelTypes = {
requisites?: string | undefined | null
};
["ExpenseProposalHeaderInput"]: {
/** Срок исполнения («в срок до»), формат DD.MM.YYYY */
deadline?: string | undefined | null,
/** Описание цели расходов */
description: string,
/** Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно */
fund_name?: string | undefined | null,
/** Количество позиций */
items_count: number,
/** Кошелёк-источник */
@@ -32631,7 +32643,7 @@ export type GraphQLTypes = {
payment_method_id?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель (username / eosio::name организации). */
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
recipient: string,
/** Тип получателя. */
recipient_type: GraphQLTypes["ExpenseRecipientType"],
@@ -32741,8 +32753,12 @@ export type GraphQLTypes = {
requisites?: string | undefined | null
};
["ExpenseProposalHeaderInput"]: {
/** Описание цели расходов */
/** Срок исполнения («в срок до»), формат DD.MM.YYYY */
deadline?: string | undefined | null,
/** Описание цели расходов */
description: string,
/** Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно */
fund_name?: string | undefined | null,
/** Количество позиций */
items_count: number,
/** Кошелёк-источник */
@@ -21,6 +21,10 @@ export interface IExpenseProposalHeader {
total_amount: string
items_count: number
source_wallet: string
/** Срок исполнения («в срок до»), формат DD.MM.YYYY — передаётся при создании расхода */
deadline?: string
/** Фонд списания в дательном падеже («по …») — подставляет сервер из параметров шасси расходов */
fund_name?: string
}
export interface Action extends IGenerate {
@@ -48,7 +52,7 @@ export const description = 'Заявка-смета председателю к
// дата слева, центрированный заголовок с идентификатором (= proposal_hash,
// по нему записку можно найти), позиции — нумерованным списком с полными
// реквизитами получателей. Кошелёк-источник в документе не указывается.
export const context = `<style>h1{margin:0;text-align:center;}.digital-document{padding:20px;}.doc-header{text-align:right;padding-bottom:25px;}.doc-header p{margin:2px 0;}.doc-id{text-align:center;font-size:12px;word-break:break-all;padding-top:6px;padding-bottom:25px;}ol.items{padding-left:25px;margin:10px 0;}ol.items li{padding-bottom:10px;}.signature{padding-top:40px;}</style><div class="digital-document"><div class="doc-header"><p>{% trans 'TO_COUNCIL' %} {{vars.full_abbr_genitive}} «{{vars.name}}»</p><p>{% trans 'FROM_MEMBER' %} {{ user.full_name_or_short_name }}</p></div><p>{% trans 'DATE' %}: {{ meta.created_at }}</p><h1 style="padding-top:25px;">{% trans 'PROPOSAL_TITLE' %}</h1><p class="doc-id">№ {{ proposal_hash }}</p><p>{% trans 'BODY_INTRO' %} {{ proposal.total_amount }}, {% trans 'BODY_NAMELY' %}:</p><ol class="items">{% for item in items %}<li>{{ item.description }} — {{ item.amount }} ({% if item.mechanics == 'ADVANCE' %}{% trans 'MECH_ADVANCE' %}{% else %}{% trans 'MECH_DIRECT' %}{% endif %}). {% trans 'ITEM_RECIPIENT' %}: {% if item.recipient_type == 'SELF' %}{{ user.full_name_or_short_name }}{% else %}{{ item.recipient_name }}{% endif %}{% if item.requisites %}. {% trans 'ITEM_REQUISITES' %}: {{ item.requisites }}{% endif %}</li>{% endfor %}</ol><p>{% trans 'PURPOSE' %}: {{ proposal.description }}</p><div class="signature"><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'SIGNED_DIGITALLY' %}</p></div></div>`
export const context = `<style>h1{margin:0;text-align:center;}.digital-document{padding:20px;}.doc-header{text-align:right;padding-bottom:25px;}.doc-header p{margin:2px 0;}.doc-id{text-align:center;font-size:12px;word-break:break-all;padding-top:6px;padding-bottom:25px;}ol.items{padding-left:25px;margin:10px 0;}ol.items li{padding-bottom:10px;}.signature{padding-top:40px;}</style><div class="digital-document"><div class="doc-header"><p>{% trans 'TO_COUNCIL' %} {{vars.full_abbr_genitive}} «{{vars.name}}»</p><p>{% trans 'FROM_MEMBER' %} {{ user.full_name_or_short_name }}</p></div><p>{% trans 'DATE' %}: {{ meta.created_at }}</p><h1 style="padding-top:25px;">{% trans 'PROPOSAL_TITLE' %}</h1><p class="doc-id">№ {{ proposal_hash }}</p><p>{% trans 'BODY_INTRO' %}{% if proposal.fund_name %} {% trans 'BY_FUND' %} {{ proposal.fund_name }}{% endif %} {% trans 'IN_TOTAL' %} {{ proposal.total_amount }}{% if proposal.deadline %} {% trans 'DUE_BY' %} {{ proposal.deadline }}{% endif %}, {% trans 'BODY_NAMELY' %}:</p><ol class="items">{% for item in items %}<li>{{ item.description }} — {{ item.amount }} ({% if item.mechanics == 'ADVANCE' %}{% trans 'MECH_ADVANCE' %}{% else %}{% trans 'MECH_DIRECT' %}{% endif %}). {% trans 'ITEM_RECIPIENT' %}: {% if item.recipient_type == 'SELF' %}{{ user.full_name_or_short_name }}{% else %}{{ item.recipient_name }}{% endif %}{% if item.requisites %}. {% trans 'ITEM_REQUISITES' %}: {{ item.requisites }}{% endif %}</li>{% endfor %}</ol><p>{% trans 'PURPOSE' %}: {{ proposal.description }}</p><div class="signature"><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'SIGNED_DIGITALLY' %}</p></div></div>`
export const translations = {
ru: {
@@ -56,7 +60,10 @@ export const translations = {
FROM_MEMBER: 'от пайщика',
DATE: 'Дата',
PROPOSAL_TITLE: 'СЛУЖЕБНАЯ ЗАПИСКА',
BODY_INTRO: 'Прошу согласовать списание затрат в общей сумме',
BODY_INTRO: 'Прошу согласовать списание затрат',
BY_FUND: 'по',
IN_TOTAL: 'в общей сумме',
DUE_BY: 'в срок до',
BODY_NAMELY: 'а именно',
MECH_ADVANCE: 'аванс под отчёт',
MECH_DIRECT: 'прямая оплата',
@@ -78,6 +85,8 @@ export const exampleData = {
total_amount: '15000.00 RUB',
items_count: 2,
source_wallet: 'w.cap.bla',
deadline: '30.06.2026',
fund_name: 'Фонду хозяйственной деятельности',
},
items: [
{
@@ -27,6 +27,8 @@ export interface ICreateProgramExpenseDraftItem {
export interface ICreateProgramExpenseDraft {
description: string;
/** Срок исполнения («в срок до»), значение date-input `YYYY-MM-DD`. */
deadline: string;
items: ICreateProgramExpenseDraftItem[];
}
@@ -91,6 +93,7 @@ export function useCreateProgramExpense() {
total_amount,
items_count: draft.items.length,
source_wallet: PROGRAM_EXPENSE_SOURCE_WALLET,
deadline: formatDeadline(draft.deadline),
},
items: itemsForDoc,
};
@@ -134,3 +137,9 @@ export function useCreateProgramExpense() {
function generateItemHash(expense_hash: string, idx: number): string {
return `${expense_hash.slice(0, 56)}${idx.toString(16).padStart(8, '0')}`;
}
/** `YYYY-MM-DD` (date-input) → `DD.MM.YYYY` (документ). */
function formatDeadline(value: string): string {
const [year, month, day] = value.split('-');
return `${day}.${month}.${year}`;
}
@@ -14,6 +14,12 @@ BaseDialog(
placeholder='Например: «Закупка хостинга и канцелярии на июнь»',
required
)
BaseInput(
v-model='form.deadline',
type='date',
label='Срок исполнения (в срок до)',
required
)
.field-group
.field-group__head
@@ -44,14 +50,15 @@ BaseDialog(
v-model='item.recipient_type',
:options='recipientTypeOptions',
label='Тип получателя',
@update:model-value='item.payment_method_id = null'
@update:model-value='onRecipientTypeChange(item)'
)
.col-12.col-md-6
BaseSelect(
v-model='item.mechanics',
:options='mechanicsOptions',
label='Способ оплаты',
hint='Аванс — под отчёт получателю; прямая — оплата по реквизитам'
disabled,
hint='Пайщику — только аванс под отчёт; организации — только прямая оплата'
)
.col-12.col-md-6(v-if='item.recipient_type === Zeus.ExpenseRecipientType.MEMBER')
BaseInput(
@@ -148,6 +155,7 @@ const amountPlaceholder = computed(() => {
const form = reactive({
description: '',
deadline: '',
items: [] as ICreateProgramExpenseDraftItem[],
});
@@ -164,9 +172,23 @@ const recipientTypeOptions = [
{ label: 'Организация', value: Zeus.ExpenseRecipientType.ORG },
];
// Пайщик получает только аванс под отчёт (личные реквизиты, отчитается чеком);
// организация — только прямую оплату по выставленным реквизитам.
function mechanicsFor(recipientType: Zeus.ExpenseRecipientType): Zeus.ExpenseMechanics {
return recipientType === Zeus.ExpenseRecipientType.ORG
? Zeus.ExpenseMechanics.DIRECT
: Zeus.ExpenseMechanics.ADVANCE;
}
function onRecipientTypeChange(item: ICreateProgramExpenseDraftItem): void {
item.payment_method_id = null;
item.mechanics = mechanicsFor(item.recipient_type);
}
const canSubmit = computed(
() =>
form.description.trim().length > 0 &&
form.deadline.trim().length > 0 &&
form.items.length > 0 &&
form.items.every(
(i) =>
@@ -206,6 +228,7 @@ async function submit(): Promise<void> {
submitting.value = true;
await submitProgramExpense({
description: form.description,
deadline: form.deadline,
items: form.items,
});
SuccessAlert('Программный расход подан — заявление подписано и передано в шасси расходов');
@@ -23,6 +23,8 @@ export interface ICreateProposalDraftItem {
export interface ICreateProposalDraft {
source_wallet: string;
description: string;
/** Срок исполнения («в срок до»), значение date-input `YYYY-MM-DD`. */
deadline: string;
items: ICreateProposalDraftItem[];
}
@@ -51,6 +53,7 @@ export function useExpenseProposalActions() {
total_amount,
items_count: draft.items.length,
source_wallet: draft.source_wallet,
deadline: formatDeadline(draft.deadline),
};
const generated = await generateExpenseProposalStatementDocument({
@@ -95,3 +98,9 @@ export function useExpenseProposalActions() {
function generateItemHash(proposal_hash: string, idx: number): string {
return `${proposal_hash.slice(0, 56)}${idx.toString(16).padStart(8, '0')}`;
}
/** `YYYY-MM-DD` (date-input) → `DD.MM.YYYY` (документ). */
function formatDeadline(value: string): string {
const [year, month, day] = value.split('-');
return `${day}.${month}.${year}`;
}
@@ -20,6 +20,12 @@ BaseDialog(
placeholder='w.cap.blago / w.cap.gen / …',
required
)
BaseInput(
v-model='form.deadline',
type='date',
label='Срок исполнения (в срок до)',
required
)
.field-group
.field-group__head
@@ -58,7 +64,8 @@ BaseDialog(
outlined,
dense,
emit-value,
map-options
map-options,
@update:model-value='onRecipientTypeChange(item)'
)
.col-12.col-md-6
q-select(
@@ -68,7 +75,9 @@ BaseDialog(
outlined,
dense,
emit-value,
map-options
map-options,
disable,
hint='Пайщику — только аванс под отчёт; организации — только прямая оплата'
)
.col-12.col-md-6
BaseInput(
@@ -133,6 +142,7 @@ const { submitProposal } = useExpenseProposalActions();
const form = reactive({
description: '',
source_wallet: 'w.cap.blago',
deadline: '',
items: [] as ICreateProposalDraftItem[],
});
@@ -149,10 +159,16 @@ const mechanicsOptions = [
{ label: 'Прямая оплата', value: 'DIRECT' as const },
];
// Пайщик получает только аванс под отчёт; организация — только прямую оплату.
function onRecipientTypeChange(item: ICreateProposalDraftItem): void {
item.mechanics = item.recipient_type === 'ORG' ? 'DIRECT' : 'ADVANCE';
}
const canSubmit = computed(
() =>
form.description.trim().length > 0 &&
form.source_wallet.trim().length > 0 &&
form.deadline.trim().length > 0 &&
form.items.length > 0 &&
form.items.every((i) => i.amount.trim() && i.description.trim()),
);
@@ -184,6 +200,7 @@ async function submit(): Promise<void> {
await submitProposal({
description: form.description,
source_wallet: form.source_wallet,
deadline: form.deadline,
items: form.items,
});
SuccessAlert('Служебная записка подана — заявление подписано и отправлено в блокчейн');
@@ -90,6 +90,12 @@ export interface InterExpenseRequisiteItemInput {
recipient: string;
/** true — получатель-организация: реквизиты приходят строкой `requisites`. */
isOrganization: boolean;
/**
* Способ оплаты строки. Инвариант шасси: пайщик (SELF/MEMBER) получает только
* ADVANCE (аванс под отчёт на личные реквизиты, расходом станет после отчёта
* чеком), организация — только DIRECT (прямая оплата по выставленным реквизитам).
*/
mechanics: 'ADVANCE' | 'DIRECT';
/** Идентификатор платёжного метода получателя-пайщика. */
paymentMethodId?: string;
/** Реквизиты строкой (организации — ручной ввод из формы). */
+21 -5
View File
@@ -5284,7 +5284,7 @@ export type ValueTypes = {
payment_method_id?: string | undefined | null | Variable<any, string>,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string | Variable<any, string>,
/** Получатель (username / eosio::name организации). */
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
recipient: string | Variable<any, string>,
/** Тип получателя. */
recipient_type: ValueTypes["ExpenseRecipientType"] | Variable<any, string>,
@@ -5394,8 +5394,12 @@ export type ValueTypes = {
requisites?: string | undefined | null | Variable<any, string>
};
["ExpenseProposalHeaderInput"]: {
/** Срок исполнения («в срок до»), формат DD.MM.YYYY */
deadline?: string | undefined | null | Variable<any, string>,
/** Описание цели расходов */
description: string | Variable<any, string>,
/** Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно */
fund_name?: string | undefined | null | Variable<any, string>,
/** Количество позиций */
items_count: number | Variable<any, string>,
/** Кошелёк-источник */
@@ -14310,7 +14314,7 @@ export type ResolverInputTypes = {
payment_method_id?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель (username / eosio::name организации). */
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
recipient: string,
/** Тип получателя. */
recipient_type: ResolverInputTypes["ExpenseRecipientType"],
@@ -14419,8 +14423,12 @@ export type ResolverInputTypes = {
requisites?: string | undefined | null
};
["ExpenseProposalHeaderInput"]: {
/** Срок исполнения («в срок до»), формат DD.MM.YYYY */
deadline?: string | undefined | null,
/** Описание цели расходов */
description: string,
/** Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно */
fund_name?: string | undefined | null,
/** Количество позиций */
items_count: number,
/** Кошелёк-источник */
@@ -23077,7 +23085,7 @@ export type ModelTypes = {
payment_method_id?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель (username / eosio::name организации). */
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
recipient: string,
/** Тип получателя. */
recipient_type: ModelTypes["ExpenseRecipientType"],
@@ -23183,8 +23191,12 @@ export type ModelTypes = {
requisites?: string | undefined | null
};
["ExpenseProposalHeaderInput"]: {
/** Срок исполнения («в срок до»), формат DD.MM.YYYY */
deadline?: string | undefined | null,
/** Описание цели расходов */
description: string,
/** Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно */
fund_name?: string | undefined | null,
/** Количество позиций */
items_count: number,
/** Кошелёк-источник */
@@ -32631,7 +32643,7 @@ export type GraphQLTypes = {
payment_method_id?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель (username / eosio::name организации). */
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
recipient: string,
/** Тип получателя. */
recipient_type: GraphQLTypes["ExpenseRecipientType"],
@@ -32741,8 +32753,12 @@ export type GraphQLTypes = {
requisites?: string | undefined | null
};
["ExpenseProposalHeaderInput"]: {
/** Описание цели расходов */
/** Срок исполнения («в срок до»), формат DD.MM.YYYY */
deadline?: string | undefined | null,
/** Описание цели расходов */
description: string,
/** Фонд списания — подставляется сервером из параметров шасси расходов, передавать не нужно */
fund_name?: string | undefined | null,
/** Количество позиций */
items_count: number,
/** Кошелёк-источник */