feat(factory): документы выхода из кооператива (registry 200/201)
Typecheck / desktop (pull_request) Successful in 13m34s
Typecheck / controller (pull_request) Successful in 13m13s

Заявление о выходе из состава пайщиков (200) с условным рендером по трём
ролям (физлицо/ИП/юрлицо) — зеркало 100.ParticipantApplication, текст по
утверждённой форме. Решение совета о выходе (201) — зеркало 501.

- cooptypes: registry 200/201 (Model + context + переводы + exampleData),
  поле vars.participant_exit_application для шапки «ФОРМА УТВЕРЖДЕНА».
- factory: Templates/Actions 200/201, регистрация в индексах и factories-map.
- test: генерация 200 в трёх ролях + 201; сидинг participant_exit_application.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
coopops
2026-06-13 10:24:19 +00:00
parent 75cd0976e2
commit ee60ece571
14 changed files with 719 additions and 18 deletions
@@ -68,6 +68,10 @@ export interface IVars {
protocol_number: string
protocol_day_month_year: string
}
participant_exit_application?: { // Заявление на выход из кооператива
protocol_number: string
protocol_day_month_year: string
}
coopenomics_agreement?: { // Оферта на подключение кооператива
protocol_number: string
protocol_day_month_year: string
@@ -0,0 +1,184 @@
import type { IGenerate, IMetaDocument } from '../../document'
import type { ICooperativeData, IVars } from '../../model'
import type { IEntrepreneurData, IIndividualData, IOrganizationData } from '../../users'
export const registry_id = 200
/**
* Интерфейс генерации заявления на выход из состава пайщиков кооператива
*/
export interface Action extends IGenerate {
signature?: string
skip_save: boolean
}
export type Meta = IMetaDocument & Action
// Модель данных
export interface Model {
type: string
individual?: IIndividualData
organization?: IOrganizationData
entrepreneur?: IEntrepreneurData
coop: ICooperativeData
meta: IMetaDocument
vars: IVars
signature?: string
}
export const title = 'Заявление на выход из кооператива'
export const description = 'Форма заявления физического лица, индивидуального предпринимателя или юридического лица о выходе из состава пайщиков потребительского кооператива'
export const context = `<style>
.digital-document h1 {
margin: 0px;
text-align:center;
}
.digital-document {padding: 20px;}
.subheader {
padding-bottom: 20px;
}
.signature {
padding-top: 30px;
}
</style>
<div class="digital-document">
<div style="text-align: right;">
<p style="margin: 0px !important">{% trans 'APPROVED' %}</p>
<p style="margin: 0px !important">{% trans 'approved_by_council' %} {{ coop.short_name }}</p>
<p style="margin: 0px !important">({% trans 'protocol' %} {{ vars.participant_exit_application.protocol_number }} {% trans 'from' %} {{ vars.participant_exit_application.protocol_day_month_year }})</p>
</div>
{% if type == 'individual' %}
<h1 class="header">{% trans 'application_exit_individual' %}</h1>
<p style="text-align: center" class="subheader">{% trans 'of_consumer_cooperative' %} {{ coop.full_name }}<p>
<p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p>
<p>{% trans 'to_council_of' %} {{ coop.full_name }} {% trans 'from' %} {{ individual.last_name }} {{ individual.first_name }} {{ individual.middle_name }}, {% trans 'birthdate' %} {{ individual.birthdate }}, {% trans 'registration_address' %} {{ individual.full_address }}, {% trans 'phone_and_email_notice', individual.phone, individual.email %}</p>
<p>{% trans 'request_to_exit', coop.full_name, coop.details.ogrn, coop.details.inn, coop.details.kpp %}</p>
<p>{% trans 'obligation_to_settle_individual' %}</p>
<div class="signature">
<img style="max-width: 150px;" src="{{ signature }}"/>
<p>{% trans 'signature_individual' %}</p>
<p style="text-align: right;">{{ individual.last_name }} {{ individual.first_name }} {{ individual.middle_name }}</p>
</div>
{% elif type == 'entrepreneur' %}
<h1 class="header">{% trans 'application_exit_entrepreneur' %}</h1>
<p style="text-align: center" class="subheader">{% trans 'of_consumer_cooperative' %} {{ coop.full_name }}<p>
<p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p>
<p>{% trans 'to_council_of' %} {{ coop.full_name }} {% trans 'from_entrepreneur' %} {{ entrepreneur.last_name }} {{ entrepreneur.first_name }} {{ entrepreneur.middle_name }}, {% trans 'birthdate' %} {{ entrepreneur.birthdate }}, {% trans 'registration_address' %} {{ entrepreneur.full_address }}, {% trans 'entrepreneur_details', entrepreneur.details.inn, entrepreneur.details.ogrn %}, {% trans 'phone_and_email_notice', entrepreneur.phone, entrepreneur.email %}</p>
<p>{% trans 'request_to_exit', coop.full_name, coop.details.ogrn, coop.details.inn, coop.details.kpp %}</p>
<p>{% trans 'obligation_to_settle_individual' %}</p>
<div class="signature">
<img style="max-width: 150px;" src="{{ signature }}"/>
<p>{% trans 'signature_individual' %}</p>
<p style="text-align: right;">{{ entrepreneur.last_name }} {{ entrepreneur.first_name }} {{ entrepreneur.middle_name }}</p>
</div>
{% elif type == 'organization' %}
<h1 class="header">{% trans 'application_exit_legal_entity' %}</h1>
<p style="text-align: center" class="subheader">{% trans 'of_consumer_cooperative' %} {{ coop.full_name }}<p>
<p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p>
<p>{% trans 'to_council_of' %} {{ coop.full_name }} {% trans 'from_legal_entity' %} {{ organization.full_name }}, {% trans 'legal_address' %}: {{ organization.full_address }}, {% trans 'fact_address' %}: {{ organization.fact_address }}, {% trans 'legal_entity_details', organization.details.inn, organization.details.ogrn, organization.details.kpp %}, {% trans 'phone_and_email_notice', organization.phone, organization.email %}</p>
<p>{% trans 'request_to_exit_legal_entity', organization.represented_by.position, organization.represented_by.last_name, organization.represented_by.first_name, organization.represented_by.middle_name, organization.represented_by.based_on, organization.full_name, coop.full_name %}</p>
<p>{% trans 'obligation_to_settle_legal_entity' %}</p>
<div class="signature">
<img style="max-width: 150px;" src="{{ signature }}"/>
<p>{% trans 'signature_individual' %}</p>
<p style="text-align: right;">{{ organization.represented_by.last_name }} {{ organization.represented_by.first_name }} {{ organization.represented_by.middle_name }}</p>
</div>
{% endif %}
</div>`
export const translations = {
ru: {
APPROVED: 'ФОРМА УТВЕРЖДЕНА',
approved_by_council: 'решением Собрания Совета',
protocol: 'Протокол № СС-',
from: 'от',
of_consumer_cooperative: 'Потребительского кооператива',
to_council_of: 'В Совет',
birthdate: 'дата рождения',
registration_address: 'адрес регистрации (как в паспорте): ',
phone_and_email_notice: 'номер телефона: {0}, адрес электронной почты: {1}.',
application_exit_individual: 'Заявление физического лица о выходе из состава пайщиков',
application_exit_entrepreneur: 'Заявление индивидуального предпринимателя о выходе из состава пайщиков',
application_exit_legal_entity: 'Заявление юридического лица о выходе из состава пайщиков',
from_entrepreneur: 'от индивидуального предпринимателя',
from_legal_entity: 'от юридического лица',
legal_address: 'юридический адрес',
fact_address: 'фактический адрес',
entrepreneur_details: 'ИНН {0}, ОГРНИП {1}',
legal_entity_details: 'ИНН {0}, ОГРН {1}, КПП {2}',
request_to_exit: 'В соответствии с Уставом {0} (ОГРН {1}, ИНН {2}, КПП {3}) (далее по тексту Общество) прошу вывести меня из состава пайщиков Общества.',
request_to_exit_legal_entity: 'Заявитель, в лице представителя юридического лица — {0} {1} {2} {3}, действующего на основании {4}, в соответствии с Уставом Общества просит вывести {5} из состава пайщиков {6}.',
obligation_to_settle_individual: 'Обязуюсь погасить все свои обязательства перед Обществом, при наличии таковых, а также получить возврат своих паевых взносов в связи с моим участием в хозяйственной деятельности и целевых потребительских программах Общества, предусмотренном Уставом Общества и его действующих Положений и в соответствии с действующим законодательством РФ.',
obligation_to_settle_legal_entity: 'Заявитель обязуется погасить все свои обязательства перед Обществом, при наличии таковых, а также получить возврат своих паевых взносов в связи с участием в хозяйственной деятельности и целевых потребительских программах Общества, предусмотренном Уставом Общества и его действующих Положений и в соответствии с действующим законодательством РФ.',
signature_individual: 'личная подпись заявителя',
},
}
export const exampleData = {
coop: {
short_name: 'ПК "ВОСХОД"',
full_name: 'потребительский кооператив "Восход"',
city: 'Москва',
details: {
inn: '9728130611',
ogrn: '1247700283346',
kpp: '772801001',
},
},
meta: {
created_at: '04.03.2024 10:54',
},
individual: {
last_name: 'Муравьев',
first_name: 'Алексей',
middle_name: 'Николаевич',
birthdate: '04.03.1990',
phone: '790343432423',
email: 'email@gmail.com',
full_address: 'Советов 3-84',
},
entrepreneur: {
last_name: 'Муравьев',
first_name: 'Алексей',
middle_name: 'Николаевич',
birthdate: '04.03.1990',
full_address: 'Советов 3-84',
details: {
inn: '34534534534',
ogrn: '345345345',
},
phone: '+734534534534',
email: 'email@gmail.com',
},
organization: {
full_name: 'ООО РОМАШКА',
full_address: 'Советов 3-84',
fact_address: 'Советов 3-84',
represented_by: {
last_name: 'Муравьев',
first_name: 'Алексей',
middle_name: 'Николаевич',
position: 'директор',
based_on: 'решения учредителей №1 от 05.03.2024',
},
details: {
inn: '234234234',
ogrn: '234234234234',
kpp: '772801001',
},
phone: '+35345345345',
email: 'an.mddf@gmail.com',
},
type: 'individual',
signature: '',
vars: {
participant_exit_application: {
protocol_number: '10-04-2024',
protocol_day_month_year: '10 апреля 2024 г.',
},
},
}
@@ -0,0 +1,124 @@
import type { IDecisionData, IGenerate, IMetaDocument } from '../../document'
import type { ICooperativeData, IVars } from '../../model'
import type { IEntrepreneurData, IIndividualData, IOrganizationData } from '../../users'
export const registry_id = 201
/**
* Интерфейс генерации решения совета о выходе пайщика из кооператива
*/
export interface Action extends IGenerate {
decision_id: number
}
// Модель данных
export interface Model {
type: string
individual?: IIndividualData
organization?: IOrganizationData
entrepreneur?: IEntrepreneurData
coop: ICooperativeData
meta: IMetaDocument
decision: IDecisionData
vars: IVars
}
export const title = 'Решение совета о выходе пайщика из кооператива'
export const description = 'Форма решения совета о выходе пайщика из состава потребительского кооператива'
export const context = '<style> \nh1 {\nmargin: 0px; \ntext-align:center;\n}\nh3{\nmargin: 0px;\npadding-top: 15px;\n}\n.about {\npadding: 20px;\n}\n.digital-document {\npadding: 20px;\nwhite-space: pre-wrap;\n}\n.subheader {\npadding-bottom: 20px; \n}\ntable {\n width: 100%;\n border-collapse: collapse;\n}\nth, td {\n border: 1px solid #ccc;\n padding: 8px;\n text-align: left;\n word-wrap: break-word; \n overflow-wrap: break-word; \n}\nth {\n background-color: #f4f4f4;\n width: 30%;\n}\n</style>\n\n<div class="digital-document">\n <h1 class="header">{% trans \'protocol_number\', decision.id %}</h1>\n <p style="text-align:center" class="subheader">{% trans \'council_meeting_name\' %} {{vars.full_abbr_genitive}} "{{vars.name}}"</p>\n <p style="text-align: right"> {{ meta.created_at }}, {{ coop.city }}</p>\n <table class="about">\n <tbody>\n <tr>\n <th>{% trans \'meeting_format\' %}</th>\n <td>{% trans \'meeting_format_value\' %}</td>\n </tr>\n <tr>\n <th>{% trans \'meeting_place\' %}</th>\n <td>{{ coop.full_address }}</td>\n </tr>\n <tr>\n <th>{% trans \'meeting_date\' %}</th>\n <td>{{ decision.date }}</td>\n </tr>\n <tr>\n <th>{% trans \'opening_time\' %}</th>\n <td>{{ decision.time }}</td>\n </tr>\n </tbody>\n </table>\n <h3>{% trans \'council_members\' %}</h3>\n <table>\n <tbody>\n {% for member in coop.members %}\n <tr>\n <th>{% if member.is_chairman %}{% trans \'chairman_of_the_council\' %}{% else %}{% trans \'member_of_the_council\' %}{% endif %}</th>\n <td>{{ member.last_name }} {{ member.first_name }} {{ member.middle_name }}</td>\n</tr>\n {% endfor %}\n </tbody>\n </table>\n <h3>{% trans \'meeting_legality\' %}</h3>\n <p>{% trans \'voting_results\', decision.voters_percent %} {% trans \'quorum\' %} {% trans \'chairman_of_the_meeting\', coop.chairman.last_name, coop.chairman.first_name, coop.chairman.middle_name %}.</p>\n <h3>{% trans \'agenda\' %}</h3>\n <table>\n <tbody>\n <tr>\n <th>№</th>\n <td>{% trans \'question\' %}</td>\n </tr>\n <tr>\n <th>{% trans \'agenda_item\' %}</th>\n <td>{% trans \'decision_leavecoop1\' %} {% if type == \'individual\' %}{{individual.last_name}} {{individual.first_name}} {{individual.middle_name}} ({{individual.birthdate}} {% trans \'birthdate\' %}){% endif %}{% if type == \'entrepreneur\' %}{% trans \'entrepreneur\' %} {{entrepreneur.last_name}} {{entrepreneur.first_name}} {{entrepreneur.middle_name}} ({% trans \'ogrnip\' %} {{entrepreneur.details.ogrn}}){% endif %}{% if type == \'organization\' %} {{organization.short_name}} ({% trans \'ogrn\' %} {{organization.details.ogrn}}){% endif %}{% trans \'in_participants\' %} {{ coop.short_name }}.\n </td>\n </tr>\n </tbody>\n </table>\n<h3>{% trans \'voting\' %}</h3>\n<p>{% trans \'vote_results\' %}</p><table>\n <tbody>\n <tr>\n <th>{% trans \'votes_for\' %}</th>\n <td>{{ decision.votes_for }}</td>\n </tr>\n <tr>\n <th>{% trans \'votes_against\' %}</th>\n <td>{{ decision.votes_against }}</td>\n </tr>\n <tr>\n <th>{% trans \'votes_abstained\' %}</th>\n <td>{{ decision.votes_abstained }}</td>\n </tr>\n </tbody>\n </table>\n <h3>{% trans \'decision_made\' %}</h3>\n <table>\n <tbody>\n <tr>\n <tr>\n <th>№</th>\n <td>{% trans \'question\' %}</td>\n </tr>\n\n <th>{% trans \'decision\' %}</th>\n <td>{% trans \'decision_leavecoop2\' %}\n{% if type == \'individual\' %}{{individual.last_name}} {{individual.first_name}} {{individual.middle_name}} {{individual.birthdate}} {% trans \'birthdate\' %} {% endif %}{% if type == \'entrepreneur\' %}{% trans \'entrepreneur\' %} {{entrepreneur.last_name}} {{entrepreneur.first_name}} {{entrepreneur.middle_name}}, {% trans \'ogrnip\' %} {{entrepreneur.details.ogrn}}{% endif %}{% if type == \'organization\' %}{{organization.short_name}}, {% trans \'ogrn\' %} {{organization.details.ogrn}}{% endif %}\n </td>\n </tr>\n </tbody>\n </table>\n <hr>\n<p>{% trans \'closing_time\', decision.time %}</p>\n<div class="signature"><p>{% trans \'signature\' %}</p><p>{% trans \'chairman\' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p></div>\n</div>\n'
export const translations = {
ru: {
meeting_format: 'Форма',
meeting_date: 'Дата',
meeting_place: 'Место',
opening_time: 'Время открытия',
council_members: 'ЧЛЕНЫ СОВЕТА',
voting_results: 'Количество голосов составляет {0}% от общего числа членов Совета.',
meeting_legality: 'СОБРАНИЕ ПРАВОМОЧНО',
chairman_of_the_meeting: 'Председатель собрания совета: {0} {1} {2}',
agenda: 'ПОВЕСТКА ДНЯ',
decision_made: 'РЕШИЛИ',
closing_time: 'Время закрытия собрания совета: {0}.',
protocol_number: 'ПРОТОКОЛ № {0}',
council_meeting_name: 'Собрания Совета',
chairman_of_the_council: 'Председатель совета',
signature: 'Документ подписан электронной подписью.',
chairman: 'Председатель',
birthdate: 'г.р.',
ogrnip: 'ОГРНИП',
entrepreneur: 'ИП',
ogrn: 'ОГРН',
quorum: 'Кворум для решения поставленных на повестку дня вопросов имеется.',
voting: 'ГОЛОСОВАНИЕ',
in_participants: ' о выходе из состава пайщиков',
decision_leavecoop1: 'Рассмотреть заявление о выходе',
decision_leavecoop2: 'Вывести из состава пайщиков',
meeting_format_value: 'заочная',
agenda_item: '1',
votes_for: 'ЗА',
votes_against: 'ПРОТИВ',
votes_abstained: 'ВОЗДЕРЖАЛСЯ',
decision: '1',
question: 'Вопрос',
vote_results: 'По первому вопросу повестки дня проголосовали:',
member_of_the_council: 'Член совета',
},
}
export const exampleData = {
meta: {
created_at: '12.02.2024 00:01',
},
coop: {
city: 'Москва',
full_address: 'Смольная 3-84',
chairman: {
last_name: 'Муравьев',
first_name: 'Алексей',
middle_name: 'Николаевич',
},
short_name: 'ПК "Восход"',
},
decision: {
time: '00:01',
date: '12.02.2024',
votes_for: '3',
votes_against: '0',
votes_abstained: '0',
voters_percent: '100',
id: '1',
},
member: {
is_chairman: true,
last_name: 'Муравьев',
first_name: 'Алексей',
middle_name: 'Николаевич',
},
organization: {
details: {
ogrn: '2222222222',
},
short_name: 'ООО "Ромашка"',
},
type: 'organization',
individual: {
last_name: 'Мартин',
first_name: 'Роберт',
middle_name: 'Иванович',
birthdate: '04.04.2000',
},
entrepreneur: {
last_name: 'Мартин',
first_name: 'Роберт',
middle_name: 'Иванович',
details: {
ogrn: '11111111111',
},
},
vars: {
full_abbr_genitive: 'Потребительского Кооператива',
name: 'ВОСХОД',
},
}
@@ -8,6 +8,9 @@ export * as ConvertToAxonStatement from './51.ConvertToAxonStatement'
export * as ParticipantApplication from './100.ParticipantApplication'
export * as DecisionOfParticipantApplication from './501.DecisionOfParticipantApplication'
export * as ParticipantExitApplication from './200.ParticipantExitApplication'
export * as DecisionOfParticipantExit from './201.DecisionOfParticipantExit'
export * as SelectBranchStatement from './101.SelectBranchStatement'
export * as ProjectFreeDecision from './599.ProjectFreeDecision'
export * as FreeDecision from './600.FreeDecision'