[C28-33][@ant] feat: СЗ 2010 по канону вёрстки реестра + назначение платежа отдельным полем после реквизитов — фиксируется в снимке для кассира; «оплата по счету», «Организация/ИП», алерт «передано в совет», хинт механики убран
Typecheck / desktop (pull_request) Failing after 8m25s
Typecheck / controller (pull_request) Failing after 7m57s

This commit is contained in:
coopops
2026-06-12 06:07:44 +00:00
parent 61038a6f8c
commit c8a15511ee
16 changed files with 110 additions and 29 deletions
+1 -1
View File
@@ -97,7 +97,7 @@ void expense::createexp(name coopname, name username,
// прямую оплату по выставленным реквизитам, аванс ей не выдаётся.
if (it.recipient_type == static_cast<uint8_t>(D::RecipientType::ORG)) {
eosio::check(it.mechanics == static_cast<uint8_t>(D::Mechanics::DIRECT),
"Организации доступна только прямая оплата (DIRECT)");
"Организации/ИП доступна только оплата по счёту (DIRECT)");
} else {
eosio::check(it.mechanics == static_cast<uint8_t>(D::Mechanics::ADVANCE),
"Пайщику средства выдаются только авансом под отчёт (ADVANCE)");
@@ -42,6 +42,11 @@ class ExpenseProposalItemInputDTO implements ItemAction {
@IsString()
requisites?: string;
@Field({ description: 'Назначение платежа — отдельной строкой после реквизитов', nullable: true })
@IsOptional()
@IsString()
payment_purpose?: string;
@Field({
description:
'Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ.',
@@ -27,7 +27,7 @@ export class CreateProgramExpenseInputDTO {
@IsString()
creator!: string;
@Field(() => [ExpenseItemInputDTO], { description: 'Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно.' })
@Field(() => [ExpenseItemInputDTO], { description: 'Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно.' })
@IsArray()
@ArrayMinSize(1)
@ValidateNested({ each: true })
@@ -61,6 +61,7 @@ export class ProgramExpensesManagementService {
mechanics: it.mechanics === ExpenseMechanics.DIRECT ? 'DIRECT' : 'ADVANCE',
paymentMethodId: it.payment_method_id,
requisites: it.requisites,
paymentPurpose: it.payment_purpose,
}));
await this.expenseChassis.validateRequisites(data.coopname, requisiteItems);
@@ -51,4 +51,12 @@ export class ExpenseItemInputDTO {
@IsOptional()
@IsString()
requisites?: string;
@Field(() => String, {
nullable: true,
description: 'Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира.',
})
@IsOptional()
@IsString()
payment_purpose?: string;
}
@@ -60,12 +60,12 @@ export class ExpenseRequisiteSnapshotsService {
// прямая оплата по выставленным реквизитам.
if (it.isOrganization && it.mechanics !== 'DIRECT') {
throw new BadRequestException(
'Организации доступна только прямая оплата по реквизитам (DIRECT) — аванс под отчёт ей не выдаётся'
'Организации/ИП доступна только оплата по счёту (DIRECT) — аванс под отчёт ей не выдаётся'
)
}
if (!it.isOrganization && it.mechanics !== 'ADVANCE') {
throw new BadRequestException(
`Пайщику ${it.recipient} средства передаются только авансом под отчёт (ADVANCE) — прямая оплата доступна только организации`
`Пайщику ${it.recipient} средства передаются только авансом под отчёт (ADVANCE) — оплата по счёту доступна только организации/ИП`
)
}
@@ -78,6 +78,7 @@ export class ExpenseRequisiteSnapshotsService {
method_type: null,
data: null,
requisites: it.requisites ?? '',
payment_purpose: it.paymentPurpose ?? null,
})
if (it.isOrganization) {
@@ -67,6 +67,7 @@ export class ExpensesMutationsService {
mechanics: item.mechanics,
recipient_name: item.recipient_name,
requisites,
payment_purpose: item.payment_purpose,
}
})
)
@@ -184,5 +185,6 @@ function toRequisiteItems(proposalHash: string, items: ExpenseItemInputDTO[]): I
mechanics: it.mechanics === ExpenseMechanics.DIRECT ? 'DIRECT' : 'ADVANCE',
paymentMethodId: it.payment_method_id,
requisites: it.requisites,
paymentPurpose: it.payment_purpose,
}))
}
@@ -43,6 +43,9 @@ export class ExpenseRequisiteSnapshotTypeormEntity {
@Column({ type: 'text', comment: 'Реквизиты строкой — как в документе СЗ' })
requisites!: string;
@Column({ type: 'text', nullable: true, comment: 'Назначение платежа (оплата по счёту) — для поручения кассиру' })
payment_purpose!: string | null;
@CreateDateColumn()
created_at!: Date;
}
+20 -4
View File
@@ -2644,7 +2644,7 @@ export type ValueTypes = {
description: string | Variable<any, string>,
/** Хэш СЗ-расхода (детерминированный, из UI). Он же станет proposal_hash в шасси. */
expense_hash: string | Variable<any, string>,
/** Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно. */
/** Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно. */
items: Array<ValueTypes["ExpenseItemInput"]> | Variable<any, string>,
/** Подписанная СЗ-смета (document2, registry 2010). */
statement: ValueTypes["ExpenseProposalStatementSignedDocumentInput"] | Variable<any, string>
@@ -5282,6 +5282,8 @@ export type ValueTypes = {
mechanics: ValueTypes["ExpenseMechanics"] | Variable<any, string>,
/** Идентификатор сохранённых реквизитов получателя-пайщика — реквизиты снимаются в момент создания и прикладываются к платежу. */
payment_method_id?: string | undefined | null | Variable<any, string>,
/** Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира. */
payment_purpose?: string | undefined | null | Variable<any, string>,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string | Variable<any, string>,
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
@@ -5418,6 +5420,8 @@ export type ValueTypes = {
number: string | Variable<any, string>,
/** Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ. */
payment_method_id?: string | undefined | null | Variable<any, string>,
/** Назначение платежа — отдельной строкой после реквизитов */
payment_purpose?: string | undefined | null | Variable<any, string>,
/** Имя получателя */
recipient_name?: string | undefined | null | Variable<any, string>,
/** Тип получателя (SELF / MEMBER / ORG) */
@@ -11737,7 +11741,7 @@ export type ResolverInputTypes = {
description: string,
/** Хэш СЗ-расхода (детерминированный, из UI). Он же станет proposal_hash в шасси. */
expense_hash: string,
/** Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно. */
/** Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно. */
items: Array<ResolverInputTypes["ExpenseItemInput"]>,
/** Подписанная СЗ-смета (document2, registry 2010). */
statement: ResolverInputTypes["ExpenseProposalStatementSignedDocumentInput"]
@@ -14312,6 +14316,8 @@ export type ResolverInputTypes = {
mechanics: ResolverInputTypes["ExpenseMechanics"],
/** Идентификатор сохранённых реквизитов получателя-пайщика — реквизиты снимаются в момент создания и прикладываются к платежу. */
payment_method_id?: string | undefined | null,
/** Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира. */
payment_purpose?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
@@ -14447,6 +14453,8 @@ export type ResolverInputTypes = {
number: string,
/** Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ. */
payment_method_id?: string | undefined | null,
/** Назначение платежа — отдельной строкой после реквизитов */
payment_purpose?: string | undefined | null,
/** Имя получателя */
recipient_name?: string | undefined | null,
/** Тип получателя (SELF / MEMBER / ORG) */
@@ -20579,7 +20587,7 @@ export type ModelTypes = {
description: string,
/** Хэш СЗ-расхода (детерминированный, из UI). Он же станет proposal_hash в шасси. */
expense_hash: string,
/** Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно. */
/** Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно. */
items: Array<ModelTypes["ExpenseItemInput"]>,
/** Подписанная СЗ-смета (document2, registry 2010). */
statement: ModelTypes["ExpenseProposalStatementSignedDocumentInput"]
@@ -23083,6 +23091,8 @@ export type ModelTypes = {
mechanics: ModelTypes["ExpenseMechanics"],
/** Идентификатор сохранённых реквизитов получателя-пайщика — реквизиты снимаются в момент создания и прикладываются к платежу. */
payment_method_id?: string | undefined | null,
/** Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира. */
payment_purpose?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
@@ -23215,6 +23225,8 @@ export type ModelTypes = {
number: string,
/** Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ. */
payment_method_id?: string | undefined | null,
/** Назначение платежа — отдельной строкой после реквизитов */
payment_purpose?: string | undefined | null,
/** Имя получателя */
recipient_name?: string | undefined | null,
/** Тип получателя (SELF / MEMBER / ORG) */
@@ -30003,7 +30015,7 @@ export type GraphQLTypes = {
description: string,
/** Хэш СЗ-расхода (детерминированный, из UI). Он же станет proposal_hash в шасси. */
expense_hash: string,
/** Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно. */
/** Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно. */
items: Array<GraphQLTypes["ExpenseItemInput"]>,
/** Подписанная СЗ-смета (document2, registry 2010). */
statement: GraphQLTypes["ExpenseProposalStatementSignedDocumentInput"]
@@ -32641,6 +32653,8 @@ export type GraphQLTypes = {
mechanics: GraphQLTypes["ExpenseMechanics"],
/** Идентификатор сохранённых реквизитов получателя-пайщика — реквизиты снимаются в момент создания и прикладываются к платежу. */
payment_method_id?: string | undefined | null,
/** Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира. */
payment_purpose?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
@@ -32777,6 +32791,8 @@ export type GraphQLTypes = {
number: string,
/** Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ. */
payment_method_id?: string | undefined | null,
/** Назначение платежа — отдельной строкой после реквизитов */
payment_purpose?: string | undefined | null,
/** Имя получателя */
recipient_name?: string | undefined | null,
/** Тип получателя (SELF / MEMBER / ORG) */
@@ -14,6 +14,8 @@ export interface IExpenseItem {
mechanics: ExpenseItemPaymentMechanics
recipient_name?: string
requisites?: string
/** Назначение платежа — отдельной строкой после реквизитов (для оплаты по счёту) */
payment_purpose?: string
}
export interface IExpenseProposalHeader {
@@ -48,11 +50,13 @@ export interface Model {
export const title = 'Служебная записка-смета о расходах'
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' %}{% 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>`
// Вёрстка по канону документов реестра (см. 1040): без <style>-блока — превью
// его не применяет; только inline text-align на div-обёртках. Шапка-адресат
// справа, центрированный заголовок с идентификатором (= proposal_hash, по нему
// записку можно найти), позиции — нумерованным списком: описание и сумма,
// затем построчно получатель, реквизиты и назначение платежа (для кассира).
// Кошелёк-источник в документе не указывается.
export const context = `<div class="digital-document"><div style="text-align: right"><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><div style="text-align: center"><h2>{% trans 'PROPOSAL_TITLE' %}</h2><p style="word-break: break-all">№ {{ proposal_hash }}</p></div><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>{% for item in items %}<li><p>{{ item.description }} — {{ item.amount }} ({% if item.mechanics == 'ADVANCE' %}{% trans 'MECH_ADVANCE' %}{% else %}{% trans 'MECH_DIRECT' %}{% endif %})</p><p>{% trans 'ITEM_RECIPIENT' %}: {% if item.recipient_type == 'SELF' %}{{ user.full_name_or_short_name }}{% else %}{{ item.recipient_name }}{% endif %}</p>{% if item.requisites %}<p>{% trans 'ITEM_REQUISITES' %}: {{ item.requisites }}</p>{% endif %}{% if item.payment_purpose %}<p>{% trans 'ITEM_PAYMENT_PURPOSE' %}: {{ item.payment_purpose }}</p>{% endif %}</li>{% endfor %}</ol><p>{% trans 'PURPOSE' %}: {{ proposal.description }}</p><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'SIGNED_DIGITALLY' %}</p></div>`
export const translations = {
ru: {
@@ -66,9 +70,10 @@ export const translations = {
DUE_BY: 'в срок до',
BODY_NAMELY: 'а именно',
MECH_ADVANCE: 'аванс под отчёт',
MECH_DIRECT: 'прямая оплата',
MECH_DIRECT: 'оплата по счёту',
ITEM_RECIPIENT: 'Получатель',
ITEM_REQUISITES: 'Реквизиты',
ITEM_PAYMENT_PURPOSE: 'Назначение платежа',
PURPOSE: 'Цель расходов',
SIGNED_DIGITALLY: 'подписано электронной подписью',
},
@@ -97,6 +102,7 @@ export const exampleData = {
mechanics: 'DIRECT',
recipient_name: 'ООО «Яндекс.Облако»',
requisites: 'ИНН 7704414297, р/с 40702810000000000000, БИК 044525000',
payment_purpose: 'Оплата по счёту № 814 от 01.06.2026 за аренду серверов',
},
{
number: '2',
@@ -19,6 +19,8 @@ export interface ICreateProgramExpenseDraftItem {
recipient_type: Zeus.ExpenseRecipientType;
recipient_name?: string;
requisites?: string;
/** Назначение платежа (оплата по счёту организации/ИП). */
payment_purpose?: string;
recipient_account?: string;
item_hash?: string;
/** Идентификатор платёжного метода получателя-пайщика (SELF/MEMBER). */
@@ -77,6 +79,7 @@ export function useCreateProgramExpense() {
mechanics: it.mechanics,
recipient_name: it.recipient_name ?? '',
requisites: it.requisites ?? '',
payment_purpose: it.payment_purpose || undefined,
payment_method_id: it.payment_method_id ?? undefined,
recipient_username:
it.recipient_type === Zeus.ExpenseRecipientType.MEMBER
@@ -116,6 +119,7 @@ export function useCreateProgramExpense() {
planned_amount: formatToAsset(it.amount, symbol, precision),
payment_method_id: it.payment_method_id ?? undefined,
requisites: it.requisites || undefined,
payment_purpose: it.payment_purpose || undefined,
}));
const result = await createProgramExpense({
@@ -57,8 +57,7 @@ BaseDialog(
v-model='item.mechanics',
:options='mechanicsOptions',
label='Способ оплаты',
disabled,
hint='Пайщику — только аванс под отчёт; организации — только прямая оплата'
disabled
)
.col-12.col-md-6(v-if='item.recipient_type === Zeus.ExpenseRecipientType.MEMBER')
BaseInput(
@@ -109,6 +108,13 @@ BaseDialog(
placeholder='ИНН, р/с, БИК',
required
)
.col-12(v-if='item.recipient_type === Zeus.ExpenseRecipientType.ORG')
BaseInput(
v-model='item.payment_purpose',
label='Назначение платежа',
placeholder='Например: «Оплата по счёту № 814 от 01.06.2026 за аренду серверов»',
required
)
template(#footer)
.footer-bar
@@ -163,13 +169,13 @@ const submitting = ref(false);
const mechanicsOptions = [
{ label: 'Аванс под отчёт', value: Zeus.ExpenseMechanics.ADVANCE },
{ label: 'Прямая оплата', value: Zeus.ExpenseMechanics.DIRECT },
{ label: 'Оплата по счету', value: Zeus.ExpenseMechanics.DIRECT },
];
const recipientTypeOptions = [
{ label: 'Я сам', value: Zeus.ExpenseRecipientType.SELF },
{ label: 'Пайщик', value: Zeus.ExpenseRecipientType.MEMBER },
{ label: 'Организация', value: Zeus.ExpenseRecipientType.ORG },
{ label: 'Организация/ИП', value: Zeus.ExpenseRecipientType.ORG },
];
// Пайщик получает только аванс под отчёт (личные реквизиты, отчитается чеком);
@@ -196,7 +202,7 @@ const canSubmit = computed(
i.description.trim() &&
(i.recipient_type !== Zeus.ExpenseRecipientType.MEMBER || i.recipient_account?.trim()) &&
(i.recipient_type === Zeus.ExpenseRecipientType.ORG
? Boolean(i.recipient_name?.trim() && i.requisites?.trim())
? Boolean(i.recipient_name?.trim() && i.requisites?.trim() && i.payment_purpose?.trim())
: Boolean(i.payment_method_id)),
),
);
@@ -210,6 +216,7 @@ function addItem(): void {
recipient_type: Zeus.ExpenseRecipientType.SELF,
recipient_name: '',
requisites: '',
payment_purpose: '',
recipient_account: '',
payment_method_id: null,
});
@@ -231,7 +238,7 @@ async function submit(): Promise<void> {
deadline: form.deadline,
items: form.items,
});
SuccessAlert('Программный расход подан — заявление подписано и передано в шасси расходов');
SuccessAlert('Программный расход подан — заявление подписано и передано в совет');
emit('created');
close();
} catch (e) {
@@ -16,6 +16,8 @@ export interface ICreateProposalDraftItem {
mechanics: 'ADVANCE' | 'DIRECT';
recipient_name?: string;
requisites?: string;
/** Назначение платежа (оплата по счёту организации/ИП). */
payment_purpose?: string;
item_hash?: string;
recipient_account?: string;
}
@@ -46,6 +48,7 @@ export function useExpenseProposalActions() {
mechanics: it.mechanics,
recipient_name: it.recipient_name ?? '',
requisites: it.requisites ?? '',
payment_purpose: it.payment_purpose || undefined,
}));
const proposalHeader = {
@@ -80,6 +83,7 @@ export function useExpenseProposalActions() {
recipient: it.recipient_account ?? it.recipient_name ?? session.username,
description: it.description,
planned_amount: it.amount,
payment_purpose: it.payment_purpose || undefined,
}));
return createExpenseProposal({
@@ -76,8 +76,7 @@ BaseDialog(
dense,
emit-value,
map-options,
disable,
hint='Пайщику — только аванс под отчёт; организации — только прямая оплата'
disable
)
.col-12.col-md-6
BaseInput(
@@ -110,6 +109,12 @@ BaseDialog(
label='Реквизиты получателя',
placeholder='ИНН, р/с, БИК'
)
.col-12(v-if='item.recipient_type === "ORG"')
BaseInput(
v-model='item.payment_purpose',
label='Назначение платежа',
placeholder='Например: «Оплата по счёту № 814 от 01.06.2026 за аренду серверов»'
)
template(#footer)
.footer-bar
@@ -151,12 +156,12 @@ const submitting = ref(false);
const recipientTypeOptions = [
{ label: 'Я сам', value: 'SELF' as const },
{ label: 'Пайщик', value: 'MEMBER' as const },
{ label: 'Организация', value: 'ORG' as const },
{ label: 'Организация/ИП', value: 'ORG' as const },
];
const mechanicsOptions = [
{ label: 'Аванс под отчёт', value: 'ADVANCE' as const },
{ label: 'Прямая оплата', value: 'DIRECT' as const },
{ label: 'Оплата по счету', value: 'DIRECT' as const },
];
// Пайщик получает только аванс под отчёт; организация — только прямую оплату.
@@ -182,6 +187,7 @@ function addItem(): void {
mechanics: 'ADVANCE',
recipient_name: '',
requisites: '',
payment_purpose: '',
recipient_account: '',
});
}
@@ -203,7 +209,7 @@ async function submit(): Promise<void> {
deadline: form.deadline,
items: form.items,
});
SuccessAlert('Служебная записка подана — заявление подписано и отправлено в блокчейн');
SuccessAlert('Служебная записка подана — заявление подписано и передано в совет');
emit('created');
close();
} catch (e) {
@@ -100,6 +100,8 @@ export interface InterExpenseRequisiteItemInput {
paymentMethodId?: string;
/** Реквизиты строкой (организации — ручной ввод из формы). */
requisites?: string;
/** Назначение платежа (оплата по счёту) — фиксируется в снимке для кассира. */
paymentPurpose?: string;
}
export interface InterExpenseChassisPort {
+20 -4
View File
@@ -2644,7 +2644,7 @@ export type ValueTypes = {
description: string | Variable<any, string>,
/** Хэш СЗ-расхода (детерминированный, из UI). Он же станет proposal_hash в шасси. */
expense_hash: string | Variable<any, string>,
/** Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно. */
/** Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно. */
items: Array<ValueTypes["ExpenseItemInput"]> | Variable<any, string>,
/** Подписанная СЗ-смета (document2, registry 2010). */
statement: ValueTypes["ExpenseProposalStatementSignedDocumentInput"] | Variable<any, string>
@@ -5282,6 +5282,8 @@ export type ValueTypes = {
mechanics: ValueTypes["ExpenseMechanics"] | Variable<any, string>,
/** Идентификатор сохранённых реквизитов получателя-пайщика — реквизиты снимаются в момент создания и прикладываются к платежу. */
payment_method_id?: string | undefined | null | Variable<any, string>,
/** Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира. */
payment_purpose?: string | undefined | null | Variable<any, string>,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string | Variable<any, string>,
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
@@ -5418,6 +5420,8 @@ export type ValueTypes = {
number: string | Variable<any, string>,
/** Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ. */
payment_method_id?: string | undefined | null | Variable<any, string>,
/** Назначение платежа — отдельной строкой после реквизитов */
payment_purpose?: string | undefined | null | Variable<any, string>,
/** Имя получателя */
recipient_name?: string | undefined | null | Variable<any, string>,
/** Тип получателя (SELF / MEMBER / ORG) */
@@ -11737,7 +11741,7 @@ export type ResolverInputTypes = {
description: string,
/** Хэш СЗ-расхода (детерминированный, из UI). Он же станет proposal_hash в шасси. */
expense_hash: string,
/** Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно. */
/** Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно. */
items: Array<ResolverInputTypes["ExpenseItemInput"]>,
/** Подписанная СЗ-смета (document2, registry 2010). */
statement: ResolverInputTypes["ExpenseProposalStatementSignedDocumentInput"]
@@ -14312,6 +14316,8 @@ export type ResolverInputTypes = {
mechanics: ResolverInputTypes["ExpenseMechanics"],
/** Идентификатор сохранённых реквизитов получателя-пайщика — реквизиты снимаются в момент создания и прикладываются к платежу. */
payment_method_id?: string | undefined | null,
/** Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира. */
payment_purpose?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
@@ -14447,6 +14453,8 @@ export type ResolverInputTypes = {
number: string,
/** Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ. */
payment_method_id?: string | undefined | null,
/** Назначение платежа — отдельной строкой после реквизитов */
payment_purpose?: string | undefined | null,
/** Имя получателя */
recipient_name?: string | undefined | null,
/** Тип получателя (SELF / MEMBER / ORG) */
@@ -20579,7 +20587,7 @@ export type ModelTypes = {
description: string,
/** Хэш СЗ-расхода (детерминированный, из UI). Он же станет proposal_hash в шасси. */
expense_hash: string,
/** Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно. */
/** Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно. */
items: Array<ModelTypes["ExpenseItemInput"]>,
/** Подписанная СЗ-смета (document2, registry 2010). */
statement: ModelTypes["ExpenseProposalStatementSignedDocumentInput"]
@@ -23083,6 +23091,8 @@ export type ModelTypes = {
mechanics: ModelTypes["ExpenseMechanics"],
/** Идентификатор сохранённых реквизитов получателя-пайщика — реквизиты снимаются в момент создания и прикладываются к платежу. */
payment_method_id?: string | undefined | null,
/** Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира. */
payment_purpose?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
@@ -23215,6 +23225,8 @@ export type ModelTypes = {
number: string,
/** Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ. */
payment_method_id?: string | undefined | null,
/** Назначение платежа — отдельной строкой после реквизитов */
payment_purpose?: string | undefined | null,
/** Имя получателя */
recipient_name?: string | undefined | null,
/** Тип получателя (SELF / MEMBER / ORG) */
@@ -30003,7 +30015,7 @@ export type GraphQLTypes = {
description: string,
/** Хэш СЗ-расхода (детерминированный, из UI). Он же станет proposal_hash в шасси. */
expense_hash: string,
/** Строки расхода. Способ оплаты (аванс / прямая оплата) задаётся на каждой строке отдельно. */
/** Строки расхода. Способ оплаты (аванс под отчёт / оплата по счёту) задаётся на каждой строке отдельно. */
items: Array<GraphQLTypes["ExpenseItemInput"]>,
/** Подписанная СЗ-смета (document2, registry 2010). */
statement: GraphQLTypes["ExpenseProposalStatementSignedDocumentInput"]
@@ -32641,6 +32653,8 @@ export type GraphQLTypes = {
mechanics: GraphQLTypes["ExpenseMechanics"],
/** Идентификатор сохранённых реквизитов получателя-пайщика — реквизиты снимаются в момент создания и прикладываются к платежу. */
payment_method_id?: string | undefined | null,
/** Назначение платежа (для оплаты по счёту) — фиксируется в снимке для кассира. */
payment_purpose?: string | undefined | null,
/** Планируемая сумма (asset, eg "1000.0000 RUB"). */
planned_amount: string,
/** Получатель: username пайщика; для организации — пустая строка (аккаунта в кооперативе нет). */
@@ -32777,6 +32791,8 @@ export type GraphQLTypes = {
number: string,
/** Идентификатор сохранённых реквизитов получателя-пайщика — сервер подставит полные реквизиты в документ. */
payment_method_id?: string | undefined | null,
/** Назначение платежа — отдельной строкой после реквизитов */
payment_purpose?: string | undefined | null,
/** Имя получателя */
recipient_name?: string | undefined | null,
/** Тип получателя (SELF / MEMBER / ORG) */