make invest statement

This commit is contained in:
Alex Ant
2026-01-23 13:00:24 +05:00
parent b807df3ee8
commit aa60484315
58 changed files with 1034 additions and 296 deletions
@@ -1,10 +0,0 @@
---
description:
globs:
alwaysApply: true
---
ВАЖНО!!! Мы работаем в МОНО-репозитории pnpm, любая установка пакетов производится ЧЕРЕЗ ФИЛЬТР компонента в корне: pnpm add glob --filter notificator2.
ВАЖНО!!! НИКОГДА НЕ ЗАПУСКАЙ ПРИЛОЖЕНИЕ ИЛИ ЕГО СБОРКУ!!! Просто отчитайся что всё сделал.
ВАЖНО! НИКОГДА НЕ ЗАПУСКАЙ ТЕСТЫ ИЛИ ПРОВЕРКУ ТИПОВ ИЛИ ЛИНТЕР!!!
@@ -1,151 +0,0 @@
---
description:
globs: **/controller/**/*.ts
alwaysApply: false
---
# NestJS Controller и Чистая архитектура
## Основные принципы
1. Чистая архитектура - главный архитектурный подход. Пиши код с комментариями.
2. Типы IName, IChecksum256, ITimePointSec - это просто строки.
3. Домен должен быть полностью изолирован от инфраструктурных деталей.
4. Направление зависимостей - внутрь (к ядру, домену).
5. Домен, инфраструктура и приложение связаны через App.module, НЕ НУЖНО импортировать их друг в друга, а достаточно просто импортировать домен на уровне приложения чтобы использовать все экспорты домена.
## Структура проекта
- `domain/` - доменный слой (бизнес-логика, независимая от инфраструктуры)
- `infrastructure/` - инфраструктурный слой (адаптеры к внешним системам)
- `modules/` - слой приложения (DTO, резолверы, сервисы)
## Слои и их взаимодействие
1. **Домен**:
- Содержит чистые доменные интерфейсы и реализованные на них сущности
- НЕ должен зависеть от `cooptypes` (инфраструктурный контракт)
- Использует собственные доменные типы (например, Date вместо строковых timestamp)
- Интерфейсы портов описывают взаимодействие с внешними системами
2. **Инфраструктура**:
- Содержит адаптеры к внешним системам (блокчейн, БД и т.д.)
- Осуществляет преобразование между доменными и инфраструктурными типами
- Общая логика преобразования выносится в утилитарные классы (например, `DomainToBlockchainUtils`)
3. **Модули (приложение)**:
- DTO имплементируют доменные интерфейсы напрямую
- Резолвер вызывает сервис, который принимает DTO
- Сервис передает объекты DTO в интерактор приложения (юз-кейс)
## Поток данных
1. Резолвер принимает входные данные и передает их в сервис
2. Сервис вызывает интерактор приложения (юзкейс), передавая ему объекты DTO (имплементирующие доменный интерфейс)
3. Интерактор выполняет бизнес-логику и взаимодействует с портами домена
4. Адаптеры (инфраструктурный слой) преобразуют доменные объекты в формат внешних систем (JSON для хранения мета-данных, ISO для дат и т.д.)
5. Адаптеры возвращают результаты в домен, домен возвращает данные в сервис, который возвращает их в резолвер
## Правила преобразования данных
1. Преобразование DTO → доменный объект: не требуется, если DTO имплементирует доменный интерфейс
2. Преобразование доменный объект → инфраструктурный тип: происходит в адаптерах
3. Преобразование документов, дат и других сложных объектов: используются утилитарные классы уровня инфраструктуры
## Работа с типами данных
1. **Даты**:
- В доменных интерфейсах используется тип `Date`
- В DTO используется тип `Date` с декораторами `@IsDate()` и `@Type(() => Date)`
- В инфраструктурном слое происходит преобразование `Date` → `string` (ISO формат)
```typescript
// Доменный интерфейс
interface MeetDomainInterface {
open_at: Date;
}
// DTO
@Field(() => Date)
@IsDate()
@Type(() => Date)
open_at!: Date;
// Адаптер
const blockchainData = {
open_at: domainToBlockchainUtils.convertDateToBlockchainFormat(data.open_at)
};
```
2. **Документы**:
- В доменных интерфейсах используется собственный тип `SignedDocumentDomainInterface<T>`
- В DTO используется соответствующий DTO-класс (например, `SignedDigitalDocumentInputDTO`)
- В инфраструктурном слое происходит преобразование между форматами (meta-поля в JSON и т.д.)
## Типовые ошибки
1. **Нарушение изоляции домена**: домен должен быть изолирован от инфраструктуры. Не используйте импорты из `cooptypes` в доменных интерфейсах.
```typescript
// Неправильно
import { MeetContract } from 'cooptypes';
export type VoteDomainInterface = MeetContract.Actions.Vote.IInput;
// Правильно
export interface VoteDomainInterface {
coopname: string;
hash: string;
// ... доменные поля
}
```
2. **Преобразование в неправильном слое**: преобразование доменных объектов в инфраструктурные типы должно происходить в адаптерах, а не в доменном слое или сервисе.
```typescript
// Неправильно (в интеракторе)
async vote(data: VoteDomainInterface) {
const blockchainData = { ...data, meta: JSON.stringify(data.meta) };
// ...
}
// Правильно (в адаптере)
async vote(data: VoteDomainInterface) {
const blockchainData = this.convertToBlockchainFormat(data);
// ...
}
```
3. **Дублирование логики преобразования**: общая логика преобразования должна быть вынесена в утилитарные классы.
```typescript
// Неправильно (дублирование в разных адаптерах)
// В MeetAdapter
private convertDoc(doc) { return { ...doc, meta: JSON.stringify(doc.meta) }; }
// В BranchAdapter
private convertDoc(doc) { return { ...doc, meta: JSON.stringify(doc.meta) }; }
// Правильно (общий утилитарный класс)
// DomainToBlockchainUtils
convertSignedDocumentToBlockchainFormat(doc) {
return { ...doc, meta: JSON.stringify(doc.meta) };
}
```
## Примеры
```typescript
// Доменный интерфейс - чистый, без зависимостей от инфраструктуры
export interface VoteOnAnnualGeneralMeetInputDomainInterface {
coopname: string;
hash: string;
member: string;
ballot: VoteItemInputDomainInterface[];
}
// DTO имплементирует доменный интерфейс напрямую
@InputType('VoteOnAnnualGeneralMeetInput')
export class VoteOnAnnualGeneralMeetInputDTO implements VoteOnAnnualGeneralMeetInputDomainInterface {
@Field(() => String)
@IsString()
coopname!: string;
// ... остальные поля
}
// Адаптер преобразует доменный объект в инфраструктурный тип
async vote(data: VoteOnAnnualGeneralMeetInputDomainInterface): Promise<TransactionResult> {
// Преобразуем доменный объект в инфраструктурный тип
const blockchainData: MeetContract.Actions.Vote.IInput = {
coopname: data.coopname,
hash: data.hash,
// ... преобразование других полей
};
// ... отправка данных во внешнюю систему
}
```
@@ -0,0 +1,11 @@
---
description: Общие правила
alwaysApply: true
---
Мы работаем в МОНО-репозитории pnpm, любая установка пакетов производится ЧЕРЕЗ ФИЛЬТР компонента в корне: pnpm add glob --filter <package>.
НИКОГДА НЕ ЗАПУСКАЙ ПРИЛОЖЕНИЕ ИЛИ ЕГО СБОРКУ!!! Просто отчитайся что всё сделал.
НИКОГДА НЕ ЗАПУСКАЙ ТЕСТЫ ИЛИ ПРОВЕРКУ ТИПОВ ИЛИ ЛИНТЕР!!!
Никаких ANY типов! Строгая типизация всегда.
@@ -0,0 +1,53 @@
---
description: О правилах на бэкенде
globs: **/controller/**/*.ts
---
# NestJS Controller и Чистая архитектура
## Основные принципы
1. Чистая архитектура - главный архитектурный подход. Пиши код с комментариями.
2. Типы IName, IChecksum256, ITimePointSec - это просто строки.
3. Домен должен быть полностью изолирован от инфраструктурных деталей.
4. Направление зависимостей - внутрь (к ядру, домену).
5. Домен, инфраструктура и приложение связаны через App.module, НЕ НУЖНО импортировать их друг в друга, а достаточно просто импортировать домен на уровне приложения чтобы использовать все экспорты домена.
## Структура проекта
- `domain/` - доменный слой (бизнес-логика, независимая от инфраструктуры)
- `infrastructure/` - инфраструктурный слой (адаптеры к внешним системам)
- `modules/` - слой приложения (DTO, резолверы, сервисы)
## Слои и их взаимодействие
1. **Домен**:
- Содержит чистые доменные интерфейсы и реализованные на них сущности
- НЕ должен зависеть от `cooptypes` (инфраструктурный контракт)
- Использует собственные доменные типы (например, Date вместо строковых timestamp)
- Интерфейсы портов описывают взаимодействие с внешними системами
2. **Инфраструктура**:
- Содержит адаптеры к внешним системам (блокчейн, БД и т.д.)
- Осуществляет преобразование между доменными и инфраструктурными типами
- Общая логика преобразования выносится в утилитарные классы (например, `DomainToBlockchainUtils`)
3. **Модули (приложение)**:
- DTO имплементируют доменные интерфейсы напрямую
- Резолвер вызывает сервис, который принимает DTO
- Сервис передает объекты DTO в интерактор приложения (юз-кейс)
## Правила
Чистая фрактальная трехуровневая архитектура срезов домена (domain) и инфраструктуры (infrastructure), оркестрируемая приложением (application). Фрактал раскрывается в расширениях (extensions), каждое из которых также выстраивается по правилам чистой трехуровневой архитектуры срезов домена и инфраструктуры с окрестрацией на уровне своего приложения.
Общая архитектура связей:
- AppResolver -> AppService[DTO<->Domain] -> AppInteractor -> DomainService -> DomainPort <- InfraAdapter -> [при необходимости] AnyAppOrDomainService
Все сервисы внедряются через инъекцию (DI) с указанием символа реализации. Импорты разрешены только вглубь - к домену. Из домена переход разрешен только в инфраструктуру через порт и его адаптер.
Прямые импорты без DI запрещены. Импорты из соседних срезов того же архитектурного уровня запрещены. Направление зависимостей от приложения - к домену, от домена через порт в его инфраструктурный адаптер.
Взаимодействие расширений с основным приложением осуществляется только через порты домена основного приложения.
Глобальные модули запрещены. В редких случаях сложных циклических зависимостей на период рефакторинга разрешается обоснованно использовать forwardRef.
Уровень приложения оркестрирует вызовы доменов через порты в инфраструктуру. Домены не обращаются друг к друга. Срезы уровня приложений не обращаются друг к другу, а только вызывают порты домена.
```
@@ -1,4 +1,5 @@
--- ---
description: О правилах на фронтенде
globs: **/desktop/** globs: **/desktop/**
alwaysApply: false alwaysApply: false
--- ---
@@ -1,6 +1,5 @@
--- ---
description: description: Правила работы с макросом main.py в компоненте docs
globs:
alwaysApply: false alwaysApply: false
--- ---
Файл [main.py](mdc:monocoop/monocoop/monocoop/components/docs/main.py) автоматически генерит ссылки на документацию SDK и GraphQL, которые формируются и публикуются автоматически. При создании документации к методам всегда применяй ссылки на SDK и GraphQL по форме: Файл [main.py](mdc:monocoop/monocoop/monocoop/components/docs/main.py) автоматически генерит ссылки на документацию SDK и GraphQL, которые формируются и публикуются автоматически. При создании документации к методам всегда применяй ссылки на SDK и GraphQL по форме:
@@ -1,6 +1,6 @@
--- ---
description: Правила формирования агрегатов документов в controller
alwaysApply: false alwaysApply: false
globs: **/controller/**/*.resolver.ts
--- ---
## 📋 Правила формирования агрегатов документов ## 📋 Правила формирования агрегатов документов
@@ -1,9 +1,7 @@
--- ---
description: description: Правила контроля изменений документов в фабрике (factory)
globs:
alwaysApply: false alwaysApply: false
--- ---
# Структура файлов шаблонов документов и алгоритм правки # Структура файлов шаблонов документов и алгоритм правки
## Основные директории и файлы ## Основные директории и файлы
@@ -94,3 +92,4 @@ alwaysApply: false
- Поддерживаются конструкции: `{% if %}`, `{% for %}`, `{% trans %}` - Поддерживаются конструкции: `{% if %}`, `{% for %}`, `{% trans %}`
- Переменные вставляются через `{{ variable }}` - Переменные вставляются через `{{ variable }}`
- Переводы через `{% trans 'KEY' %}` - Переводы через `{% trans 'KEY' %}`
- Дополнительно поддерживается передача переменной в перевод через `{% trans 'KEY', some_var1, some_var2 %}`, при этом в самом переводе необходимо использовать порядковые ключи {0}, {1} для доступа к переданным переменным.
@@ -1,6 +1,5 @@
--- ---
description: description: Архитектура и правила расширений extensions в controller
globs: **/controller/src/extensions/**
alwaysApply: false alwaysApply: false
--- ---
# Архитектура расширений в MonoCoop # Архитектура расширений в MonoCoop
@@ -1,4 +1,5 @@
--- ---
description: Создание шаблона документа без шапки из его основной версии в фабрике документов
alwaysApply: false alwaysApply: false
--- ---
Смотри, у меня есть проект документа оферты, @cooptypes/src/cooperative/registry/999.BlagorostOfferTemplate/index.ts мы его принимаем затем, чтобы получить данные для генерации @cooptypes/src/cooperative/registry/1000.BlagorostOffer/index.ts уже самой пользовательской оферты. Они в целом почти абсолютно идентичны за той лишь разницей, что в проекте кругом прочерки остаются вместо переменных для заполнения, и нет шапки с надписью "УТВЕРЖДЕНО" протоколом решения № ___ и дата ___. Т.е. мы как бы из первого в итоге получаем второе. Приняв первое - мы можем начать генерировать второе. Смотри, у меня есть проект документа оферты, @cooptypes/src/cooperative/registry/999.BlagorostOfferTemplate/index.ts мы его принимаем затем, чтобы получить данные для генерации @cooptypes/src/cooperative/registry/1000.BlagorostOffer/index.ts уже самой пользовательской оферты. Они в целом почти абсолютно идентичны за той лишь разницей, что в проекте кругом прочерки остаются вместо переменных для заполнения, и нет шапки с надписью "УТВЕРЖДЕНО" протоколом решения № ___ и дата ___. Т.е. мы как бы из первого в итоге получаем второе. Приняв первое - мы можем начать генерировать второе.
@@ -1,6 +1,5 @@
--- ---
description: description: Правила работы с фабрикой документов кооперативов (factory)
globs: src/**/*.ts
alwaysApply: false alwaysApply: false
--- ---
# Фабрика Документов Кооперативов # Фабрика Документов Кооперативов
@@ -1,5 +1,5 @@
--- ---
globs: **/controller/**/*.ts description: Логирование и логгер на бэкенде (controller)
alwaysApply: false alwaysApply: false
--- ---
# Logger Rule # Logger Rule
@@ -1,9 +1,8 @@
--- ---
description: description: Как добавлять селекторы, мутации и запросы в SDK
globs: components/sdk/** globs: **/sdk/**
alwaysApply: false alwaysApply: false
--- ---
# Руководство по работе с GraphQL Zeus в SDK # Руководство по работе с GraphQL Zeus в SDK
## Основной процесс ## Основной процесс
+113 -2
View File
@@ -4403,7 +4403,7 @@ input CreateProjectInvestInput {
project_hash: String! project_hash: String!
"""Заявление на инвестирование""" """Заявление на инвестирование"""
statement: SignedDigitalDocumentInput! statement: GenerationMoneyInvestStatementSignedDocumentInput!
"""Имя инвестора""" """Имя инвестора"""
username: String! username: String!
@@ -5631,6 +5631,117 @@ input GenerationContractSignedMetaDocumentInput {
version: String! version: String!
} }
input GenerationMoneyInvestStatementGenerateDocumentInput {
"""Сумма инвестирования"""
amount: String!
"""Номер блока, на котором был создан документ"""
block_num: Int
"""Название кооператива, связанное с документом"""
coopname: String!
"""Дата и время создания документа"""
created_at: String
"""Имя генератора, использованного для создания документа"""
generator: String
"""Язык документа"""
lang: String
"""Ссылки, связанные с документом"""
links: [String!]
"""Хэш проекта"""
project_hash: String!
"""Часовой пояс, в котором был создан документ"""
timezone: String
"""Название документа"""
title: String
"""Имя пользователя, создавшего документ"""
username: String!
"""Версия генератора, использованного для создания документа"""
version: String
}
input GenerationMoneyInvestStatementSignedDocumentInput {
"""Хэш содержимого документа"""
doc_hash: String!
"""Общий хэш (doc_hash + meta_hash)"""
hash: String!
"""Метаинформация для документа заявления об инвестировании в генерацию"""
meta: GenerationMoneyInvestStatementSignedMetaDocumentInput!
"""Хэш мета-данных"""
meta_hash: String!
"""Вектор подписей"""
signatures: [SignatureInfoInput!]!
"""Версия стандарта документа"""
version: String!
}
input GenerationMoneyInvestStatementSignedMetaDocumentInput {
"""Сумма инвестирования"""
amount: String!
"""Дата создания приложения к проекту"""
appendix_created_at: String!
"""Хэш приложения к проекту"""
appendix_hash: String!
"""Номер блока, на котором был создан документ"""
block_num: Int!
"""Дата создания участника"""
contributor_created_at: String!
"""Хэш участника"""
contributor_hash: String!
"""Название кооператива, связанное с документом"""
coopname: String!
"""Дата и время создания документа"""
created_at: String!
"""Имя генератора, использованного для создания документа"""
generator: String!
"""Язык документа"""
lang: String!
"""Ссылки, связанные с документом"""
links: [String!]!
"""Хэш проекта"""
project_hash: String!
"""ID документа в реестре"""
registry_id: Int!
"""Часовой пояс, в котором был создан документ"""
timezone: String!
"""Название документа"""
title: String!
"""Имя пользователя, создавшего документ"""
username: String!
"""Версия генератора, использованного для создания документа"""
version: String!
}
input GetAccountInput { input GetAccountInput {
"""Имя аккаунта пользователя""" """Имя аккаунта пользователя"""
username: String! username: String!
@@ -6563,7 +6674,7 @@ type Mutation {
capitalGenerateGenerationContract(data: GenerationContractGenerateDocumentInput!, options: GenerateDocumentOptionsInput): GeneratedDocument! capitalGenerateGenerationContract(data: GenerationContractGenerateDocumentInput!, options: GenerateDocumentOptionsInput): GeneratedDocument!
"""Сгенерировать заявление об инвестировании в генерацию""" """Сгенерировать заявление об инвестировании в генерацию"""
capitalGenerateGenerationMoneyInvestStatement(data: GenerateDocumentInput!, options: GenerateDocumentOptionsInput): GeneratedDocument! capitalGenerateGenerationMoneyInvestStatement(data: GenerationMoneyInvestStatementGenerateDocumentInput!, options: GenerateDocumentOptionsInput): GeneratedDocument!
"""Сгенерировать заявление о возврате неиспользованных средств генерации""" """Сгенерировать заявление о возврате неиспользованных средств генерации"""
capitalGenerateGenerationMoneyReturnUnusedStatement(data: GenerateDocumentInput!, options: GenerateDocumentOptionsInput): GeneratedDocument! capitalGenerateGenerationMoneyReturnUnusedStatement(data: GenerateDocumentInput!, options: GenerateDocumentOptionsInput): GeneratedDocument!
@@ -39,7 +39,7 @@ export class ComponentGenerationContractSignedMetaDocumentInputDTO extends Inter
) { ) {
@Field({ description: 'Хэш дополнения к приложению (для компонента)' }) @Field({ description: 'Хэш дополнения к приложению (для компонента)' })
@IsString() @IsString()
component_appendix_hash!: string; appendix_hash!: string;
@Field({ description: 'Хэш родительского приложения (к родительскому проекту)' }) @Field({ description: 'Хэш родительского приложения (к родительскому проекту)' })
@IsString() @IsString()
@@ -59,7 +59,7 @@ export class ComponentGenerationContractSignedMetaDocumentInputDTO extends Inter
@Field({ description: 'ID компонента' }) @Field({ description: 'ID компонента' })
@IsString() @IsString()
component_id!: string; component_hash!: string;
@Field({ description: 'Название проекта' }) @Field({ description: 'Название проекта' })
@IsString() @IsString()
@@ -67,7 +67,7 @@ export class ComponentGenerationContractSignedMetaDocumentInputDTO extends Inter
@Field({ description: 'ID проекта' }) @Field({ description: 'ID проекта' })
@IsString() @IsString()
project_id!: string; project_hash!: string;
} }
@InputType(`ComponentGenerationContractSignedDocumentInput`) @InputType(`ComponentGenerationContractSignedDocumentInput`)
@@ -0,0 +1,63 @@
import { InputType, Field, IntersectionType, OmitType } from '@nestjs/graphql';
import { IsString, IsNotEmpty } from 'class-validator';
import { Cooperative } from 'cooptypes';
import { GenerateMetaDocumentInputDTO } from '~/application/document/dto/generate-meta-document-input.dto';
import { MetaDocumentInputDTO } from '~/application/document/dto/meta-document-input.dto';
import { SignedDigitalDocumentInputDTO } from '~/application/document/dto/signed-digital-document-input.dto';
// утилита для выборки повторяющихся параметров из базовых интерфейсов
type ExcludeCommonProps<T> = Omit<T, 'coopname' | 'username' | 'registry_id' | 'block_num' | 'lang'>;
// интерфейс параметров для генерации
type action = Cooperative.Registry.GenerationMoneyInvestStatement.Action;
@InputType(`BaseGenerationMoneyInvestStatementMetaDocumentInput`)
class BaseGenerationMoneyInvestStatementMetaDocumentInputDTO implements ExcludeCommonProps<Pick<action, 'project_hash' | 'amount'>> {
@Field({ description: 'Хэш проекта' })
@IsString()
@IsNotEmpty()
project_hash!: string;
@Field({ description: 'Сумма инвестирования' })
@IsString()
@IsNotEmpty()
amount!: string;
}
@InputType(`GenerationMoneyInvestStatementGenerateDocumentInput`)
export class GenerationMoneyInvestStatementGenerateDocumentInputDTO extends IntersectionType(
BaseGenerationMoneyInvestStatementMetaDocumentInputDTO,
OmitType(GenerateMetaDocumentInputDTO, ['registry_id'] as const)
) {
registry_id!: number;
}
@InputType(`GenerationMoneyInvestStatementSignedMetaDocumentInput`)
export class GenerationMoneyInvestStatementSignedMetaDocumentInputDTO extends IntersectionType(
BaseGenerationMoneyInvestStatementMetaDocumentInputDTO,
MetaDocumentInputDTO
) {
@Field({ description: 'Хэш приложения к проекту' })
@IsString()
appendix_hash!: string;
@Field({ description: 'Дата создания приложения к проекту' })
@IsString()
appendix_created_at!: string;
@Field({ description: 'Хэш участника' })
@IsString()
contributor_hash!: string;
@Field({ description: 'Дата создания участника' })
@IsString()
contributor_created_at!: string;
}
@InputType(`GenerationMoneyInvestStatementSignedDocumentInput`)
export class GenerationMoneyInvestStatementSignedDocumentInputDTO extends SignedDigitalDocumentInputDTO {
@Field(() => GenerationMoneyInvestStatementSignedMetaDocumentInputDTO, {
description: 'Метаинформация для документа заявления об инвестировании в генерацию',
})
public readonly meta!: GenerationMoneyInvestStatementSignedMetaDocumentInputDTO;
}
@@ -50,7 +50,7 @@ export class ProjectGenerationContractSignedMetaDocumentInputDTO extends Interse
@Field({ description: 'ID проекта' }) @Field({ description: 'ID проекта' })
@IsString() @IsString()
project_id!: string; project_hash!: string;
} }
@InputType(`ProjectGenerationContractSignedDocumentInput`) @InputType(`ProjectGenerationContractSignedDocumentInput`)
@@ -3,8 +3,8 @@
*/ */
export enum ProgramKey { export enum ProgramKey {
/** Программа Генерация - вклад временем, имуществом или деньгами в конкретные проекты */ /** Программа Генерация - вклад временем, имуществом или деньгами в конкретные проекты */
GENERATION = 'generation', GENERATION = 'GENERATION',
/** Программа Капитализация - вклад имуществом или денег в систему */ /** Программа Капитализация - вклад имуществом или денег в систему */
CAPITALIZATION = 'capitalization', CAPITALIZATION = 'CAPITALIZATION',
} }
@@ -1,8 +1,8 @@
import { Field, InputType } from '@nestjs/graphql'; import { Field, InputType } from '@nestjs/graphql';
import { IsNotEmpty, IsString } from 'class-validator'; import { IsNotEmpty, IsString } from 'class-validator';
import type { CreateProjectInvestDomainInput } from '~/extensions/capital/domain/actions/create-project-invest-domain-input.interface'; import type { CreateProjectInvestDomainInput } from '~/extensions/capital/domain/actions/create-project-invest-domain-input.interface';
import { SignedDigitalDocumentInputDTO } from '~/application/document/dto/signed-digital-document-input.dto';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { GenerationMoneyInvestStatementSignedDocumentInputDTO } from '~/application/document/documents-dto/generation-money-invest-statement-document.dto';
/** /**
* GraphQL DTO для инвестирования в проект CAPITAL контракта * GraphQL DTO для инвестирования в проект CAPITAL контракта
@@ -29,7 +29,7 @@ export class CreateProjectInvestInputDTO implements Omit<CreateProjectInvestDoma
@IsString({ message: 'Сумма инвестиции должна быть строкой' }) @IsString({ message: 'Сумма инвестиции должна быть строкой' })
amount!: string; amount!: string;
@Field(() => SignedDigitalDocumentInputDTO, { description: 'Заявление на инвестирование' }) @Field(() => GenerationMoneyInvestStatementSignedDocumentInputDTO, { description: 'Заявление на инвестирование' })
@Type(() => SignedDigitalDocumentInputDTO) @Type(() => GenerationMoneyInvestStatementSignedDocumentInputDTO)
statement!: SignedDigitalDocumentInputDTO; statement!: GenerationMoneyInvestStatementSignedDocumentInputDTO;
} }
@@ -24,7 +24,6 @@ import { Throttle } from '@nestjs/throttler';
import { AuthRoles } from '~/application/auth/decorators/auth.decorator'; import { AuthRoles } from '~/application/auth/decorators/auth.decorator';
import { CurrentUser } from '~/application/auth/decorators/current-user.decorator'; import { CurrentUser } from '~/application/auth/decorators/current-user.decorator';
import type { MonoAccountDomainInterface } from '~/domain/account/interfaces/mono-account-domain.interface'; import type { MonoAccountDomainInterface } from '~/domain/account/interfaces/mono-account-domain.interface';
import { TransactionDTO } from '~/application/common/dto/transaction-result-response.dto';
import { StoryOutputDTO } from '../dto/generation/story.dto'; import { StoryOutputDTO } from '../dto/generation/story.dto';
import { IssueOutputDTO } from '../dto/generation/issue.dto'; import { IssueOutputDTO } from '../dto/generation/issue.dto';
import { CommitOutputDTO } from '../dto/generation/commit.dto'; import { CommitOutputDTO } from '../dto/generation/commit.dto';
@@ -32,6 +31,7 @@ import { CycleOutputDTO } from '../dto/generation/cycle.dto';
import { createPaginationResult, PaginationInputDTO, PaginationResult } from '~/application/common/dto/pagination.dto'; import { createPaginationResult, PaginationInputDTO, PaginationResult } from '~/application/common/dto/pagination.dto';
import { GeneratedDocumentDTO } from '~/application/document/dto/generated-document.dto'; import { GeneratedDocumentDTO } from '~/application/document/dto/generated-document.dto';
import { GenerateDocumentInputDTO } from '~/application/document/dto/generate-document-input.dto'; import { GenerateDocumentInputDTO } from '~/application/document/dto/generate-document-input.dto';
import { GenerationMoneyInvestStatementGenerateDocumentInputDTO } from '~/application/document/documents-dto/generation-money-invest-statement-document.dto';
import { GenerateDocumentOptionsInputDTO } from '~/application/document/dto/generate-document-options-input.dto'; import { GenerateDocumentOptionsInputDTO } from '~/application/document/dto/generate-document-options-input.dto';
// Пагинированные результаты // Пагинированные результаты
@@ -358,12 +358,13 @@ export class GenerationResolver {
@UseGuards(GqlJwtAuthGuard, RolesGuard) @UseGuards(GqlJwtAuthGuard, RolesGuard)
@AuthRoles(['chairman', 'member']) @AuthRoles(['chairman', 'member'])
async generateGenerationMoneyInvestStatement( async generateGenerationMoneyInvestStatement(
@Args('data', { type: () => GenerateDocumentInputDTO }) @Args('data', { type: () => GenerationMoneyInvestStatementGenerateDocumentInputDTO })
data: GenerateDocumentInputDTO, data: GenerationMoneyInvestStatementGenerateDocumentInputDTO,
@Args('options', { type: () => GenerateDocumentOptionsInputDTO, nullable: true }) @Args('options', { type: () => GenerateDocumentOptionsInputDTO, nullable: true })
options: GenerateDocumentOptionsInputDTO options: GenerateDocumentOptionsInputDTO,
@CurrentUser() currentUser: MonoAccountDomainInterface
): Promise<GeneratedDocumentDTO> { ): Promise<GeneratedDocumentDTO> {
return this.generationService.generateGenerationMoneyInvestStatement(data, options); return this.generationService.generateGenerationMoneyInvestStatement(data, options, currentUser);
} }
/** /**
@@ -29,7 +29,6 @@ import { IssueOutputDTO } from '../dto/generation/issue.dto';
import { CommitOutputDTO } from '../dto/generation/commit.dto'; import { CommitOutputDTO } from '../dto/generation/commit.dto';
import { CycleOutputDTO } from '../dto/generation/cycle.dto'; import { CycleOutputDTO } from '../dto/generation/cycle.dto';
import { PaginationInputDTO, PaginationResult } from '~/application/common/dto/pagination.dto'; import { PaginationInputDTO, PaginationResult } from '~/application/common/dto/pagination.dto';
import type { TransactResult } from '@wharfkit/session';
import { StoryStatus } from '../../domain/enums/story-status.enum'; import { StoryStatus } from '../../domain/enums/story-status.enum';
import { IssuePriority } from '../../domain/enums/issue-priority.enum'; import { IssuePriority } from '../../domain/enums/issue-priority.enum';
import { IssueStatus } from '../../domain/enums/issue-status.enum'; import { IssueStatus } from '../../domain/enums/issue-status.enum';
@@ -43,8 +42,10 @@ import type { ICycleDatabaseData } from '../../domain/interfaces/cycle-database.
import { GenerateDocumentOptionsInputDTO } from '~/application/document/dto/generate-document-options-input.dto'; import { GenerateDocumentOptionsInputDTO } from '~/application/document/dto/generate-document-options-input.dto';
import { GeneratedDocumentDTO } from '~/application/document/dto/generated-document.dto'; import { GeneratedDocumentDTO } from '~/application/document/dto/generated-document.dto';
import { GenerateDocumentInputDTO } from '~/application/document/dto/generate-document-input.dto'; import { GenerateDocumentInputDTO } from '~/application/document/dto/generate-document-input.dto';
import { GenerationMoneyInvestStatementGenerateDocumentInputDTO } from '~/application/document/documents-dto/generation-money-invest-statement-document.dto';
import { DocumentInteractor } from '~/application/document/interactors/document.interactor'; import { DocumentInteractor } from '~/application/document/interactors/document.interactor';
import { Cooperative } from 'cooptypes'; import { Cooperative } from 'cooptypes';
import { InvestsManagementInteractor } from '../use-cases/invests-management.interactor';
import { IssuePermissionsService } from './issue-permissions.service'; import { IssuePermissionsService } from './issue-permissions.service';
import { PermissionsService } from './permissions.service'; import { PermissionsService } from './permissions.service';
import { ProjectMapperService } from './project-mapper.service'; import { ProjectMapperService } from './project-mapper.service';
@@ -88,6 +89,7 @@ export class GenerationService {
private readonly contributorRepository: ContributorRepository, private readonly contributorRepository: ContributorRepository,
private readonly issueIdGenerationService: IssueIdGenerationService, private readonly issueIdGenerationService: IssueIdGenerationService,
private readonly documentInteractor: DocumentInteractor, private readonly documentInteractor: DocumentInteractor,
private readonly investsManagementInteractor: InvestsManagementInteractor,
private readonly issuePermissionsService: IssuePermissionsService, private readonly issuePermissionsService: IssuePermissionsService,
private readonly permissionsService: PermissionsService, private readonly permissionsService: PermissionsService,
private readonly projectMapperService: ProjectMapperService, private readonly projectMapperService: ProjectMapperService,
@@ -711,12 +713,16 @@ export class GenerationService {
* Генерация заявления об инвестировании в генерацию * Генерация заявления об инвестировании в генерацию
*/ */
async generateGenerationMoneyInvestStatement( async generateGenerationMoneyInvestStatement(
data: GenerateDocumentInputDTO, data: GenerationMoneyInvestStatementGenerateDocumentInputDTO,
options: GenerateDocumentOptionsInputDTO options: GenerateDocumentOptionsInputDTO,
currentUser: MonoAccountDomainInterface
): Promise<GeneratedDocumentDTO> { ): Promise<GeneratedDocumentDTO> {
// Подготавливаем данные через интерактор
const enrichedData = await this.investsManagementInteractor.prepareGenerationMoneyInvestStatementData(data, currentUser);
const document = await this.documentInteractor.generateDocument({ const document = await this.documentInteractor.generateDocument({
data: { data: {
...data, ...enrichedData,
registry_id: Cooperative.Registry.GenerationMoneyInvestStatement.registry_id, registry_id: Cooperative.Registry.GenerationMoneyInvestStatement.registry_id,
}, },
options, options,
@@ -5,6 +5,8 @@ import type { ReturnUnusedDomainInput } from '../../domain/actions/return-unused
import type { TransactResult } from '@wharfkit/session'; import type { TransactResult } from '@wharfkit/session';
import { INVEST_REPOSITORY, InvestRepository } from '../../domain/repositories/invest.repository'; import { INVEST_REPOSITORY, InvestRepository } from '../../domain/repositories/invest.repository';
import { PROGRAM_INVEST_REPOSITORY, ProgramInvestRepository } from '../../domain/repositories/program-invest.repository'; import { PROGRAM_INVEST_REPOSITORY, ProgramInvestRepository } from '../../domain/repositories/program-invest.repository';
import { APPENDIX_REPOSITORY, AppendixRepository } from '../../domain/repositories/appendix.repository';
import { CONTRIBUTOR_REPOSITORY, ContributorRepository } from '../../domain/repositories/contributor.repository';
import { InvestDomainEntity } from '../../domain/entities/invest.entity'; import { InvestDomainEntity } from '../../domain/entities/invest.entity';
import { ProgramInvestDomainEntity } from '../../domain/entities/program-invest.entity'; import { ProgramInvestDomainEntity } from '../../domain/entities/program-invest.entity';
import type { InvestFilterInputDTO } from '../dto/invests_management/invest-filter.input'; import type { InvestFilterInputDTO } from '../dto/invests_management/invest-filter.input';
@@ -16,6 +18,9 @@ import { DomainToBlockchainUtils } from '~/shared/utils/domain-to-blockchain.uti
import type { MonoAccountDomainInterface } from '~/domain/account/interfaces/mono-account-domain.interface'; import type { MonoAccountDomainInterface } from '~/domain/account/interfaces/mono-account-domain.interface';
import { InvestSyncService } from '../syncers/invest-sync.service'; import { InvestSyncService } from '../syncers/invest-sync.service';
import { WinstonLoggerService } from '~/application/logger/logger-app.service'; import { WinstonLoggerService } from '~/application/logger/logger-app.service';
import { GenerationMoneyInvestStatementGenerateDocumentInputDTO } from '~/application/document/documents-dto/generation-money-invest-statement-document.dto';
import { CurrencyValidationUtil } from '~/utils/currency-validation.util';
import { Cooperative } from 'cooptypes';
/** /**
* Интерактор домена для управления инвестициями CAPITAL контракта * Интерактор домена для управления инвестициями CAPITAL контракта
@@ -30,6 +35,10 @@ export class InvestsManagementInteractor {
private readonly investRepository: InvestRepository, private readonly investRepository: InvestRepository,
@Inject(PROGRAM_INVEST_REPOSITORY) @Inject(PROGRAM_INVEST_REPOSITORY)
private readonly programInvestRepository: ProgramInvestRepository, private readonly programInvestRepository: ProgramInvestRepository,
@Inject(APPENDIX_REPOSITORY)
private readonly appendixRepository: AppendixRepository,
@Inject(CONTRIBUTOR_REPOSITORY)
private readonly contributorRepository: ContributorRepository,
private readonly domainToBlockchainUtils: DomainToBlockchainUtils, private readonly domainToBlockchainUtils: DomainToBlockchainUtils,
private readonly investSyncService: InvestSyncService, private readonly investSyncService: InvestSyncService,
private readonly logger: WinstonLoggerService private readonly logger: WinstonLoggerService
@@ -37,6 +46,72 @@ export class InvestsManagementInteractor {
this.logger.setContext(InvestsManagementInteractor.name); this.logger.setContext(InvestsManagementInteractor.name);
} }
/**
* Подготавливает данные для генерации заявления об инвестировании в генерацию
* Находит соглашения пользователя по project_hash и извлекает родительское соглашение
*/
async prepareGenerationMoneyInvestStatementData(
data: GenerationMoneyInvestStatementGenerateDocumentInputDTO,
currentUser: MonoAccountDomainInterface
): Promise<Cooperative.Registry.GenerationMoneyInvestStatement.Action> {
const projectHash = data.project_hash;
if (!projectHash) {
throw new Error('project_hash обязателен для генерации заявления об инвестировании');
}
// 1. Находим подтвержденное приложение пользователя по project_hash
const userAppendix = await this.appendixRepository.findConfirmedByUsernameAndProjectHash(
currentUser.username,
projectHash
);
if (!userAppendix) {
throw new Error(`Не найдено подтвержденное соглашение пользователя ${currentUser.username} для проекта ${projectHash}`);
}
// 2. Получаем contributor_hash и contributor_created_at из приложения к проекту
const contributorHash = userAppendix.appendix?.meta?.contributor_hash;
const contributorCreatedAt = userAppendix.appendix?.meta?.contributor_created_at;
if (!contributorHash || !contributorCreatedAt) {
throw new Error('Не найдены данные участника в приложении к проекту');
}
console.log('userAppendix.appendix?.meta', userAppendix.appendix?.meta)
// 3. Получаем parent_hash из метаданных документа приложения к проекту
const parentAppendixHash = userAppendix.appendix?.meta?.parent_appendix_hash;
if (!parentAppendixHash) {
throw new Error('Не найден parent_appendix_hash в метаданных приложения к проекту');
}
// 4. Находим родительское приложение по parent_appendix_hash
const parentAppendix = await this.appendixRepository.findByAppendixHash(parentAppendixHash);
if (!parentAppendix) {
throw new Error(`Не найдено родительское соглашение с hash ${parentAppendixHash}`);
}
// 5. Получаем created_at из метаданных родительского документа
const appendixCreatedAt = parentAppendix.appendix?.meta?.created_at;
if (!appendixCreatedAt) {
throw new Error('Не найдена дата создания родительского соглашения');
}
// Проверяем, что amount содержит правильный символ валюты
CurrencyValidationUtil.validateCurrencySymbol(data.amount, 'сумме инвестирования');
// 6. Возвращаем enriched data с данными родительского соглашения
return {
...data,
appendix_hash: parentAppendix.appendix_hash,
appendix_created_at: appendixCreatedAt,
contributor_hash: contributorHash,
contributor_created_at: contributorCreatedAt,
project_hash: projectHash,
};
}
/** /**
* Инвестирование в проект CAPITAL контракта * Инвестирование в проект CAPITAL контракта
*/ */
@@ -202,6 +202,7 @@ export class ParticipationManagementInteractor {
* Теперь принимает минимальный набор данных и подписанный документ * Теперь принимает минимальный набор данных и подписанный документ
*/ */
async makeClearance(data: MakeClearanceInputDTO): Promise<TransactResult> { async makeClearance(data: MakeClearanceInputDTO): Promise<TransactResult> {
console.log('data', data)
// Извлекаем документ из базы данных для верификации // Извлекаем документ из базы данных для верификации
const document = await this.documentInteractor.getDocumentByHash( const document = await this.documentInteractor.getDocumentByHash(
data.document.doc_hash data.document.doc_hash
@@ -217,6 +218,7 @@ export class ParticipationManagementInteractor {
// Извлекаем appendix_hash из метаданных документа // Извлекаем appendix_hash из метаданных документа
const appendix_hash = (document.meta as any).appendix_hash; const appendix_hash = (document.meta as any).appendix_hash;
//TODO: адаптировать или документ или код ниже к parent_appendix_hash
if (!appendix_hash) { if (!appendix_hash) {
throw new HttpApiError( throw new HttpApiError(
httpStatus.BAD_REQUEST, httpStatus.BAD_REQUEST,
@@ -415,7 +417,7 @@ export class ParticipationManagementInteractor {
contributor_hash: contributor.contributor_hash, contributor_hash: contributor.contributor_hash,
contributor_created_at: contributor.created_at, contributor_created_at: contributor.created_at,
project_name: project.title || project.data || '', project_name: project.title || project.data || '',
project_id: project.project_hash, project_hash: project.project_hash,
}; };
// 6. Генерируем документ // 6. Генерируем документ
@@ -504,7 +506,7 @@ export class ParticipationManagementInteractor {
} }
// 7. Генерируем уникальный хэш для дополнения к приложению // 7. Генерируем уникальный хэш для дополнения к приложению
const component_appendix_hash = generateUniqueHash(); const appendix_hash = generateUniqueHash();
// 8. Формируем данные для генерации документа // 8. Формируем данные для генерации документа
const documentData = { const documentData = {
@@ -512,14 +514,14 @@ export class ParticipationManagementInteractor {
username: data.username, username: data.username,
lang: data.lang || 'ru', lang: data.lang || 'ru',
registry_id: Cooperative.Registry.ComponentGenerationContract.registry_id, registry_id: Cooperative.Registry.ComponentGenerationContract.registry_id,
component_appendix_hash, appendix_hash,
parent_appendix_hash: parentAppendix.appendix_hash, parent_appendix_hash: parentAppendix.appendix_hash,
contributor_hash: contributor.contributor_hash, contributor_hash: contributor.contributor_hash,
contributor_created_at: contributor.created_at, contributor_created_at: contributor.created_at,
component_name: component.title || component.data || '', component_name: component.title || component.data || '',
component_id: component.project_hash, component_hash: component.project_hash,
project_name: parentProject.title || parentProject.data || '', project_name: parentProject.title || parentProject.data || '',
project_id: parentProject.project_hash, project_hash: parentProject.project_hash,
}; };
// 9. Генерируем документ // 9. Генерируем документ
@@ -74,6 +74,44 @@ export class GraphQLExceptionFilter implements GqlExceptionFilter {
} }
} }
// Обработка GraphQL Validation ошибок (например, несоответствие типов переменных)
else if (exception instanceof GraphQLError && exception.message.includes('used in position expecting type')) {
statusCode = HttpStatus.BAD_REQUEST;
message = exception.message;
// Специальное логирование для ошибок типов GraphQL
logger.error({
message: `GraphQL Type Validation Error: ${message}`,
statusCode,
stack: exception.stack,
username: user?.username || null,
operation: operationName || null,
field: fieldName || null,
path: path || null,
locations: exception.locations || locations,
extensions: exception.extensions,
originalError: exception.originalError?.message || null,
});
}
// Обработка других GraphQLError
else if (exception instanceof GraphQLError) {
statusCode = HttpStatus.BAD_REQUEST;
message = exception.message;
// Логируем все GraphQL ошибки для отладки
logger.error({
message: `GraphQL Error: ${message}`,
statusCode,
stack: exception.stack,
username: user?.username || null,
operation: operationName || null,
field: fieldName || null,
path: path || null,
locations: exception.locations || locations,
extensions: exception.extensions,
originalError: exception.originalError?.message || null,
});
}
// Обработка конкретных типов исключений // Обработка конкретных типов исключений
else if (exception instanceof RpcError) { else if (exception instanceof RpcError) {
message = exception.json.error.details[0].message.replace('assertion failure with message: ', ''); message = exception.json.error.details[0].message.replace('assertion failure with message: ', '');
@@ -152,6 +190,7 @@ export class GraphQLExceptionFilter implements GqlExceptionFilter {
return new GraphQLError(message, { return new GraphQLError(message, {
extensions: { extensions: {
code: statusCode, code: statusCode,
isExecutionError: true, // Флаг для отличия execution ошибок от validation ошибок
...(process.env.NODE_ENV === 'development' && { stacktrace: exception.stack }), ...(process.env.NODE_ENV === 'development' && { stacktrace: exception.stack }),
}, },
}); });
@@ -6,6 +6,7 @@ import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { docDirectiveTransformer } from './directives/doc.directive'; import { docDirectiveTransformer } from './directives/doc.directive';
import { GraphQLError, GraphQLFormattedError } from 'graphql'; import { GraphQLError, GraphQLFormattedError } from 'graphql';
import { fieldAuthDirectiveTransformer } from './directives/fieldAuth.directive'; import { fieldAuthDirectiveTransformer } from './directives/fieldAuth.directive';
import logger from '~/config/logger';
@Global() @Global()
@Module({ @Module({
@@ -53,13 +54,27 @@ import { fieldAuthDirectiveTransformer } from './directives/fieldAuth.directive'
context.res.locals.errorMessage = message; context.res.locals.errorMessage = message;
} }
// Логирование (Unauthorized ошибки уже залогированы в GraphQLExceptionFilter)
// if (extensions.code !== 401) { // Логирование GraphQL ошибок (только validation ошибки, execution ошибки логируются в GraphQLExceptionFilter)
// logger.error({ if (extensions.code !== 401 && !formattedError.extensions?.isExecutionError) {
// message: `GraphQL Error: ${message}`, // Извлекаем информацию о типе операции из запроса
// extensions, const queryText = context?.req?.body?.query || '';
// }); const operationType = queryText.trim().startsWith('mutation') ? 'mutation' :
// } queryText.trim().startsWith('query') ? 'query' :
queryText.trim().startsWith('subscription') ? 'subscription' : 'unknown';
logger.error({
message: `GraphQL Error: ${message}`,
errorType: message.includes('used in position expecting type') ? 'GRAPHQL_TYPE_VALIDATION' : 'GRAPHQL_VALIDATION',
extensions,
locations: formattedError.locations,
path: formattedError.path,
username: context?.req?.user?.username || null,
operation: context?.req?.body?.operationName || null,
operationType,
// Не показываем полный запрос, только тип операции
});
}
return { return {
message, message,
@@ -0,0 +1,75 @@
import { config } from '~/config';
/**
* Утилитарный класс для валидации валютных сумм
* Проверяет соответствие символа валюты конфигурации системы
*/
export class CurrencyValidationUtil {
/**
* Проверяет, что сумма содержит правильный символ валюты
* @param amount Сумма в формате "число символ" (например, "1000 RUB")
* @returns boolean - true если символ валюты правильный
*/
static hasValidCurrencySymbol(amount: string): boolean {
if (!amount || typeof amount !== 'string') {
return false;
}
const expectedSymbol = config.blockchain.root_govern_symbol;
return amount.includes(expectedSymbol);
}
/**
* Валидирует сумму и выбрасывает ошибку, если символ валюты неправильный
* @param amount Сумма в формате "число символ" (например, "1000 RUB")
* @param fieldName Название поля для сообщения об ошибке (по умолчанию "сумма")
* @throws Error если символ валюты неправильный
*/
static validateCurrencySymbol(amount: string, fieldName = 'сумма'): void {
if (!this.hasValidCurrencySymbol(amount)) {
const expectedSymbol = config.blockchain.root_govern_symbol;
throw new Error(`Неверный символ валюты в ${fieldName}. Ожидался: ${expectedSymbol}`);
}
}
/**
* Извлекает символ валюты из суммы
* @param amount Сумма в формате "число символ"
* @returns string - символ валюты или пустая строка, если не найден
*/
static extractCurrencySymbol(amount: string): string {
if (!amount || typeof amount !== 'string') {
return '';
}
const parts = amount.trim().split(' ');
return parts.length > 1 ? parts[parts.length - 1] : '';
}
/**
* Извлекает числовое значение из суммы
* @param amount Сумма в формате "число символ"
* @returns number - числовое значение или NaN, если не удалось распарсить
*/
static extractAmountValue(amount: string): number {
if (!amount || typeof amount !== 'string') {
return NaN;
}
const parts = amount.trim().split(' ');
const numericPart = parts.length > 1 ? parts[0] : amount;
return parseFloat(numericPart);
}
/**
* Форматирует сумму с правильным символом валюты
* @param value Числовое значение
* @param precision Количество знаков после запятой (по умолчанию из конфига)
* @returns string - отформатированная сумма
*/
static formatAmount(value: number, precision?: number): string {
const actualPrecision = precision ?? config.blockchain.root_govern_precision;
const symbol = config.blockchain.root_govern_symbol;
return `${value.toFixed(actualPrecision)} ${symbol}`;
}
}
+7 -7
View File
@@ -1144,7 +1144,7 @@
"required": [ "required": [
"coopname", "coopname",
"decision_id", "decision_id",
"project_id", "project_hash",
"username" "username"
], ],
"properties": { "properties": {
@@ -1172,7 +1172,7 @@
"type": "string" "type": "string"
} }
}, },
"project_id": { "project_hash": {
"type": "string" "type": "string"
}, },
"timezone": { "timezone": {
@@ -1793,7 +1793,7 @@
"type": "object", "type": "object",
"required": [ "required": [
"coopname", "coopname",
"project_id", "project_hash",
"username" "username"
], ],
"properties": { "properties": {
@@ -1818,7 +1818,7 @@
"type": "string" "type": "string"
} }
}, },
"project_id": { "project_hash": {
"type": "string" "type": "string"
}, },
"timezone": { "timezone": {
@@ -1867,7 +1867,7 @@
"generator", "generator",
"lang", "lang",
"links", "links",
"project_id", "project_hash",
"registry_id", "registry_id",
"timezone", "timezone",
"title", "title",
@@ -1893,7 +1893,7 @@
"links": { "links": {
"type": "string" "type": "string"
}, },
"project_id": { "project_hash": {
"type": "string" "type": "string"
}, },
"registry_id": { "registry_id": {
@@ -3869,4 +3869,4 @@
} }
} }
} }
} }
@@ -10,7 +10,7 @@ export interface Action extends IGenerate {
contributor_hash: string contributor_hash: string
contributor_created_at: string contributor_created_at: string
project_name: string project_name: string
project_id: string project_hash: string
} }
export type Meta = IMetaDocument & Action export type Meta = IMetaDocument & Action
@@ -27,13 +27,13 @@ export interface Model {
short_contributor_hash: string short_contributor_hash: string
contributor_created_at: string contributor_created_at: string
project_name: string project_name: string
project_id: string project_hash: string
} }
export const title = 'Приложение к договору участия в проекте' export const title = 'Приложение к договору участия в проекте'
export const description = 'Приложение к договору участия в хозяйственной деятельности для проектов' export const description = 'Приложение к договору участия в хозяйственной деятельности для проектов'
export const context = `<div class="digital-document"><div style="text-align: center"><h1>ПРИЛОЖЕНИЕ № {{ short_appendix_hash }}</h1><h2>к Договору об участии в хозяйственной деятельности № УХД-{{ short_contributor_hash }}</h2></div><p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p><p>{% trans 'parties_intro' %} "{{ vars.name }}" {% trans 'in_face_of_chairman' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}, {% trans 'acting_on_basis_of_charter' %}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'society' %}", {% trans 'and_participant' %} {{ user.full_name_or_short_name }}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'participant' %}", {% trans 'jointly_referred_to_as' %} "{% trans 'parties' %}", {% trans 'have_concluded_this_appendix' %} {% trans 'hereinafter_referred_to_as' %} "{% trans 'appendix' %}" {% trans 'to_agreement' %} УХД-{{ short_contributor_hash }} {% trans 'from_date' %} {{ contributor_created_at }} {% trans 'of_the_following' %}:</p><p>{% trans 'according_to_regulations' %} "{{ vars.generation_contract_template.protocol_number }}" {% trans 'from_date' %} {{ vars.generation_contract_template.protocol_day_month_year }}), {% trans 'participant_commits_project' %} "{{ project_name }}" (№{{ project_id }}).</p><h2>{% trans 'details_and_signatures_of_parties' %}</h2><p><strong>{% trans 'society' %}/{{ vars.full_abbr }} "{{ vars.name }}"/:</strong></p><p>ИНН {{ coop.details.inn }}, КПП {{ coop.details.kpp }}, ОГРН {{ coop.details.ogrn }}</p><p>{% trans 'legal_address' %}: {{ coop.full_address }}</p><p>{% trans 'contact_phone' %}: {{ coop.phone }}</p><p>{% trans 'email' %}: {{ coop.email }}</p><p>{% trans 'bank_account' %}: {{ coop.defaultBankAccount.account_number }}</p><p>{% trans 'bank_name' %}: {{ coop.defaultBankAccount.bank_name }}</p><p>{% trans 'bik' %}: {{ coop.defaultBankAccount.details.bik }}</p><p>{% trans 'correspondent_account' %}: {{ coop.defaultBankAccount.details.corr }}</p><p>{% trans 'chairman' %} {{ vars.full_abbr_genitive }} "{{ vars.name }}"</p><p>{{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p><p>{% trans 'signed_by_digital_signature' %}</p><p><strong>{% trans 'participant' %}:</strong></p><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'contact_phone' %}: {{ user.phone }}</p><p>{% trans 'email' %}: {{ user.email }}</p><p>{% trans 'signed_by_digital_signature' %}</p></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}</style>` export const context = `<div class="digital-document"><div style="text-align: center"><h1>ПРИЛОЖЕНИЕ № {{ short_appendix_hash }}</h1><h2>к Договору об участии в хозяйственной деятельности № УХД-{{ short_contributor_hash }}</h2></div><p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p><p>{% trans 'parties_intro' %} "{{ vars.name }}" {% trans 'in_face_of_chairman' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}, {% trans 'acting_on_basis_of_charter' %}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'society' %}", {% trans 'and_participant' %} {{ user.full_name_or_short_name }}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'participant' %}", {% trans 'jointly_referred_to_as' %} "{% trans 'parties' %}", {% trans 'have_concluded_this_appendix' %} {% trans 'hereinafter_referred_to_as' %} "{% trans 'appendix' %}" {% trans 'to_agreement' %} УХД-{{ short_contributor_hash }} {% trans 'from_date' %} {{ contributor_created_at }} {% trans 'of_the_following' %}:</p><p>{% trans 'according_to_regulations' %} "{{ vars.generation_contract_template.protocol_number }}" {% trans 'from_date' %} {{ vars.generation_contract_template.protocol_day_month_year }}), {% trans 'participant_commits_project' %} "{{ project_name }}" (№{{ project_hash }}).</p><h2>{% trans 'details_and_signatures_of_parties' %}</h2><p><strong>{% trans 'society' %}/{{ vars.full_abbr }} "{{ vars.name }}"/:</strong></p><p>ИНН {{ coop.details.inn }}, КПП {{ coop.details.kpp }}, ОГРН {{ coop.details.ogrn }}</p><p>{% trans 'legal_address' %}: {{ coop.full_address }}</p><p>{% trans 'contact_phone' %}: {{ coop.phone }}</p><p>{% trans 'email' %}: {{ coop.email }}</p><p>{% trans 'bank_account' %}: {{ coop.defaultBankAccount.account_number }}</p><p>{% trans 'bank_name' %}: {{ coop.defaultBankAccount.bank_name }}</p><p>{% trans 'bik' %}: {{ coop.defaultBankAccount.details.bik }}</p><p>{% trans 'correspondent_account' %}: {{ coop.defaultBankAccount.details.corr }}</p><p>{% trans 'chairman' %} {{ vars.full_abbr_genitive }} "{{ vars.name }}"</p><p>{{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p><p>{% trans 'signed_by_digital_signature' %}</p><p><strong>{% trans 'participant' %}:</strong></p><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'contact_phone' %}: {{ user.phone }}</p><p>{% trans 'email' %}: {{ user.email }}</p><p>{% trans 'signed_by_digital_signature' %}</p></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}</style>`
export const translations = { export const translations = {
ru: { ru: {
@@ -76,7 +76,7 @@ export const exampleData = {
short_contributor_hash: 'ED3BCFC5B681AA83D', short_contributor_hash: 'ED3BCFC5B681AA83D',
contributor_created_at: '11.04.2024', contributor_created_at: '11.04.2024',
project_name: 'Проект цифровой платформы', project_name: 'Проект цифровой платформы',
project_id: 'B2C3D4E5F6789ABC', project_hash: 'B2C3D4E5F6789ABC',
vars: { vars: {
generation_contract_template: { generation_contract_template: {
protocol_number: 'СС-11-04-24', protocol_number: 'СС-11-04-24',
@@ -6,14 +6,14 @@ export const registry_id = 1003
// Модель действия для генерации // Модель действия для генерации
export interface Action extends IGenerate { export interface Action extends IGenerate {
registry_id: number registry_id: number
component_appendix_hash: string appendix_hash: string
parent_appendix_hash: string parent_appendix_hash: string
contributor_hash: string contributor_hash: string
contributor_created_at: string contributor_created_at: string
component_name: string component_name: string
component_id: string component_hash: string
project_name: string project_name: string
project_id: string project_hash: string
} }
export type Meta = IMetaDocument & Action export type Meta = IMetaDocument & Action
@@ -24,23 +24,23 @@ export interface Model {
coop: ICooperativeData coop: ICooperativeData
vars: IVars vars: IVars
user: ICommonUser user: ICommonUser
component_appendix_hash: string appendix_hash: string
short_component_appendix_hash: string short_appendix_hash: string
parent_appendix_hash: string parent_appendix_hash: string
short_parent_appendix_hash: string short_parent_appendix_hash: string
contributor_hash: string contributor_hash: string
short_contributor_hash: string short_contributor_hash: string
contributor_created_at: string contributor_created_at: string
component_name: string component_name: string
component_id: string component_hash: string
project_name: string project_name: string
project_id: string project_hash: string
} }
export const title = 'Дополнение к приложению договора участия в компоненте' export const title = 'Дополнение к приложению договора участия в компоненте'
export const description = 'Дополнение к приложению договора участия в хозяйственной деятельности для компонентов проекта' export const description = 'Дополнение к приложению договора участия в хозяйственной деятельности для компонентов проекта'
export const context = `<div class="digital-document"><div style="text-align: center"><h1>ДОПОЛНЕНИЕ № {{ short_component_appendix_hash }}</h1><h2>к ПРИЛОЖЕНИЮ № {{ short_parent_appendix_hash }}</h2><h2>к Договору об участии в хозяйственной деятельности № УХД-{{ short_contributor_hash }}</h2></div><p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p><p>{% trans 'parties_intro' %} "{{ vars.name }}" {% trans 'in_face_of_chairman' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}, {% trans 'acting_on_basis_of_charter' %}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'society' %}", {% trans 'and_participant' %} {{ user.full_name_or_short_name }}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'participant' %}", {% trans 'jointly_referred_to_as' %} "{% trans 'parties' %}", {% trans 'have_concluded_this_supplement' %} {% trans 'hereinafter_referred_to_as' %} "{% trans 'supplement' %}" {% trans 'to_appendix' %} {{ short_parent_appendix_hash }} {% trans 'to_agreement' %} УХД-{{ short_contributor_hash }} {% trans 'from_date' %} {{ contributor_created_at }} {% trans 'of_the_following' %}:</p><p>{% trans 'within_obligations' %} {{ short_parent_appendix_hash }} {% trans 'to_agreement' %} УХД-{{ short_contributor_hash }} {% trans 'from_date' %} {{ contributor_created_at }}, {% trans 'parties_agreed' %} {% trans 'participant_commits_component' %} "{{ component_name }}" {% trans 'to_project' %} № {{ project_id }}.</p><h2>{% trans 'details_and_signatures_of_parties' %}</h2><p><strong>{% trans 'society' %}/{{ vars.full_abbr }} "{{ vars.name }}"/:</strong></p><p>ИНН {{ coop.details.inn }}, КПП {{ coop.details.kpp }}, ОГРН {{ coop.details.ogrn }}</p><p>{% trans 'legal_address' %}: {{ coop.full_address }}</p><p>{% trans 'contact_phone' %}: {{ coop.phone }}</p><p>{% trans 'email' %}: {{ coop.email }}</p><p>{% trans 'bank_account' %}: {{ coop.defaultBankAccount.account_number }}</p><p>{% trans 'bank_name' %}: {{ coop.defaultBankAccount.bank_name }}</p><p>{% trans 'bik' %}: {{ coop.defaultBankAccount.details.bik }}</p><p>{% trans 'correspondent_account' %}: {{ coop.defaultBankAccount.details.corr }}</p><p>{% trans 'chairman' %} {{ vars.full_abbr_genitive }} "{{ vars.name }}"</p><p>{{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p><p>{% trans 'signed_by_digital_signature' %}</p><p><strong>{% trans 'participant' %}:</strong></p><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'contact_phone' %}: {{ user.phone }}</p><p>{% trans 'email' %}: {{ user.email }}</p><p>{% trans 'signed_by_digital_signature' %}</p></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}</style>` export const context = `<div class="digital-document"><div style="text-align: center"><h1>ДОПОЛНЕНИЕ № {{ short_appendix_hash }}</h1><h2>к ПРИЛОЖЕНИЮ № {{ short_parent_appendix_hash }}</h2><h2>к Договору об участии в хозяйственной деятельности № УХД-{{ short_contributor_hash }}</h2></div><p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p><p>{% trans 'parties_intro' %} "{{ vars.name }}" {% trans 'in_face_of_chairman' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}, {% trans 'acting_on_basis_of_charter' %}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'society' %}", {% trans 'and_participant' %} {{ user.full_name_or_short_name }}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'participant' %}", {% trans 'jointly_referred_to_as' %} "{% trans 'parties' %}", {% trans 'have_concluded_this_supplement' %} {% trans 'hereinafter_referred_to_as' %} "{% trans 'supplement' %}" {% trans 'to_appendix' %} {{ short_parent_appendix_hash }} {% trans 'to_agreement' %} УХД-{{ short_contributor_hash }} {% trans 'from_date' %} {{ contributor_created_at }} {% trans 'of_the_following' %}:</p><p>{% trans 'within_obligations' %} {{ short_parent_appendix_hash }} {% trans 'to_agreement' %} УХД-{{ short_contributor_hash }} {% trans 'from_date' %} {{ contributor_created_at }}, {% trans 'parties_agreed' %} {% trans 'participant_commits_component' %} "{{ component_name }}" {% trans 'to_project' %} № {{ project_hash }}.</p><h2>{% trans 'details_and_signatures_of_parties' %}</h2><p><strong>{% trans 'society' %}/{{ vars.full_abbr }} "{{ vars.name }}"/:</strong></p><p>ИНН {{ coop.details.inn }}, КПП {{ coop.details.kpp }}, ОГРН {{ coop.details.ogrn }}</p><p>{% trans 'legal_address' %}: {{ coop.full_address }}</p><p>{% trans 'contact_phone' %}: {{ coop.phone }}</p><p>{% trans 'email' %}: {{ coop.email }}</p><p>{% trans 'bank_account' %}: {{ coop.defaultBankAccount.account_number }}</p><p>{% trans 'bank_name' %}: {{ coop.defaultBankAccount.bank_name }}</p><p>{% trans 'bik' %}: {{ coop.defaultBankAccount.details.bik }}</p><p>{% trans 'correspondent_account' %}: {{ coop.defaultBankAccount.details.corr }}</p><p>{% trans 'chairman' %} {{ vars.full_abbr_genitive }} "{{ vars.name }}"</p><p>{{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p><p>{% trans 'signed_by_digital_signature' %}</p><p><strong>{% trans 'participant' %}:</strong></p><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'contact_phone' %}: {{ user.phone }}</p><p>{% trans 'email' %}: {{ user.email }}</p><p>{% trans 'signed_by_digital_signature' %}</p></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}</style>`
export const translations = { export const translations = {
ru: { ru: {
@@ -80,17 +80,17 @@ export const exampleData = {
meta: { meta: {
created_at: '11.04.2024 12:00', created_at: '11.04.2024 12:00',
}, },
component_appendix_hash: 'A002ZSA2', appendix_hash: 'A002ZSA2',
short_component_appendix_hash: 'A002ZSA2', short_appendix_hash: 'A002ZSA2',
parent_appendix_hash: 'A001ZSA1', parent_appendix_hash: 'A001ZSA1',
short_parent_appendix_hash: 'A001ZSA1', short_parent_appendix_hash: 'A001ZSA1',
contributor_hash: 'ED3BCFC5B681AA83D123456789ABCDEF', contributor_hash: 'ED3BCFC5B681AA83D123456789ABCDEF',
short_contributor_hash: 'ED3BCFC5B681AA83D', short_contributor_hash: 'ED3BCFC5B681AA83D',
contributor_created_at: '11.04.2024', contributor_created_at: '11.04.2024',
component_name: 'Компонент разработки', component_name: 'Компонент разработки',
component_id: 'A1B2C3D4E5F6789A', component_hash: 'A1B2C3D4E5F6789A',
project_name: 'Проект цифровой платформы', project_name: 'Проект цифровой платформы',
project_id: 'B2C3D4E5F6789ABC', project_hash: 'B2C3D4E5F6789ABC',
vars: { vars: {
generation_contract_template: { generation_contract_template: {
protocol_number: 'СС-11-04-24', protocol_number: 'СС-11-04-24',
@@ -7,9 +7,9 @@ export const registry_id = 1005
export interface Action extends IGenerate { export interface Action extends IGenerate {
registry_id: number registry_id: number
project_name: string project_name: string
project_id: string project_hash: string
component_name: string component_name: string
component_id: string component_hash: string
is_component: boolean is_component: boolean
} }
@@ -22,16 +22,16 @@ export interface Model {
vars: IVars vars: IVars
user: ICommonUser user: ICommonUser
project_name: string project_name: string
project_id: string project_hash: string
component_name: string component_name: string
component_id: string component_hash: string
is_component: boolean is_component: boolean
} }
export const title = 'Заявление на инициализацию проекта' export const title = 'Заявление на инициализацию проекта'
export const description = 'Заявление на инициализацию проекта или компонента' export const description = 'Заявление на инициализацию проекта или компонента'
export const context = `<div class="digital-document"><div style="text-align: center"><h1>ЗАЯВЛЕНИЕ</h1><h2>на инициализацию проекта</h2></div><p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p><p>{% trans 'parties_intro' %} "{{ vars.name }}" {% trans 'in_face_of_chairman' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}, {% trans 'acting_on_basis_of_charter' %}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'society' %}", {% trans 'and_participant' %} {{ user.full_name_or_short_name }}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'participant' %}", {% trans 'jointly_referred_to_as' %} "{% trans 'parties' %}", {% trans 'have_concluded_this_statement' %} {% trans 'hereinafter_referred_to_as' %} "{% trans 'statement' %}" {% trans 'of_the_following' %}:</p><p>{% if is_component %}{% trans 'participant_requests_component_init' %} "{{ component_name }}" (№{{ component_id }}) {% trans 'as_part_of_project' %} "{{ project_name }}" (№{{ project_id }}).{% else %}{% trans 'participant_requests_project_init' %} "{{ project_name }}" (№{{ project_id }}).{% endif %}</p><h2>{% trans 'details_and_signatures_of_parties' %}</h2><p><strong>{% trans 'society' %}/{{ vars.full_abbr }} "{{ vars.name }}"/:</strong></p><p>ИНН {{ coop.details.inn }}, КПП {{ coop.details.kpp }}, ОГРН {{ coop.details.ogrn }}</p><p>{% trans 'legal_address' %}: {{ coop.full_address }}</p><p>{% trans 'contact_phone' %}: {{ coop.phone }}</p><p>{% trans 'email' %}: {{ coop.email }}</p><p>{% trans 'bank_account' %}: {{ coop.defaultBankAccount.account_number }}</p><p>{% trans 'bank_name' %}: {{ coop.defaultBankAccount.bank_name }}</p><p>{% trans 'bik' %}: {{ coop.defaultBankAccount.details.bik }}</p><p>{% trans 'correspondent_account' %}: {{ coop.defaultBankAccount.details.corr }}</p><p>{% trans 'chairman' %} {{ vars.full_abbr_genitive }} "{{ vars.name }}"</p><p>{{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p><p>{% trans 'signed_by_digital_signature' %}</p><p><strong>{% trans 'participant' %}:</strong></p><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'contact_phone' %}: {{ user.phone }}</p><p>{% trans 'email' %}: {{ user.email }}</p><p>{% trans 'signed_by_digital_signature' %}</p></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}</style>` export const context = `<div class="digital-document"><div style="text-align: center"><h1>ЗАЯВЛЕНИЕ</h1><h2>на инициализацию проекта</h2></div><p style="text-align: right">{{ meta.created_at }}, {{ coop.city }}</p><p>{% trans 'parties_intro' %} "{{ vars.name }}" {% trans 'in_face_of_chairman' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}, {% trans 'acting_on_basis_of_charter' %}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'society' %}", {% trans 'and_participant' %} {{ user.full_name_or_short_name }}, {% trans 'hereinafter_referred_to_as' %} "{% trans 'participant' %}", {% trans 'jointly_referred_to_as' %} "{% trans 'parties' %}", {% trans 'have_concluded_this_statement' %} {% trans 'hereinafter_referred_to_as' %} "{% trans 'statement' %}" {% trans 'of_the_following' %}:</p><p>{% if is_component %}{% trans 'participant_requests_component_init' %} "{{ component_name }}" (№{{ component_hash }}) {% trans 'as_part_of_project' %} "{{ project_name }}" (№{{ project_hash }}).{% else %}{% trans 'participant_requests_project_init' %} "{{ project_name }}" (№{{ project_hash }}).{% endif %}</p><h2>{% trans 'details_and_signatures_of_parties' %}</h2><p><strong>{% trans 'society' %}/{{ vars.full_abbr }} "{{ vars.name }}"/:</strong></p><p>ИНН {{ coop.details.inn }}, КПП {{ coop.details.kpp }}, ОГРН {{ coop.details.ogrn }}</p><p>{% trans 'legal_address' %}: {{ coop.full_address }}</p><p>{% trans 'contact_phone' %}: {{ coop.phone }}</p><p>{% trans 'email' %}: {{ coop.email }}</p><p>{% trans 'bank_account' %}: {{ coop.defaultBankAccount.account_number }}</p><p>{% trans 'bank_name' %}: {{ coop.defaultBankAccount.bank_name }}</p><p>{% trans 'bik' %}: {{ coop.defaultBankAccount.details.bik }}</p><p>{% trans 'correspondent_account' %}: {{ coop.defaultBankAccount.details.corr }}</p><p>{% trans 'chairman' %} {{ vars.full_abbr_genitive }} "{{ vars.name }}"</p><p>{{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p><p>{% trans 'signed_by_digital_signature' %}</p><p><strong>{% trans 'participant' %}:</strong></p><p>{{ user.full_name_or_short_name }}</p><p>{% trans 'contact_phone' %}: {{ user.phone }}</p><p>{% trans 'email' %}: {{ user.email }}</p><p>{% trans 'signed_by_digital_signature' %}</p></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}</style>`
export const translations = { export const translations = {
ru: { ru: {
@@ -68,9 +68,9 @@ export const exampleData = {
created_at: '11.04.2024 12:00', created_at: '11.04.2024 12:00',
}, },
project_name: 'Проект цифровой платформы', project_name: 'Проект цифровой платформы',
project_id: 'B2C3D4E5F6789ABC', project_hash: 'B2C3D4E5F6789ABC',
component_name: 'Компонент разработки', component_name: 'Компонент разработки',
component_id: 'A1B2C3D4E5F6789A', component_hash: 'A1B2C3D4E5F6789A',
is_component: true, is_component: true,
vars: { vars: {
name: 'ВОСХОД', name: 'ВОСХОД',
@@ -9,9 +9,9 @@ export const registry_id = 1006
export interface Action extends IGenerate { export interface Action extends IGenerate {
decision_id: number decision_id: number
project_name: string project_name: string
project_id: string project_hash: string
component_name: string component_name: string
component_id: string component_hash: string
is_component: boolean is_component: boolean
} }
@@ -24,15 +24,15 @@ export interface Model {
decision: IDecisionData decision: IDecisionData
vars: IVars vars: IVars
project_name: string project_name: string
project_id: string project_hash: string
component_name: string component_name: string
component_id: string component_hash: string
is_component: boolean is_component: boolean
} }
export const title = 'Протокол решения совета об инициализации проекта' export const title = 'Протокол решения совета об инициализации проекта'
export const description = 'Форма протокола решения совета об инициализации проекта или компонента' export const description = 'Форма протокола решения совета об инициализации проекта или компонента'
export const context = '<style> \nh1 {\nmargin: 0px; \ntext-align:center;\n}\nh3{\nmargin: 0px;\npadding-top: 15px;\n}\n.about {\npadding: 20px;\n}\n.about p{\nmargin: 0px;\n}\n.signature {\npadding-top: 20px;\n}\n.digital-document {\npadding: 20px;\nwhite-space: pre-wrap;\n}\n.subheader {\npadding-bottom: 20px; \n}\ntable {\n width: 100%;\n border-collapse: collapse;\n}\nth, td {\n border: 1px solid #ccc;\n padding: 8px;\n text-align: left;\n word-wrap: break-word; \n overflow-wrap: break-word; \n}\nth {\n background-color: #f4f4f4;\n width: 30%;\n}\n</style>\n\n<div class="digital-document"><h1 class="header">{% trans \'protocol_number\', decision.id %}</h1>\n<p style="text-align:center" class="subheader">{% trans \'council_meeting_name\' %} {{vars.full_abbr_genitive}} "{{vars.name}}"</p>\n<p style="text-align: right"> {{ meta.created_at }}, {{ coop.city }}</p>\n<table class="about">\n<tbody>\n<tr>\n<th>{% trans \'meeting_format\' %}</th>\n<td>{% trans \'meeting_format_value\' %}</td>\n</tr>\n<tr>\n<th>{% trans \'meeting_place\' %}</th>\n<td>{{ coop.full_address }}</td>\n</tr>\n<tr>\n<th>{% trans \'meeting_date\' %}</th>\n<td>{{ decision.date }}</td>\n</tr>\n<tr>\n<th>{% trans \'opening_time\' %}</th>\n<td>{{ decision.time }}</td>\n</tr>\n</tbody>\n</table>\n<h3>{% trans \'council_members\' %}</h3>\n<table>\n<tbody>\n{% for member in coop.members %}\n<tr>\n<th>{% if member.is_chairman %}{% trans \'chairman_of_the_council\' %}{% else %}{% trans \'member_of_the_council\' %}{% endif %}</th>\n<td>{{ member.last_name }} {{ member.first_name }} {{ member.middle_name }}</td>\n</tr>\n{% endfor %}\n</tbody>\n</table>\n<h3>{% trans \'meeting_legality\' %} </h3>\n<p>{% trans \'voting_results\', decision.voters_percent %} {% trans \'quorum\' %} {% trans \'chairman_of_the_meeting\', coop.chairman.last_name, coop.chairman.first_name, coop.chairman.middle_name %}.</p>\n<h3>{% trans \'agenda\' %}</h3>\n<table>\n<tbody>\n<tr>\n<th>№</th>\n<td>{% trans \'question\' %}</td>\n</tr>\n<tr>\n<th>1</th>\n<td>{% if is_component %}{% trans \'init_component_question\', component_name, component_id, project_name, project_id %}{% else %}{% trans \'init_project_question\', project_name, project_id %}{% endif %}</td>\n</tr>\n</tbody>\n</table>\n<h3>{% trans \'voting\' %}</h3>\n<p>{% trans \'vote_results\' %} </p><table>\n<tbody>\n<tr>\n<th>{% trans \'votes_for\' %}</th>\n<td>{{ decision.votes_for }}</td>\n</tr>\n<tr>\n<th>{% trans \'votes_against\' %}</th>\n<td>{{ decision.votes_against }}</td>\n</tr>\n<tr>\n<th>{% trans \'votes_abstained\' %}</th>\n<td>{{ decision.votes_abstained }}</td>\n</tr>\n</tbody>\n</table>\n<h3>{% trans \'decision_made\' %}</h3>\n<table>\n<tbody>\n<tr>\n<th>№</th>\n<td>{% trans \'decision\' %}</td>\n</tr>\n<tr>\n<th>1</th>\n<td>{% if is_component %}{% trans \'init_component_decision\', component_name, component_id, project_name, project_id %}{% else %}{% trans \'init_project_decision\', project_name, project_id %}{% endif %}</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<p>{% trans \'closing_time\', decision.time %}</p>\n<div class="signature"><p>{% trans \'signature\' %}</p><p>{% trans \'chairman\' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p></div></div>\n' export const context = '<style> \nh1 {\nmargin: 0px; \ntext-align:center;\n}\nh3{\nmargin: 0px;\npadding-top: 15px;\n}\n.about {\npadding: 20px;\n}\n.about p{\nmargin: 0px;\n}\n.signature {\npadding-top: 20px;\n}\n.digital-document {\npadding: 20px;\nwhite-space: pre-wrap;\n}\n.subheader {\npadding-bottom: 20px; \n}\ntable {\n width: 100%;\n border-collapse: collapse;\n}\nth, td {\n border: 1px solid #ccc;\n padding: 8px;\n text-align: left;\n word-wrap: break-word; \n overflow-wrap: break-word; \n}\nth {\n background-color: #f4f4f4;\n width: 30%;\n}\n</style>\n\n<div class="digital-document"><h1 class="header">{% trans \'protocol_number\', decision.id %}</h1>\n<p style="text-align:center" class="subheader">{% trans \'council_meeting_name\' %} {{vars.full_abbr_genitive}} "{{vars.name}}"</p>\n<p style="text-align: right"> {{ meta.created_at }}, {{ coop.city }}</p>\n<table class="about">\n<tbody>\n<tr>\n<th>{% trans \'meeting_format\' %}</th>\n<td>{% trans \'meeting_format_value\' %}</td>\n</tr>\n<tr>\n<th>{% trans \'meeting_place\' %}</th>\n<td>{{ coop.full_address }}</td>\n</tr>\n<tr>\n<th>{% trans \'meeting_date\' %}</th>\n<td>{{ decision.date }}</td>\n</tr>\n<tr>\n<th>{% trans \'opening_time\' %}</th>\n<td>{{ decision.time }}</td>\n</tr>\n</tbody>\n</table>\n<h3>{% trans \'council_members\' %}</h3>\n<table>\n<tbody>\n{% for member in coop.members %}\n<tr>\n<th>{% if member.is_chairman %}{% trans \'chairman_of_the_council\' %}{% else %}{% trans \'member_of_the_council\' %}{% endif %}</th>\n<td>{{ member.last_name }} {{ member.first_name }} {{ member.middle_name }}</td>\n</tr>\n{% endfor %}\n</tbody>\n</table>\n<h3>{% trans \'meeting_legality\' %} </h3>\n<p>{% trans \'voting_results\', decision.voters_percent %} {% trans \'quorum\' %} {% trans \'chairman_of_the_meeting\', coop.chairman.last_name, coop.chairman.first_name, coop.chairman.middle_name %}.</p>\n<h3>{% trans \'agenda\' %}</h3>\n<table>\n<tbody>\n<tr>\n<th>№</th>\n<td>{% trans \'question\' %}</td>\n</tr>\n<tr>\n<th>1</th>\n<td>{% if is_component %}{% trans \'init_component_question\', component_name, component_hash, project_name, project_hash %}{% else %}{% trans \'init_project_question\', project_name, project_hash %}{% endif %}</td>\n</tr>\n</tbody>\n</table>\n<h3>{% trans \'voting\' %}</h3>\n<p>{% trans \'vote_results\' %} </p><table>\n<tbody>\n<tr>\n<th>{% trans \'votes_for\' %}</th>\n<td>{{ decision.votes_for }}</td>\n</tr>\n<tr>\n<th>{% trans \'votes_against\' %}</th>\n<td>{{ decision.votes_against }}</td>\n</tr>\n<tr>\n<th>{% trans \'votes_abstained\' %}</th>\n<td>{{ decision.votes_abstained }}</td>\n</tr>\n</tbody>\n</table>\n<h3>{% trans \'decision_made\' %}</h3>\n<table>\n<tbody>\n<tr>\n<th>№</th>\n<td>{% trans \'decision\' %}</td>\n</tr>\n<tr>\n<th>1</th>\n<td>{% if is_component %}{% trans \'init_component_decision\', component_name, component_hash, project_name, project_hash %}{% else %}{% trans \'init_project_decision\', project_name, project_hash %}{% endif %}</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<p>{% trans \'closing_time\', decision.time %}</p>\n<div class="signature"><p>{% trans \'signature\' %}</p><p>{% trans \'chairman\' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p></div></div>\n'
export const translations = { export const translations = {
ru: { ru: {
@@ -75,9 +75,9 @@ export const exampleData = {
created_at: '12.02.2024 00:01', created_at: '12.02.2024 00:01',
}, },
project_name: 'Проект цифровой платформы', project_name: 'Проект цифровой платформы',
project_id: 'B2C3D4E5F6789ABC', project_hash: 'B2C3D4E5F6789ABC',
component_name: 'Компонент разработки', component_name: 'Компонент разработки',
component_id: 'A1B2C3D4E5F6789A', component_hash: 'A1B2C3D4E5F6789A',
is_component: true, is_component: true,
coop: { coop: {
city: 'Москва', city: 'Москва',
@@ -1,3 +1,4 @@
import type { ICommonUser, ICooperativeData, IVars } from '../../model'
import type { IGenerate, IMetaDocument } from '../../document' import type { IGenerate, IMetaDocument } from '../../document'
export const registry_id = 1020 export const registry_id = 1020
@@ -5,6 +6,12 @@ export const registry_id = 1020
// Модель действия для генерации // Модель действия для генерации
export interface Action extends IGenerate { export interface Action extends IGenerate {
registry_id: number registry_id: number
appendix_hash: string
appendix_created_at: string
contributor_hash: string
contributor_created_at: string
project_hash: string
amount: string
} }
export type Meta = IMetaDocument & Action export type Meta = IMetaDocument & Action
@@ -12,11 +19,65 @@ export type Meta = IMetaDocument & Action
// Модель данных документа // Модель данных документа
export interface Model { export interface Model {
meta: IMetaDocument meta: IMetaDocument
coop: ICooperativeData
vars: IVars
user: ICommonUser
appendix_hash: string
short_appendix_hash: string
contributor_hash: string
short_contributor_hash: string
contributor_created_at: string
appendix_created_at: string
project_hash: string
amount: string
} }
export const title = 'Заявление об инвестировании денежных средств в генерацию' export const title = 'Заявление об инвестировании денежных средств в генерацию'
export const description = 'Форма заявления об инвестировании денежных средств в генерацию кооператива' export const description = 'Заявление о зачете части паевого взноса в качестве инвестиции в проект'
export const context = '<div class="digital-document"><div style="text-align: center"><h2>ЗАЯВЛЕНИЕ ОБ ИНВЕСТИРОВАНИИ СРЕДСТВ В ГЕНЕРАЦИЮ</h2></div><p>Прошу принять мои денежные средства в качестве инвестиций в генерацию кооператива.</p><p>Подпись: Иван Иванович</p></div>'
export const translations = {} export const context = `<div class="digital-document"><p style="text-align: right">{% trans 'council_of' %} {{ vars.full_abbr_genitive }} "{{ vars.name }}"</p><p style="text-align: right">{% trans 'from_shareholder' %} {{ user.full_name_or_short_name }}</p><div style="text-align: center"><h1>{% trans 'statement' %}</h1></div><p>{% trans 'in_accordance_with_appendix' %} №{{ short_appendix_hash }} {% trans 'from_date' %} {{ appendix_created_at }} {% trans 'to_agreement' %} УХД-{{ short_contributor_hash }} {% trans 'from_date' %} {{ contributor_created_at }}, {% trans 'request_to_credit' %} {% trans 'target_share_contribution' %} {% trans 'target_consumer_program' %} "{% trans 'digital_wallet' %}" {% trans 'in_amount' %} {{ amount }} {% trans 'as_share_contribution' %} {% trans 'to_project' %} №{{ project_hash }}.</p><p style="text-align: right">{{ meta.created_at }}</p><p style="text-align: right">{% trans 'signed_by_digital_signature' %}</p></div><style>.digital-document {padding: 20px;white-space: pre-wrap;}</style>`
export const exampleData = {}
export const translations = {
ru: {
council_of: 'В Совет',
from_shareholder: 'От пайщика',
statement: 'ЗАЯВЛЕНИЕ',
in_accordance_with_appendix: 'В соответствии с Приложением',
from_date: 'от',
to_agreement: 'к Договору об участии в хозяйственной деятельности №',
request_to_credit: 'прошу зачесть часть моего',
target_share_contribution: 'целевого паевого взноса',
target_consumer_program: 'по Целевой Потребительской Программе',
digital_wallet: 'ЦИФРОВОЙ КОШЕЛЕК',
in_amount: 'в размере',
as_share_contribution: 'в качестве паевого взноса',
to_project: 'в Проект',
signed_by_digital_signature: 'Подписано электронной подписью',
},
}
export const exampleData = {
meta: {
created_at: '15.01.2026 14:30',
},
appendix_hash: 'A001INV1',
short_appendix_hash: 'A001INV1',
contributor_hash: 'INV123456789ABCDEF',
short_contributor_hash: 'INV123456789',
contributor_created_at: '10.01.2026',
appendix_created_at: '12.01.2026',
project_hash: 'PRJ20260115001',
amount: '50000.00 RUB',
vars: {
name: 'ВОСХОД',
full_abbr_genitive: 'Потребительского Кооператива',
},
user: {
full_name_or_short_name: 'Иванов Иван Иванович',
phone: '+7 999 123-45-67',
email: 'ivanov@example.com',
},
coop: {
city: 'Москва',
},
}
@@ -0,0 +1,9 @@
В Совет {{vars.full_abbr_genitive}} “{{vars.name}}”
От пайщика: {{common_user.full_name_or_short_name}}
ЗАЯВЛЕНИЕ
В соответствии с Приложением №{{short_appendix_hash}} от{{appendix_created_at}} к Договору об участии в хозяйственной деятельности № УХД-{{short_contributor_hash}} от {{contributor_created_at}}, прошу зачесть часть моего целевого паевого взноса по Целевой Потребительской Программе “ЦИФРОВОЙ КОШЕЛЕК” в размере {{amount}} в качестве паевого взноса в Проект №{{project_hash}}.
{{meta.created_at}}
Подписано электронной подписью.
@@ -39,7 +39,7 @@ export function useCreateProjectInvest() {
} }
// Генерация заявления на инвестицию // Генерация заявления на инвестицию
async function generateInvestStatement(): Promise<IGeneratedDocumentOutput | null> { async function generateInvestStatement(projectHash: string, amount: string): Promise<IGeneratedDocumentOutput | null> {
try { try {
isGenerating.value = true; isGenerating.value = true;
generationError.value = false; generationError.value = false;
@@ -48,6 +48,8 @@ export function useCreateProjectInvest() {
const data = { const data = {
coopname: system.info.coopname, coopname: system.info.coopname,
username: session.username, username: session.username,
project_hash: projectHash,
amount: parseFloat(amount).toFixed(system.info.symbols.root_govern_precision) + ' ' + system.info.symbols.root_govern_symbol,
}; };
generatedDocument.value = await api.generateGenerationMoneyInvestStatement(data); generatedDocument.value = await api.generateGenerationMoneyInvestStatement(data);
@@ -71,7 +73,7 @@ export function useCreateProjectInvest() {
isGenerating.value = true; isGenerating.value = true;
// Генерируем заявление // Генерируем заявление
const document = await generateInvestStatement(); const document = await generateInvestStatement(projectHash, amount);
if (!document) { if (!document) {
throw new Error('Не удалось сгенерировать заявление'); throw new Error('Не удалось сгенерировать заявление');
} }
@@ -132,7 +132,16 @@ export function useCreateUser() {
const capitalizationDoc = registrationStore.getDocumentById('blagorost_offer'); const capitalizationDoc = registrationStore.getDocumentById('blagorost_offer');
const generatorDoc = registrationStore.getDocumentById('generator_offer'); const generatorDoc = registrationStore.getDocumentById('generator_offer');
const data: ISendStatement & { blagorost_offer?: IDocument; generator_offer?: IDocument; program_key?: string } = { // Преобразуем program_key в правильный enum формат
let programKey: Zeus.ProgramKey | undefined;
if (registratorStore.state.selectedProgramKey) {
const key = registratorStore.state.selectedProgramKey;
if (key === 'CAPITALIZATION' || key === 'GENERATION') {
programKey = key as Zeus.ProgramKey;
}
}
const data: ISendStatement & { blagorost_offer?: IDocument; generator_offer?: IDocument; program_key?: Zeus.ProgramKey } = {
username: store.account.username, username: store.account.username,
braname: store.selectedBranch, braname: store.selectedBranch,
statement: store.statement, statement: store.statement,
@@ -140,9 +149,11 @@ export function useCreateUser() {
privacy_agreement: privacyDoc?.signed_document || store.privacyAgreement, privacy_agreement: privacyDoc?.signed_document || store.privacyAgreement,
signature_agreement: signatureDoc?.signed_document || store.signatureAgreement, signature_agreement: signatureDoc?.signed_document || store.signatureAgreement,
user_agreement: userDoc?.signed_document || store.userAgreement, user_agreement: userDoc?.signed_document || store.userAgreement,
program_key: registratorStore.state.selectedProgramKey as Zeus.ProgramKey | undefined, program_key: programKey,
}; };
console.log('Sending data with program_key:', data.program_key);
// Добавляем blagorost_offer если есть // Добавляем blagorost_offer если есть
if (capitalizationDoc?.signed_document) { if (capitalizationDoc?.signed_document) {
data.blagorost_offer = capitalizationDoc.signed_document; data.blagorost_offer = capitalizationDoc.signed_document;
@@ -44,7 +44,7 @@ export class Factory extends DocFactory<ProjectGenerationContract.Action> {
short_contributor_hash: this.getShortHash(data.contributor_hash), short_contributor_hash: this.getShortHash(data.contributor_hash),
contributor_created_at: data.contributor_created_at, contributor_created_at: data.contributor_created_at,
project_name: data.project_name, project_name: data.project_name,
project_id: data.project_id, project_hash: data.project_hash,
} }
await this.validate(combinedData, template.model) await this.validate(combinedData, template.model)
@@ -38,17 +38,17 @@ export class Factory extends DocFactory<ComponentGenerationContract.Action> {
coop, coop,
vars, vars,
user, user,
component_appendix_hash: data.component_appendix_hash, appendix_hash: data.appendix_hash,
short_component_appendix_hash: this.getShortHash(data.component_appendix_hash), short_appendix_hash: this.getShortHash(data.appendix_hash),
parent_appendix_hash: data.parent_appendix_hash, parent_appendix_hash: data.parent_appendix_hash,
short_parent_appendix_hash: this.getShortHash(data.parent_appendix_hash), short_parent_appendix_hash: this.getShortHash(data.parent_appendix_hash),
contributor_hash: data.contributor_hash, contributor_hash: data.contributor_hash,
short_contributor_hash: this.getShortHash(data.contributor_hash), short_contributor_hash: this.getShortHash(data.contributor_hash),
contributor_created_at: data.contributor_created_at, contributor_created_at: data.contributor_created_at,
component_name: data.component_name, component_name: data.component_name,
component_id: data.component_id, component_hash: data.component_hash,
project_name: data.project_name, project_name: data.project_name,
project_id: data.project_id, project_hash: data.project_hash,
} }
await this.validate(combinedData, template.model) await this.validate(combinedData, template.model)
@@ -34,9 +34,9 @@ export class Factory extends DocFactory<InitProjectStatement.Action> {
vars, vars,
user, user,
project_name: data.project_name, project_name: data.project_name,
project_id: data.project_id, project_hash: data.project_hash,
component_name: data.component_name, component_name: data.component_name,
component_id: data.component_id, component_hash: data.component_hash,
is_component: data.is_component, is_component: data.is_component,
} }
@@ -59,9 +59,9 @@ export class Factory extends DocFactory<InitProjectDecision.Action> {
coop, coop,
decision, decision,
project_name: data.project_name, project_name: data.project_name,
project_id: data.project_id, project_hash: data.project_hash,
component_name: data.component_name, component_name: data.component_name,
component_id: data.component_id, component_hash: data.component_hash,
is_component: data.is_component, is_component: data.is_component,
vars, vars,
} }
@@ -3,6 +3,7 @@ import { GenerationMoneyInvestStatement } from '../Templates'
import { DocFactory } from '../Factory' import { DocFactory } from '../Factory'
import type { IGeneratedDocument, IGenerationOptions, IMetaDocument, ITemplate } from '../Interfaces' import type { IGeneratedDocument, IGenerationOptions, IMetaDocument, ITemplate } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor' import type { MongoDBConnector } from '../Services/Databazor'
import { formatDateTime } from '../Utils'
export { GenerationMoneyInvestStatement as Template } from '../Templates' export { GenerationMoneyInvestStatement as Template } from '../Templates'
@@ -22,8 +23,25 @@ export class Factory extends DocFactory<GenerationMoneyInvestStatement.Action> {
} }
const meta: IMetaDocument = await this.getMeta({ title: template.title, ...data }) const meta: IMetaDocument = await this.getMeta({ title: template.title, ...data })
const coop = await super.getCooperative(data.coopname, data.block_num)
const vars = await super.getVars(data.coopname, data.block_num)
const userData = await super.getUser(data.username, data.block_num)
const user = super.getCommonUser(userData)
const combinedData: GenerationMoneyInvestStatement.Model = {meta} const combinedData: GenerationMoneyInvestStatement.Model = {
meta,
coop,
vars,
user,
appendix_hash: data.appendix_hash,
short_appendix_hash: this.getShortHash(data.appendix_hash),
contributor_hash: data.contributor_hash,
short_contributor_hash: this.getShortHash(data.contributor_hash),
contributor_created_at: formatDateTime(data.contributor_created_at),
appendix_created_at: formatDateTime(data.appendix_created_at),
project_hash: data.project_hash,
amount: super.formatAsset(data.amount),
}
await this.validate(combinedData, template.model) await this.validate(combinedData, template.model)
@@ -28,9 +28,9 @@ export const Schema: JSONSchemaType<Model> = {
short_contributor_hash: { type: 'string' }, short_contributor_hash: { type: 'string' },
contributor_created_at: { type: 'string' }, contributor_created_at: { type: 'string' },
project_name: { type: 'string' }, project_name: { type: 'string' },
project_id: { type: 'string' }, project_hash: { type: 'string' },
}, },
required: ['meta', 'coop', 'vars', 'user', 'appendix_hash', 'short_appendix_hash', 'contributor_hash', 'short_contributor_hash', 'contributor_created_at', 'project_name', 'project_id'], required: ['meta', 'coop', 'vars', 'user', 'appendix_hash', 'short_appendix_hash', 'contributor_hash', 'short_contributor_hash', 'contributor_created_at', 'project_name', 'project_hash'],
additionalProperties: true, additionalProperties: true,
} }
@@ -22,19 +22,19 @@ export const Schema: JSONSchemaType<Model> = {
coop: CooperativeSchema, coop: CooperativeSchema,
vars: VarsSchema, vars: VarsSchema,
user: CommonUserSchema, user: CommonUserSchema,
component_appendix_hash: { type: 'string' }, appendix_hash: { type: 'string' },
short_component_appendix_hash: { type: 'string' }, short_appendix_hash: { type: 'string' },
parent_appendix_hash: { type: 'string' }, parent_appendix_hash: { type: 'string' },
short_parent_appendix_hash: { type: 'string' }, short_parent_appendix_hash: { type: 'string' },
contributor_hash: { type: 'string' }, contributor_hash: { type: 'string' },
short_contributor_hash: { type: 'string' }, short_contributor_hash: { type: 'string' },
contributor_created_at: { type: 'string' }, contributor_created_at: { type: 'string' },
component_name: { type: 'string' }, component_name: { type: 'string' },
component_id: { type: 'string' }, component_hash: { type: 'string' },
project_name: { type: 'string' }, project_name: { type: 'string' },
project_id: { type: 'string' }, project_hash: { type: 'string' },
}, },
required: ['meta', 'coop', 'vars', 'user', 'component_appendix_hash', 'short_component_appendix_hash', 'parent_appendix_hash', 'short_parent_appendix_hash', 'contributor_hash', 'short_contributor_hash', 'contributor_created_at', 'component_name', 'component_id', 'project_name', 'project_id'], required: ['meta', 'coop', 'vars', 'user', 'appendix_hash', 'short_appendix_hash', 'parent_appendix_hash', 'short_parent_appendix_hash', 'contributor_hash', 'short_contributor_hash', 'contributor_created_at', 'component_name', 'component_hash', 'project_name', 'project_hash'],
additionalProperties: true, additionalProperties: true,
} }
@@ -23,12 +23,12 @@ export const Schema: JSONSchemaType<Model> = {
vars: VarsSchema, vars: VarsSchema,
user: CommonUserSchema, user: CommonUserSchema,
project_name: { type: 'string' }, project_name: { type: 'string' },
project_id: { type: 'string' }, project_hash: { type: 'string' },
component_name: { type: 'string' }, component_name: { type: 'string' },
component_id: { type: 'string' }, component_hash: { type: 'string' },
is_component: { type: 'boolean' }, is_component: { type: 'boolean' },
}, },
required: ['meta', 'coop', 'vars', 'user', 'project_name', 'project_id', 'component_name', 'component_id', 'is_component'], required: ['meta', 'coop', 'vars', 'user', 'project_name', 'project_hash', 'component_name', 'component_hash', 'is_component'],
additionalProperties: true, additionalProperties: true,
} }
@@ -46,12 +46,12 @@ export const Schema: JSONSchemaType<Model> = {
}, },
vars: VarsSchema, vars: VarsSchema,
project_name: { type: 'string' }, project_name: { type: 'string' },
project_id: { type: 'string' }, project_hash: { type: 'string' },
component_name: { type: 'string' }, component_name: { type: 'string' },
component_id: { type: 'string' }, component_hash: { type: 'string' },
is_component: { type: 'boolean' }, is_component: { type: 'boolean' },
}, },
required: ['meta', 'coop', 'decision', 'project_name', 'project_id', 'component_name', 'component_id', 'is_component'], required: ['meta', 'coop', 'decision', 'project_name', 'project_hash', 'component_name', 'component_hash', 'is_component'],
additionalProperties: true, additionalProperties: true,
} }
@@ -1,6 +1,7 @@
import type { JSONSchemaType } from 'ajv' import type { JSONSchemaType } from 'ajv'
import { Cooperative } from 'cooptypes' import { Cooperative } from 'cooptypes'
import type { ITemplate } from '../Interfaces' import type { ITemplate } from '../Interfaces'
import { CommonUserSchema, CooperativeSchema, VarsSchema } from '../Schema'
import { IMetaJSONSchema } from '../Schema/MetaSchema' import { IMetaJSONSchema } from '../Schema/MetaSchema'
export const registry_id = Cooperative.Registry.GenerationMoneyInvestStatement.registry_id export const registry_id = Cooperative.Registry.GenerationMoneyInvestStatement.registry_id
@@ -16,8 +17,32 @@ export const Schema: JSONSchemaType<Model> = {
type: 'object', type: 'object',
properties: { properties: {
meta: IMetaJSONSchema, meta: IMetaJSONSchema,
coop: CooperativeSchema,
vars: VarsSchema,
user: CommonUserSchema,
appendix_hash: { type: 'string' },
short_appendix_hash: { type: 'string' },
contributor_hash: { type: 'string' },
short_contributor_hash: { type: 'string' },
contributor_created_at: { type: 'string' },
appendix_created_at: { type: 'string' },
project_hash: { type: 'string' },
amount: { type: 'string' },
}, },
required: ['meta'], required: [
'meta',
'coop',
'vars',
'user',
'appendix_hash',
'short_appendix_hash',
'contributor_hash',
'short_contributor_hash',
'contributor_created_at',
'appendix_created_at',
'project_hash',
'amount',
],
additionalProperties: true, additionalProperties: true,
} }
@@ -75,7 +75,7 @@ describe('тест генератора документов с registry_id >= 1
contributor_hash: 'ED3BCFC5B681AA83D123456789ABCDEF', contributor_hash: 'ED3BCFC5B681AA83D123456789ABCDEF',
contributor_created_at: '11.04.2024', contributor_created_at: '11.04.2024',
project_name: 'Проект цифровой платформы', project_name: 'Проект цифровой платформы',
project_id: 'B2C3D4E5F6789ABC', project_hash: 'B2C3D4E5F6789ABC',
lang: 'ru', lang: 'ru',
}) })
}) })
@@ -85,14 +85,14 @@ describe('тест генератора документов с registry_id >= 1
registry_id: 1003, registry_id: 1003,
coopname: 'voskhod', coopname: 'voskhod',
username: 'ant', username: 'ant',
component_appendix_hash: 'A002ZSA2', appendix_hash: 'A002ZSA2',
parent_appendix_hash: 'A001ZSA1', parent_appendix_hash: 'A001ZSA1',
contributor_hash: 'ED3BCFC5B681AA83D123456789ABCDEF', contributor_hash: 'ED3BCFC5B681AA83D123456789ABCDEF',
contributor_created_at: '11.04.2024', contributor_created_at: '11.04.2024',
component_name: 'Компонент разработки', component_name: 'Компонент разработки',
component_id: 'A1B2C3D4E5F6789A', component_hash: 'A1B2C3D4E5F6789A',
project_name: 'Проект цифровой платформы', project_name: 'Проект цифровой платформы',
project_id: 'B2C3D4E5F6789ABC', project_hash: 'B2C3D4E5F6789ABC',
lang: 'ru', lang: 'ru',
}) })
}) })
@@ -103,9 +103,9 @@ describe('тест генератора документов с registry_id >= 1
coopname: 'voskhod', coopname: 'voskhod',
username: 'ant', username: 'ant',
project_name: 'Проект цифровой платформы', project_name: 'Проект цифровой платформы',
project_id: 'B2C3D4E5F6789ABC', project_hash: 'B2C3D4E5F6789ABC',
component_name: 'Компонент разработки', component_name: 'Компонент разработки',
component_id: 'A1B2C3D4E5F6789A', component_hash: 'A1B2C3D4E5F6789A',
is_component: true, is_component: true,
lang: 'ru', lang: 'ru',
}) })
@@ -118,9 +118,9 @@ describe('тест генератора документов с registry_id >= 1
username: 'ant', username: 'ant',
decision_id: 1, decision_id: 1,
project_name: 'Проект цифровой платформы', project_name: 'Проект цифровой платформы',
project_id: 'B2C3D4E5F6789ABC', project_hash: 'B2C3D4E5F6789ABC',
component_name: 'Компонент разработки', component_name: 'Компонент разработки',
component_id: 'A1B2C3D4E5F6789A', component_hash: 'A1B2C3D4E5F6789A',
is_component: true, is_component: true,
lang: 'ru', lang: 'ru',
}) })
@@ -152,6 +152,12 @@ describe('тест генератора документов с registry_id >= 1
coopname: 'voskhod', coopname: 'voskhod',
username: 'ant', username: 'ant',
lang: 'ru', lang: 'ru',
appendix_hash: 'A001INV1',
appendix_created_at: '12.01.2026',
contributor_hash: 'INV123456789ABCDEF',
contributor_created_at: '10.01.2026',
project_hash: 'PRJ20260115001',
amount: '50000.00 RUB',
}) })
}) })
@@ -1,5 +1,7 @@
--- ---
globs: notifications/src/workflows/**/*.ts description: Правила создания воркфлоу оповещений (notifications)
globs: **/notifications/src/**/**.ts
alwaysApply: false
--- ---
# Правила валидации воркфлоу # Правила валидации воркфлоу
@@ -4,7 +4,7 @@ import { $, type GraphQLTypes, type InputType, type ModelTypes, Selector } from
export const name = 'capitalGenerateGenerationMoneyInvestStatement' export const name = 'capitalGenerateGenerationMoneyInvestStatement'
export const mutation = Selector('Mutation')({ export const mutation = Selector('Mutation')({
[name]: [{ data: $('data', 'GenerateDocumentInput!'), options: $('options', 'GenerateDocumentOptionsInput') }, documentSelector], [name]: [{ data: $('data', 'GenerationMoneyInvestStatementGenerateDocumentInput!'), options: $('options', 'GenerateDocumentOptionsInput') }, documentSelector],
}) })
export interface IInput { export interface IInput {
@@ -13,7 +13,7 @@ export interface IInput {
*/ */
[key: string]: unknown [key: string]: unknown
data: ModelTypes['GenerateDocumentInput'] data: ModelTypes['GenerationMoneyInvestStatementGenerateDocumentInput']
options?: ModelTypes['GenerateDocumentOptionsInput'] options?: ModelTypes['GenerateDocumentOptionsInput']
} }
+12 -2
View File
@@ -308,7 +308,7 @@ export const AllTypesProps: Record<string,any> = {
}, },
CreateProjectInvestInput:{ CreateProjectInvestInput:{
statement:"SignedDigitalDocumentInput" statement:"GenerationMoneyInvestStatementSignedDocumentInput"
}, },
CreateProjectPropertyInput:{ CreateProjectPropertyInput:{
@@ -430,6 +430,16 @@ export const AllTypesProps: Record<string,any> = {
}, },
GenerationContractSignedMetaDocumentInput:{ GenerationContractSignedMetaDocumentInput:{
},
GenerationMoneyInvestStatementGenerateDocumentInput:{
},
GenerationMoneyInvestStatementSignedDocumentInput:{
meta:"GenerationMoneyInvestStatementSignedMetaDocumentInput",
signatures:"SignatureInfoInput"
},
GenerationMoneyInvestStatementSignedMetaDocumentInput:{
}, },
GetAccountInput:{ GetAccountInput:{
@@ -683,7 +693,7 @@ export const AllTypesProps: Record<string,any> = {
options:"GenerateDocumentOptionsInput" options:"GenerateDocumentOptionsInput"
}, },
capitalGenerateGenerationMoneyInvestStatement:{ capitalGenerateGenerationMoneyInvestStatement:{
data:"GenerateDocumentInput", data:"GenerationMoneyInvestStatementGenerateDocumentInput",
options:"GenerateDocumentOptionsInput" options:"GenerateDocumentOptionsInput"
}, },
capitalGenerateGenerationMoneyReturnUnusedStatement:{ capitalGenerateGenerationMoneyReturnUnusedStatement:{
+313 -6
View File
@@ -3993,7 +3993,7 @@ export type ValueTypes = {
/** Хэш проекта */ /** Хэш проекта */
project_hash: string | Variable<any, string>, project_hash: string | Variable<any, string>,
/** Заявление на инвестирование */ /** Заявление на инвестирование */
statement: ValueTypes["SignedDigitalDocumentInput"] | Variable<any, string>, statement: ValueTypes["GenerationMoneyInvestStatementSignedDocumentInput"] | Variable<any, string>,
/** Имя инвестора */ /** Имя инвестора */
username: string | Variable<any, string> username: string | Variable<any, string>
}; };
@@ -4837,6 +4837,82 @@ export type ValueTypes = {
username: string | Variable<any, string>, username: string | Variable<any, string>,
/** Версия генератора, использованного для создания документа */ /** Версия генератора, использованного для создания документа */
version: string | Variable<any, string> version: string | Variable<any, string>
};
["GenerationMoneyInvestStatementGenerateDocumentInput"]: {
/** Сумма инвестирования */
amount: string | Variable<any, string>,
/** Номер блока, на котором был создан документ */
block_num?: number | undefined | null | Variable<any, string>,
/** Название кооператива, связанное с документом */
coopname: string | Variable<any, string>,
/** Дата и время создания документа */
created_at?: string | undefined | null | Variable<any, string>,
/** Имя генератора, использованного для создания документа */
generator?: string | undefined | null | Variable<any, string>,
/** Язык документа */
lang?: string | undefined | null | Variable<any, string>,
/** Ссылки, связанные с документом */
links?: Array<string> | undefined | null | Variable<any, string>,
/** Хэш проекта */
project_hash: string | Variable<any, string>,
/** Часовой пояс, в котором был создан документ */
timezone?: string | undefined | null | Variable<any, string>,
/** Название документа */
title?: string | undefined | null | Variable<any, string>,
/** Имя пользователя, создавшего документ */
username: string | Variable<any, string>,
/** Версия генератора, использованного для создания документа */
version?: string | undefined | null | Variable<any, string>
};
["GenerationMoneyInvestStatementSignedDocumentInput"]: {
/** Хэш содержимого документа */
doc_hash: string | Variable<any, string>,
/** Общий хэш (doc_hash + meta_hash) */
hash: string | Variable<any, string>,
/** Метаинформация для документа заявления об инвестировании в генерацию */
meta: ValueTypes["GenerationMoneyInvestStatementSignedMetaDocumentInput"] | Variable<any, string>,
/** Хэш мета-данных */
meta_hash: string | Variable<any, string>,
/** Вектор подписей */
signatures: Array<ValueTypes["SignatureInfoInput"]> | Variable<any, string>,
/** Версия стандарта документа */
version: string | Variable<any, string>
};
["GenerationMoneyInvestStatementSignedMetaDocumentInput"]: {
/** Сумма инвестирования */
amount: string | Variable<any, string>,
/** Дата создания приложения к проекту */
appendix_created_at: string | Variable<any, string>,
/** Хэш приложения к проекту */
appendix_hash: string | Variable<any, string>,
/** Номер блока, на котором был создан документ */
block_num: number | Variable<any, string>,
/** Дата создания участника */
contributor_created_at: string | Variable<any, string>,
/** Хэш участника */
contributor_hash: string | Variable<any, string>,
/** Название кооператива, связанное с документом */
coopname: string | Variable<any, string>,
/** Дата и время создания документа */
created_at: string | Variable<any, string>,
/** Имя генератора, использованного для создания документа */
generator: string | Variable<any, string>,
/** Язык документа */
lang: string | Variable<any, string>,
/** Ссылки, связанные с документом */
links: Array<string> | Variable<any, string>,
/** Хэш проекта */
project_hash: string | Variable<any, string>,
/** ID документа в реестре */
registry_id: number | Variable<any, string>,
/** Часовой пояс, в котором был создан документ */
timezone: string | Variable<any, string>,
/** Название документа */
title: string | Variable<any, string>,
/** Имя пользователя, создавшего документ */
username: string | Variable<any, string>,
/** Версия генератора, использованного для создания документа */
version: string | Variable<any, string>
}; };
["GetAccountInput"]: { ["GetAccountInput"]: {
/** Имя аккаунта пользователя */ /** Имя аккаунта пользователя */
@@ -5409,7 +5485,7 @@ capitalGenerateComponentGenerationContract?: [{ data: ValueTypes["ComponentGener
capitalGenerateExpenseDecision?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]], capitalGenerateExpenseDecision?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]],
capitalGenerateExpenseStatement?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]], capitalGenerateExpenseStatement?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]],
capitalGenerateGenerationContract?: [{ data: ValueTypes["GenerationContractGenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]], capitalGenerateGenerationContract?: [{ data: ValueTypes["GenerationContractGenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]],
capitalGenerateGenerationMoneyInvestStatement?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]], capitalGenerateGenerationMoneyInvestStatement?: [{ data: ValueTypes["GenerationMoneyInvestStatementGenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]],
capitalGenerateGenerationMoneyReturnUnusedStatement?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]], capitalGenerateGenerationMoneyReturnUnusedStatement?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]],
capitalGenerateGenerationPropertyInvestAct?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]], capitalGenerateGenerationPropertyInvestAct?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]],
capitalGenerateGenerationPropertyInvestDecision?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]], capitalGenerateGenerationPropertyInvestDecision?: [{ data: ValueTypes["GenerateDocumentInput"] | Variable<any, string>, options?: ValueTypes["GenerateDocumentOptionsInput"] | undefined | null | Variable<any, string>},ValueTypes["GeneratedDocument"]],
@@ -10847,7 +10923,7 @@ export type ResolverInputTypes = {
/** Хэш проекта */ /** Хэш проекта */
project_hash: string, project_hash: string,
/** Заявление на инвестирование */ /** Заявление на инвестирование */
statement: ResolverInputTypes["SignedDigitalDocumentInput"], statement: ResolverInputTypes["GenerationMoneyInvestStatementSignedDocumentInput"],
/** Имя инвестора */ /** Имя инвестора */
username: string username: string
}; };
@@ -11691,6 +11767,82 @@ export type ResolverInputTypes = {
username: string, username: string,
/** Версия генератора, использованного для создания документа */ /** Версия генератора, использованного для создания документа */
version: string version: string
};
["GenerationMoneyInvestStatementGenerateDocumentInput"]: {
/** Сумма инвестирования */
amount: string,
/** Номер блока, на котором был создан документ */
block_num?: number | undefined | null,
/** Название кооператива, связанное с документом */
coopname: string,
/** Дата и время создания документа */
created_at?: string | undefined | null,
/** Имя генератора, использованного для создания документа */
generator?: string | undefined | null,
/** Язык документа */
lang?: string | undefined | null,
/** Ссылки, связанные с документом */
links?: Array<string> | undefined | null,
/** Хэш проекта */
project_hash: string,
/** Часовой пояс, в котором был создан документ */
timezone?: string | undefined | null,
/** Название документа */
title?: string | undefined | null,
/** Имя пользователя, создавшего документ */
username: string,
/** Версия генератора, использованного для создания документа */
version?: string | undefined | null
};
["GenerationMoneyInvestStatementSignedDocumentInput"]: {
/** Хэш содержимого документа */
doc_hash: string,
/** Общий хэш (doc_hash + meta_hash) */
hash: string,
/** Метаинформация для документа заявления об инвестировании в генерацию */
meta: ResolverInputTypes["GenerationMoneyInvestStatementSignedMetaDocumentInput"],
/** Хэш мета-данных */
meta_hash: string,
/** Вектор подписей */
signatures: Array<ResolverInputTypes["SignatureInfoInput"]>,
/** Версия стандарта документа */
version: string
};
["GenerationMoneyInvestStatementSignedMetaDocumentInput"]: {
/** Сумма инвестирования */
amount: string,
/** Дата создания приложения к проекту */
appendix_created_at: string,
/** Хэш приложения к проекту */
appendix_hash: string,
/** Номер блока, на котором был создан документ */
block_num: number,
/** Дата создания участника */
contributor_created_at: string,
/** Хэш участника */
contributor_hash: string,
/** Название кооператива, связанное с документом */
coopname: string,
/** Дата и время создания документа */
created_at: string,
/** Имя генератора, использованного для создания документа */
generator: string,
/** Язык документа */
lang: string,
/** Ссылки, связанные с документом */
links: Array<string>,
/** Хэш проекта */
project_hash: string,
/** ID документа в реестре */
registry_id: number,
/** Часовой пояс, в котором был создан документ */
timezone: string,
/** Название документа */
title: string,
/** Имя пользователя, создавшего документ */
username: string,
/** Версия генератора, использованного для создания документа */
version: string
}; };
["GetAccountInput"]: { ["GetAccountInput"]: {
/** Имя аккаунта пользователя */ /** Имя аккаунта пользователя */
@@ -12263,7 +12415,7 @@ capitalGenerateComponentGenerationContract?: [{ data: ResolverInputTypes["Compon
capitalGenerateExpenseDecision?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]], capitalGenerateExpenseDecision?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]],
capitalGenerateExpenseStatement?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]], capitalGenerateExpenseStatement?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]],
capitalGenerateGenerationContract?: [{ data: ResolverInputTypes["GenerationContractGenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]], capitalGenerateGenerationContract?: [{ data: ResolverInputTypes["GenerationContractGenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]],
capitalGenerateGenerationMoneyInvestStatement?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]], capitalGenerateGenerationMoneyInvestStatement?: [{ data: ResolverInputTypes["GenerationMoneyInvestStatementGenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]],
capitalGenerateGenerationMoneyReturnUnusedStatement?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]], capitalGenerateGenerationMoneyReturnUnusedStatement?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]],
capitalGenerateGenerationPropertyInvestAct?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]], capitalGenerateGenerationPropertyInvestAct?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]],
capitalGenerateGenerationPropertyInvestDecision?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]], capitalGenerateGenerationPropertyInvestDecision?: [{ data: ResolverInputTypes["GenerateDocumentInput"], options?: ResolverInputTypes["GenerateDocumentOptionsInput"] | undefined | null},ResolverInputTypes["GeneratedDocument"]],
@@ -17643,7 +17795,7 @@ export type ModelTypes = {
/** Хэш проекта */ /** Хэш проекта */
project_hash: string, project_hash: string,
/** Заявление на инвестирование */ /** Заявление на инвестирование */
statement: ModelTypes["SignedDigitalDocumentInput"], statement: ModelTypes["GenerationMoneyInvestStatementSignedDocumentInput"],
/** Имя инвестора */ /** Имя инвестора */
username: string username: string
}; };
@@ -18458,6 +18610,82 @@ export type ModelTypes = {
username: string, username: string,
/** Версия генератора, использованного для создания документа */ /** Версия генератора, использованного для создания документа */
version: string version: string
};
["GenerationMoneyInvestStatementGenerateDocumentInput"]: {
/** Сумма инвестирования */
amount: string,
/** Номер блока, на котором был создан документ */
block_num?: number | undefined | null,
/** Название кооператива, связанное с документом */
coopname: string,
/** Дата и время создания документа */
created_at?: string | undefined | null,
/** Имя генератора, использованного для создания документа */
generator?: string | undefined | null,
/** Язык документа */
lang?: string | undefined | null,
/** Ссылки, связанные с документом */
links?: Array<string> | undefined | null,
/** Хэш проекта */
project_hash: string,
/** Часовой пояс, в котором был создан документ */
timezone?: string | undefined | null,
/** Название документа */
title?: string | undefined | null,
/** Имя пользователя, создавшего документ */
username: string,
/** Версия генератора, использованного для создания документа */
version?: string | undefined | null
};
["GenerationMoneyInvestStatementSignedDocumentInput"]: {
/** Хэш содержимого документа */
doc_hash: string,
/** Общий хэш (doc_hash + meta_hash) */
hash: string,
/** Метаинформация для документа заявления об инвестировании в генерацию */
meta: ModelTypes["GenerationMoneyInvestStatementSignedMetaDocumentInput"],
/** Хэш мета-данных */
meta_hash: string,
/** Вектор подписей */
signatures: Array<ModelTypes["SignatureInfoInput"]>,
/** Версия стандарта документа */
version: string
};
["GenerationMoneyInvestStatementSignedMetaDocumentInput"]: {
/** Сумма инвестирования */
amount: string,
/** Дата создания приложения к проекту */
appendix_created_at: string,
/** Хэш приложения к проекту */
appendix_hash: string,
/** Номер блока, на котором был создан документ */
block_num: number,
/** Дата создания участника */
contributor_created_at: string,
/** Хэш участника */
contributor_hash: string,
/** Название кооператива, связанное с документом */
coopname: string,
/** Дата и время создания документа */
created_at: string,
/** Имя генератора, использованного для создания документа */
generator: string,
/** Язык документа */
lang: string,
/** Ссылки, связанные с документом */
links: Array<string>,
/** Хэш проекта */
project_hash: string,
/** ID документа в реестре */
registry_id: number,
/** Часовой пояс, в котором был создан документ */
timezone: string,
/** Название документа */
title: string,
/** Имя пользователя, создавшего документ */
username: string,
/** Версия генератора, использованного для создания документа */
version: string
}; };
["GetAccountInput"]: { ["GetAccountInput"]: {
/** Имя аккаунта пользователя */ /** Имя аккаунта пользователя */
@@ -24582,7 +24810,7 @@ export type GraphQLTypes = {
/** Хэш проекта */ /** Хэш проекта */
project_hash: string, project_hash: string,
/** Заявление на инвестирование */ /** Заявление на инвестирование */
statement: GraphQLTypes["SignedDigitalDocumentInput"], statement: GraphQLTypes["GenerationMoneyInvestStatementSignedDocumentInput"],
/** Имя инвестора */ /** Имя инвестора */
username: string username: string
}; };
@@ -25426,6 +25654,82 @@ export type GraphQLTypes = {
username: string, username: string,
/** Версия генератора, использованного для создания документа */ /** Версия генератора, использованного для создания документа */
version: string version: string
};
["GenerationMoneyInvestStatementGenerateDocumentInput"]: {
/** Сумма инвестирования */
amount: string,
/** Номер блока, на котором был создан документ */
block_num?: number | undefined | null,
/** Название кооператива, связанное с документом */
coopname: string,
/** Дата и время создания документа */
created_at?: string | undefined | null,
/** Имя генератора, использованного для создания документа */
generator?: string | undefined | null,
/** Язык документа */
lang?: string | undefined | null,
/** Ссылки, связанные с документом */
links?: Array<string> | undefined | null,
/** Хэш проекта */
project_hash: string,
/** Часовой пояс, в котором был создан документ */
timezone?: string | undefined | null,
/** Название документа */
title?: string | undefined | null,
/** Имя пользователя, создавшего документ */
username: string,
/** Версия генератора, использованного для создания документа */
version?: string | undefined | null
};
["GenerationMoneyInvestStatementSignedDocumentInput"]: {
/** Хэш содержимого документа */
doc_hash: string,
/** Общий хэш (doc_hash + meta_hash) */
hash: string,
/** Метаинформация для документа заявления об инвестировании в генерацию */
meta: GraphQLTypes["GenerationMoneyInvestStatementSignedMetaDocumentInput"],
/** Хэш мета-данных */
meta_hash: string,
/** Вектор подписей */
signatures: Array<GraphQLTypes["SignatureInfoInput"]>,
/** Версия стандарта документа */
version: string
};
["GenerationMoneyInvestStatementSignedMetaDocumentInput"]: {
/** Сумма инвестирования */
amount: string,
/** Дата создания приложения к проекту */
appendix_created_at: string,
/** Хэш приложения к проекту */
appendix_hash: string,
/** Номер блока, на котором был создан документ */
block_num: number,
/** Дата создания участника */
contributor_created_at: string,
/** Хэш участника */
contributor_hash: string,
/** Название кооператива, связанное с документом */
coopname: string,
/** Дата и время создания документа */
created_at: string,
/** Имя генератора, использованного для создания документа */
generator: string,
/** Язык документа */
lang: string,
/** Ссылки, связанные с документом */
links: Array<string>,
/** Хэш проекта */
project_hash: string,
/** ID документа в реестре */
registry_id: number,
/** Часовой пояс, в котором был создан документ */
timezone: string,
/** Название документа */
title: string,
/** Имя пользователя, создавшего документ */
username: string,
/** Версия генератора, использованного для создания документа */
version: string
}; };
["GetAccountInput"]: { ["GetAccountInput"]: {
/** Имя аккаунта пользователя */ /** Имя аккаунта пользователя */
@@ -29015,6 +29319,9 @@ type ZEUS_VARIABLES = {
["GenerationContractGenerateDocumentInput"]: ValueTypes["GenerationContractGenerateDocumentInput"]; ["GenerationContractGenerateDocumentInput"]: ValueTypes["GenerationContractGenerateDocumentInput"];
["GenerationContractSignedDocumentInput"]: ValueTypes["GenerationContractSignedDocumentInput"]; ["GenerationContractSignedDocumentInput"]: ValueTypes["GenerationContractSignedDocumentInput"];
["GenerationContractSignedMetaDocumentInput"]: ValueTypes["GenerationContractSignedMetaDocumentInput"]; ["GenerationContractSignedMetaDocumentInput"]: ValueTypes["GenerationContractSignedMetaDocumentInput"];
["GenerationMoneyInvestStatementGenerateDocumentInput"]: ValueTypes["GenerationMoneyInvestStatementGenerateDocumentInput"];
["GenerationMoneyInvestStatementSignedDocumentInput"]: ValueTypes["GenerationMoneyInvestStatementSignedDocumentInput"];
["GenerationMoneyInvestStatementSignedMetaDocumentInput"]: ValueTypes["GenerationMoneyInvestStatementSignedMetaDocumentInput"];
["GetAccountInput"]: ValueTypes["GetAccountInput"]; ["GetAccountInput"]: ValueTypes["GetAccountInput"];
["GetAccountsInput"]: ValueTypes["GetAccountsInput"]; ["GetAccountsInput"]: ValueTypes["GetAccountsInput"];
["GetBranchesInput"]: ValueTypes["GetBranchesInput"]; ["GetBranchesInput"]: ValueTypes["GetBranchesInput"];