registration with programs and agreements
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
alwaysApply: false
|
||||
---
|
||||
Смотри, у меня есть проект документа оферты, @cooptypes/src/cooperative/registry/999.BlagorostOfferTemplate/index.ts мы его принимаем затем, чтобы получить данные для генерации @cooptypes/src/cooperative/registry/1000.CapitalizationAgreement/index.ts уже самой пользовательской оферты. Они в целом почти абсолютно идентичны за той лишь разницей, что в проекте кругом прочерки остаются вместо переменных для заполнения, и нет шапки с надписью "УТВЕРЖДЕНО" протоколом решения № ___ и дата ___. Т.е. мы как бы из первого в итоге получаем второе. Приняв первое - мы можем начать генерировать второе.
|
||||
Смотри, у меня есть проект документа оферты, @cooptypes/src/cooperative/registry/999.BlagorostOfferTemplate/index.ts мы его принимаем затем, чтобы получить данные для генерации @cooptypes/src/cooperative/registry/1000.BlagorostOffer/index.ts уже самой пользовательской оферты. Они в целом почти абсолютно идентичны за той лишь разницей, что в проекте кругом прочерки остаются вместо переменных для заполнения, и нет шапки с надписью "УТВЕРЖДЕНО" протоколом решения № ___ и дата ___. Т.е. мы как бы из первого в итоге получаем второе. Приняв первое - мы можем начать генерировать второе.
|
||||
|
||||
Мне надо, чтобы ты сделал аналогично для указанного мной документа. Для этого нужно переменные по аналогии заполнить пробелами и убрать шапку. Т.е. в итоге мы должны получить шаблон документа, который можно распечатать и заполнить ручкой. Вот такой вот документ мне надо чтоб ты создал. Он должен обладать принадлежностью к конкретному кооперативу, т.е. vars и chairman мы используем, как и coop. Всё остальное по сути нужно заменить на прочерки. Создай этот шаблон документа, исследовав что нужно тебе для этого.
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
# 🔄 Динамический поток регистрации
|
||||
|
||||
Система регистрации полностью управляется через конфигурацию без хардкода в бизнес-логике.
|
||||
|
||||
## 📋 Источники конфигурации
|
||||
|
||||
### 1. Конфигурация соглашений
|
||||
**Файл**: `src/domain/registration/config/registration-agreements.config.ts`
|
||||
|
||||
Определяет все доступные соглашения:
|
||||
|
||||
```typescript
|
||||
{
|
||||
id: 'generator_offer',
|
||||
registry_id: 996,
|
||||
agreement_type: 'generator', // ← Используется при отправке в блокчейн
|
||||
title: 'Оферта по программе "Генератор"',
|
||||
is_blockchain_agreement: true,
|
||||
link_to_statement: true,
|
||||
applicable_account_types: [],
|
||||
order: 6,
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Конфигурация программ
|
||||
**Файл**: `src/domain/registration/config/registration-programs.config.ts`
|
||||
|
||||
Определяет доступные программы регистрации:
|
||||
|
||||
```typescript
|
||||
{
|
||||
key: 'generation',
|
||||
title: 'Программа Генерация',
|
||||
description: '...',
|
||||
applicable_account_types: [AccountType.individual, AccountType.entrepreneur],
|
||||
agreement_ids: ['generator_offer'], // ← Связь с соглашениями
|
||||
order: 1,
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 Как это работает
|
||||
|
||||
### 1️⃣ Генерация документов
|
||||
**Сервис**: `RegistrationDocumentsService.generateRegistrationDocuments()`
|
||||
|
||||
```typescript
|
||||
// Получаем соглашения из конфигурации
|
||||
const agreementsConfig = this.agreementConfigService.getAgreementsForAccountType(
|
||||
account_type,
|
||||
coopname,
|
||||
program_key // ← Ключ выбранной программы
|
||||
);
|
||||
|
||||
// Генерируем документы для каждого соглашения
|
||||
for (const config of agreementsConfig) {
|
||||
const document = await generateDocument({
|
||||
registry_id: config.registry_id,
|
||||
...
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 2️⃣ Валидация при регистрации
|
||||
**Интерактор**: `ParticipantInteractor.registerParticipant()`
|
||||
|
||||
```typescript
|
||||
// ПРОВЕРКА 1: Получаем требуемые соглашения из конфигурации
|
||||
const requiredAgreements = this.agreementConfigService.getRequiredAgreementIds(
|
||||
candidate.type,
|
||||
config.coopname,
|
||||
data.program_key // ← Передаем ключ программы
|
||||
);
|
||||
|
||||
// ПРОВЕРКА 2: Валидируем все требуемые документы динамически
|
||||
const documentsToValidate = [{ id: 'statement', document: data.statement }];
|
||||
|
||||
for (const agreementId of requiredAgreements) {
|
||||
if (data[agreementId]) {
|
||||
documentsToValidate.push({ id: agreementId, document: data[agreementId] });
|
||||
} else {
|
||||
missingAgreements.push(agreementId);
|
||||
}
|
||||
}
|
||||
|
||||
// ПРОВЕРКА 3: Проверяем линкованные документы из конфигурации
|
||||
const linkedAgreements = this.agreementConfigService.getLinkedAgreements(
|
||||
candidate.type,
|
||||
config.coopname,
|
||||
data.program_key // ← Передаем ключ программы
|
||||
);
|
||||
|
||||
// СОХРАНЕНИЕ: Сохраняем все требуемые соглашения
|
||||
for (const agreementId of requiredAgreements) {
|
||||
if (data[agreementId]) {
|
||||
await this.candidateRepository.saveDocument(username, agreementId, data[agreementId]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3️⃣ Отправка в блокчейн
|
||||
**Адаптер**: `AccountBlockchainAdapter.registerBlockchainAccount()`
|
||||
|
||||
```typescript
|
||||
// Получаем соглашения для блокчейна из конфигурации
|
||||
const blockchainAgreements = this.agreementConfigService.getBlockchainAgreements(
|
||||
accountType,
|
||||
config.coopname,
|
||||
candidate.program_key // ← Используем сохраненный ключ программы
|
||||
);
|
||||
|
||||
// Динамически добавляем транзакции sendAgreement
|
||||
for (const agreementConfig of blockchainAgreements) {
|
||||
const document = candidate.documents[agreementConfig.id];
|
||||
|
||||
if (document) {
|
||||
const action = this.createSendAgreementAction(
|
||||
candidate.username,
|
||||
agreementConfig.agreement_type, // ← Берем из конфигурации!
|
||||
document
|
||||
);
|
||||
actions.push(action);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ✨ Преимущества
|
||||
|
||||
### ✅ Никакого хардкода
|
||||
```typescript
|
||||
// ❌ ПЛОХО - хардкод
|
||||
if (data.program_key === 'generation' && data.generator_offer) {
|
||||
documentsToValidate.push({ id: 'generator_offer', document: data.generator_offer });
|
||||
}
|
||||
|
||||
// ✅ ХОРОШО - динамика из конфигурации
|
||||
for (const agreementId of requiredAgreements) {
|
||||
if (data[agreementId]) {
|
||||
documentsToValidate.push({ id: agreementId, document: data[agreementId] });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Легко добавить новую программу
|
||||
|
||||
1. Добавляем соглашение в `registration-agreements.config.ts`:
|
||||
```typescript
|
||||
{
|
||||
id: 'new_program_offer',
|
||||
agreement_type: 'new_type',
|
||||
registry_id: 1001,
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
2. Добавляем программу в `registration-programs.config.ts`:
|
||||
```typescript
|
||||
{
|
||||
key: 'new_program',
|
||||
title: 'Новая программа',
|
||||
agreement_ids: ['new_program_offer'],
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
3. **Всё!** Код работает без изменений 🎉
|
||||
|
||||
### ✅ Единый источник истины
|
||||
|
||||
Конфигурация определяет:
|
||||
- Какие документы генерировать
|
||||
- Какие документы валидировать
|
||||
- Какие документы линковать в заявление
|
||||
- Какие документы сохранять
|
||||
- Какие транзакции отправлять в блокчейн
|
||||
- Какой `agreement_type` использовать
|
||||
|
||||
## 🔍 Полный цикл для программы "Генерация"
|
||||
|
||||
```
|
||||
1. Frontend → generateRegistrationDocuments({ program_key: 'generation' })
|
||||
↓
|
||||
2. Backend определяет: generation → ['generator_offer']
|
||||
↓
|
||||
3. Генерируется документ с registry_id=996
|
||||
↓
|
||||
4. Frontend подписывает документы
|
||||
↓
|
||||
5. Frontend → registerParticipant({ program_key: 'generation', generator_offer: {...} })
|
||||
↓
|
||||
6. Backend валидирует все требуемые документы (динамически)
|
||||
↓
|
||||
7. Backend сохраняет program_key и все документы
|
||||
↓
|
||||
8. Payment → registerBlockchainAccount(candidate)
|
||||
↓
|
||||
9. Backend получает соглашения для блокчейна на основе candidate.program_key
|
||||
↓
|
||||
10. Backend отправляет sendAgreement с agreement_type='generator'
|
||||
```
|
||||
|
||||
## 📝 Итог
|
||||
|
||||
**Вся система управляется через конфигурацию!**
|
||||
|
||||
Добавление новых программ и соглашений не требует изменения бизнес-логики - только обновление конфигурационных файлов.
|
||||
@@ -2303,7 +2303,7 @@ type CapitalOnboardingState {
|
||||
|
||||
enum CapitalOnboardingStep {
|
||||
blagorost_offer_template
|
||||
blagorost_provision
|
||||
blagorost_program
|
||||
generation_agreement_template
|
||||
generator_program_template
|
||||
}
|
||||
@@ -5470,6 +5470,9 @@ input GenerateRegistrationDocumentsInput {
|
||||
"""Имя кооператива"""
|
||||
coopname: String!
|
||||
|
||||
"""Ключ выбранной программы регистрации (опционально)"""
|
||||
program_key: String
|
||||
|
||||
"""Имя пользователя (аккаунт)"""
|
||||
username: String!
|
||||
}
|
||||
@@ -8331,6 +8334,9 @@ type Query {
|
||||
"""Получить подписки пользователя у провайдера"""
|
||||
getProviderSubscriptions: [ProviderSubscription!]!
|
||||
|
||||
"""Получить конфигурацию программ регистрации для кооператива"""
|
||||
getRegistrationConfig(account_type: AccountType!, coopname: String!): RegistrationConfig!
|
||||
|
||||
"""Получить сводную публичную информацию о системе"""
|
||||
getSystemInfo: SystemInfo!
|
||||
|
||||
@@ -8529,7 +8535,7 @@ input RegisterParticipantInput {
|
||||
"""
|
||||
Подписанный документ соглашения по капитализации (опционально, только если требуется)
|
||||
"""
|
||||
capitalization_agreement: SignedDigitalDocumentInput
|
||||
blagorost_offer: SignedDigitalDocumentInput
|
||||
|
||||
"""Подписанный документ политики конфиденциальности от пайщика"""
|
||||
privacy_agreement: SignedDigitalDocumentInput!
|
||||
@@ -8560,6 +8566,37 @@ type RegisteredAccount {
|
||||
tokens: Tokens!
|
||||
}
|
||||
|
||||
type RegistrationConfig {
|
||||
"""Доступные программы"""
|
||||
programs: [RegistrationProgram!]!
|
||||
|
||||
"""Нужен ли выбор программы"""
|
||||
requires_selection: Boolean!
|
||||
}
|
||||
|
||||
type RegistrationProgram {
|
||||
"""Для каких типов аккаунтов доступна программа"""
|
||||
applicable_account_types: [AccountType!]!
|
||||
|
||||
"""Описание программы"""
|
||||
description: String!
|
||||
|
||||
"""URL изображения (опционально)"""
|
||||
image_url: String
|
||||
|
||||
"""Уникальный ключ программы"""
|
||||
key: String!
|
||||
|
||||
"""Порядок отображения"""
|
||||
order: Int!
|
||||
|
||||
"""Минимальные требования для участия"""
|
||||
requirements: String
|
||||
|
||||
"""Название программы для отображения"""
|
||||
title: String!
|
||||
}
|
||||
|
||||
type RepresentedBy {
|
||||
"""На основании чего действует"""
|
||||
based_on: String!
|
||||
|
||||
+21
-2
@@ -1,8 +1,15 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
import { Field, InputType, registerEnumType } from '@nestjs/graphql';
|
||||
import { IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator';
|
||||
import { ParticipantApplicationSignedDocumentInputDTO } from '../../document/documents-dto/participant-application-document.dto';
|
||||
import { SignedDigitalDocumentInputDTO } from '~/application/document/dto/signed-digital-document-input.dto';
|
||||
import type { RegisterParticipantDomainInterface } from '~/domain/participant/interfaces/register-participant-domain.interface';
|
||||
import { ProgramKey } from '~/domain/registration/enum';
|
||||
|
||||
// Регистрируем enum для GraphQL
|
||||
registerEnumType(ProgramKey, {
|
||||
name: 'ProgramKey',
|
||||
description: 'Ключ выбранной программы регистрации',
|
||||
});
|
||||
|
||||
@InputType('RegisterParticipantInput')
|
||||
export class RegisterParticipantInputDTO implements RegisterParticipantDomainInterface {
|
||||
@@ -57,5 +64,17 @@ export class RegisterParticipantInputDTO implements RegisterParticipantDomainInt
|
||||
})
|
||||
@ValidateNested()
|
||||
@IsOptional()
|
||||
capitalization_agreement?: SignedDigitalDocumentInputDTO;
|
||||
blagorost_offer?: SignedDigitalDocumentInputDTO;
|
||||
|
||||
@Field(() => SignedDigitalDocumentInputDTO, {
|
||||
description: 'Подписанный документ оферты по программе "Генератор" (опционально, только для программы generation)',
|
||||
nullable: true,
|
||||
})
|
||||
@ValidateNested()
|
||||
@IsOptional()
|
||||
generator_offer?: SignedDigitalDocumentInputDTO;
|
||||
|
||||
@Field(() => ProgramKey, { description: 'Ключ выбранной программы регистрации', nullable: true })
|
||||
@IsOptional()
|
||||
program_key?: ProgramKey;
|
||||
}
|
||||
|
||||
+87
-45
@@ -35,6 +35,7 @@ import {
|
||||
AGREEMENT_CONFIGURATION_SERVICE,
|
||||
} from '~/domain/registration/services/agreement-configuration.service';
|
||||
import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import { DocumentType, AgreementId } from '~/domain/registration/enum';
|
||||
|
||||
@Injectable()
|
||||
export class ParticipantInteractor {
|
||||
@@ -122,41 +123,29 @@ export class ParticipantInteractor {
|
||||
);
|
||||
}
|
||||
|
||||
// Подготавливаем структуру для валидации документов с использованием нового сервиса
|
||||
const documentsToValidate: IDocumentToValidate[] = [
|
||||
{ id: 'statement', document: data.statement },
|
||||
{ id: 'wallet_agreement', document: data.wallet_agreement },
|
||||
{ id: 'user_agreement', document: data.user_agreement },
|
||||
{ id: 'privacy_agreement', document: data.privacy_agreement },
|
||||
{ id: 'signature_agreement', document: data.signature_agreement },
|
||||
];
|
||||
|
||||
// Добавляем capitalization_agreement если есть
|
||||
if (data.capitalization_agreement) {
|
||||
documentsToValidate.push({ id: 'capitalization_agreement', document: data.capitalization_agreement });
|
||||
}
|
||||
|
||||
// Валидируем документы с проверкой оригиналов в базе
|
||||
const validationResults = await this.documentValidationService.validateRegistrationDocuments(documentsToValidate);
|
||||
|
||||
if (!this.documentValidationService.allDocumentsValid(validationResults)) {
|
||||
const errors = this.documentValidationService.getErrorMessages(validationResults);
|
||||
this.logger.error(`Ошибка валидации документов: ${errors.join('; ')}`);
|
||||
throw new HttpApiError(http.BAD_REQUEST, `Ошибка валидации документов: ${errors.join('; ')}`);
|
||||
}
|
||||
|
||||
// ПРОВЕРКА 2: Все ли требуемые соглашения предоставлены?
|
||||
// Проверяем наличие всех обязательных соглашений для типа аккаунта кандидата
|
||||
// ПРОВЕРКА 1: Получаем список всех требуемых соглашений из конфигурации
|
||||
// Это единственный источник истины - конфигурация определяет что требуется
|
||||
const requiredAgreements = this.agreementConfigurationService.getRequiredAgreementIds(
|
||||
candidate.type as AccountType,
|
||||
config.coopname
|
||||
config.coopname,
|
||||
data.program_key
|
||||
);
|
||||
|
||||
// ПРОВЕРКА 2: Подготавливаем структуру для валидации документов динамически на основе конфигурации
|
||||
const documentsToValidate: IDocumentToValidate[] = [
|
||||
// Заявление всегда обязательно
|
||||
{ id: 'statement', document: data.statement },
|
||||
];
|
||||
|
||||
// Проверяем наличие и валидируем все требуемые соглашения из конфигурации
|
||||
const missingAgreements: string[] = [];
|
||||
for (const agreementId of requiredAgreements) {
|
||||
const agreementData = data[agreementId];
|
||||
if (!agreementData) {
|
||||
missingAgreements.push(agreementId);
|
||||
} else {
|
||||
// Добавляем документ в список для валидации
|
||||
documentsToValidate.push({ id: agreementId, document: agreementData });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,17 +156,39 @@ export class ParticipantInteractor {
|
||||
);
|
||||
}
|
||||
|
||||
// ПРОВЕРКА 3: Проверка линкованных документов в заявлении
|
||||
const statementLinks = (data.statement.meta as any)?.links || [];
|
||||
const expectedLinks = [
|
||||
data.wallet_agreement.doc_hash,
|
||||
data.signature_agreement.doc_hash,
|
||||
data.privacy_agreement.doc_hash,
|
||||
data.user_agreement.doc_hash,
|
||||
];
|
||||
// ПРОВЕРКА 3: Валидируем все собранные документы с проверкой оригиналов в базе
|
||||
const validationResults = await this.documentValidationService.validateRegistrationDocuments(documentsToValidate);
|
||||
|
||||
if (data.capitalization_agreement) {
|
||||
expectedLinks.push(data.capitalization_agreement.doc_hash);
|
||||
if (!this.documentValidationService.allDocumentsValid(validationResults)) {
|
||||
const errors = this.documentValidationService.getErrorMessages(validationResults);
|
||||
this.logger.error(`Ошибка валидации документов: ${errors.join('; ')}`);
|
||||
throw new HttpApiError(http.BAD_REQUEST, `Ошибка валидации документов: ${errors.join('; ')}`);
|
||||
}
|
||||
|
||||
// ПРОВЕРКА 4: Проверка линкованных документов в заявлении на основе конфигурации
|
||||
const statementLinks = (data.statement.meta as any)?.links || [];
|
||||
|
||||
// Получаем список документов, которые должны быть линкованы, из конфигурации
|
||||
const linkedAgreements = this.agreementConfigurationService.getLinkedAgreements(
|
||||
candidate.type as AccountType,
|
||||
config.coopname,
|
||||
data.program_key
|
||||
);
|
||||
|
||||
const expectedLinks: string[] = [];
|
||||
const missingLinkedDocs: string[] = [];
|
||||
|
||||
for (const agreement of linkedAgreements) {
|
||||
const doc = data[agreement.id];
|
||||
if (doc) {
|
||||
expectedLinks.push(doc.doc_hash);
|
||||
} else {
|
||||
missingLinkedDocs.push(agreement.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingLinkedDocs.length > 0) {
|
||||
this.logger.warn(`Отсутствуют документы для линковки: ${missingLinkedDocs.join(', ')}`);
|
||||
}
|
||||
|
||||
// Проверяем, что все ожидаемые хеши присутствуют в заявлении
|
||||
@@ -190,20 +201,28 @@ export class ParticipantInteractor {
|
||||
);
|
||||
}
|
||||
|
||||
// Сохраняем документы в репозиторий кандидатов
|
||||
await this.candidateRepository.saveDocument(data.username, 'statement', data.statement);
|
||||
await this.candidateRepository.saveDocument(data.username, 'wallet_agreement', data.wallet_agreement);
|
||||
await this.candidateRepository.saveDocument(data.username, 'privacy_agreement', data.privacy_agreement);
|
||||
await this.candidateRepository.saveDocument(data.username, 'signature_agreement', data.signature_agreement);
|
||||
await this.candidateRepository.saveDocument(data.username, 'user_agreement', data.user_agreement);
|
||||
// Сохраняем заявление
|
||||
await this.candidateRepository.saveDocument(data.username, DocumentType.STATEMENT, data.statement);
|
||||
|
||||
// Сохраняем capitalization_agreement если есть
|
||||
if (data.capitalization_agreement) {
|
||||
await this.candidateRepository.saveDocument(data.username, 'capitalization_agreement', data.capitalization_agreement);
|
||||
// Сохраняем все требуемые соглашения динамически на основе конфигурации
|
||||
for (const agreementId of requiredAgreements) {
|
||||
const doc = data[agreementId];
|
||||
if (doc) {
|
||||
// Преобразуем agreementId в соответствующий DocumentType
|
||||
const documentType = this.mapAgreementIdToDocumentType(agreementId);
|
||||
if (documentType) {
|
||||
await this.candidateRepository.saveDocument(
|
||||
data.username,
|
||||
documentType,
|
||||
doc
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await this.candidateRepository.update(data.username, {
|
||||
braname: data.braname,
|
||||
program_key: data.program_key,
|
||||
});
|
||||
|
||||
// Обновляем статус пользователя
|
||||
@@ -216,6 +235,29 @@ export class ParticipantInteractor {
|
||||
return await this.accountDomainService.getAccount(data.username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразует AgreementId в соответствующий DocumentType
|
||||
*/
|
||||
private mapAgreementIdToDocumentType(agreementId: string): DocumentType | null {
|
||||
switch (agreementId) {
|
||||
case AgreementId.SIGNATURE_AGREEMENT:
|
||||
return DocumentType.SIGNATURE_AGREEMENT;
|
||||
case AgreementId.WALLET_AGREEMENT:
|
||||
return DocumentType.WALLET_AGREEMENT;
|
||||
case AgreementId.USER_AGREEMENT:
|
||||
return DocumentType.USER_AGREEMENT;
|
||||
case AgreementId.PRIVACY_AGREEMENT:
|
||||
return DocumentType.PRIVACY_AGREEMENT;
|
||||
case AgreementId.BLAGOROST_OFFER:
|
||||
return DocumentType.BLAGOROST_OFFER;
|
||||
case AgreementId.GENERATOR_OFFER:
|
||||
return DocumentType.GENERATOR_OFFER;
|
||||
default:
|
||||
this.logger.warn(`Неизвестный agreementId: ${agreementId}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async addParticipant(data: AddParticipantDomainInterface): Promise<AccountDomainEntity> {
|
||||
const newAccount: RegisterAccountDomainInterface = {
|
||||
...data,
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import { ObjectType, Field, Int } from '@nestjs/graphql';
|
||||
import { IsString, IsBoolean, IsNumber, IsArray, IsOptional } from 'class-validator';
|
||||
import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import type { IRegistrationProgram } from '~/domain/registration/config/agreement-config.interface';
|
||||
|
||||
/**
|
||||
* DTO для описания программы регистрации
|
||||
*/
|
||||
@ObjectType('RegistrationProgram')
|
||||
export class RegistrationProgramDTO {
|
||||
@Field({ description: 'Уникальный ключ программы' })
|
||||
@IsString()
|
||||
key!: string;
|
||||
|
||||
@Field({ description: 'Название программы для отображения' })
|
||||
@IsString()
|
||||
title!: string;
|
||||
|
||||
@Field({ description: 'Описание программы' })
|
||||
@IsString()
|
||||
description!: string;
|
||||
|
||||
@Field({ nullable: true, description: 'URL изображения (опционально)' })
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
image_url?: string;
|
||||
|
||||
@Field({ nullable: true, description: 'Минимальные требования для участия' })
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
requirements?: string;
|
||||
|
||||
@Field(() => [AccountType], { description: 'Для каких типов аккаунтов доступна программа' })
|
||||
@IsArray()
|
||||
applicable_account_types!: AccountType[];
|
||||
|
||||
@Field(() => Int, { description: 'Порядок отображения' })
|
||||
@IsNumber()
|
||||
order!: number;
|
||||
|
||||
constructor(data?: IRegistrationProgram) {
|
||||
if (data) {
|
||||
this.key = data.key;
|
||||
this.title = data.title;
|
||||
this.description = data.description;
|
||||
this.image_url = data.image_url;
|
||||
this.requirements = data.requirements;
|
||||
this.applicable_account_types = data.applicable_account_types;
|
||||
this.order = data.order;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO для конфигурации программ регистрации
|
||||
*/
|
||||
@ObjectType('RegistrationConfig')
|
||||
export class RegistrationConfigDTO {
|
||||
@Field({ description: 'Нужен ли выбор программы' })
|
||||
@IsBoolean()
|
||||
requires_selection!: boolean;
|
||||
|
||||
@Field(() => [RegistrationProgramDTO], { description: 'Доступные программы' })
|
||||
@IsArray()
|
||||
programs!: RegistrationProgramDTO[];
|
||||
|
||||
constructor(data?: { requires_selection: boolean; programs: IRegistrationProgram[] }) {
|
||||
if (data) {
|
||||
this.requires_selection = data.requires_selection;
|
||||
this.programs = data.programs.map((p) => new RegistrationProgramDTO(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,9 @@ import { SettingsDTO, UpdateSettingsInputDTO } from '../dto/settings.dto';
|
||||
import { StartInstallInputDTO } from '../dto/start-install-input.dto';
|
||||
import { StartInstallResultDTO } from '../dto/start-install-result.dto';
|
||||
import { GetInstallationStatusInputDTO, InstallationStatusDTO } from '../dto/installation-status.dto';
|
||||
import { RegistrationConfigDTO } from '../dto/registration-config.dto';
|
||||
import { AuthRoles } from '~/application/auth/decorators/auth.decorator';
|
||||
import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
|
||||
@Resolver(() => SystemInfoDTO)
|
||||
export class SystemResolver {
|
||||
@@ -102,4 +104,15 @@ export class SystemResolver {
|
||||
): Promise<SettingsDTO> {
|
||||
return this.systemService.updateSettings(data);
|
||||
}
|
||||
|
||||
@Query(() => RegistrationConfigDTO, {
|
||||
name: 'getRegistrationConfig',
|
||||
description: 'Получить конфигурацию программ регистрации для кооператива',
|
||||
})
|
||||
async getRegistrationConfig(
|
||||
@Args('coopname', { type: () => String }) coopname: string,
|
||||
@Args('account_type', { type: () => AccountType }) accountType: AccountType
|
||||
): Promise<RegistrationConfigDTO> {
|
||||
return this.systemService.getRegistrationConfig(coopname, accountType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { SystemInfoDTO } from '../dto/system.dto';
|
||||
import { SystemInteractor } from '../interactors/system.interactor';
|
||||
import { ProviderService } from '~/application/provider/services/provider.service';
|
||||
@@ -14,10 +14,21 @@ import { OrganizationWithBankAccountDTO } from '~/application/common/dto/organiz
|
||||
import { OrganizationDomainEntity } from '~/domain/branch/entities/organization-domain.entity';
|
||||
import config from '~/config/config';
|
||||
import { SettingsDTO, UpdateSettingsInputDTO } from '../dto/settings.dto';
|
||||
import { RegistrationConfigDTO } from '../dto/registration-config.dto';
|
||||
import {
|
||||
AgreementConfigurationService,
|
||||
AGREEMENT_CONFIGURATION_SERVICE,
|
||||
} from '~/domain/registration/services/agreement-configuration.service';
|
||||
import type { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
|
||||
@Injectable()
|
||||
export class SystemService {
|
||||
constructor(private readonly systemInteractor: SystemInteractor, private readonly providerService: ProviderService) {}
|
||||
constructor(
|
||||
private readonly systemInteractor: SystemInteractor,
|
||||
private readonly providerService: ProviderService,
|
||||
@Inject(AGREEMENT_CONFIGURATION_SERVICE)
|
||||
private readonly agreementConfigService: AgreementConfigurationService
|
||||
) {}
|
||||
|
||||
public async getInfo(): Promise<SystemInfoDTO> {
|
||||
const info = await this.systemInteractor.getInfo();
|
||||
@@ -91,4 +102,28 @@ export class SystemService {
|
||||
const settings = await this.systemInteractor.updateSettings(data);
|
||||
return new SettingsDTO(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить конфигурацию программ регистрации для кооператива
|
||||
* @param coopname - название кооператива
|
||||
* @param accountType - тип аккаунта
|
||||
* @returns конфигурация программ регистрации
|
||||
*/
|
||||
public async getRegistrationConfig(coopname: string, accountType: AccountType): Promise<RegistrationConfigDTO> {
|
||||
const config = this.agreementConfigService.getCooperativeProgramsConfig(coopname);
|
||||
|
||||
if (!config) {
|
||||
return new RegistrationConfigDTO({
|
||||
requires_selection: false,
|
||||
programs: [],
|
||||
});
|
||||
}
|
||||
|
||||
const programs = this.agreementConfigService.getAvailablePrograms(coopname, accountType);
|
||||
|
||||
return new RegistrationConfigDTO({
|
||||
requires_selection: config.requires_selection && programs.length > 1,
|
||||
programs,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -1,6 +1,7 @@
|
||||
import { InputType, Field } from '@nestjs/graphql';
|
||||
import { IsString, IsEnum } from 'class-validator';
|
||||
import { IsString, IsEnum, IsOptional } from 'class-validator';
|
||||
import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import { ProgramKey } from '~/domain/registration/enum';
|
||||
|
||||
@InputType('GenerateRegistrationDocumentsInput')
|
||||
export class GenerateRegistrationDocumentsInputDTO {
|
||||
@@ -15,4 +16,9 @@ export class GenerateRegistrationDocumentsInputDTO {
|
||||
@Field(() => AccountType, { description: 'Тип аккаунта пайщика' })
|
||||
@IsEnum(AccountType)
|
||||
account_type!: AccountType;
|
||||
|
||||
@Field({ nullable: true, description: 'Ключ выбранной программы регистрации (опционально)' })
|
||||
@IsEnum(ProgramKey)
|
||||
@IsOptional()
|
||||
program_key?: ProgramKey;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
} from '~/domain/registration/services/registration-documents.service';
|
||||
import type { GenerateRegistrationDocumentsInputDTO } from '../dto/generate-registration-documents-input.dto';
|
||||
import { GenerateRegistrationDocumentsOutputDTO } from '../dto/generate-registration-documents-output.dto';
|
||||
import type { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
|
||||
@Injectable()
|
||||
export class RegistrationService {
|
||||
@@ -20,11 +19,7 @@ export class RegistrationService {
|
||||
async generateRegistrationDocuments(
|
||||
data: GenerateRegistrationDocumentsInputDTO
|
||||
): Promise<GenerateRegistrationDocumentsOutputDTO> {
|
||||
const result = await this.registrationDocumentsService.generateRegistrationDocuments({
|
||||
coopname: data.coopname,
|
||||
username: data.username,
|
||||
account_type: data.account_type as AccountType,
|
||||
});
|
||||
const result = await this.registrationDocumentsService.generateRegistrationDocuments(data);
|
||||
|
||||
return new GenerateRegistrationDocumentsOutputDTO(result);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
|
||||
import { ProgramKey } from '~/domain/registration/enum';
|
||||
|
||||
/**
|
||||
* Домен-интерфейс кандидата в пайщики
|
||||
@@ -16,10 +17,12 @@ export interface CandidateDomainInterface {
|
||||
signature_agreement?: ISignedDocumentDomainInterface;
|
||||
privacy_agreement?: ISignedDocumentDomainInterface;
|
||||
user_agreement?: ISignedDocumentDomainInterface;
|
||||
capitalization_agreement?: ISignedDocumentDomainInterface;
|
||||
blagorost_offer?: ISignedDocumentDomainInterface;
|
||||
generator_offer?: ISignedDocumentDomainInterface;
|
||||
};
|
||||
registration_hash: string;
|
||||
referer?: string;
|
||||
public_key: string;
|
||||
meta?: string;
|
||||
program_key?: ProgramKey; // Ключ выбранной программы регистрации
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import type { CandidateDomainInterface } from '../interfaces/candidate-domain.interface';
|
||||
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
|
||||
import { DocumentType } from '~/domain/registration/enum';
|
||||
|
||||
export interface CandidateRepository {
|
||||
findByUsername(username: string): Promise<CandidateDomainInterface | null>;
|
||||
@@ -10,13 +11,7 @@ export interface CandidateRepository {
|
||||
update(username: string, data: Partial<CandidateDomainInterface>): Promise<CandidateDomainInterface | null>;
|
||||
saveDocument(
|
||||
username: string,
|
||||
documentType:
|
||||
| 'statement'
|
||||
| 'wallet_agreement'
|
||||
| 'signature_agreement'
|
||||
| 'privacy_agreement'
|
||||
| 'user_agreement'
|
||||
| 'capitalization_agreement',
|
||||
documentType: DocumentType,
|
||||
document: ISignedDocumentDomainInterface
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
+6
-1
@@ -1,4 +1,5 @@
|
||||
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
|
||||
import { ProgramKey } from '~/domain/registration/enum';
|
||||
|
||||
export interface RegisterParticipantDomainInterface {
|
||||
username: string;
|
||||
@@ -9,5 +10,9 @@ export interface RegisterParticipantDomainInterface {
|
||||
user_agreement: ISignedDocumentDomainInterface;
|
||||
wallet_agreement: ISignedDocumentDomainInterface;
|
||||
/** Опциональное соглашение по капитализации (только для individual) */
|
||||
capitalization_agreement?: ISignedDocumentDomainInterface;
|
||||
blagorost_offer?: ISignedDocumentDomainInterface;
|
||||
/** Опциональное соглашение по генератору (для программы generation) */
|
||||
generator_offer?: ISignedDocumentDomainInterface;
|
||||
/** Ключ выбранной программы регистрации */
|
||||
program_key?: ProgramKey;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import type { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import { AgreementType, AgreementId, ProgramKey } from '../enum';
|
||||
|
||||
/**
|
||||
* Конфигурация одного соглашения при регистрации
|
||||
*/
|
||||
export interface IAgreementConfigItem {
|
||||
/**
|
||||
* Уникальный идентификатор типа соглашения (wallet, signature, privacy, user, capitalization)
|
||||
* Уникальный идентификатор типа соглашения
|
||||
*/
|
||||
id: string;
|
||||
id: AgreementId;
|
||||
|
||||
/**
|
||||
* registry_id для генерации документа на фабрике документов
|
||||
@@ -15,9 +16,9 @@ export interface IAgreementConfigItem {
|
||||
registry_id: number;
|
||||
|
||||
/**
|
||||
* Тип соглашения для блокчейна (wallet, signature, privacy, user, capitalization)
|
||||
* Тип соглашения для блокчейна
|
||||
*/
|
||||
agreement_type: string;
|
||||
agreement_type: AgreementType;
|
||||
|
||||
/**
|
||||
* Человекочитаемое название документа
|
||||
@@ -64,3 +65,46 @@ export interface IRegistrationAgreementsConfig {
|
||||
*/
|
||||
agreements: IAgreementConfigItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Описание программы регистрации с её соглашениями
|
||||
*/
|
||||
export interface IRegistrationProgram {
|
||||
/** Уникальный ключ программы */
|
||||
key: ProgramKey;
|
||||
|
||||
/** Название программы для отображения */
|
||||
title: string;
|
||||
|
||||
/** Описание программы */
|
||||
description: string;
|
||||
|
||||
/** URL изображения (опционально) */
|
||||
image_url?: string;
|
||||
|
||||
/** Минимальные требования для участия */
|
||||
requirements?: string;
|
||||
|
||||
/** Для каких типов аккаунтов доступна эта программа */
|
||||
applicable_account_types: AccountType[];
|
||||
|
||||
/** Список ID соглашений, которые требуются для этой программы */
|
||||
agreement_ids: AgreementId[];
|
||||
|
||||
/** Порядок отображения */
|
||||
order: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Конфигурация программ регистрации для кооператива
|
||||
*/
|
||||
export interface ICooperativeRegistrationPrograms {
|
||||
/** Название кооператива */
|
||||
coopname: string;
|
||||
|
||||
/** Доступные программы */
|
||||
programs: IRegistrationProgram[];
|
||||
|
||||
/** Нужен ли выбор программы (если false - используется первая подходящая) */
|
||||
requires_selection: boolean;
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './agreement-config.interface';
|
||||
export * from './registration-agreements.config';
|
||||
export * from './registration-programs.config';
|
||||
|
||||
+24
-11
@@ -1,6 +1,7 @@
|
||||
import { Cooperative } from 'cooptypes';
|
||||
import type { IRegistrationAgreementsConfig } from './agreement-config.interface';
|
||||
import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import { AgreementType, AgreementId } from '../enum';
|
||||
|
||||
/**
|
||||
* Конфигурация соглашений, требуемых при регистрации пайщика.
|
||||
@@ -12,9 +13,9 @@ import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
export const REGISTRATION_AGREEMENTS_CONFIG: IRegistrationAgreementsConfig = {
|
||||
agreements: [
|
||||
{
|
||||
id: 'signature_agreement',
|
||||
id: AgreementId.SIGNATURE_AGREEMENT,
|
||||
registry_id: Cooperative.Registry.RegulationElectronicSignature.registry_id,
|
||||
agreement_type: 'signature',
|
||||
agreement_type: AgreementType.SIGNATURE,
|
||||
title: 'Соглашение о порядке и правилах использования простой электронной подписи',
|
||||
checkbox_text: 'Я прочитал и принимаю',
|
||||
link_text: 'положение о порядке и правилах использования простой электронной подписи',
|
||||
@@ -24,9 +25,9 @@ export const REGISTRATION_AGREEMENTS_CONFIG: IRegistrationAgreementsConfig = {
|
||||
order: 1,
|
||||
},
|
||||
{
|
||||
id: 'wallet_agreement',
|
||||
id: AgreementId.WALLET_AGREEMENT,
|
||||
registry_id: Cooperative.Registry.WalletAgreement.registry_id,
|
||||
agreement_type: 'wallet',
|
||||
agreement_type: AgreementType.WALLET,
|
||||
title: 'Соглашение о целевой потребительской программе "Цифровой Кошелёк"',
|
||||
checkbox_text: 'Я прочитал и принимаю',
|
||||
link_text: 'положение о целевой потребительской программе "Цифровой Кошелёк"',
|
||||
@@ -36,9 +37,9 @@ export const REGISTRATION_AGREEMENTS_CONFIG: IRegistrationAgreementsConfig = {
|
||||
order: 2,
|
||||
},
|
||||
{
|
||||
id: 'user_agreement',
|
||||
id: AgreementId.USER_AGREEMENT,
|
||||
registry_id: Cooperative.Registry.UserAgreement.registry_id,
|
||||
agreement_type: 'user',
|
||||
agreement_type: AgreementType.USER,
|
||||
title: 'Пользовательское соглашение',
|
||||
checkbox_text: 'Я прочитал и принимаю',
|
||||
link_text: 'пользовательское соглашение',
|
||||
@@ -48,9 +49,9 @@ export const REGISTRATION_AGREEMENTS_CONFIG: IRegistrationAgreementsConfig = {
|
||||
order: 3,
|
||||
},
|
||||
{
|
||||
id: 'privacy_agreement',
|
||||
id: AgreementId.PRIVACY_AGREEMENT,
|
||||
registry_id: Cooperative.Registry.PrivacyPolicy.registry_id,
|
||||
agreement_type: 'privacy',
|
||||
agreement_type: AgreementType.PRIVACY,
|
||||
title: 'Политика конфиденциальности',
|
||||
checkbox_text: 'Я прочитал и принимаю',
|
||||
link_text: 'политику конфиденциальности',
|
||||
@@ -60,9 +61,9 @@ export const REGISTRATION_AGREEMENTS_CONFIG: IRegistrationAgreementsConfig = {
|
||||
order: 4,
|
||||
},
|
||||
{
|
||||
id: 'capitalization_agreement',
|
||||
registry_id: Cooperative.Registry.CapitalizationAgreement.registry_id,
|
||||
agreement_type: 'capital',
|
||||
id: AgreementId.BLAGOROST_OFFER,
|
||||
registry_id: Cooperative.Registry.BlagorostOffer.registry_id,
|
||||
agreement_type: AgreementType.CAPITAL,
|
||||
title: 'Оферта по целевой потребительской программе "Благорост"',
|
||||
checkbox_text: 'Я прочитал и принимаю',
|
||||
link_text: 'оферту по целевой потребительской программе "Благорост"',
|
||||
@@ -71,5 +72,17 @@ export const REGISTRATION_AGREEMENTS_CONFIG: IRegistrationAgreementsConfig = {
|
||||
applicable_account_types: [AccountType.individual],
|
||||
order: 5,
|
||||
},
|
||||
{
|
||||
id: AgreementId.GENERATOR_OFFER,
|
||||
registry_id: Cooperative.Registry.GeneratorOffer.registry_id,
|
||||
agreement_type: AgreementType.GENERATOR,
|
||||
title: 'Оферта по целевой потребительской программе "Генератор"',
|
||||
checkbox_text: 'Я прочитал и принимаю',
|
||||
link_text: 'оферту по целевой потребительской программе "Генератор"',
|
||||
is_blockchain_agreement: true,
|
||||
link_to_statement: true,
|
||||
applicable_account_types: [],
|
||||
order: 6,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { ICooperativeRegistrationPrograms } from './agreement-config.interface';
|
||||
import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import { ProgramKey, AgreementId } from '../enum';
|
||||
|
||||
/**
|
||||
* Конфигурация программ регистрации для разных кооперативов.
|
||||
* Здесь определяются доступные программы, их описания и связанные соглашения.
|
||||
*/
|
||||
export const REGISTRATION_PROGRAMS_CONFIG: ICooperativeRegistrationPrograms[] = [
|
||||
{
|
||||
coopname: 'voskhod',
|
||||
requires_selection: true,
|
||||
programs: [
|
||||
{
|
||||
key: ProgramKey.GENERATION,
|
||||
title: 'Программа Генерация',
|
||||
description:
|
||||
'Участвовать в производстве Кооперативной Экономики через вклад временем, имуществом или деньгами в конкретные проекты. Минимальный взнос 10 часов в месяц.',
|
||||
applicable_account_types: [AccountType.individual, AccountType.entrepreneur],
|
||||
agreement_ids: [AgreementId.GENERATOR_OFFER],
|
||||
order: 1,
|
||||
},
|
||||
{
|
||||
key: ProgramKey.CAPITALIZATION,
|
||||
title: 'Программа Капитализация',
|
||||
description:
|
||||
'Участвовать в производстве Кооперативной Экономики через вклад имуществом или денег в систему. Минимальный взнос 100 000 руб в течение 14 дней.',
|
||||
applicable_account_types: [AccountType.individual, AccountType.entrepreneur],
|
||||
agreement_ids: [AgreementId.BLAGOROST_OFFER],
|
||||
order: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Идентификаторы соглашений для регистрации
|
||||
*/
|
||||
export enum AgreementId {
|
||||
/** Соглашение о порядке и правилах использования простой электронной подписи */
|
||||
SIGNATURE_AGREEMENT = 'signature_agreement',
|
||||
|
||||
/** Соглашение о целевой потребительской программе "Цифровой Кошелёк" */
|
||||
WALLET_AGREEMENT = 'wallet_agreement',
|
||||
|
||||
/** Пользовательское соглашение */
|
||||
USER_AGREEMENT = 'user_agreement',
|
||||
|
||||
/** Политика конфиденциальности */
|
||||
PRIVACY_AGREEMENT = 'privacy_agreement',
|
||||
|
||||
/** Соглашение о капитализации */
|
||||
BLAGOROST_OFFER = 'blagorost_offer',
|
||||
|
||||
/** Оферта по целевой потребительской программе "Генератор" */
|
||||
GENERATOR_OFFER = 'generator_offer',
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Типы соглашений для отправки в блокчейн
|
||||
*/
|
||||
export enum AgreementType {
|
||||
/** Соглашение о порядке и правилах использования простой электронной подписи */
|
||||
SIGNATURE = 'signature',
|
||||
|
||||
/** Соглашение о целевой потребительской программе "Цифровой Кошелёк" */
|
||||
WALLET = 'wallet',
|
||||
|
||||
/** Пользовательское соглашение */
|
||||
USER = 'user',
|
||||
|
||||
/** Политика конфиденциальности */
|
||||
PRIVACY = 'privacy',
|
||||
|
||||
/** Соглашение о капитализации */
|
||||
CAPITAL = 'capital',
|
||||
|
||||
/** Оферта по целевой потребительской программе "Генератор" */
|
||||
GENERATOR = 'generator',
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Типы документов для регистрации кандидата
|
||||
*/
|
||||
export enum DocumentType {
|
||||
/** Заявление на вступление в кооператив */
|
||||
STATEMENT = 'statement',
|
||||
|
||||
/** Соглашение о цифровом кошельке */
|
||||
WALLET_AGREEMENT = 'wallet_agreement',
|
||||
|
||||
/** Соглашение о порядке использования электронной подписи */
|
||||
SIGNATURE_AGREEMENT = 'signature_agreement',
|
||||
|
||||
/** Политика конфиденциальности */
|
||||
PRIVACY_AGREEMENT = 'privacy_agreement',
|
||||
|
||||
/** Пользовательское соглашение */
|
||||
USER_AGREEMENT = 'user_agreement',
|
||||
|
||||
/** Соглашение о капитализации */
|
||||
BLAGOROST_OFFER = 'blagorost_offer',
|
||||
|
||||
/** Оферта по программе генератора */
|
||||
GENERATOR_OFFER = 'generator_offer',
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export { AgreementType } from './agreement-type.enum';
|
||||
export { AgreementId } from './agreement-id.enum';
|
||||
export { ProgramKey } from './program-key.enum';
|
||||
export { DocumentType } from './document-type.enum';
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Ключи программ регистрации
|
||||
*/
|
||||
export enum ProgramKey {
|
||||
/** Программа Генерация - вклад временем, имуществом или деньгами в конкретные проекты */
|
||||
GENERATION = 'generation',
|
||||
|
||||
/** Программа Капитализация - вклад имуществом или денег в систему */
|
||||
CAPITALIZATION = 'capitalization',
|
||||
}
|
||||
+5
-2
@@ -1,5 +1,6 @@
|
||||
import type { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import type { GeneratedDocumentDomainInterface } from '~/domain/document/interfaces/generated-document-domain.interface';
|
||||
import { ProgramKey, type AgreementId, type AgreementType } from '../enum';
|
||||
|
||||
/**
|
||||
* Входные данные для генерации пакета документов при регистрации
|
||||
@@ -11,6 +12,8 @@ export interface IGenerateRegistrationDocumentsInput {
|
||||
username: string;
|
||||
/** Тип аккаунта пайщика */
|
||||
account_type: AccountType;
|
||||
/** Ключ выбранной программы регистрации (опционально) */
|
||||
program_key?: ProgramKey;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18,9 +21,9 @@ export interface IGenerateRegistrationDocumentsInput {
|
||||
*/
|
||||
export interface IGeneratedRegistrationDocument {
|
||||
/** Идентификатор соглашения (wallet_agreement, signature_agreement, etc.) */
|
||||
id: string;
|
||||
id: AgreementId;
|
||||
/** Тип соглашения для блокчейна */
|
||||
agreement_type: string;
|
||||
agreement_type: AgreementType;
|
||||
/** Название документа */
|
||||
title: string;
|
||||
/** Текст для галочки на фронте */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Global, Module, forwardRef } from '@nestjs/common';
|
||||
import { AgreementConfigurationService, AGREEMENT_CONFIGURATION_SERVICE } from './services/agreement-configuration.service';
|
||||
import { RegistrationDocumentsService, REGISTRATION_DOCUMENTS_SERVICE } from './services/registration-documents.service';
|
||||
import { CooperativeConfigService } from './services/cooperative-config.service';
|
||||
import { DocumentModule } from '~/application/document/document.module';
|
||||
|
||||
/**
|
||||
@@ -12,6 +13,7 @@ import { DocumentModule } from '~/application/document/document.module';
|
||||
@Module({
|
||||
imports: [forwardRef(() => DocumentModule)],
|
||||
providers: [
|
||||
CooperativeConfigService,
|
||||
AgreementConfigurationService,
|
||||
{
|
||||
provide: AGREEMENT_CONFIGURATION_SERVICE,
|
||||
|
||||
+111
-35
@@ -1,7 +1,14 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { REGISTRATION_AGREEMENTS_CONFIG } from '../config/registration-agreements.config';
|
||||
import type { IAgreementConfigItem } from '../config/agreement-config.interface';
|
||||
import type { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import { REGISTRATION_PROGRAMS_CONFIG } from '../config/registration-programs.config';
|
||||
import type {
|
||||
IAgreementConfigItem,
|
||||
ICooperativeRegistrationPrograms,
|
||||
IRegistrationProgram,
|
||||
} from '../config/agreement-config.interface';
|
||||
import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import { AgreementId, ProgramKey } from '../enum';
|
||||
import { CooperativeConfigService } from './cooperative-config.service';
|
||||
|
||||
export const AGREEMENT_CONFIGURATION_SERVICE = Symbol('AgreementConfigurationService');
|
||||
|
||||
@@ -10,43 +17,75 @@ export const AGREEMENT_CONFIGURATION_SERVICE = Symbol('AgreementConfigurationSer
|
||||
*/
|
||||
@Injectable()
|
||||
export class AgreementConfigurationService {
|
||||
constructor(private readonly cooperativeConfigService: CooperativeConfigService) {}
|
||||
/**
|
||||
* Получить все соглашения для указанного типа аккаунта
|
||||
* @param accountType - тип аккаунта (individual, organization, entrepreneur)
|
||||
* @param coopname - название кооператива (для временного исключения capitalization_agreement)
|
||||
* @param coopname - название кооператива (для временного исключения blagorost_offer)
|
||||
* @param programKey - ключ выбранной программы регистрации (опционально)
|
||||
* @returns отсортированный по order массив конфигураций соглашений
|
||||
*/
|
||||
getAgreementsForAccountType(accountType: AccountType, coopname?: string): IAgreementConfigItem[] {
|
||||
return REGISTRATION_AGREEMENTS_CONFIG.agreements
|
||||
.filter((agreement) => agreement.applicable_account_types.includes(accountType))
|
||||
.filter((agreement) => {
|
||||
// ВРЕМЕННО: исключаем capitalization_agreement для всех кооперативов кроме voskhod
|
||||
if (agreement.id === 'capitalization_agreement' && coopname && coopname !== 'voskhod') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.sort((a, b) => a.order - b.order);
|
||||
/**
|
||||
* Получить соглашения по умолчанию для кооператива (без учета программ)
|
||||
*/
|
||||
private getDefaultAgreementsForCooperative(
|
||||
accountType: AccountType,
|
||||
coopname?: string
|
||||
): IAgreementConfigItem[] {
|
||||
const coopnameValue = coopname || '';
|
||||
const excludedAgreements = this.cooperativeConfigService.getExcludedFromBaseAgreements(coopnameValue);
|
||||
|
||||
// Получить базовые соглашения, исключая те, которые управляются отдельно
|
||||
const baseAgreements = REGISTRATION_AGREEMENTS_CONFIG.agreements
|
||||
.filter((a) => a.applicable_account_types.includes(accountType))
|
||||
.filter((a) => !excludedAgreements.includes(a.id));
|
||||
|
||||
// Добавить дополнительные соглашения по умолчанию для кооператива
|
||||
const additionalAgreements = this.cooperativeConfigService
|
||||
.getDefaultAdditionalAgreements(coopnameValue, accountType)
|
||||
.map(id => this.getAgreementById(id))
|
||||
.filter((a): a is IAgreementConfigItem => a !== null);
|
||||
|
||||
return [...baseAgreements, ...additionalAgreements].sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
getAgreementsForAccountType(
|
||||
accountType: AccountType,
|
||||
coopname?: string,
|
||||
programKey?: ProgramKey
|
||||
): IAgreementConfigItem[] {
|
||||
// Получить соглашения по умолчанию для кооператива
|
||||
const defaultAgreements = this.getDefaultAgreementsForCooperative(accountType, coopname);
|
||||
|
||||
// Если указана программа - добавляем её соглашения
|
||||
if (programKey && coopname) {
|
||||
const programAgreements = this.getAgreementsForProgram(programKey, coopname);
|
||||
return [...defaultAgreements, ...programAgreements].sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
return defaultAgreements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить соглашения, которые нужно отправить в блокчейн через sendAgreement
|
||||
* @param accountType - тип аккаунта
|
||||
* @param coopname - название кооператива (для временного исключения capitalization_agreement)
|
||||
* @param coopname - название кооператива (для временного исключения blagorost_offer)
|
||||
* @param programKey - ключ выбранной программы регистрации
|
||||
* @returns массив конфигураций blockchain agreements
|
||||
*/
|
||||
getBlockchainAgreements(accountType: AccountType, coopname?: string): IAgreementConfigItem[] {
|
||||
return this.getAgreementsForAccountType(accountType, coopname).filter((agreement) => agreement.is_blockchain_agreement);
|
||||
getBlockchainAgreements(accountType: AccountType, coopname?: string, programKey?: ProgramKey): IAgreementConfigItem[] {
|
||||
return this.getAgreementsForAccountType(accountType, coopname, programKey).filter((agreement) => agreement.is_blockchain_agreement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить соглашения, которые нужно линковать в заявление на вступление
|
||||
* @param accountType - тип аккаунта
|
||||
* @param coopname - название кооператива (для временного исключения capitalization_agreement)
|
||||
* @param coopname - название кооператива (для временного исключения blagorost_offer)
|
||||
* @param programKey - ключ выбранной программы регистрации
|
||||
* @returns массив конфигураций соглашений для линковки
|
||||
*/
|
||||
getLinkedAgreements(accountType: AccountType, coopname?: string): IAgreementConfigItem[] {
|
||||
return this.getAgreementsForAccountType(accountType, coopname).filter((agreement) => agreement.link_to_statement);
|
||||
getLinkedAgreements(accountType: AccountType, coopname?: string, programKey?: ProgramKey): IAgreementConfigItem[] {
|
||||
return this.getAgreementsForAccountType(accountType, coopname, programKey).filter((agreement) => agreement.link_to_statement);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +93,7 @@ export class AgreementConfigurationService {
|
||||
* @param id - идентификатор соглашения (wallet_agreement, signature_agreement, etc.)
|
||||
* @returns конфигурация соглашения или null
|
||||
*/
|
||||
getAgreementById(id: string): IAgreementConfigItem | null {
|
||||
getAgreementById(id: AgreementId): IAgreementConfigItem | null {
|
||||
return REGISTRATION_AGREEMENTS_CONFIG.agreements.find((agreement) => agreement.id === id) || null;
|
||||
}
|
||||
|
||||
@@ -70,28 +109,65 @@ export class AgreementConfigurationService {
|
||||
* Проверить, требуется ли соглашение для данного типа аккаунта
|
||||
* @param agreementId - идентификатор соглашения
|
||||
* @param accountType - тип аккаунта
|
||||
* @param coopname - название кооператива (для временного исключения capitalization_agreement)
|
||||
* @param coopname - название кооператива (для временного исключения blagorost_offer)
|
||||
* @returns true если соглашение требуется
|
||||
*/
|
||||
isAgreementRequired(agreementId: string, accountType: AccountType, coopname?: string): boolean {
|
||||
const agreement = this.getAgreementById(agreementId);
|
||||
if (!agreement) return false;
|
||||
|
||||
// ВРЕМЕННО: исключаем capitalization_agreement для всех кооперативов кроме voskhod
|
||||
if (agreementId === 'capitalization_agreement' && coopname && coopname !== 'voskhod') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return agreement.applicable_account_types.includes(accountType);
|
||||
isAgreementRequired(agreementId: AgreementId, accountType: AccountType, coopname?: string, programKey?: ProgramKey): boolean {
|
||||
// Проверить, входит ли соглашение в список требуемых для данного кооператива и типа аккаунта
|
||||
const requiredAgreements = this.getRequiredAgreementIds(accountType, coopname, programKey);
|
||||
return requiredAgreements.includes(agreementId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список идентификаторов всех требуемых соглашений для типа аккаунта
|
||||
* @param accountType - тип аккаунта
|
||||
* @param coopname - название кооператива (для временного исключения capitalization_agreement)
|
||||
* @param coopname - название кооператива (для временного исключения blagorost_offer)
|
||||
* @param programKey - ключ выбранной программы регистрации
|
||||
* @returns массив идентификаторов
|
||||
*/
|
||||
getRequiredAgreementIds(accountType: AccountType, coopname?: string): string[] {
|
||||
return this.getAgreementsForAccountType(accountType, coopname).map((a) => a.id);
|
||||
getRequiredAgreementIds(accountType: AccountType, coopname?: string, programKey?: ProgramKey): string[] {
|
||||
return this.getAgreementsForAccountType(accountType, coopname, programKey).map((a) => a.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить доступные программы регистрации для кооператива и типа аккаунта
|
||||
* @param coopname - название кооператива
|
||||
* @param accountType - тип аккаунта
|
||||
* @returns массив доступных программ
|
||||
*/
|
||||
getAvailablePrograms(coopname: string, accountType: AccountType): IRegistrationProgram[] {
|
||||
const config = REGISTRATION_PROGRAMS_CONFIG.find((c) => c.coopname === coopname);
|
||||
if (!config) return [];
|
||||
|
||||
return config.programs
|
||||
.filter((p) => p.applicable_account_types.includes(accountType))
|
||||
.sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить конфигурацию программ для кооператива
|
||||
* @param coopname - название кооператива
|
||||
* @returns конфигурация программ или null
|
||||
*/
|
||||
getCooperativeProgramsConfig(coopname: string): ICooperativeRegistrationPrograms | null {
|
||||
return REGISTRATION_PROGRAMS_CONFIG.find((c) => c.coopname === coopname) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить соглашения для программы
|
||||
* @param programKey - ключ программы
|
||||
* @param coopname - название кооператива
|
||||
* @returns массив соглашений для программы
|
||||
*/
|
||||
getAgreementsForProgram(programKey: ProgramKey, coopname: string): IAgreementConfigItem[] {
|
||||
const config = REGISTRATION_PROGRAMS_CONFIG.find((c) => c.coopname === coopname);
|
||||
if (!config) return [];
|
||||
|
||||
const program = config.programs.find((p) => p.key === programKey);
|
||||
if (!program) return [];
|
||||
|
||||
return program.agreement_ids
|
||||
.map((id) => this.getAgreementById(id))
|
||||
.filter((a): a is IAgreementConfigItem => a !== null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { AgreementId } from '../enum';
|
||||
import { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
|
||||
/**
|
||||
* Сервис для определения конфигурации кооперативов
|
||||
*/
|
||||
@Injectable()
|
||||
export class CooperativeConfigService {
|
||||
/**
|
||||
* Получить список кооперативов, которые поддерживают программы регистрации
|
||||
*/
|
||||
getCooperativesWithPrograms(): string[] {
|
||||
return ['voskhod'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить, поддерживает ли кооператив программы регистрации
|
||||
*/
|
||||
hasPrograms(coopname: string): boolean {
|
||||
return this.getCooperativesWithPrograms().includes(coopname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить дополнительные соглашения по умолчанию для кооператива
|
||||
*/
|
||||
getDefaultAdditionalAgreements(coopname: string, accountType: AccountType): AgreementId[] {
|
||||
if (coopname === 'voskhod' && accountType === AccountType.individual) {
|
||||
return [AgreementId.BLAGOROST_OFFER];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список соглашений, которые нужно исключить из базовых для данного кооператива
|
||||
*/
|
||||
getExcludedFromBaseAgreements(coopname: string): AgreementId[] {
|
||||
// Для всех кооперативов исключаем соглашения, которые добавляются через программы или дополнительные
|
||||
return [AgreementId.BLAGOROST_OFFER, AgreementId.GENERATOR_OFFER];
|
||||
}
|
||||
}
|
||||
+19
-10
@@ -8,6 +8,7 @@ import type {
|
||||
IGeneratedRegistrationDocument,
|
||||
} from '../interfaces/registration-documents.interface';
|
||||
import type { AccountType } from '~/application/account/enum/account-type.enum';
|
||||
import { ProgramKey } from '../enum';
|
||||
|
||||
export const REGISTRATION_DOCUMENTS_SERVICE = Symbol('RegistrationDocumentsService');
|
||||
|
||||
@@ -33,16 +34,22 @@ export class RegistrationDocumentsService {
|
||||
async generateRegistrationDocuments(
|
||||
input: IGenerateRegistrationDocumentsInput
|
||||
): Promise<IGenerateRegistrationDocumentsOutput> {
|
||||
const { coopname, username, account_type } = input;
|
||||
const { coopname, username, account_type, program_key } = input;
|
||||
|
||||
this.logger.log(`Начало генерации документов для регистрации: username=${username}, account_type=${account_type}`);
|
||||
this.logger.log(
|
||||
`Начало генерации документов для регистрации: username=${username}, account_type=${account_type}, program_key=${program_key || 'не указан'}`
|
||||
);
|
||||
|
||||
// ВАЖНО: Проверяем, что запрашиваемый тип аккаунта совпадает с типом зарегистрированного кандидата
|
||||
// Эта проверка делается на уровне сервиса для ранней валидации
|
||||
// (дополнительная проверка также будет в registerParticipant)
|
||||
|
||||
// Получаем список соглашений для данного типа аккаунта
|
||||
const agreementsConfig = this.agreementConfigService.getAgreementsForAccountType(account_type, coopname);
|
||||
// Получаем список соглашений для данного типа аккаунта и выбранной программы
|
||||
const agreementsConfig = this.agreementConfigService.getAgreementsForAccountType(
|
||||
account_type,
|
||||
coopname,
|
||||
program_key
|
||||
);
|
||||
|
||||
this.logger.log(`Найдено ${agreementsConfig.length} соглашений для типа ${account_type} (кооператив: ${coopname})`);
|
||||
|
||||
@@ -103,20 +110,22 @@ export class RegistrationDocumentsService {
|
||||
/**
|
||||
* Получить список идентификаторов документов, которые нужно линковать в заявление
|
||||
* @param accountType - тип аккаунта
|
||||
* @param coopname - название кооператива (для временного исключения capitalization_agreement)
|
||||
* @param coopname - название кооператива (для временного исключения blagorost_offer)
|
||||
* @param programKey - ключ выбранной программы регистрации
|
||||
* @returns массив id документов для линковки
|
||||
*/
|
||||
getLinkedDocumentIds(accountType: AccountType, coopname?: string): string[] {
|
||||
return this.agreementConfigService.getLinkedAgreements(accountType, coopname).map((a) => a.id);
|
||||
getLinkedDocumentIds(accountType: AccountType, coopname?: string, programKey?: ProgramKey): string[] {
|
||||
return this.agreementConfigService.getLinkedAgreements(accountType, coopname, programKey).map((a) => a.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список идентификаторов документов, которые нужно отправить в блокчейн
|
||||
* @param accountType - тип аккаунта
|
||||
* @param coopname - название кооператива (для временного исключения capitalization_agreement)
|
||||
* @param coopname - название кооператива (для временного исключения blagorost_offer)
|
||||
* @param programKey - ключ выбранной программы регистрации
|
||||
* @returns массив id документов для отправки в блокчейн
|
||||
*/
|
||||
getBlockchainDocumentIds(accountType: AccountType, coopname?: string): string[] {
|
||||
return this.agreementConfigService.getBlockchainAgreements(accountType, coopname).map((a) => a.id);
|
||||
getBlockchainDocumentIds(accountType: AccountType, coopname?: string, programKey?: ProgramKey): string[] {
|
||||
return this.agreementConfigService.getBlockchainAgreements(accountType, coopname, programKey).map((a) => a.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { IsEnum, IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-valid
|
||||
export enum CapitalOnboardingStepEnum {
|
||||
generator_program_template = 'generator_program_template',
|
||||
generation_agreement_template = 'generation_agreement_template',
|
||||
blagorost_provision = 'blagorost_provision',
|
||||
blagorost_program = 'blagorost_program',
|
||||
blagorost_offer_template = 'blagorost_offer_template',
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ export class CapitalOnboardingEventsService {
|
||||
const mapping: Record<string, keyof IConfig> = {
|
||||
generator_program_template: 'onboarding_generator_program_template_done',
|
||||
generation_agreement_template: 'onboarding_generation_agreement_template_done',
|
||||
blagorost_provision: 'onboarding_blagorost_provision_done',
|
||||
blagorost_program: 'onboarding_blagorost_provision_done',
|
||||
blagorost_offer_template: 'onboarding_blagorost_offer_template_done',
|
||||
};
|
||||
|
||||
|
||||
+5
-5
@@ -40,7 +40,7 @@ export class CapitalOnboardingService {
|
||||
return 'onboarding_generator_program_template_done';
|
||||
case CapitalOnboardingStepEnum.generation_agreement_template:
|
||||
return 'onboarding_generation_agreement_template_done';
|
||||
case CapitalOnboardingStepEnum.blagorost_provision:
|
||||
case CapitalOnboardingStepEnum.blagorost_program:
|
||||
return 'onboarding_blagorost_provision_done';
|
||||
case CapitalOnboardingStepEnum.blagorost_offer_template:
|
||||
return 'onboarding_blagorost_offer_template_done';
|
||||
@@ -55,7 +55,7 @@ export class CapitalOnboardingService {
|
||||
return 'onboarding_generator_program_template_hash';
|
||||
case CapitalOnboardingStepEnum.generation_agreement_template:
|
||||
return 'onboarding_generation_agreement_template_hash';
|
||||
case CapitalOnboardingStepEnum.blagorost_provision:
|
||||
case CapitalOnboardingStepEnum.blagorost_program:
|
||||
return 'onboarding_blagorost_provision_hash';
|
||||
case CapitalOnboardingStepEnum.blagorost_offer_template:
|
||||
return 'onboarding_blagorost_offer_template_hash';
|
||||
@@ -67,11 +67,11 @@ export class CapitalOnboardingService {
|
||||
private mapStepToVarsField(step: CapitalOnboardingStepEnum): string {
|
||||
switch (step) {
|
||||
case CapitalOnboardingStepEnum.generator_program_template:
|
||||
return 'generator_program_template';
|
||||
return 'generator_program';
|
||||
case CapitalOnboardingStepEnum.generation_agreement_template:
|
||||
return 'generation_agreement_template';
|
||||
case CapitalOnboardingStepEnum.blagorost_provision:
|
||||
return 'blagorost_provision';
|
||||
case CapitalOnboardingStepEnum.blagorost_program:
|
||||
return 'blagorost_program';
|
||||
case CapitalOnboardingStepEnum.blagorost_offer_template:
|
||||
return 'blagorost_offer_template';
|
||||
default:
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ export class ParticipationManagementService {
|
||||
const document = await this.documentInteractor.generateDocument({
|
||||
data: {
|
||||
...data,
|
||||
registry_id: Cooperative.Registry.CapitalizationAgreement.registry_id,
|
||||
registry_id: Cooperative.Registry.BlagorostOffer.registry_id,
|
||||
},
|
||||
options,
|
||||
});
|
||||
|
||||
@@ -33,9 +33,9 @@ export class AccountBlockchainAdapter implements AccountBlockchainPort {
|
||||
throw new HttpApiError(HttpStatus.BAD_REQUEST, 'Не найдено заявление на вступление');
|
||||
}
|
||||
|
||||
// Получаем конфигурацию соглашений для типа аккаунта кандидата
|
||||
// Получаем конфигурацию соглашений для типа аккаунта кандидата и выбранной программы
|
||||
const accountType = candidate.type as AccountType;
|
||||
const blockchainAgreements = this.agreementConfigService.getBlockchainAgreements(accountType, config.coopname);
|
||||
const blockchainAgreements = this.agreementConfigService.getBlockchainAgreements(accountType, config.coopname, candidate.program_key);
|
||||
|
||||
// Проверяем наличие всех требуемых документов на основе конфигурации
|
||||
for (const agreementConfig of blockchainAgreements) {
|
||||
|
||||
+7
-1
@@ -37,7 +37,13 @@ export class CandidateEntity {
|
||||
user_agreement?: ISignedDocumentDomainInterface;
|
||||
|
||||
@Column('json', { nullable: true })
|
||||
capitalization_agreement?: ISignedDocumentDomainInterface;
|
||||
blagorost_offer?: ISignedDocumentDomainInterface;
|
||||
|
||||
@Column('json', { nullable: true })
|
||||
generator_offer?: ISignedDocumentDomainInterface;
|
||||
|
||||
@Column({ nullable: true })
|
||||
program_key?: string;
|
||||
|
||||
@Column({ nullable: false })
|
||||
registration_hash!: string;
|
||||
|
||||
+20
-17
@@ -5,6 +5,7 @@ import { CandidateEntity } from '../entities/candidate.entity';
|
||||
import type { CandidateRepository } from '~/domain/account/repository/candidate.repository';
|
||||
import type { CandidateDomainInterface } from '~/domain/account/interfaces/candidate-domain.interface';
|
||||
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
|
||||
import { DocumentType, ProgramKey } from '~/domain/registration/enum';
|
||||
|
||||
@Injectable()
|
||||
export class TypeOrmCandidateRepository implements CandidateRepository {
|
||||
@@ -39,6 +40,7 @@ export class TypeOrmCandidateRepository implements CandidateRepository {
|
||||
candidate.referer = data.referer;
|
||||
candidate.public_key = data.public_key;
|
||||
candidate.meta = data.meta;
|
||||
candidate.program_key = data.program_key;
|
||||
|
||||
const createdEntity = await this.candidateRepository.save(candidate);
|
||||
return this.mapToDomainEntity(createdEntity);
|
||||
@@ -52,6 +54,7 @@ export class TypeOrmCandidateRepository implements CandidateRepository {
|
||||
if (data.type) candidate.type = data.type;
|
||||
if (data.braname) candidate.braname = data.braname;
|
||||
if (data.registration_hash) candidate.registration_hash = data.registration_hash;
|
||||
if (data.program_key !== undefined) candidate.program_key = data.program_key;
|
||||
|
||||
if (data.documents) {
|
||||
if (data.documents.statement) candidate.statement = data.documents.statement;
|
||||
@@ -59,8 +62,9 @@ export class TypeOrmCandidateRepository implements CandidateRepository {
|
||||
if (data.documents.signature_agreement) candidate.signature_agreement = data.documents.signature_agreement;
|
||||
if (data.documents.privacy_agreement) candidate.privacy_agreement = data.documents.privacy_agreement;
|
||||
if (data.documents.user_agreement) candidate.user_agreement = data.documents.user_agreement;
|
||||
if (data.documents.capitalization_agreement)
|
||||
candidate.capitalization_agreement = data.documents.capitalization_agreement;
|
||||
if (data.documents.blagorost_offer)
|
||||
candidate.blagorost_offer = data.documents.blagorost_offer;
|
||||
if (data.documents.generator_offer) candidate.generator_offer = data.documents.generator_offer;
|
||||
}
|
||||
|
||||
const updatedEntity = await this.candidateRepository.save(candidate);
|
||||
@@ -69,13 +73,7 @@ export class TypeOrmCandidateRepository implements CandidateRepository {
|
||||
|
||||
async saveDocument(
|
||||
username: string,
|
||||
documentType:
|
||||
| 'statement'
|
||||
| 'wallet_agreement'
|
||||
| 'signature_agreement'
|
||||
| 'privacy_agreement'
|
||||
| 'user_agreement'
|
||||
| 'capitalization_agreement',
|
||||
documentType: DocumentType,
|
||||
document: ISignedDocumentDomainInterface
|
||||
): Promise<void> {
|
||||
const candidate = await this.candidateRepository.findOneBy({ username });
|
||||
@@ -84,23 +82,26 @@ export class TypeOrmCandidateRepository implements CandidateRepository {
|
||||
}
|
||||
|
||||
switch (documentType) {
|
||||
case 'statement':
|
||||
case DocumentType.STATEMENT:
|
||||
candidate.statement = document;
|
||||
break;
|
||||
case 'wallet_agreement':
|
||||
case DocumentType.WALLET_AGREEMENT:
|
||||
candidate.wallet_agreement = document;
|
||||
break;
|
||||
case 'signature_agreement':
|
||||
case DocumentType.SIGNATURE_AGREEMENT:
|
||||
candidate.signature_agreement = document;
|
||||
break;
|
||||
case 'privacy_agreement':
|
||||
case DocumentType.PRIVACY_AGREEMENT:
|
||||
candidate.privacy_agreement = document;
|
||||
break;
|
||||
case 'user_agreement':
|
||||
case DocumentType.USER_AGREEMENT:
|
||||
candidate.user_agreement = document;
|
||||
break;
|
||||
case 'capitalization_agreement':
|
||||
candidate.capitalization_agreement = document;
|
||||
case DocumentType.BLAGOROST_OFFER:
|
||||
candidate.blagorost_offer = document;
|
||||
break;
|
||||
case DocumentType.GENERATOR_OFFER:
|
||||
candidate.generator_offer = document;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -121,12 +122,14 @@ export class TypeOrmCandidateRepository implements CandidateRepository {
|
||||
signature_agreement: entity.signature_agreement,
|
||||
privacy_agreement: entity.privacy_agreement,
|
||||
user_agreement: entity.user_agreement,
|
||||
capitalization_agreement: entity.capitalization_agreement,
|
||||
blagorost_offer: entity.blagorost_offer,
|
||||
generator_offer: entity.generator_offer,
|
||||
},
|
||||
registration_hash: entity.registration_hash,
|
||||
referer: entity.referer,
|
||||
public_key: entity.public_key,
|
||||
meta: entity.meta,
|
||||
program_key: entity.program_key as ProgramKey | undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,34 +64,36 @@ export interface IVars {
|
||||
protocol_number: string
|
||||
protocol_day_month_year: string
|
||||
}
|
||||
participant_application?: {
|
||||
participant_application?: { // Заявление на вступление
|
||||
protocol_number: string
|
||||
protocol_day_month_year: string
|
||||
}
|
||||
coopenomics_agreement?: {
|
||||
coopenomics_agreement?: { // Оферта на подключение кооператива
|
||||
protocol_number: string
|
||||
protocol_day_month_year: string
|
||||
}
|
||||
generation_agreement_template?: {
|
||||
// Благорост
|
||||
blagorost_program?: { // Положение о программе "Благорост"
|
||||
protocol_number: string
|
||||
protocol_day_month_year: string
|
||||
}
|
||||
blagorost_provision?: {
|
||||
blagorost_offer_template?: { // Шаблон оферты "Благорост"
|
||||
protocol_number: string
|
||||
protocol_day_month_year: string
|
||||
}
|
||||
blagorost_offer_template?: {
|
||||
generator_program?: { // Положение о программе "Гененатор"
|
||||
protocol_number: string
|
||||
protocol_day_month_year: string
|
||||
}
|
||||
generation_program?: {
|
||||
generator_offer_template?: { // Шаблон оферты "Генератора"
|
||||
protocol_number: string
|
||||
protocol_day_month_year: string
|
||||
}
|
||||
generation_offer_template?: {
|
||||
generation_agreement_template?: { // Шаблон договора участия в хозяйственной деятельности
|
||||
protocol_number: string
|
||||
protocol_day_month_year: string
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-3
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -9,7 +9,7 @@
|
||||
{{coop.chairman.last_name}} {{coop.chairman.first_name}} {{coop.chairman.middle_name}}, действующего на основании Устава с одной стороны, и Пайщик Общества __________________________, действующий на основании собственного волеизъявления, с другой стороны, а вместе Стороны, согласились с нижеследующим:
|
||||
Настоящее Пользовательское соглашение, составленное в соответствии с Гражданским кодексом
|
||||
РФ, Уставом Общества и на основании Положения Общества о целевой потребительской
|
||||
программе “ГЕНЕРАТОР”, утвержденном Собранием Совета Общества (Протокол №{{vars.generation_program.protocol_number}} от {{vars.generation_program.protocol_day_month_year}}), формулируют соглашение между Обществом и Пайщиком а также является по отношению к Пайщику Офертой от Общества, где Общество является Оферентом, а Пайщик является Акцептантом.
|
||||
программе “ГЕНЕРАТОР”, утвержденном Собранием Совета Общества (Протокол №{{vars.generator_program.protocol_number}} от {{vars.generator_program.protocol_day_month_year}}), формулируют соглашение между Обществом и Пайщиком а также является по отношению к Пайщику Офертой от Общества, где Общество является Оферентом, а Пайщик является Акцептантом.
|
||||
|
||||
Отметка о Согласии
|
||||
с Настоящим Пользовательским соглашением производится электронно, а дата создания Личного кабинета пайщика на сайте {{vars.website}} считается датой акцепта настоящей Оферты как пайщика Общества по взаимодействию между Пайщиком и Обществом в соответствии с условиями целевой потребительской программы “ГЕНЕРАТОР” (далее “ЦПП”).
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -15,7 +15,7 @@ export interface Model {
|
||||
meta: IMetaDocument
|
||||
coop: ICooperativeData
|
||||
vars: IVars
|
||||
blagorost_provision: {
|
||||
blagorost_program: {
|
||||
protocol_number: string
|
||||
protocol_date: string
|
||||
}
|
||||
@@ -23,7 +23,7 @@ export interface Model {
|
||||
|
||||
export const title = 'Пользовательское соглашение (оферта) по присоединению к ЦПП «БЛАГОРОСТ»'
|
||||
export const description = 'Шаблон публичной оферты по ЦПП «БЛАГОРОСТ» для утверждения Советом'
|
||||
export const context = `<div class="digital-document"><div style="text-align: center"><h1 class="header">{% trans 'OFFER_TITLE' %}</h1><p class="subheader">{% trans 'offer_template_subtitle' %}</p></div><p>{% trans 'offer_template_intro_1' %} {{coop.chairman.last_name}} {{coop.chairman.first_name}} {{coop.chairman.middle_name}}{% trans 'offer_template_intro_2' %}</p><p>{% trans 'offer_template_legal_basis' %} {{ blagorost_provision.protocol_number }} {% trans 'from' %} {{ blagorost_provision.protocol_date }}{% trans 'offer_template_legal_basis_2' %}</p><p>{% trans 'offer_template_acceptance' %} {{vars.website}} {% trans 'offer_template_acceptance_2' %}</p><div style="text-align: center"><h3>{% trans 'terms_title' %}</h3></div><p><strong>{% trans 'platform_term' %}</strong> - {% trans 'platform_definition' %}</p><p><strong>{% trans 'property_term' %}</strong> - {% trans 'property_definition_template' %}</p><p><strong>{% trans 'money_term' %}</strong> - {% trans 'money_definition_template' %}</p><p><strong>{% trans 'participant_term' %}</strong> - {{vars.short_abbr}} "{{vars.name}}"{% trans 'participant_definition_template' %}</p><p><strong>{% trans 'site_term' %}</strong> - {{vars.website}}{% trans 'site_definition_template' %}</p><p><strong>{% trans 'share_contribution_term' %}</strong> - {% trans 'share_contribution_definition' %}</p><p><strong>{% trans 'share_capital_term' %}</strong> - {% trans 'share_capital_definition' %}</p><p><strong>{% trans 'personal_cabinet_term' %}</strong> - {% trans 'personal_cabinet_definition_template' %}</p><p><strong>{% trans 'personal_account_term' %}</strong> - {% trans 'personal_account_definition_template' %}</p><div style="text-align: center"><h3>{% trans 'goals_title' %}</h3></div><p>{% trans 'goals_intro_template' %}</p><p>{% trans 'goal_1' %}</p><p>{% trans 'goal_2' %}</p><p>{% trans 'tasks_intro' %}</p><p>{% trans 'task_1' %}</p><p>{% trans 'task_2' %}</p><div style="text-align: center"><h3>{% trans 'economic_mechanism_title' %}</h3></div><p>{% trans 'economic_mechanism_intro_template' %}</p><p>{% trans 'participation_proportion' %}</p><p>{% trans 'share_equivalence_template' %}</p><p>{% trans 'society_notification_template' %}</p><p>{% trans 'participant_rights_contributions' %}</p><p>{% trans 'minimum_contribution' %}</p><p>{% trans 'property_contributions' %}</p><p>{% trans 'money_contribution_procedure' %}</p><p>{% trans 'property_contribution_procedure_template' %}</p><p>{% trans 'council_consideration_delay' %}</p><p>{% trans 'council_consideration_time' %}</p><p>{% trans 'property_acceptance_act' %}</p><div style="text-align: center"><h3>{% trans 'return_mechanism_title' %}</h3></div><p>{% trans 'return_source' %}</p><p>{% trans 'economic_effect_template' %}</p><p>{% trans 'participant_return_right' %}</p><p>{% trans 'society_return_notification_template' %}</p><p>{% trans 'return_application' %}</p><p>{% trans 'return_procedure' %}</p><p>{% trans 'return_to_wallet' %}</p><p>{% trans 'exit_return_procedure_template' %}</p><p>{% trans 'exit_consideration_time_template' %}</p><div style="text-align: center"><h3>{% trans 'rights_obligations_title' %}</h3></div><p><strong>{% trans 'participant_rights_title' %}</strong></p><p>{% trans 'participant_right_1' %}</p><p>{% trans 'participant_right_2' %}</p><p>{% trans 'participant_right_3' %}</p><p>{% trans 'participant_right_4' %}</p><p><strong>{% trans 'participant_obligations_title' %}</strong></p><p>{% trans 'participant_obligation_1' %}</p><p>{% trans 'participant_obligation_2' %}</p><p><strong>{% trans 'society_obligations_title' %}</strong></p><p>{% trans 'society_obligation_1_template' %}</p><p>{% trans 'society_obligation_2_template' %}</p><p><strong>{% trans 'society_rights_title' %}</strong></p><p>{% trans 'society_right_1' %}</p><p>{% trans 'society_right_2_template' %}</p><div style="text-align: center"><h3>{% trans 'force_majeure_title' %}</h3></div><p>{% trans 'legislation_changes' %}</p><p>{% trans 'force_majeure_circumstances_template' %}</p><p>{% trans 'force_majeure_cases' %}</p><p>{% trans 'force_majeure_notification' %}</p><div style="text-align: center"><h3>{% trans 'other_conditions_title' %}</h3></div><p>{% trans 'site_definition_extended_template' %}</p><p>{% trans 'governing_relations_template' %}</p><p>{% trans 'amendments_procedure_template' %}</p><div class="signature"><p style="margin-top: 40px;"><strong>{% trans 'agreement_signature_template' %}</strong></p><p>{% trans 'signature_fields' %}</p></div></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}.subheader {padding-bottom: 20px;}.signature {padding-top: 20px;}</style>`
|
||||
export const context = `<div class="digital-document"><div style="text-align: center"><h1 class="header">{% trans 'OFFER_TITLE' %}</h1><p class="subheader">{% trans 'offer_template_subtitle' %}</p></div><p>{% trans 'offer_template_intro_1' %} {{coop.chairman.last_name}} {{coop.chairman.first_name}} {{coop.chairman.middle_name}}{% trans 'offer_template_intro_2' %}</p><p>{% trans 'offer_template_legal_basis' %} {{ blagorost_program.protocol_number }} {% trans 'from' %} {{ blagorost_program.protocol_date }}{% trans 'offer_template_legal_basis_2' %}</p><p>{% trans 'offer_template_acceptance' %} {{vars.website}} {% trans 'offer_template_acceptance_2' %}</p><div style="text-align: center"><h3>{% trans 'terms_title' %}</h3></div><p><strong>{% trans 'platform_term' %}</strong> - {% trans 'platform_definition' %}</p><p><strong>{% trans 'property_term' %}</strong> - {% trans 'property_definition_template' %}</p><p><strong>{% trans 'money_term' %}</strong> - {% trans 'money_definition_template' %}</p><p><strong>{% trans 'participant_term' %}</strong> - {{vars.short_abbr}} "{{vars.name}}"{% trans 'participant_definition_template' %}</p><p><strong>{% trans 'site_term' %}</strong> - {{vars.website}}{% trans 'site_definition_template' %}</p><p><strong>{% trans 'share_contribution_term' %}</strong> - {% trans 'share_contribution_definition' %}</p><p><strong>{% trans 'share_capital_term' %}</strong> - {% trans 'share_capital_definition' %}</p><p><strong>{% trans 'personal_cabinet_term' %}</strong> - {% trans 'personal_cabinet_definition_template' %}</p><p><strong>{% trans 'personal_account_term' %}</strong> - {% trans 'personal_account_definition_template' %}</p><div style="text-align: center"><h3>{% trans 'goals_title' %}</h3></div><p>{% trans 'goals_intro_template' %}</p><p>{% trans 'goal_1' %}</p><p>{% trans 'goal_2' %}</p><p>{% trans 'tasks_intro' %}</p><p>{% trans 'task_1' %}</p><p>{% trans 'task_2' %}</p><div style="text-align: center"><h3>{% trans 'economic_mechanism_title' %}</h3></div><p>{% trans 'economic_mechanism_intro_template' %}</p><p>{% trans 'participation_proportion' %}</p><p>{% trans 'share_equivalence_template' %}</p><p>{% trans 'society_notification_template' %}</p><p>{% trans 'participant_rights_contributions' %}</p><p>{% trans 'minimum_contribution' %}</p><p>{% trans 'property_contributions' %}</p><p>{% trans 'money_contribution_procedure' %}</p><p>{% trans 'property_contribution_procedure_template' %}</p><p>{% trans 'council_consideration_delay' %}</p><p>{% trans 'council_consideration_time' %}</p><p>{% trans 'property_acceptance_act' %}</p><div style="text-align: center"><h3>{% trans 'return_mechanism_title' %}</h3></div><p>{% trans 'return_source' %}</p><p>{% trans 'economic_effect_template' %}</p><p>{% trans 'participant_return_right' %}</p><p>{% trans 'society_return_notification_template' %}</p><p>{% trans 'return_application' %}</p><p>{% trans 'return_procedure' %}</p><p>{% trans 'return_to_wallet' %}</p><p>{% trans 'exit_return_procedure_template' %}</p><p>{% trans 'exit_consideration_time_template' %}</p><div style="text-align: center"><h3>{% trans 'rights_obligations_title' %}</h3></div><p><strong>{% trans 'participant_rights_title' %}</strong></p><p>{% trans 'participant_right_1' %}</p><p>{% trans 'participant_right_2' %}</p><p>{% trans 'participant_right_3' %}</p><p>{% trans 'participant_right_4' %}</p><p><strong>{% trans 'participant_obligations_title' %}</strong></p><p>{% trans 'participant_obligation_1' %}</p><p>{% trans 'participant_obligation_2' %}</p><p><strong>{% trans 'society_obligations_title' %}</strong></p><p>{% trans 'society_obligation_1_template' %}</p><p>{% trans 'society_obligation_2_template' %}</p><p><strong>{% trans 'society_rights_title' %}</strong></p><p>{% trans 'society_right_1' %}</p><p>{% trans 'society_right_2_template' %}</p><div style="text-align: center"><h3>{% trans 'force_majeure_title' %}</h3></div><p>{% trans 'legislation_changes' %}</p><p>{% trans 'force_majeure_circumstances_template' %}</p><p>{% trans 'force_majeure_cases' %}</p><p>{% trans 'force_majeure_notification' %}</p><div style="text-align: center"><h3>{% trans 'other_conditions_title' %}</h3></div><p>{% trans 'site_definition_extended_template' %}</p><p>{% trans 'governing_relations_template' %}</p><p>{% trans 'amendments_procedure_template' %}</p><div class="signature"><p style="margin-top: 40px;"><strong>{% trans 'agreement_signature_template' %}</strong></p><p>{% trans 'signature_fields' %}</p></div></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}.subheader {padding-bottom: 20px;}.signature {padding-top: 20px;}</style>`
|
||||
|
||||
export const translations = {
|
||||
ru: {
|
||||
@@ -127,7 +127,7 @@ export const exampleData = {
|
||||
short_abbr: 'ПК',
|
||||
website: 'цифровой-кооператив.рф',
|
||||
},
|
||||
blagorost_provision: {
|
||||
blagorost_program: {
|
||||
protocol_number: '01-12-2024',
|
||||
protocol_date: '01 декабря 2024 г.',
|
||||
},
|
||||
|
||||
@@ -26,8 +26,8 @@ export * as ReturnByMoneyDecision from './901.ReturnByMoneyDecision'
|
||||
export * as GeneratorProgramTemplate from './994.GeneratorProgramTemplate'
|
||||
export * as GeneratorOfferTemplate from './995.GeneratorOfferTemplate'
|
||||
export * as GeneratorOffer from './996.GeneratorOffer'
|
||||
export * as CapitalizationAgreement from './1000.CapitalizationAgreement'
|
||||
export * as BlagorostProvision from './998.BlagorostProvision'
|
||||
export * as BlagorostOffer from './1000.BlagorostOffer'
|
||||
export * as BlagorostProgramTemplate from './998.BlagorostProgramTemplate'
|
||||
export * as BlagorostOfferTemplate from './999.BlagorostOfferTemplate'
|
||||
export * as GenerationAgreementTemplate from './997.GenerationAgreementTemplate'
|
||||
export * as GenerationAgreement from './1001.GenerationAgreement'
|
||||
|
||||
+16
-16
@@ -4,40 +4,40 @@ overview: Создание гибкого конструктора програ
|
||||
todos:
|
||||
- id: backend-interfaces
|
||||
content: Создать новые интерфейсы для программ регистрации в agreement-config.interface.ts
|
||||
status: in_progress
|
||||
status: completed
|
||||
- id: backend-programs-config
|
||||
content: Создать конфигурацию программ registration-programs.config.ts с программами для voskhod
|
||||
status: pending
|
||||
status: completed
|
||||
- id: backend-agreement-service
|
||||
content: Обновить AgreementConfigurationService с методами работы с программами
|
||||
status: pending
|
||||
status: completed
|
||||
- id: backend-documents-service
|
||||
content: Добавить поддержку program_key в RegistrationDocumentsService
|
||||
status: pending
|
||||
status: completed
|
||||
- id: backend-dto
|
||||
content: Обновить DTO для добавления program_key и создать RegistrationConfigDTO
|
||||
status: pending
|
||||
status: completed
|
||||
- id: backend-resolver
|
||||
content: Добавить query getRegistrationConfig в SystemResolver
|
||||
status: pending
|
||||
status: completed
|
||||
- id: frontend-store
|
||||
content: Обновить Registrator store для хранения selectedProgramKey и добавить шаг SelectProgram
|
||||
status: pending
|
||||
status: completed
|
||||
- id: frontend-select-component
|
||||
content: Создать компонент SelectProgram.vue для выбора программы
|
||||
status: pending
|
||||
status: completed
|
||||
- id: frontend-conditional-rendering
|
||||
content: Добавить условный рендеринг шага SelectProgram в SignUp.vue
|
||||
status: pending
|
||||
status: completed
|
||||
- id: frontend-pass-program-key
|
||||
content: Обновить вызов generateRegistrationDocuments для передачи program_key
|
||||
status: pending
|
||||
status: completed
|
||||
- id: sdk-update
|
||||
content: Обновить SDK мутацию и добавить query getRegistrationConfig
|
||||
status: pending
|
||||
status: completed
|
||||
- id: add-generator-agreement
|
||||
content: Добавить соглашение generator_offer в registration-agreements.config.ts
|
||||
status: pending
|
||||
status: completed
|
||||
---
|
||||
|
||||
# План реализации конструктора программ регистрации
|
||||
@@ -132,7 +132,7 @@ export const REGISTRATION_PROGRAMS_CONFIG: ICooperativeRegistrationPrograms[] =
|
||||
title: 'Программа Капитализация',
|
||||
description: 'Участвовать в производстве Кооперативной Экономики через вклад имуществом или денег в систему. Минимальный взнос 100 000 руб в течение 14 дней.',
|
||||
applicable_account_types: [AccountType.individual, AccountType.entrepreneur],
|
||||
agreement_ids: ['capitalization_agreement'],
|
||||
agreement_ids: ['blagorost_offer'],
|
||||
order: 2,
|
||||
},
|
||||
],
|
||||
@@ -214,7 +214,7 @@ getAgreementsForAccountType(
|
||||
// Базовые соглашения (всегда включаются)
|
||||
const baseAgreements = REGISTRATION_AGREEMENTS_CONFIG.agreements
|
||||
.filter(a => a.applicable_account_types.includes(accountType))
|
||||
.filter(a => a.id !== 'capitalization_agreement' && a.id !== 'generator_offer');
|
||||
.filter(a => a.id !== 'blagorost_offer' && a.id !== 'generator_offer');
|
||||
|
||||
// Если указана программа - добавляем её соглашения
|
||||
if (programKey && coopname) {
|
||||
@@ -224,7 +224,7 @@ getAgreementsForAccountType(
|
||||
|
||||
// Старая логика для обратной совместимости (voskhod без program_key)
|
||||
if (coopname === 'voskhod' && accountType === AccountType.individual) {
|
||||
const capitalization = this.getAgreementById('capitalization_agreement');
|
||||
const capitalization = this.getAgreementById('blagorost_offer');
|
||||
if (capitalization) {
|
||||
return [...baseAgreements, capitalization].sort((a, b) => a.order - b.order);
|
||||
}
|
||||
@@ -533,5 +533,5 @@ export const getRegistrationConfig = {
|
||||
## Миграция и обратная совместимость
|
||||
|
||||
- Для всех кооперативов кроме voskhod ничего не меняется
|
||||
- Для voskhod: если не передан `program_key`, используется старая логика (capitalization_agreement для физиков)
|
||||
- Для voskhod: если не передан `program_key`, используется старая логика (blagorost_offer для физиков)
|
||||
- После развертывания можно убрать хардкод для voskhod из `AgreementConfigurationService`
|
||||
|
||||
@@ -27,7 +27,7 @@ export const useCapitalOnboarding = () => {
|
||||
const stepToRegistryId: Record<string, number> = {
|
||||
'generator_program_template': 994,
|
||||
'generation_agreement_template': 997,
|
||||
'blagorost_provision': 998,
|
||||
'blagorost_program': 998,
|
||||
'blagorost_offer_template': 999,
|
||||
};
|
||||
|
||||
@@ -100,7 +100,7 @@ export const useCapitalOnboarding = () => {
|
||||
hash: typeof state?.onboarding_generation_agreement_template_hash === 'string' && state.onboarding_generation_agreement_template_hash ? state.onboarding_generation_agreement_template_hash : null,
|
||||
},
|
||||
{
|
||||
id: 'blagorost_provision',
|
||||
id: 'blagorost_program',
|
||||
title: 'Положение о ЦПП «БЛАГОРОСТ»',
|
||||
description: 'Утверждение Положения о целевой потребительской программе «БЛАГОРОСТ»',
|
||||
question: 'О утверждении Положения о целевой потребительской программе «БЛАГОРОСТ»',
|
||||
@@ -121,7 +121,7 @@ export const useCapitalOnboarding = () => {
|
||||
status: state?.blagorost_offer_template_done ? 'completed' :
|
||||
state?.onboarding_blagorost_offer_template_hash ? 'in_progress' : 'pending',
|
||||
hash: typeof state?.onboarding_blagorost_offer_template_hash === 'string' && state.onboarding_blagorost_offer_template_hash ? state.onboarding_blagorost_offer_template_hash : null,
|
||||
depends_on: ['blagorost_provision'], // Зависит от утверждения положения
|
||||
depends_on: ['blagorost_program'], // Зависит от утверждения положения
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ export const useBlagorostPresets = (): IDocumentPreset[] => {
|
||||
|
||||
return [
|
||||
{
|
||||
id: 'blagorost_provision',
|
||||
id: 'blagorost_program',
|
||||
registry_id: 998,
|
||||
title: 'Положение о ЦПП «БЛАГОРОСТ»',
|
||||
description: 'Утверждение Положения о целевой потребительской программе «БЛАГОРОСТ»',
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { IGenerateRegistrationDocumentsInput, IGenerateRegistrationDocument
|
||||
async function generateRegistrationDocuments(
|
||||
data: IGenerateRegistrationDocumentsInput
|
||||
): Promise<IGenerateRegistrationDocumentsOutput> {
|
||||
|
||||
const { [Mutations.Registration.GenerateRegistrationDocuments.name]: output } =
|
||||
await client.Mutation(Mutations.Registration.GenerateRegistrationDocuments.mutation, {
|
||||
variables: {
|
||||
|
||||
@@ -37,12 +37,14 @@ export const useRegistrationStore = defineStore(namespace, () => {
|
||||
const loadRegistrationDocuments = async (
|
||||
coopname: string,
|
||||
username: string,
|
||||
accountType: Zeus.AccountType
|
||||
accountType: Zeus.AccountType,
|
||||
programKey?: string
|
||||
): Promise<IRegistrationDocument[]> => {
|
||||
const output = await api.generateRegistrationDocuments({
|
||||
coopname,
|
||||
username,
|
||||
account_type: accountType,
|
||||
program_key: programKey,
|
||||
})
|
||||
|
||||
registrationDocuments.value = output.documents.map((doc) => ({
|
||||
|
||||
@@ -118,6 +118,8 @@ export const useRegistratorStore = defineStore(
|
||||
role: 'user',
|
||||
email: '',
|
||||
selectedBranch: '',
|
||||
selectedProgramKey: '',
|
||||
requiresProgramSelection: false,
|
||||
account: structuredClone(initialAccountState),
|
||||
userData: structuredClone(initialUserDataState),
|
||||
signature: '',
|
||||
@@ -135,6 +137,7 @@ export const useRegistratorStore = defineStore(
|
||||
const stepNames = [
|
||||
'EmailInput',
|
||||
'SetUserData',
|
||||
'SelectProgram',
|
||||
'GenerateAccount',
|
||||
'SelectBranch',
|
||||
'ReadStatement',
|
||||
@@ -160,7 +163,11 @@ export const useRegistratorStore = defineStore(
|
||||
);
|
||||
|
||||
const filteredSteps = computed(() =>
|
||||
stepNames.filter((step) => step !== 'SelectBranch' || isBranched.value),
|
||||
stepNames.filter((step) => {
|
||||
if (step === 'SelectBranch' && !isBranched.value) return false;
|
||||
if (step === 'SelectProgram' && !state.requiresProgramSelection) return false;
|
||||
return true;
|
||||
}),
|
||||
);
|
||||
|
||||
const isStepDone = (stepName: StepName) => {
|
||||
@@ -207,6 +214,8 @@ export const useRegistratorStore = defineStore(
|
||||
const clearUserData = () => {
|
||||
state.step = 1;
|
||||
state.selectedBranch = '';
|
||||
state.selectedProgramKey = '';
|
||||
state.requiresProgramSelection = false;
|
||||
state.email = '';
|
||||
state.account = structuredClone(initialAccountState);
|
||||
state.agreements = structuredClone(initialAgreementsState);
|
||||
|
||||
@@ -58,7 +58,8 @@ export function useCreateUser() {
|
||||
* Генерирует все документы регистрации с бэкенда через Registration store
|
||||
* Использует SDK для вызова generateRegistrationDocuments
|
||||
*/
|
||||
async function generateAllRegistrationDocuments() {
|
||||
async function generateAllRegistrationDocuments(programKey?: string) {
|
||||
|
||||
const accountType = store.userData.type;
|
||||
if (!accountType) {
|
||||
throw new Error('Тип аккаунта не определён');
|
||||
@@ -80,7 +81,8 @@ export function useCreateUser() {
|
||||
await registrationStore.loadRegistrationDocuments(
|
||||
info.coopname,
|
||||
store.account.username,
|
||||
zeusAccountType
|
||||
zeusAccountType,
|
||||
programKey || undefined
|
||||
);
|
||||
}
|
||||
|
||||
@@ -127,9 +129,10 @@ export function useCreateUser() {
|
||||
const privacyDoc = registrationStore.getDocumentById('privacy_agreement');
|
||||
const signatureDoc = registrationStore.getDocumentById('signature_agreement');
|
||||
const userDoc = registrationStore.getDocumentById('user_agreement');
|
||||
const capitalizationDoc = registrationStore.getDocumentById('capitalization_agreement');
|
||||
const capitalizationDoc = registrationStore.getDocumentById('blagorost_offer');
|
||||
const generatorDoc = registrationStore.getDocumentById('generator_offer');
|
||||
|
||||
const data: ISendStatement & { capitalization_agreement?: IDocument } = {
|
||||
const data: ISendStatement & { blagorost_offer?: IDocument; generator_offer?: IDocument; program_key?: string } = {
|
||||
username: store.account.username,
|
||||
braname: store.selectedBranch,
|
||||
statement: store.statement,
|
||||
@@ -137,11 +140,17 @@ export function useCreateUser() {
|
||||
privacy_agreement: privacyDoc?.signed_document || store.privacyAgreement,
|
||||
signature_agreement: signatureDoc?.signed_document || store.signatureAgreement,
|
||||
user_agreement: userDoc?.signed_document || store.userAgreement,
|
||||
program_key: registratorStore.state.selectedProgramKey || undefined,
|
||||
};
|
||||
|
||||
// Добавляем capitalization_agreement если есть
|
||||
// Добавляем blagorost_offer если есть
|
||||
if (capitalizationDoc?.signed_document) {
|
||||
data.capitalization_agreement = capitalizationDoc.signed_document;
|
||||
data.blagorost_offer = capitalizationDoc.signed_document;
|
||||
}
|
||||
|
||||
// Добавляем generator_offer если есть
|
||||
if (generatorDoc?.signed_document) {
|
||||
data.generator_offer = generatorDoc.signed_document;
|
||||
}
|
||||
|
||||
await api.sendStatement(data);
|
||||
|
||||
@@ -79,7 +79,7 @@ const loadDocuments = async (): Promise<void> => {
|
||||
loadingText.value = 'Генерируем документы для подписи...'
|
||||
|
||||
// Генерируем все документы регистрации с бэкенда (они уже содержат HTML для отображения)
|
||||
await generateAllRegistrationDocuments()
|
||||
await generateAllRegistrationDocuments(registratorStore.state.selectedProgramKey)
|
||||
|
||||
loadingText.value = 'Заполняем заявление...'
|
||||
|
||||
@@ -97,10 +97,11 @@ const loadDocuments = async (): Promise<void> => {
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
if (registratorStore.isBranched)
|
||||
registratorStore.goTo('SelectBranch')
|
||||
else
|
||||
registratorStore.goTo('GenerateAccount')
|
||||
if (registratorStore.isBranched) {
|
||||
registratorStore.goTo('SelectBranch');
|
||||
} else {
|
||||
registratorStore.goTo('GenerateAccount');
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
<template lang="pug">
|
||||
div
|
||||
q-step(
|
||||
:name='registratorStore.steps.SelectProgram',
|
||||
title='Выберите программу участия',
|
||||
:done='registratorStore.isStepDone("SelectProgram")'
|
||||
)
|
||||
div(v-if='isLoading').full-width.text-center.q-mt-lg.q-mb-lg
|
||||
Loader(text='Загружаем доступные программы...')
|
||||
|
||||
div(v-else-if='programs.length > 0')
|
||||
p.text-body1.q-mb-md Выберите программу, в которой вы хотите участвовать:
|
||||
|
||||
q-list.q-mt-md(separator)
|
||||
q-item(
|
||||
v-for='program in programs',
|
||||
:key='program.key',
|
||||
clickable,
|
||||
v-ripple,
|
||||
:active='registratorStore.state.selectedProgramKey === program.key',
|
||||
|
||||
@click='selectProgram(program.key)'
|
||||
)
|
||||
q-item-section
|
||||
q-item-label.text-h6 {{ program.title }}
|
||||
q-item-label(caption).q-mt-sm.text-body2 {{ program.description }}
|
||||
q-item-label(v-if='program.requirements', caption).q-mt-xs.text-weight-medium.text-primary
|
||||
| {{ program.requirements }}
|
||||
q-item-section(side, top)
|
||||
q-radio(
|
||||
:model-value='registratorStore.state.selectedProgramKey',
|
||||
:val='program.key',
|
||||
@update:model-value='selectProgram(program.key)',
|
||||
color='primary'
|
||||
)
|
||||
|
||||
div(v-else).text-center.q-mt-lg
|
||||
p.text-body1 Доступных программ не найдено
|
||||
|
||||
div.q-mt-lg
|
||||
q-btn.col-md-6.col-xs-12(flat, @click='registratorStore.prev()')
|
||||
i.fa.fa-arrow-left
|
||||
span.q-ml-md назад
|
||||
|
||||
q-btn.q-mt-lg.q-mb-lg(
|
||||
color='primary',
|
||||
label='Продолжить',
|
||||
:disabled='!registratorStore.state.selectedProgramKey',
|
||||
@click='registratorStore.next()'
|
||||
)
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { useRegistratorStore } from 'src/entities/Registrator';
|
||||
import { useSystemStore } from 'src/entities/System/model';
|
||||
import { Loader } from 'src/shared/ui/Loader';
|
||||
import { FailAlert } from 'src/shared/api';
|
||||
import { client } from 'src/shared/api/client';
|
||||
import { Queries } from '@coopenomics/sdk';
|
||||
|
||||
const registratorStore = useRegistratorStore();
|
||||
const systemStore = useSystemStore();
|
||||
|
||||
const isLoading = ref(false);
|
||||
const programs = ref<any[]>([]);
|
||||
|
||||
const loadPrograms = async () => {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
|
||||
const accountType = registratorStore.state.userData.type;
|
||||
if (!accountType) {
|
||||
console.error('Account type not selected');
|
||||
return;
|
||||
}
|
||||
|
||||
const { [Queries.System.GetRegistrationConfig.name]: config } = await client.Query(
|
||||
Queries.System.GetRegistrationConfig.query,
|
||||
{
|
||||
variables: {
|
||||
coopname: systemStore.info.coopname,
|
||||
account_type: accountType,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
programs.value = config.programs || [];
|
||||
|
||||
// Если программа только одна - автоматически выбираем её и переходим дальше
|
||||
if (programs.value.length === 1) {
|
||||
registratorStore.state.selectedProgramKey = programs.value[0].key;
|
||||
registratorStore.next();
|
||||
} else if (programs.value.length === 0) {
|
||||
// Если программ нет - просто переходим дальше
|
||||
registratorStore.next();
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error('Error loading programs:', e);
|
||||
FailAlert(e);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const selectProgram = (key: string) => {
|
||||
registratorStore.state.selectedProgramKey = key;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (registratorStore.state.step === registratorStore.steps.SelectProgram) {
|
||||
loadPrograms();
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => registratorStore.state.step, (value: number) => {
|
||||
if (value === registratorStore.steps.SelectProgram) {
|
||||
loadPrograms();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -39,9 +39,13 @@ div
|
||||
import { ref } from 'vue';
|
||||
import { UserDataForm } from 'src/shared/ui/UserDataForm/UserDataForm';
|
||||
import { useRegistratorStore } from 'src/entities/Registrator';
|
||||
import { useSystemStore } from 'src/entities/System/model';
|
||||
import { StaticPrivacyDialog } from 'src/features/Agreementer/StaticPrivacyDialog';
|
||||
import { Queries } from '@coopenomics/sdk';
|
||||
import { client } from 'src/shared/api/client';
|
||||
|
||||
const store = useRegistratorStore();
|
||||
const systemStore = useSystemStore();
|
||||
|
||||
// Отслеживание выбран ли тип аккаунта
|
||||
const isAccountTypeSelected = ref<boolean>(
|
||||
@@ -51,18 +55,43 @@ const isAccountTypeSelected = ref<boolean>(
|
||||
);
|
||||
|
||||
// Обработчики событий от UserDataForm
|
||||
const onTypeSelected = () =>
|
||||
// type: 'individual' | 'entrepreneur' | 'organization',
|
||||
{
|
||||
isAccountTypeSelected.value = true;
|
||||
// Можно использовать type для дополнительной логики в будущем
|
||||
// const selectedType = type;
|
||||
};
|
||||
const onTypeSelected = async () => {
|
||||
isAccountTypeSelected.value = true;
|
||||
|
||||
// Проверяем, нужен ли выбор программы для данного типа аккаунта
|
||||
try {
|
||||
const accountType = store.state.userData.type;
|
||||
if (accountType) {
|
||||
const { [Queries.System.GetRegistrationConfig.name]: config } = await client.Query(
|
||||
Queries.System.GetRegistrationConfig.query,
|
||||
{
|
||||
variables: {
|
||||
coopname: systemStore.info.coopname,
|
||||
account_type: accountType,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
store.state.requiresProgramSelection = config.requires_selection && config.programs.length > 0;
|
||||
|
||||
// Если программа только одна - автоматически выбираем её
|
||||
if (config.programs.length === 1) {
|
||||
store.state.selectedProgramKey = config.programs[0].key;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error checking program selection requirement:', e);
|
||||
store.state.requiresProgramSelection = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onTypeCleared = () => {
|
||||
isAccountTypeSelected.value = false;
|
||||
// Сбрасываем чекбокс согласия при сбросе типа
|
||||
store.state.agreements.condidential = false;
|
||||
// Сбрасываем выбор программы
|
||||
store.state.selectedProgramKey = '';
|
||||
store.state.requiresProgramSelection = false;
|
||||
};
|
||||
|
||||
const setData = (userDataForm: any) => {
|
||||
|
||||
@@ -13,6 +13,8 @@ div
|
||||
|
||||
SetUserData
|
||||
|
||||
SelectProgram
|
||||
|
||||
GenerateAccount
|
||||
|
||||
SelectBranch(v-if='isBranched')
|
||||
@@ -33,6 +35,7 @@ import { watch, onMounted, onBeforeUnmount, computed } from 'vue';
|
||||
import EmailInput from './EmailInput.vue';
|
||||
import GenerateAccount from './GenerateAccount.vue';
|
||||
import SetUserData from './SetUserData.vue';
|
||||
import SelectProgram from './SelectProgram.vue';
|
||||
import SignStatement from './SignStatement.vue';
|
||||
import ReadStatement from './ReadStatement.vue';
|
||||
import PayInitial from './PayInitial.vue';
|
||||
|
||||
+5
-5
@@ -30,7 +30,7 @@ export class Factory extends DocFactory<BlagorostOffer.Action> {
|
||||
const common_user = this.getCommonUser(userData)
|
||||
|
||||
// Проверяем наличие данных протоколов, утвердивших предыдущие документы
|
||||
if (!vars.blagorost_provision?.protocol_number || !vars.blagorost_provision?.protocol_day_month_year) {
|
||||
if (!vars.blagorost_program?.protocol_number || !vars.blagorost_program?.protocol_day_month_year) {
|
||||
throw new Error('Данные протокола об утверждении Положения о ЦПП «БЛАГОРОСТ» не найдены. Сначала утвердите Положение и сохраните данные протокола.')
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ export class Factory extends DocFactory<BlagorostOffer.Action> {
|
||||
throw new Error('Данные протокола об утверждении шаблона публичной оферты ЦПП «БЛАГОРОСТ» не найдены. Сначала утвердите шаблон оферты и сохраните данные протокола.')
|
||||
}
|
||||
|
||||
const blagorost_provision = {
|
||||
protocol_number: vars.blagorost_provision.protocol_number,
|
||||
protocol_date: vars.blagorost_provision.protocol_day_month_year,
|
||||
const blagorost_program = {
|
||||
protocol_number: vars.blagorost_program.protocol_number,
|
||||
protocol_date: vars.blagorost_program.protocol_day_month_year,
|
||||
}
|
||||
|
||||
const blagorost_offer_template = {
|
||||
@@ -54,7 +54,7 @@ export class Factory extends DocFactory<BlagorostOffer.Action> {
|
||||
coop,
|
||||
vars,
|
||||
common_user,
|
||||
blagorost_provision,
|
||||
blagorost_program,
|
||||
blagorost_offer_template,
|
||||
}
|
||||
|
||||
@@ -28,12 +28,12 @@ export class Factory extends DocFactory<GeneratorOfferTemplate.Action> {
|
||||
const common_user = this.getCommonUser(user)
|
||||
|
||||
// Проверяем наличие данных протокола, утвердившего генерационную программу
|
||||
if (!vars.generation_program?.protocol_number || !vars.generation_program?.protocol_day_month_year) {
|
||||
if (!vars.generator_program?.protocol_number || !vars.generator_program?.protocol_day_month_year) {
|
||||
throw new Error('Данные протокола об утверждении генерационной программы не найдены. Сначала утвердите генерационную программу и сохраните данные протокола.')
|
||||
}
|
||||
|
||||
// Проверяем наличие данных протокола, утвердившего шаблон оферты генератора
|
||||
if (!vars.generation_offer_template?.protocol_number || !vars.generation_offer_template?.protocol_day_month_year) {
|
||||
if (!vars.generator_offer_template?.protocol_number || !vars.generator_offer_template?.protocol_day_month_year) {
|
||||
throw new Error('Данные протокола об утверждении шаблона оферты генератора не найдены. Сначала утвердите шаблон оферты генератора и сохраните данные протокола.')
|
||||
}
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@ export class Factory extends DocFactory<GeneratorOffer.Action> {
|
||||
const common_user = this.getCommonUser(user)
|
||||
|
||||
// Проверяем наличие данных протокола, утвердившего генерационную программу
|
||||
if (!vars.generation_program?.protocol_number || !vars.generation_program?.protocol_day_month_year) {
|
||||
if (!vars.generator_program?.protocol_number || !vars.generator_program?.protocol_day_month_year) {
|
||||
throw new Error('Данные протокола об утверждении генерационной программы не найдены. Сначала утвердите генерационную программу и сохраните данные протокола.')
|
||||
}
|
||||
|
||||
// Проверяем наличие данных протокола, утвердившего шаблон оферты генератора
|
||||
if (!vars.generation_offer_template?.protocol_number || !vars.generation_offer_template?.protocol_day_month_year) {
|
||||
if (!vars.generator_offer_template?.protocol_number || !vars.generator_offer_template?.protocol_day_month_year) {
|
||||
throw new Error('Данные протокола об утверждении шаблона оферты генератора не найдены. Сначала утвердите шаблон оферты генератора и сохраните данные протокола.')
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -1,31 +1,31 @@
|
||||
import { DraftContract } from 'cooptypes'
|
||||
import { BlagorostProvision } from '../Templates'
|
||||
import { BlagorostProgramTemplate } from '../Templates'
|
||||
import { DocFactory } from '../Factory'
|
||||
import type { IGeneratedDocument, IGenerationOptions, IMetaDocument, ITemplate } from '../Interfaces'
|
||||
import type { MongoDBConnector } from '../Services/Databazor'
|
||||
|
||||
export { BlagorostProvision as Template } from '../Templates'
|
||||
export { BlagorostProgramTemplate as Template } from '../Templates'
|
||||
|
||||
export class Factory extends DocFactory<BlagorostProvision.Action> {
|
||||
export class Factory extends DocFactory<BlagorostProgramTemplate.Action> {
|
||||
constructor(storage: MongoDBConnector) {
|
||||
super(storage)
|
||||
}
|
||||
|
||||
async generateDocument(data: BlagorostProvision.Action, options?: IGenerationOptions): Promise<IGeneratedDocument> {
|
||||
let template: ITemplate<BlagorostProvision.Model>
|
||||
async generateDocument(data: BlagorostProgramTemplate.Action, options?: IGenerationOptions): Promise<IGeneratedDocument> {
|
||||
let template: ITemplate<BlagorostProgramTemplate.Model>
|
||||
|
||||
if (process.env.SOURCE === 'local') {
|
||||
template = BlagorostProvision.Template
|
||||
template = BlagorostProgramTemplate.Template
|
||||
}
|
||||
else {
|
||||
template = await this.getTemplate(DraftContract.contractName.production, BlagorostProvision.registry_id, data.block_num)
|
||||
template = await this.getTemplate(DraftContract.contractName.production, BlagorostProgramTemplate.registry_id, data.block_num)
|
||||
}
|
||||
|
||||
const meta: IMetaDocument = await this.getMeta({ title: template.title, ...data })
|
||||
|
||||
const vars = await this.getVars(data.coopname)
|
||||
|
||||
const combinedData: BlagorostProvision.Model = { meta, vars }
|
||||
const combinedData: BlagorostProgramTemplate.Model = { meta, vars }
|
||||
|
||||
await this.validate(combinedData, template.model)
|
||||
|
||||
@@ -27,20 +27,20 @@ export class Factory extends DocFactory<BlagorostOfferTemplate.Action> {
|
||||
const coop = await this.getCooperative(data.coopname)
|
||||
|
||||
// Проверяем наличие данных протокола, утвердившего Положение (документ 998)
|
||||
if (!vars.blagorost_provision?.protocol_number || !vars.blagorost_provision?.protocol_day_month_year) {
|
||||
if (!vars.blagorost_program?.protocol_number || !vars.blagorost_program?.protocol_day_month_year) {
|
||||
throw new Error('Данные протокола об утверждении Положения о ЦПП «БЛАГОРОСТ» не найдены. Сначала утвердите Положение и сохраните данные протокола.')
|
||||
}
|
||||
|
||||
const blagorost_provision = {
|
||||
protocol_number: vars.blagorost_provision.protocol_number,
|
||||
protocol_date: vars.blagorost_provision.protocol_day_month_year,
|
||||
const blagorost_program = {
|
||||
protocol_number: vars.blagorost_program.protocol_number,
|
||||
protocol_date: vars.blagorost_program.protocol_day_month_year,
|
||||
}
|
||||
|
||||
const combinedData: BlagorostOfferTemplate.Model = {
|
||||
meta,
|
||||
coop,
|
||||
vars,
|
||||
blagorost_provision,
|
||||
blagorost_program,
|
||||
}
|
||||
|
||||
await this.validate(combinedData, template.model)
|
||||
|
||||
@@ -22,7 +22,7 @@ export * as ReturnByAssetAct from './802.ReturnByAssetAct'
|
||||
export * as ReturnByMoney from './900.ReturnByMoney'
|
||||
export * as ReturnByMoneyDecision from './901.ReturnByMoneyDecision'
|
||||
|
||||
export * as BlagorostOffer from './1000.CapitalizationAgreement'
|
||||
export * as BlagorostOffer from './1000.BlagorostOffer'
|
||||
export * as GenerationAgreement from './1001.GenerationAgreement'
|
||||
export * as ProjectGenerationAgreement from './1002.ProjectGenerationAgreement'
|
||||
export * as ComponentGenerationAgreement from './1003.ComponentGenerationAgreement'
|
||||
@@ -69,6 +69,6 @@ export * as AnnualGeneralMeetingDecision from './304.AnnualGeneralMeetingDecisio
|
||||
export * as GeneratorProgramTemplate from './994.GeneratorProgramTemplate'
|
||||
export * as GeneratorOfferTemplate from './995.GeneratorOfferTemplate'
|
||||
export * as GeneratorOffer from './996.GeneratorOffer'
|
||||
export * as BlagorostProvision from './998.BlagorostProvision'
|
||||
export * as BlagorostProgramTemplate from './998.BlagorostProgramTemplate'
|
||||
export * as GenerationAgreementTemplate from './997.GenerationAgreementTemplate'
|
||||
export * as BlagorostOfferTemplate from './999.BlagorostOfferTemplate'
|
||||
|
||||
@@ -87,7 +87,7 @@ export const VarsSchema: JSONSchemaType<IVars> = {
|
||||
additionalProperties: true,
|
||||
nullable: true,
|
||||
},
|
||||
blagorost_provision: {
|
||||
blagorost_program: {
|
||||
type: 'object',
|
||||
nullable: true,
|
||||
properties: {
|
||||
@@ -107,7 +107,7 @@ export const VarsSchema: JSONSchemaType<IVars> = {
|
||||
required: ['protocol_number', 'protocol_day_month_year'],
|
||||
additionalProperties: true,
|
||||
},
|
||||
generation_program: {
|
||||
generator_program: {
|
||||
type: 'object',
|
||||
nullable: true,
|
||||
properties: {
|
||||
@@ -117,7 +117,7 @@ export const VarsSchema: JSONSchemaType<IVars> = {
|
||||
required: ['protocol_number', 'protocol_day_month_year'],
|
||||
additionalProperties: true,
|
||||
},
|
||||
generation_offer_template: {
|
||||
generator_offer_template: {
|
||||
type: 'object',
|
||||
nullable: true,
|
||||
properties: {
|
||||
@@ -148,10 +148,10 @@ export const VarsSchema: JSONSchemaType<IVars> = {
|
||||
// 'participant_application', //not_required
|
||||
// 'coopenomics_agreement', //not_required
|
||||
// 'generation_agreement_template', //not_required
|
||||
// 'blagorost_provision', //not_required
|
||||
// 'blagorost_program', //not_required
|
||||
// 'blagorost_offer_template', //not_required
|
||||
// 'generation_program', //not_required
|
||||
// 'generation_offer_template', //not_required
|
||||
// 'generator_program', //not_required
|
||||
// 'generator_offer_template', //not_required
|
||||
],
|
||||
additionalProperties: true,
|
||||
}
|
||||
|
||||
+8
-8
@@ -4,10 +4,10 @@ import type { IMetaDocument, ITemplate } from '../Interfaces'
|
||||
import { IMetaJSONSchema } from '../Schema/MetaSchema'
|
||||
import { CommonUserSchema, CooperativeSchema, VarsSchema } from '../Schema'
|
||||
|
||||
export const registry_id = Cooperative.Registry.CapitalizationAgreement.registry_id
|
||||
export const registry_id = Cooperative.Registry.BlagorostOffer.registry_id
|
||||
|
||||
// Модель действия для генерации
|
||||
export type Action = Cooperative.Registry.CapitalizationAgreement.Action
|
||||
export type Action = Cooperative.Registry.BlagorostOffer.Action
|
||||
|
||||
// Модель данных - используем полную модель с дополнительными полями
|
||||
export interface Model {
|
||||
@@ -15,7 +15,7 @@ export interface Model {
|
||||
coop: Cooperative.Model.ICooperativeData
|
||||
vars: Cooperative.Model.IVars
|
||||
common_user: Cooperative.Model.ICommonUser
|
||||
blagorost_provision: {
|
||||
blagorost_program: {
|
||||
protocol_number: string
|
||||
protocol_date: string
|
||||
}
|
||||
@@ -33,7 +33,7 @@ export const Schema: JSONSchemaType<Model> = {
|
||||
coop: CooperativeSchema,
|
||||
vars: VarsSchema,
|
||||
common_user: CommonUserSchema,
|
||||
blagorost_provision: {
|
||||
blagorost_program: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
protocol_number: { type: 'string' },
|
||||
@@ -55,9 +55,9 @@ export const Schema: JSONSchemaType<Model> = {
|
||||
} as any
|
||||
|
||||
export const Template: ITemplate<Model> = {
|
||||
title: Cooperative.Registry.CapitalizationAgreement.title,
|
||||
description: Cooperative.Registry.CapitalizationAgreement.description,
|
||||
title: Cooperative.Registry.BlagorostOffer.title,
|
||||
description: Cooperative.Registry.BlagorostOffer.description,
|
||||
model: Schema,
|
||||
context: Cooperative.Registry.CapitalizationAgreement.context,
|
||||
translations: Cooperative.Registry.CapitalizationAgreement.translations,
|
||||
context: Cooperative.Registry.BlagorostOffer.context,
|
||||
translations: Cooperative.Registry.BlagorostOffer.translations,
|
||||
}
|
||||
+5
-5
@@ -5,7 +5,7 @@ import type { IVars } from '../Models'
|
||||
import { IMetaJSONSchema } from '../Schema/MetaSchema'
|
||||
import { VarsSchema } from '../Schema'
|
||||
|
||||
export const registry_id = Cooperative.Registry.BlagorostProvision.registry_id
|
||||
export const registry_id = Cooperative.Registry.BlagorostProgramTemplate.registry_id
|
||||
|
||||
// Модель действия для генерации
|
||||
export interface Action extends IGenerate {
|
||||
@@ -30,9 +30,9 @@ export const Schema: JSONSchemaType<Model> = {
|
||||
}
|
||||
|
||||
export const Template: ITemplate<Model> = {
|
||||
title: Cooperative.Registry.BlagorostProvision.title,
|
||||
description: Cooperative.Registry.BlagorostProvision.description,
|
||||
title: Cooperative.Registry.BlagorostProgramTemplate.title,
|
||||
description: Cooperative.Registry.BlagorostProgramTemplate.description,
|
||||
model: Schema,
|
||||
context: Cooperative.Registry.BlagorostProvision.context,
|
||||
translations: Cooperative.Registry.BlagorostProvision.translations,
|
||||
context: Cooperative.Registry.BlagorostProgramTemplate.context,
|
||||
translations: Cooperative.Registry.BlagorostProgramTemplate.translations,
|
||||
}
|
||||
@@ -19,7 +19,7 @@ export const Schema: JSONSchemaType<Model> = {
|
||||
meta: IMetaJSONSchema,
|
||||
coop: CooperativeSchema,
|
||||
vars: VarsSchema,
|
||||
blagorost_provision: {
|
||||
blagorost_program: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
protocol_number: { type: 'string' },
|
||||
@@ -28,7 +28,7 @@ export const Schema: JSONSchemaType<Model> = {
|
||||
required: ['protocol_number', 'protocol_date'],
|
||||
},
|
||||
},
|
||||
required: ['meta', 'coop', 'vars', 'blagorost_provision'],
|
||||
required: ['meta', 'coop', 'vars', 'blagorost_program'],
|
||||
additionalProperties: true,
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@ export * as GeneratorOfferTemplate from './995.GeneratorOfferTemplate'
|
||||
export * as GeneratorOffer from './996.GeneratorOffer'
|
||||
|
||||
// Документы ЦПП БЛАГОРОСТ
|
||||
export * as BlagorostProvision from './998.BlagorostProvision'
|
||||
export * as BlagorostProgramTemplate from './998.BlagorostProgramTemplate'
|
||||
export * as GenerationAgreementTemplate from './997.GenerationAgreementTemplate'
|
||||
export * as BlagorostOfferTemplate from './999.BlagorostOfferTemplate'
|
||||
export * as BlagorostOffer from './1000.CapitalizationAgreement'
|
||||
export * as BlagorostOffer from './1000.BlagorostOffer'
|
||||
export * as GenerationAgreement from './1001.GenerationAgreement'
|
||||
export * as ProjectGenerationAgreement from './1002.ProjectGenerationAgreement'
|
||||
export * as ComponentGenerationAgreement from './1003.ComponentGenerationAgreement'
|
||||
|
||||
@@ -61,13 +61,13 @@ import * as AnnualGeneralMeetingNotification from './302.AnnualGeneralMeetingNot
|
||||
import * as AnnualGeneralMeetingVotingBallot from './303.AnnualGeneralMeetingVotingBallot'
|
||||
import * as AnnualGeneralMeetingDecision from './304.AnnualGeneralMeetingDecision'
|
||||
|
||||
import * as BlagorostProvision from './998.BlagorostProvision'
|
||||
import * as BlagorostProgramTemplate from './998.BlagorostProgramTemplate'
|
||||
import * as BlagorostOfferTemplate from './999.BlagorostOfferTemplate'
|
||||
import * as GenerationAgreementTemplate from './997.GenerationAgreementTemplate'
|
||||
import * as GeneratorOfferTemplate from './995.GeneratorOfferTemplate'
|
||||
import * as GeneratorOffer from './996.GeneratorOffer'
|
||||
import * as GeneratorProgramTemplate from './994.GeneratorProgramTemplate'
|
||||
import * as BlagorostOffer from './1000.CapitalizationAgreement'
|
||||
import * as BlagorostOffer from './1000.BlagorostOffer'
|
||||
|
||||
export const Registry = {
|
||||
1: WalletAgreement,
|
||||
@@ -99,7 +99,7 @@ export const Registry = {
|
||||
995: GeneratorOfferTemplate,
|
||||
996: GeneratorOffer,
|
||||
997: GenerationAgreementTemplate,
|
||||
998: BlagorostProvision,
|
||||
998: BlagorostProgramTemplate,
|
||||
999: BlagorostOfferTemplate,
|
||||
1000: BlagorostOffer,
|
||||
1001: GenerationAgreement,
|
||||
|
||||
@@ -107,7 +107,7 @@ export class Generator implements IGenerator {
|
||||
|
||||
// ЦПП БЛАГОРОСТ
|
||||
[Actions.GenerationAgreementTemplate.Template.registry_id]: new Actions.GenerationAgreementTemplate.Factory(this.storage), // 997
|
||||
[Actions.BlagorostProvision.Template.registry_id]: new Actions.BlagorostProvision.Factory(this.storage), // 998
|
||||
[Actions.BlagorostProgramTemplate.Template.registry_id]: new Actions.BlagorostProgramTemplate.Factory(this.storage), // 998
|
||||
[Actions.BlagorostOfferTemplate.Template.registry_id]: new Actions.BlagorostOfferTemplate.Factory(this.storage), // 999
|
||||
[Actions.BlagorostOffer.Template.registry_id]: new Actions.BlagorostOffer.Factory(this.storage), // 1000
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('тест генератора документов ЦПП БЛАГОР
|
||||
it('генерируем шаблон публичной оферты по ЦПП БЛАГОРОСТ', async () => {
|
||||
// Добавляем данные протокола для документа 998
|
||||
await generator.update('vars', { coopname: 'voskhod' }, {
|
||||
blagorost_provision: {
|
||||
blagorost_program: {
|
||||
protocol_number: '01-12-2024',
|
||||
protocol_day_month_year: '01 декабря 2024 г.',
|
||||
},
|
||||
|
||||
@@ -283,7 +283,7 @@ export async function preLoading() {
|
||||
protocol_number: '10-05-2024',
|
||||
protocol_day_month_year: '10 мая 2024 г.',
|
||||
},
|
||||
blagorost_provision: {
|
||||
blagorost_program: {
|
||||
protocol_number: '10-05-2024',
|
||||
protocol_day_month_year: '10 мая 2024 г.',
|
||||
},
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { registrationConfigSelector } from '../../selectors/system/registrationConfigSelector'
|
||||
import { $, type GraphQLTypes, type InputType, Selector } from '../../zeus/index'
|
||||
|
||||
export const name = 'getRegistrationConfig'
|
||||
|
||||
/**
|
||||
* Получить конфигурацию программ регистрации для кооператива
|
||||
*/
|
||||
export const query = Selector('Query')({
|
||||
[name]: [
|
||||
{
|
||||
coopname: $('coopname', 'String!'),
|
||||
account_type: $('account_type', 'AccountType!'),
|
||||
},
|
||||
registrationConfigSelector,
|
||||
],
|
||||
})
|
||||
|
||||
export interface IInput {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
[key: string]: unknown
|
||||
|
||||
coopname: string
|
||||
account_type: GraphQLTypes['AccountType']
|
||||
}
|
||||
|
||||
export type IOutput = InputType<GraphQLTypes['Query'], typeof query>
|
||||
@@ -7,5 +7,8 @@ export * as GetInstallationStatus from './getInstallationStatus'
|
||||
/** Получить подписки пользователя у провайдера */
|
||||
export * as GetProviderSubscriptions from './getProviderSubscriptions'
|
||||
|
||||
/** Получить конфигурацию программ регистрации для кооператива */
|
||||
export * as GetRegistrationConfig from './getRegistrationConfig'
|
||||
|
||||
/** Получить сводную публичную информацию о системе */
|
||||
export * as GetSystemInfo from './getSystemInfo'
|
||||
|
||||
@@ -3,4 +3,5 @@ export * from './cooperatorAccountSelector'
|
||||
export * from './currentInstanceSelector'
|
||||
export * from './installationStatusSelector'
|
||||
export * from './providerSubscriptionSelector'
|
||||
export * from './registrationConfigSelector'
|
||||
export * from './systemInfoSelector'
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Selector } from '../../zeus/index'
|
||||
|
||||
export const registrationProgramSelector = Selector('RegistrationProgram')({
|
||||
key: true,
|
||||
title: true,
|
||||
description: true,
|
||||
image_url: true,
|
||||
requirements: true,
|
||||
applicable_account_types: true,
|
||||
order: true,
|
||||
})
|
||||
|
||||
export const registrationConfigSelector = Selector('RegistrationConfig')({
|
||||
requires_selection: true,
|
||||
programs: registrationProgramSelector,
|
||||
})
|
||||
@@ -1346,6 +1346,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
},
|
||||
getProviderSubscriptionById:{
|
||||
|
||||
},
|
||||
getRegistrationConfig:{
|
||||
account_type:"AccountType"
|
||||
},
|
||||
getUserWebPushSubscriptions:{
|
||||
data:"GetUserSubscriptionsInput"
|
||||
@@ -1382,7 +1385,7 @@ export const AllTypesProps: Record<string,any> = {
|
||||
contract:"GenerationAgreementSignedDocumentInput"
|
||||
},
|
||||
RegisterParticipantInput:{
|
||||
capitalization_agreement:"SignedDigitalDocumentInput",
|
||||
blagorost_offer:"SignedDigitalDocumentInput",
|
||||
privacy_agreement:"SignedDigitalDocumentInput",
|
||||
signature_agreement:"SignedDigitalDocumentInput",
|
||||
statement:"ParticipantApplicationSignedDocumentInput",
|
||||
@@ -3386,6 +3389,7 @@ export const ReturnTypes: Record<string,any> = {
|
||||
getPayments:"PaginatedGatewayPaymentsPaginationResult",
|
||||
getProviderSubscriptionById:"ProviderSubscription",
|
||||
getProviderSubscriptions:"ProviderSubscription",
|
||||
getRegistrationConfig:"RegistrationConfig",
|
||||
getSystemInfo:"SystemInfo",
|
||||
getUserWebPushSubscriptions:"WebPushSubscriptionDto",
|
||||
getWebPushSubscriptionStats:"SubscriptionStatsDto",
|
||||
@@ -3417,6 +3421,19 @@ export const ReturnTypes: Record<string,any> = {
|
||||
account:"Account",
|
||||
tokens:"Tokens"
|
||||
},
|
||||
RegistrationConfig:{
|
||||
programs:"RegistrationProgram",
|
||||
requires_selection:"Boolean"
|
||||
},
|
||||
RegistrationProgram:{
|
||||
applicable_account_types:"AccountType",
|
||||
description:"String",
|
||||
image_url:"String",
|
||||
key:"String",
|
||||
order:"Int",
|
||||
requirements:"String",
|
||||
title:"String"
|
||||
},
|
||||
RepresentedBy:{
|
||||
based_on:"String",
|
||||
first_name:"String",
|
||||
|
||||
@@ -4726,6 +4726,8 @@ export type ValueTypes = {
|
||||
account_type: ValueTypes["AccountType"] | Variable<any, string>,
|
||||
/** Имя кооператива */
|
||||
coopname: string | Variable<any, string>,
|
||||
/** Ключ выбранной программы регистрации (опционально) */
|
||||
program_key?: string | undefined | null | Variable<any, string>,
|
||||
/** Имя пользователя (аккаунт) */
|
||||
username: string | Variable<any, string>
|
||||
};
|
||||
@@ -6435,6 +6437,7 @@ getPayments?: [{ data?: ValueTypes["PaymentFiltersInput"] | undefined | null | V
|
||||
getProviderSubscriptionById?: [{ id: number | Variable<any, string>},ValueTypes["ProviderSubscription"]],
|
||||
/** Получить подписки пользователя у провайдера */
|
||||
getProviderSubscriptions?:ValueTypes["ProviderSubscription"],
|
||||
getRegistrationConfig?: [{ account_type: ValueTypes["AccountType"] | Variable<any, string>, coopname: string | Variable<any, string>},ValueTypes["RegistrationConfig"]],
|
||||
/** Получить сводную публичную информацию о системе */
|
||||
getSystemInfo?:ValueTypes["SystemInfo"],
|
||||
getUserWebPushSubscriptions?: [{ data: ValueTypes["GetUserSubscriptionsInput"] | Variable<any, string>},ValueTypes["WebPushSubscriptionDto"]],
|
||||
@@ -6561,7 +6564,7 @@ searchPrivateAccounts?: [{ data: ValueTypes["SearchPrivateAccountsInput"] | Vari
|
||||
/** Имя кооперативного участка */
|
||||
braname?: string | undefined | null | Variable<any, string>,
|
||||
/** Подписанный документ соглашения по капитализации (опционально, только если требуется) */
|
||||
capitalization_agreement?: ValueTypes["SignedDigitalDocumentInput"] | undefined | null | Variable<any, string>,
|
||||
blagorost_offer?: ValueTypes["SignedDigitalDocumentInput"] | undefined | null | Variable<any, string>,
|
||||
/** Подписанный документ политики конфиденциальности от пайщика */
|
||||
privacy_agreement: ValueTypes["SignedDigitalDocumentInput"] | Variable<any, string>,
|
||||
/** Подписанный документ положения о цифровой подписи от пайщика */
|
||||
@@ -6581,6 +6584,30 @@ searchPrivateAccounts?: [{ data: ValueTypes["SearchPrivateAccountsInput"] | Vari
|
||||
/** Токены доступа и обновления */
|
||||
tokens?:ValueTypes["Tokens"],
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["RegistrationConfig"]: AliasType<{
|
||||
/** Доступные программы */
|
||||
programs?:ValueTypes["RegistrationProgram"],
|
||||
/** Нужен ли выбор программы */
|
||||
requires_selection?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["RegistrationProgram"]: AliasType<{
|
||||
/** Для каких типов аккаунтов доступна программа */
|
||||
applicable_account_types?:boolean | `@${string}`,
|
||||
/** Описание программы */
|
||||
description?:boolean | `@${string}`,
|
||||
/** URL изображения (опционально) */
|
||||
image_url?:boolean | `@${string}`,
|
||||
/** Уникальный ключ программы */
|
||||
key?:boolean | `@${string}`,
|
||||
/** Порядок отображения */
|
||||
order?:boolean | `@${string}`,
|
||||
/** Минимальные требования для участия */
|
||||
requirements?:boolean | `@${string}`,
|
||||
/** Название программы для отображения */
|
||||
title?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["RepresentedBy"]: AliasType<{
|
||||
/** На основании чего действует */
|
||||
@@ -11547,6 +11574,8 @@ export type ResolverInputTypes = {
|
||||
account_type: ResolverInputTypes["AccountType"],
|
||||
/** Имя кооператива */
|
||||
coopname: string,
|
||||
/** Ключ выбранной программы регистрации (опционально) */
|
||||
program_key?: string | undefined | null,
|
||||
/** Имя пользователя (аккаунт) */
|
||||
username: string
|
||||
};
|
||||
@@ -13258,6 +13287,7 @@ getPayments?: [{ data?: ResolverInputTypes["PaymentFiltersInput"] | undefined |
|
||||
getProviderSubscriptionById?: [{ id: number},ResolverInputTypes["ProviderSubscription"]],
|
||||
/** Получить подписки пользователя у провайдера */
|
||||
getProviderSubscriptions?:ResolverInputTypes["ProviderSubscription"],
|
||||
getRegistrationConfig?: [{ account_type: ResolverInputTypes["AccountType"], coopname: string},ResolverInputTypes["RegistrationConfig"]],
|
||||
/** Получить сводную публичную информацию о системе */
|
||||
getSystemInfo?:ResolverInputTypes["SystemInfo"],
|
||||
getUserWebPushSubscriptions?: [{ data: ResolverInputTypes["GetUserSubscriptionsInput"]},ResolverInputTypes["WebPushSubscriptionDto"]],
|
||||
@@ -13384,7 +13414,7 @@ searchPrivateAccounts?: [{ data: ResolverInputTypes["SearchPrivateAccountsInput"
|
||||
/** Имя кооперативного участка */
|
||||
braname?: string | undefined | null,
|
||||
/** Подписанный документ соглашения по капитализации (опционально, только если требуется) */
|
||||
capitalization_agreement?: ResolverInputTypes["SignedDigitalDocumentInput"] | undefined | null,
|
||||
blagorost_offer?: ResolverInputTypes["SignedDigitalDocumentInput"] | undefined | null,
|
||||
/** Подписанный документ политики конфиденциальности от пайщика */
|
||||
privacy_agreement: ResolverInputTypes["SignedDigitalDocumentInput"],
|
||||
/** Подписанный документ положения о цифровой подписи от пайщика */
|
||||
@@ -13404,6 +13434,30 @@ searchPrivateAccounts?: [{ data: ResolverInputTypes["SearchPrivateAccountsInput"
|
||||
/** Токены доступа и обновления */
|
||||
tokens?:ResolverInputTypes["Tokens"],
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["RegistrationConfig"]: AliasType<{
|
||||
/** Доступные программы */
|
||||
programs?:ResolverInputTypes["RegistrationProgram"],
|
||||
/** Нужен ли выбор программы */
|
||||
requires_selection?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["RegistrationProgram"]: AliasType<{
|
||||
/** Для каких типов аккаунтов доступна программа */
|
||||
applicable_account_types?:boolean | `@${string}`,
|
||||
/** Описание программы */
|
||||
description?:boolean | `@${string}`,
|
||||
/** URL изображения (опционально) */
|
||||
image_url?:boolean | `@${string}`,
|
||||
/** Уникальный ключ программы */
|
||||
key?:boolean | `@${string}`,
|
||||
/** Порядок отображения */
|
||||
order?:boolean | `@${string}`,
|
||||
/** Минимальные требования для участия */
|
||||
requirements?:boolean | `@${string}`,
|
||||
/** Название программы для отображения */
|
||||
title?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["RepresentedBy"]: AliasType<{
|
||||
/** На основании чего действует */
|
||||
@@ -18284,6 +18338,8 @@ export type ModelTypes = {
|
||||
account_type: ModelTypes["AccountType"],
|
||||
/** Имя кооператива */
|
||||
coopname: string,
|
||||
/** Ключ выбранной программы регистрации (опционально) */
|
||||
program_key?: string | undefined | null,
|
||||
/** Имя пользователя (аккаунт) */
|
||||
username: string
|
||||
};
|
||||
@@ -20131,6 +20187,8 @@ export type ModelTypes = {
|
||||
getProviderSubscriptionById: ModelTypes["ProviderSubscription"],
|
||||
/** Получить подписки пользователя у провайдера */
|
||||
getProviderSubscriptions: Array<ModelTypes["ProviderSubscription"]>,
|
||||
/** Получить конфигурацию программ регистрации для кооператива */
|
||||
getRegistrationConfig: ModelTypes["RegistrationConfig"],
|
||||
/** Получить сводную публичную информацию о системе */
|
||||
getSystemInfo: ModelTypes["SystemInfo"],
|
||||
/** Получить веб-пуш подписки пользователя */
|
||||
@@ -20257,7 +20315,7 @@ export type ModelTypes = {
|
||||
/** Имя кооперативного участка */
|
||||
braname?: string | undefined | null,
|
||||
/** Подписанный документ соглашения по капитализации (опционально, только если требуется) */
|
||||
capitalization_agreement?: ModelTypes["SignedDigitalDocumentInput"] | undefined | null,
|
||||
blagorost_offer?: ModelTypes["SignedDigitalDocumentInput"] | undefined | null,
|
||||
/** Подписанный документ политики конфиденциальности от пайщика */
|
||||
privacy_agreement: ModelTypes["SignedDigitalDocumentInput"],
|
||||
/** Подписанный документ положения о цифровой подписи от пайщика */
|
||||
@@ -20276,6 +20334,28 @@ export type ModelTypes = {
|
||||
account: ModelTypes["Account"],
|
||||
/** Токены доступа и обновления */
|
||||
tokens: ModelTypes["Tokens"]
|
||||
};
|
||||
["RegistrationConfig"]: {
|
||||
/** Доступные программы */
|
||||
programs: Array<ModelTypes["RegistrationProgram"]>,
|
||||
/** Нужен ли выбор программы */
|
||||
requires_selection: boolean
|
||||
};
|
||||
["RegistrationProgram"]: {
|
||||
/** Для каких типов аккаунтов доступна программа */
|
||||
applicable_account_types: Array<ModelTypes["AccountType"]>,
|
||||
/** Описание программы */
|
||||
description: string,
|
||||
/** URL изображения (опционально) */
|
||||
image_url?: string | undefined | null,
|
||||
/** Уникальный ключ программы */
|
||||
key: string,
|
||||
/** Порядок отображения */
|
||||
order: number,
|
||||
/** Минимальные требования для участия */
|
||||
requirements?: string | undefined | null,
|
||||
/** Название программы для отображения */
|
||||
title: string
|
||||
};
|
||||
["RepresentedBy"]: {
|
||||
/** На основании чего действует */
|
||||
@@ -25218,6 +25298,8 @@ export type GraphQLTypes = {
|
||||
account_type: GraphQLTypes["AccountType"],
|
||||
/** Имя кооператива */
|
||||
coopname: string,
|
||||
/** Ключ выбранной программы регистрации (опционально) */
|
||||
program_key?: string | undefined | null,
|
||||
/** Имя пользователя (аккаунт) */
|
||||
username: string
|
||||
};
|
||||
@@ -27146,6 +27228,8 @@ export type GraphQLTypes = {
|
||||
getProviderSubscriptionById: GraphQLTypes["ProviderSubscription"],
|
||||
/** Получить подписки пользователя у провайдера */
|
||||
getProviderSubscriptions: Array<GraphQLTypes["ProviderSubscription"]>,
|
||||
/** Получить конфигурацию программ регистрации для кооператива */
|
||||
getRegistrationConfig: GraphQLTypes["RegistrationConfig"],
|
||||
/** Получить сводную публичную информацию о системе */
|
||||
getSystemInfo: GraphQLTypes["SystemInfo"],
|
||||
/** Получить веб-пуш подписки пользователя */
|
||||
@@ -27274,7 +27358,7 @@ export type GraphQLTypes = {
|
||||
/** Имя кооперативного участка */
|
||||
braname?: string | undefined | null,
|
||||
/** Подписанный документ соглашения по капитализации (опционально, только если требуется) */
|
||||
capitalization_agreement?: GraphQLTypes["SignedDigitalDocumentInput"] | undefined | null,
|
||||
blagorost_offer?: GraphQLTypes["SignedDigitalDocumentInput"] | undefined | null,
|
||||
/** Подписанный документ политики конфиденциальности от пайщика */
|
||||
privacy_agreement: GraphQLTypes["SignedDigitalDocumentInput"],
|
||||
/** Подписанный документ положения о цифровой подписи от пайщика */
|
||||
@@ -27294,6 +27378,30 @@ export type GraphQLTypes = {
|
||||
account: GraphQLTypes["Account"],
|
||||
/** Токены доступа и обновления */
|
||||
tokens: GraphQLTypes["Tokens"]
|
||||
};
|
||||
["RegistrationConfig"]: {
|
||||
__typename: "RegistrationConfig",
|
||||
/** Доступные программы */
|
||||
programs: Array<GraphQLTypes["RegistrationProgram"]>,
|
||||
/** Нужен ли выбор программы */
|
||||
requires_selection: boolean
|
||||
};
|
||||
["RegistrationProgram"]: {
|
||||
__typename: "RegistrationProgram",
|
||||
/** Для каких типов аккаунтов доступна программа */
|
||||
applicable_account_types: Array<GraphQLTypes["AccountType"]>,
|
||||
/** Описание программы */
|
||||
description: string,
|
||||
/** URL изображения (опционально) */
|
||||
image_url?: string | undefined | null,
|
||||
/** Уникальный ключ программы */
|
||||
key: string,
|
||||
/** Порядок отображения */
|
||||
order: number,
|
||||
/** Минимальные требования для участия */
|
||||
requirements?: string | undefined | null,
|
||||
/** Название программы для отображения */
|
||||
title: string
|
||||
};
|
||||
["RepresentedBy"]: {
|
||||
__typename: "RepresentedBy",
|
||||
@@ -28476,7 +28584,7 @@ export enum ApprovalStatus {
|
||||
}
|
||||
export enum CapitalOnboardingStep {
|
||||
blagorost_offer_template = "blagorost_offer_template",
|
||||
blagorost_provision = "blagorost_provision",
|
||||
blagorost_program = "blagorost_program",
|
||||
generation_agreement_template = "generation_agreement_template",
|
||||
generator_program_template = "generator_program_template"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user