Compare commits

...

22 Commits

Author SHA1 Message Date
Alex Ant bd99697c5b chore(release): publish
- coopback@1.7.34
 - coopdoc-generator-ts@1.0.78
 - cooptypes@1.0.21
 - coop-notificator@0.0.25
 - terminal@0.1.38
2024-08-25 11:39:35 +05:00
Alex Ant 1d5c431ff6 update types 2024-08-25 11:38:40 +05:00
Alex Ant 3736c510ff chore(release): publish
- cooparser-ts@1.0.18
 - coopback@1.7.33
 - coopdoc-generator-ts@1.0.77
 - terminal@0.1.37
2024-08-25 11:27:44 +05:00
Alex Ant 26c12c3a85 update 2024-08-25 11:25:28 +05:00
Alex Ant 10bb08e5e6 chore(release): publish
- coopback@1.7.32
 - coopdoc-generator-ts@1.0.76
 - terminal@0.1.36
2024-08-25 11:19:13 +05:00
Alex Ant b50d5b6121 publish 2024-08-25 11:07:57 +05:00
Alex Ant 38b28752e1 chore(release): publish
- coopback@1.7.31
 - coopdoc-generator-ts@1.0.75
 - cooptypes@1.0.20
 - coop-notificator@0.0.24
 - terminal@0.1.35
2024-08-25 11:02:44 +05:00
Alex Ant 87c51009de ProgramProvision | ЦПП Цифровой Кошелёк 2024-08-25 10:59:57 +05:00
Alex Ant a950a47b28 chore(release): publish
- coopback@1.7.31-alpha.1
 - coopdoc-generator-ts@1.0.75-alpha.1
 - cooptypes@1.0.20-alpha.1
 - coop-notificator@0.0.24-alpha.1
 - terminal@0.1.35-alpha.1
2024-08-23 10:38:04 +05:00
Alex Ant 2609d10c0b update 2024-08-23 10:35:48 +05:00
Alex Ant 7b4cb0f66c publish 2024-08-23 10:34:38 +05:00
Alex Ant 26db0e1e69 push 2024-08-21 15:57:02 +05:00
Alex Ant 62e64cbd22 upgrade 2024-08-21 14:43:43 +05:00
Alex Ant 844a47830f fix types 2024-08-21 13:11:37 +05:00
Alex Ant 2cc1e32f45 chore(release): publish
- coopback@1.7.31-alpha.0
 - coopdoc-generator-ts@1.0.75-alpha.0
 - cooptypes@1.0.20-alpha.0
 - coop-notificator@0.0.24-alpha.0
 - terminal@0.1.35-alpha.0
2024-08-21 12:53:38 +05:00
Alex Ant 9890958b1e update contracts interface 2024-08-21 12:50:44 +05:00
Alex Ant 6dbd6d6edc fix 2024-08-19 14:31:01 +05:00
Alex Ant bf7a4dfd28 путь установки 2024-08-19 14:20:38 +05:00
Alex Ant f52626bda0 Полное разделение форм ввода данных пользователя пригодное для использования в процессе инсталляции 2024-08-16 16:17:24 +05:00
Alex Ant 88cec4bf2b рефакторинг | вынос форм для ввода пользовательской информации в shared для дальнейшего использования в модуле установки 2024-08-15 20:30:01 +05:00
Alex Ant b880def108 fix 2024-08-15 12:39:19 +05:00
Alex Ant bfd5dc039a addUser в панели управления 2024-08-15 12:28:18 +05:00
225 changed files with 4382 additions and 2367 deletions
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.18](https://github.com/copenomics/cooparser/compare/cooparser-ts@1.0.17...cooparser-ts@1.0.18) (2024-08-25)
**Note:** Version bump only for package cooparser-ts
## [1.0.17](https://github.com/copenomics/cooparser/compare/cooparser-ts@1.0.17-alpha.2...cooparser-ts@1.0.17) (2024-07-25)
**Note:** Version bump only for package cooparser-ts
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "pkg-placeholder",
"version": "1.0.17",
"version": "1.0.18",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pkg-placeholder",
"version": "1.0.17",
"version": "1.0.18",
"license": "MIT",
"devDependencies": {
"@antfu/eslint-config": "^2.16.0",
+2 -2
View File
@@ -1,8 +1,8 @@
{
"name": "cooparser-ts",
"type": "module",
"version": "1.0.17",
"private": true,
"version": "1.0.18",
"private": false,
"packageManager": "pnpm@9.0.6",
"description": "",
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
+4 -1
View File
@@ -1,5 +1,8 @@
{
"cSpell.words": [
"subcode"
]
],
"editor.formatOnSave": true,
"typescript.tsdk": "node_modules/typescript/lib",
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
+32
View File
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.7.34](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.33...coopback@1.7.34) (2024-08-25)
**Note:** Version bump only for package coopback
## [1.7.33](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.32...coopback@1.7.33) (2024-08-25)
**Note:** Version bump only for package coopback
## [1.7.32](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.31...coopback@1.7.32) (2024-08-25)
**Note:** Version bump only for package coopback
## [1.7.31](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.31-alpha.1...coopback@1.7.31) (2024-08-25)
**Note:** Version bump only for package coopback
## [1.7.30](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.29...coopback@1.7.30) (2024-08-13)
**Note:** Version bump only for package coopback
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "create-nodejs-express-app",
"version": "1.7.30",
"version": "1.7.34",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "create-nodejs-express-app",
"version": "1.7.30",
"version": "1.7.34",
"license": "MIT",
"dependencies": {
"@a2seven/yoo-checkout": "^1.1.4",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "coopback",
"version": "1.7.30",
"version": "1.7.34",
"description": "",
"private": true,
"bin": "bin/createNodejsApp.js",
@@ -17,12 +17,11 @@ const [username] = args;
async function createServiceUser(username: string) {
try {
await mongoose.connect(config.mongoose.url, config.mongoose.options);
const user = await userService.createServiceUser(username);
const token = await tokenService.generateServiceAccessToken(user);
logger.log('token:', token.access.token);
console.log('token:', token.access.token);
} catch (e: any) {
logger.log('Ошибка: ', e.message);
logger.error('Ошибка: ', e.message);
}
process.exit(0);
-6
View File
@@ -15,15 +15,10 @@ async function init() {
await mongoose.connect(config.mongoose.url, config.mongoose.options);
const wif = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3';
const password = await crypto.createHash('sha256').update(wif).digest('hex');
const hashed_password = await hash(password, 8);
console.log('password: ', hashed_password);
await userService.createUser({
username: 'ant',
email: 'dacom.dark.sun@gmail.com',
password,
public_key: 'EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV',
role: 'user',
type: 'individual',
@@ -46,7 +41,6 @@ async function init() {
const voskhod = await userService.createUser({
username: 'voskhod',
email: 'chairman.voskhod@gmail.com',
password,
public_key: 'EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV',
role: 'user',
type: 'organization',
+3 -4
View File
@@ -1,9 +1,8 @@
import {Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt'
import config from './config'
import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt';
import config from './config';
import { tokenTypes } from './tokens';
import { User } from '../models';
const jwtOptions = {
secretOrKey: config.jwt.secret,
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
@@ -14,7 +13,7 @@ const jwtVerify = async (payload, done) => {
if (payload.type !== tokenTypes.ACCESS) {
throw new Error('Invalid token type');
}
const user = await User.findOne({_id: payload.sub});
const user = await User.findOne({ _id: payload.sub });
if (!user) {
return done(null, false);
}
+1 -1
View File
@@ -1,6 +1,6 @@
const allRoles = {
user: [''],
service: ['addUser', 'sendNotification'],
service: ['addUser', 'sendNotification', 'install'],
chairman: ['addUser', 'getUsers', 'manageUsers', 'loadAgenda', 'loadStaff', 'getDocuments', 'loadInfo'],
member: ['getUsers', 'manageUsers', 'loadAgenda', 'loadStaff', 'getDocuments', 'loadInfo'],
};
@@ -1,9 +1,16 @@
import httpStatus from 'http-status';
import { getMonoStatus } from '../services/mono.service';
import { getBlockchainInfo } from '../services/blockchain.service';
import { IHealthResponse } from '../types';
import { IHealthResponse, IInstall, RInstall } from '../types';
import { Request, Response } from 'express';
import catchAsync from '../utils/catchAsync';
import { monoService } from '../services';
export const install = catchAsync(async (req: RInstall, res: Response) => {
const { body } = req;
await monoService.install(body as IInstall);
res.status(httpStatus.OK).send();
});
export const getHealth = catchAsync(async (req: Request, res: Response) => {
const status = await getMonoStatus();
@@ -91,7 +91,8 @@ export const addPaymentMethod = catchAsync(async (req: RSavePaymentMethod, res)
const paymentData: Cooperative.Payments.IPaymentData = {
username: req.body.username,
method_id: req.body.method_id,
user_type: user.type,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
user_type: user.type as any,
method_type: req.body.method_type,
is_default: false,
data: req.body.data,
@@ -23,9 +23,9 @@ import logger from '../config/logger';
* 7. (joinCooperative) Пользователь подписывает заявление на вступление и вызывает метод joinCooperative, прикладывая подписанное заявление.
* 8. Система сохраняет подписанное заявление
* 9. (createInitialPayment) Пользователь получает ордер на оплату.
* 9. Пользователь оплачивает ордер.
* 10. Система принимает оплату и регистрирует аккаунт в блокчейне.
* 11. (trx confirmpay) Пользователь подписывает велком-письмо с подтверждением собственноручности оплаты (транзакция в блокчейне для активации)
* 12. Регистрация продолжается ожиданием решения совета
*/
export const createUser = catchAsync(async (req: RCreateUser, res) => {
const user = await userService.createUser(req.body);
@@ -45,6 +45,9 @@ export const addUser = catchAsync(async (req: Request, res: Response) => {
};
const user = await userService.createUser(newUser);
user.status = 'registered';
user.is_registered = true;
await user.save();
try {
await blockchainService.addUser({
@@ -55,12 +58,14 @@ export const addUser = catchAsync(async (req: Request, res: Response) => {
coopname: config.coopname,
meta: '',
});
console.log('user: ', user);
const token = await tokenService.generateInviteToken(user.email);
await emailService.sendInviteEmail(req.body.email, token);
} catch (e) {
} catch (e: any) {
console.log('on e: ', e);
logger.warn('error on add user: ', e);
await userService.deleteUserByUsername(newUser.username);
throw new ApiError(httpStatus.BAD_GATEWAY, e.message);
}
res.status(httpStatus.CREATED).send({ user });
@@ -83,7 +88,7 @@ export const getUsers = catchAsync(async (req, res) => {
for await (const user of users.results) {
const json = user.toJSON();
if (user.type != 'service') {
json.private_data = (await user.getPrivateData()) || {};
json.private_data = await user.getPrivateData();
data.push(json);
}
}
@@ -104,7 +109,9 @@ export const getUser = catchAsync(async (req, res) => {
}
const json = user.toJSON();
json.private_data = await user.getPrivateData();
if (user.type != 'service') {
json.private_data = await user.getPrivateData();
}
res.send(json);
});
+2 -2
View File
@@ -15,7 +15,7 @@ export interface IUser {
message: string;
is_registered: boolean;
has_account: boolean;
type: 'individual' | 'entrepreneur' | 'organization';
type: 'individual' | 'entrepreneur' | 'organization' | 'service';
public_key: string;
referer: string;
email: string;
@@ -78,7 +78,7 @@ const userSchema = new Schema<IUser, IUserModel>(
},
email: {
type: String,
required: true,
required: false,
unique: true,
trim: true,
lowercase: true,
@@ -1,8 +1,12 @@
import { Router } from 'express';
import { monoController } from '../../controllers';
import auth from '../../middlewares/auth';
import validate from '../../middlewares/validate';
import { monoValidation } from '../../validations';
const router = Router();
router.route('/install').post(auth('install'), validate(monoValidation.RInstall), monoController.install);
router.route('/health').get(monoController.getHealth);
export default router;
@@ -88,7 +88,7 @@ export const refreshAuth = async (data: IRefreshTokens) => {
*/
export const resetKey = async (resetKeyToken, publicKey) => {
try {
const resetKeyTokenDoc = await tokenService.verifyToken(resetKeyToken, tokenTypes.RESET_PASSWORD);
const resetKeyTokenDoc = await tokenService.verifyToken(resetKeyToken, [tokenTypes.RESET_PASSWORD, tokenTypes.INVITE]);
const user = await userService.getUserById(resetKeyTokenDoc.user);
if (!user) {
@@ -107,6 +107,7 @@ export const resetKey = async (resetKeyToken, publicKey) => {
await Token.deleteMany({ user: user._id, type: tokenTypes.RESET_PASSWORD });
} catch (error) {
console.log(error);
throw new ApiError(httpStatus.UNAUTHORIZED, 'Token reset failed');
}
};
@@ -84,9 +84,9 @@ async function getCooperative(coopname) {
const [cooperative] = await lazyFetch(
api,
process.env.REGISTRATOR_CONTRACT,
process.env.REGISTRATOR_CONTRACT,
'orgs',
RegistratorContract.contractName.production,
RegistratorContract.contractName.production,
RegistratorContract.Tables.Cooperatives.tableName,
coopname,
coopname,
1
@@ -178,6 +178,36 @@ async function registerBlockchainAccount(user: IUser, orderData: GatewayContract
);
}
async function createBoard(data: SovietContract.Actions.Boards.CreateBoard.ICreateboard) {
const eos = await getInstance(config.service_wif);
console.log('data: ', data);
const actions = [
{
account: SovietContract.contractName.production,
name: SovietContract.Actions.Boards.CreateBoard.actionName,
authorization: [
{
actor: config.service_username,
permission: 'active',
},
],
data,
},
];
await eos.transact(
{
actions,
},
{
blocksBehind: 3,
expireSeconds: 30,
}
);
}
async function createOrder(data) {
const eos = await getInstance(process.env.REGISTRATOR_WIF);
@@ -351,4 +381,5 @@ export {
getBlockchainInfo,
getBlockchainAccount,
hasActiveKey,
createBoard,
};
@@ -30,7 +30,7 @@ export async function buildComplexDocument(
const document = await generator.getDocument({ hash: raw_document.document.hash });
const user = await User.findOne({ username: raw_document.username });
if (user) {
if (user && user.type != 'service') {
const user_data = await user?.getPrivateData();
const action: Cooperative.Blockchain.IExtendedAction = {
@@ -51,11 +51,13 @@ export const sendResetKeyEmail = async (to, token) => {
* @returns {Promise}
*/
export const sendInviteEmail = async (to, token) => {
const subject = 'Восстановление доступа';
const subject = 'Приглашение в Цифровой Кооператив';
const inviteUrl = `${config.base_url}/#/${config.coopname}/auth/reset-key?token=${token}`;
const text = `Вам отправлено приглашение на подключение к Цифровому Кооперативу в качестве пайщика.
Для того, чтобы воспользоваться приглашени, нажмите на ссылку: ${token}. Время действия ссылки - 24 часа.`;
const text = `Вам отправлено приглашение на подключение к Цифровому Кооперативу в качестве действующего пайщика.
Для того, чтобы воспользоваться приглашением и получить ключ доступа, пожалуйста, нажмите на ссылку: ${inviteUrl}
Время действия ссылки - 24 часа.`;
await sendEmail(to, subject, text);
};
@@ -3,7 +3,112 @@ import { Mono } from '../models';
import ApiError from '../utils/ApiError';
import config from '../config/config';
import logger from '../config/logger';
import { IHealthStatus } from '../types';
import { IAddUser, ICreateUser, IHealthStatus, IInstall } from '../types';
import { generateUsername } from '../../tests/utils/generateUsername';
import { generator } from './document.service';
import { blockchainService, emailService, tokenService, userService } from '.';
import { IUser } from '../models/user.model';
import axios from 'axios';
import { getBlockchainInfo } from './blockchain.service';
import { RegistratorContract } from 'cooptypes';
export const install = async (soviet: IInstall): Promise<void> => {
console.log('IInstall: ', soviet);
const mono = await Mono.findOne({ coopname: config.coopname });
const info = await getBlockchainInfo();
const coop = await blockchainService.getCooperative(config.coopname);
if (!coop) throw new ApiError(httpStatus.BAD_REQUEST, 'Информация о кооперативе не обнаружена');
if (mono && mono.status != 'install') {
throw new ApiError(httpStatus.BAD_REQUEST, 'Установка уже выполнена');
}
const users = [] as IUser[];
const members = [] as any;
const sovietExt = [] as any;
try {
for (const member of soviet) {
console.log(member);
const username = generateUsername();
sovietExt.push({ ...member, username });
const addUser: RegistratorContract.Actions.AddUser.IAddUser = {
registrator: config.service_username,
coopname: config.coopname,
referer: '',
username,
type: 'individual',
created_at: info.head_block_time,
initial: coop.initial,
minimum: coop.minimum,
spread_initial: false,
meta: '',
};
await blockchainService.addUser(addUser);
const createUser: ICreateUser = {
email: member.individual_data.email,
individual_data: member.individual_data,
referer: '',
role: 'user',
type: 'individual',
username,
};
const user = await userService.createUser(createUser);
user.status = 'registered';
user.is_registered = true;
await user.save();
//Генерируем токен и отправляем приглашение
const token = await tokenService.generateInviteToken(member.individual_data.email);
await emailService.sendInviteEmail(member.individual_data.email, token);
//Добавляем в массив членов для отправки в бч
members.push({
username: username,
is_voting: true,
position_title: member.role === 'chairman' ? 'Председатель совета' : 'Член совета',
position: member.role,
});
users.push(user);
}
const chairman = sovietExt.find((el) => el.role == 'chairman');
//TODO создаёт доску совета
await blockchainService.createBoard({
coopname: config.coopname,
username: config.service_username,
type: 'soviet',
members: members,
name: 'Совет',
description: '',
});
} catch (e: any) {
console.log('on error', e);
for (const user of users) {
await userService.deleteUserByUsername(user.username);
await generator.del('individual', { username: user.username });
}
throw new ApiError(httpStatus.BAD_REQUEST, e.message);
}
await Mono.updateOne(
{ coopname: config.coopname },
{
status: 'active',
}
);
logger.info('MONO активирован');
};
export const init = async (): Promise<void> => {
const mono = await Mono.findOne({ coopname: config.coopname });
@@ -198,7 +198,10 @@ export async function createInitialOrder(username: string, data: ICreateInitialP
}
export async function catchIPN(ipnBody: IYandexIPN) {
if (!connection.db) throw new Error('Нет подключения');
const payments = await connection.db.collection('payments');
const exist = await payments.findOne({ 'object.id': ipnBody.object.id });
if (!exist) {
@@ -48,12 +48,17 @@ export const saveToken = async (token, userId, expires, type, blacklisted = fals
/**
* Verify token and return token doc (or throw an error if it is not valid)
* @param {string} token
* @param {string} type
* @param {string[]} types
* @returns {Promise<Token>}
*/
export const verifyToken = async (token, type) => {
export const verifyToken = async (token, types) => {
const payload = jwt.verify(token, config.jwt.secret);
const tokenDoc = await Token.findOne({ token, type, user: payload.sub, blacklisted: false });
const tokenDoc = await Token.findOne({
token,
$or: types.map((type) => ({ type })),
user: payload.sub,
blacklisted: false,
});
if (!tokenDoc) {
throw new Error('Token not found');
}
@@ -68,7 +73,7 @@ export const verifyToken = async (token, type) => {
export const generateServiceAccessToken = async (user) => {
const accessTokenExpires = moment().add(100, 'years'); // Пример с очень долгим сроком действия
const accessToken = generateToken(user.id, accessTokenExpires, tokenTypes.ACCESS);
console.log('on generate', accessToken);
return {
access: {
token: accessToken,
@@ -5,17 +5,12 @@ import { generator } from './document.service';
import { ICreateUser, IJoinCooperative } from '../types/auto-generated/user.validation';
import { PublicKey, Signature } from '@wharfkit/antelope';
import faker from 'faker';
import { randomBytes } from 'crypto';
export const createServiceUser = async (username: string) => {
const password = randomBytes(16).toString('hex');
return User.create({
username,
type: 'service',
role: 'service',
public_key: 'thanks-no-need',
password,
email: faker.internet.email().toLowerCase(),
});
};
@@ -16,7 +16,9 @@ export const updateBoard = async (action: SovietContract.Actions.Boards.UpdateBo
await user.save();
}
const chairman = await userService.getUserByUsername(action.chairman);
const chairman_username = action.members.find((el) => el.position == 'chairman')?.username;
const chairman = await userService.getUserByUsername(chairman_username as string);
chairman.role = 'chairman';
await chairman.save();
};
@@ -6,6 +6,7 @@
export * from './auth.validation';
export * from './coop.validation';
export * from './document.validation';
export * from './mono.validation';
export * from './notify.validation';
export * from './payment.validation';
export * from './user.validation';
@@ -0,0 +1,32 @@
/**
* This file was automatically generated by joi-to-typescript
* Do not modify this file manually
*/
export type IInstall = {
individual_data: {
birthdate: string;
email: string;
first_name: string;
full_address: string;
last_name: string;
middle_name: string;
phone: string;
};
role: 'chairman' | 'member';
}[];
export interface RInstall {
body: {
individual_data: {
birthdate: string;
email: string;
first_name: string;
full_address: string;
last_name: string;
middle_name: string;
phone: string;
};
role: 'chairman' | 'member';
}[];
}
@@ -151,7 +151,7 @@ export interface ICreateUser {
short_name: string;
type: 'coop' | 'ooo' | 'oao' | 'zao' | 'pao' | 'ao';
};
public_key: string;
public_key?: string;
referer?: string;
role: 'user';
type: 'individual' | 'entrepreneur' | 'organization';
@@ -286,7 +286,6 @@ export interface RAddUser {
phone: string;
};
initial: string;
meta?: string;
minimum: string;
organization_data?: {
bank_account: {
@@ -398,7 +397,7 @@ export interface RCreateUser {
short_name: string;
type: 'coop' | 'ooo' | 'oao' | 'zao' | 'pao' | 'ao';
};
public_key: string;
public_key?: string;
referer?: string;
role: 'user';
type: 'individual' | 'entrepreneur' | 'organization';
@@ -5,3 +5,4 @@ export * as orderValidation from './payment.validation';
export * as coopValidation from './coop.validation';
export * as customValidation from './custom.validation';
export * as notifyValidation from './notify.validation';
export * as monoValidation from './mono.validation';
@@ -0,0 +1,13 @@
import * as Joi from 'joi';
import { IIndividualData } from './user.validation';
export const IInstall = Joi.array().items(
Joi.object({
role: Joi.string().required().valid('chairman', 'member'),
individual_data: IIndividualData.required(),
})
);
export const RInstall = Joi.object({
body: IInstall.required(),
});
@@ -58,7 +58,7 @@ export const IEntrepreneurData = Joi.object({
export const ICreateUser = Joi.object({
email: Joi.string().required().email(),
role: Joi.string().required().valid('user'),
public_key: Joi.string().required(),
public_key: Joi.string().optional(),
username: Joi.string().required().length(12),
referer: Joi.string().length(12).allow('').optional(),
type: Joi.string().required().valid('individual', 'entrepreneur', 'organization'),
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.78](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.77...coopdoc-generator-ts@1.0.78) (2024-08-25)
**Note:** Version bump only for package coopdoc-generator-ts
## [1.0.77](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.76...coopdoc-generator-ts@1.0.77) (2024-08-25)
**Note:** Version bump only for package coopdoc-generator-ts
## [1.0.76](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.75...coopdoc-generator-ts@1.0.76) (2024-08-25)
**Note:** Version bump only for package coopdoc-generator-ts
## [1.0.75](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.75-alpha.1...coopdoc-generator-ts@1.0.75) (2024-08-25)
**Note:** Version bump only for package coopdoc-generator-ts
## [1.0.74](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.73...coopdoc-generator-ts@1.0.74) (2024-08-13)
**Note:** Version bump only for package coopdoc-generator-ts
+2 -3
View File
@@ -1,8 +1,8 @@
{
"name": "coopdoc-generator-ts",
"type": "module",
"version": "1.0.74",
"private": true,
"version": "1.0.78",
"private": false,
"packageManager": "pnpm@9.0.6",
"description": "",
"author": "Alex Ant <chairman.voskhod@gmail.com>",
@@ -49,7 +49,6 @@
"ajv-formats": "^3.0.1",
"ajv-i18n": "^4.2.0",
"axios": "^1.7.2",
"cooparser-ts": "workspace:*",
"cooptypes": "workspace:*",
"dotenv": "^16.4.5",
"eosjs-ecc": "^4.0.7",
@@ -1,2 +1,3 @@
export * as JoinCoop from './registrator.joincoop'
export * as JoinCoopDecision from './registrator.joincoopdec'
export * as JoinProgram from './soviet.joinprog'
@@ -0,0 +1,57 @@
import { DocFactory } from '../Factory'
import type { IGeneratedDocument, IMetaDocument } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
import { DocumentsRegistry } from '../Templates'
import type { IGenerateJoinProgram } from '../Interfaces/Actions'
import type { IJoinProgram } from '../Templates/1000.ProgramProvision'
export class JoinProgramTemplateFactory extends DocFactory {
constructor(storage: MongoDBConnector) {
super(storage)
}
async generateDocument(options: IGenerateJoinProgram): Promise<IGeneratedDocument> {
// TODO
/**
* Получаем шаблон программы по registry_id из options (registry_id)
* Получаем из бд парсера
*/
let template
if (process.env.SOURCE === 'local') {
template = DocumentsRegistry[options.registry_id as keyof typeof DocumentsRegistry]
}
else {
template = await this.getTemplate(options.registry_id, options.block_num)
}
const coop = await super.getCooperative(options.coopname, options.block_num)
const meta: IMetaDocument = await super.getMeta({
title: template.title,
...options,
}) // Генерируем мета-данные
const combinedData: IJoinProgram = {
meta,
coop,
protocol_number: options.protocol_number,
protocol_day_month_year: options.protocol_day_month_year,
}
// валидируем скомбинированные данные
await super.validate(combinedData, template.model)
// получаем комплекс перевода
const translation = template.translations[meta.lang]
// генерируем документ
const document: IGeneratedDocument = await super.generatePDF(null, template.context, combinedData, translation, meta)
// сохраняем его в бд
await super.saveDraft(document)
return document
}
}
@@ -170,7 +170,7 @@ export abstract class DocFactory {
}
async generatePDF(
data: externalDataTypes,
data: externalDataTypes | null,
context: string,
vars: ICombinedData,
translation: ITranslations,
@@ -185,13 +185,14 @@ export abstract class DocFactory {
return document
}
getFullName(data: externalDataTypes): string {
if ('first_name' in data)
return `${data.last_name} ${data.first_name} ${data.middle_name}`
if ('represented_by' in data)
return `${data.represented_by.last_name} ${data.represented_by.first_name} ${data.represented_by.middle_name}`
getFullName(data: externalDataTypes | null): string {
if (data) {
if ('first_name' in data)
return `${data.last_name} ${data.first_name} ${data.middle_name}`
if ('represented_by' in data)
return `${data.represented_by.last_name} ${data.represented_by.first_name} ${data.represented_by.middle_name}`
}
return ''
}
@@ -2,3 +2,4 @@ import type { Cooperative } from 'cooptypes'
export type IGenerateJoinCoopDecision = Cooperative.Documents.IGenerateJoinCoopDecision
export type IGenerateJoinCoop = Cooperative.Documents.IGenerateJoinCoop
export type IGenerateJoinProgram = Cooperative.Documents.IGenerateJoinProgram
@@ -25,7 +25,9 @@ class TransExtension {
args.forEach((value, index) => {
translation = translation.replace(new RegExp(`\\{${index}\\}`, 'g'), value)
})
return translation
translation = translation.replace(/\n/g, '<br>')
return new nunjucks.runtime.SafeString(translation as unknown as string)
}
}
File diff suppressed because one or more lines are too long
@@ -1,2 +1 @@
export * from './100.ParticipantApplication'
export * from './registry'
@@ -1,11 +1,15 @@
import * as ParticipantApplication from './100.ParticipantApplication'
import * as DecisionOfParticipantApplication from './501.DecisionOfParticipantApplication'
import * as ProgramProvision from './1000.ProgramProvision'
export const DocumentsRegistry = {
100: ParticipantApplication.ParticipantApplicationTemplate,
501: DecisionOfParticipantApplication.DecisionOfParticipantApplicationTemplate,
1000: ProgramProvision.JoinProgramTemplate,
}
export interface DocumentsMappingByActionAndCode {
'registrator::joincoop': ParticipantApplication.IJoinCoopAction // Тип данных для документа 'registrator::joincoop'
'registrator::joincoopdec': DecisionOfParticipantApplication.IJoinCoopDecisionAction // Тип данных для документа 'registrator::joincoopdec'
'soviet::joinprog': ProgramProvision.IJoinProgram
}
+2 -1
View File
@@ -5,7 +5,7 @@ import type { Filter, InsertOneResult, UpdateResult } from 'mongodb'
import type { Cooperative as CooperativeModel } from 'cooptypes'
import type { Actions, IFilterDocuments, IGeneratedDocument, externalDataTypes, externalDataTypesArrays, internalFilterTypes } from './Interfaces'
import type { IGenerate } from './Interfaces/Documents'
import { JoinCoop, JoinCoopDecision } from './Actions'
import { JoinCoop, JoinCoopDecision, JoinProgram } from './Actions'
import { MongoDBConnector } from './Services/Databazor'
import type { ExternalIndividualData } from './Models/Individual'
import { Individual } from './Models/Individual'
@@ -57,6 +57,7 @@ export class Generator implements IGenerator {
this.factories = {
'registrator::joincoop': new JoinCoop.JoinCoopTemplateFactory(this.storage),
'registrator::joincoopdec': new JoinCoopDecision.DecisionOfJoinCoopTemplateFactory(this.storage),
'soviet::joinprog': new JoinProgram.JoinProgramTemplateFactory(this.storage),
}
await this.storage.connect()
}
+219 -174
View File
@@ -1,6 +1,6 @@
import { beforeAll, beforeEach, describe, expect, it } from 'vitest'
import type { RegistratorContract, SovietContract } from 'cooptypes'
import { Generator } from '../src'
import { Generator, type IGenerateJoinProgram } from '../src'
import type { IGeneratedDocument } from '../src/Interfaces/Documents'
import { saveBufferToDisk } from '../src/Utils/saveBufferToDisk'
import { loadBufferFromDisk } from '../src/Utils/loadBufferFromDisk'
@@ -298,15 +298,19 @@ describe('тест генератора документов', async () => {
}
})
it('генерируем заявление на вступление физического лица', async () => {
const document: IGeneratedDocument = await generator.generate({
code: 'registrator',
action: 'joincoop',
it('генерируем заявление на присоединение к ЦПП', async () => {
const params: IGenerateJoinProgram = {
code: 'soviet',
action: 'joinprog',
coopname: 'voskhod',
username: 'ant',
lang: 'ru',
signature: signatureExample,
})
registry_id: 1000,
protocol_number: '01-01-2024',
protocol_day_month_year: '1 января 2024 г.',
}
const document: IGeneratedDocument = await generator.generate(params)
const filename1 = `${document.meta.title}-${document.meta.username}.pdf`
await saveBufferToDisk(document.binary, filename1)
@@ -314,6 +318,7 @@ describe('тест генератора документов', async () => {
const regenerated_document: IGeneratedDocument = await generator.generate({
...document.meta,
})
const filename2 = `regenerated-${document.meta.title}-${document.meta.username}.pdf`
await saveBufferToDisk(regenerated_document.binary, filename2)
@@ -331,205 +336,245 @@ describe('тест генератора документов', async () => {
expect(getted_document).toBeDefined()
expect(getted_document.hash).toEqual(document.hash)
// console.log('hash1: ', hash1)
// console.log('hash2: ', hash2)
console.log('hash1: ', hash1)
console.log('hash2: ', hash2)
// console.log(document)
expect(hash1).toEqual(hash2)
const decision_document: IGeneratedDocument = await generator.generate({
code: 'registrator',
action: 'joincoopdec',
coopname: 'voskhod',
username: 'ant',
lang: 'ru',
decision_id: 1,
})
const filename3 = `${decision_document.meta.title}-${decision_document.meta.username}.pdf`
await saveBufferToDisk(decision_document.binary, filename3)
})
it('сохранение данных организации', async () => {
const organizationData: ExternalOrganizationData = {
username: 'exampleorg',
type: 'ooo',
is_cooperative: false,
short_name: 'ExampleOrg',
full_name: 'Примерная организация',
represented_by: {
first_name: 'Иван',
last_name: 'Иванов',
middle_name: 'Иванович',
position: 'Директор',
based_on: 'Устава организации',
},
country: 'Russia',
city: 'Moscow',
full_address: '456 Main St, Moscow, Russia',
email: 'contact@exampleorg.com',
phone: '+71234567890',
details: {
inn: '0987654321',
ogrn: '0987654321098',
},
bank_account: {
account_number: '40817810099910004312',
currency: 'RUB',
card_number: '0987654321098765',
bank_name: 'Example Bank',
details: {
bik: '098765432',
corr: '30101810400000000225',
kpp: '098765432',
},
},
}
// it('генерируем заявление на вступление физического лица', async () => {
// const document: IGeneratedDocument = await generator.generate({
// code: 'registrator',
// action: 'joincoop',
// coopname: 'voskhod',
// username: 'ant',
// lang: 'ru',
// signature: signatureExample,
// })
const saved = await generator.save('organization', organizationData)
// const filename1 = `${document.meta.title}-${document.meta.username}.pdf`
// await saveBufferToDisk(document.binary, filename1)
const organization = await generator.get('organization', { username: organizationData.username }) as any
// const regenerated_document: IGeneratedDocument = await generator.generate({
// ...document.meta,
// })
// const filename2 = `regenerated-${document.meta.title}-${document.meta.username}.pdf`
// await saveBufferToDisk(regenerated_document.binary, filename2)
expect(organization._id).toEqual(saved.insertedId)
// expect(document.meta).toEqual(regenerated_document.meta)
// expect(document.hash).toEqual(regenerated_document.hash)
Object.keys(organizationData).forEach((field) => {
expect(organization[field]).toBeDefined()
})
})
// const document_from_disk1 = await loadBufferFromDisk(filename1)
// const document_from_disk2 = await loadBufferFromDisk(filename2)
it('генерируем заявление на вступление юридического лица', async () => {
const document: IGeneratedDocument = await generator.generate({
code: 'registrator',
action: 'joincoop',
coopname: 'voskhod',
username: 'exampleorg',
lang: 'ru',
signature: signatureExample,
})
// const hash1 = calculateSha256(document_from_disk1)
// const hash2 = calculateSha256(document_from_disk2)
const filename1 = `${document.meta.title}-${document.meta.username}.pdf`
await saveBufferToDisk(document.binary, filename1)
// const getted_document = await generator.getDocument({ hash: regenerated_document.hash })
const regenerated_document: IGeneratedDocument = await generator.generate({
...document.meta,
})
// expect(getted_document).toBeDefined()
// expect(getted_document.hash).toEqual(document.hash)
const filename2 = `regenerated-${document.meta.title}-${document.meta.username}.pdf`
await saveBufferToDisk(regenerated_document.binary, filename2)
// // console.log('hash1: ', hash1)
// // console.log('hash2: ', hash2)
// // console.log(document)
expect(document.meta).toEqual(regenerated_document.meta)
expect(document.hash).toEqual(regenerated_document.hash)
// expect(hash1).toEqual(hash2)
const document_from_disk1 = await loadBufferFromDisk(filename1)
const document_from_disk2 = await loadBufferFromDisk(filename2)
// const decision_document: IGeneratedDocument = await generator.generate({
// code: 'registrator',
// action: 'joincoopdec',
// coopname: 'voskhod',
// username: 'ant',
// lang: 'ru',
// decision_id: 1,
// })
const hash1 = calculateSha256(document_from_disk1)
const hash2 = calculateSha256(document_from_disk2)
// const filename3 = `${decision_document.meta.title}-${decision_document.meta.username}.pdf`
// await saveBufferToDisk(decision_document.binary, filename3)
// })
// console.log('hash1: ', hash1)
// console.log('hash2: ', hash2)
// console.log(document)
// it('сохранение данных организации', async () => {
// const organizationData: ExternalOrganizationData = {
// username: 'exampleorg',
// type: 'ooo',
// is_cooperative: false,
// short_name: 'ExampleOrg',
// full_name: 'Примерная организация',
// represented_by: {
// first_name: 'Иван',
// last_name: 'Иванов',
// middle_name: 'Иванович',
// position: 'Директор',
// based_on: 'Устава организации',
// },
// country: 'Russia',
// city: 'Moscow',
// full_address: '456 Main St, Moscow, Russia',
// email: 'contact@exampleorg.com',
// phone: '+71234567890',
// details: {
// inn: '0987654321',
// ogrn: '0987654321098',
// },
// bank_account: {
// account_number: '40817810099910004312',
// currency: 'RUB',
// card_number: '0987654321098765',
// bank_name: 'Example Bank',
// details: {
// bik: '098765432',
// corr: '30101810400000000225',
// kpp: '098765432',
// },
// },
// }
expect(hash1).toEqual(hash2)
// const saved = await generator.save('organization', organizationData)
const decision_document: IGeneratedDocument = await generator.generate({
code: 'registrator',
action: 'joincoopdec',
coopname: 'voskhod',
username: 'exampleorg',
lang: 'ru',
decision_id: 2,
})
// const organization = await generator.get('organization', { username: organizationData.username }) as any
const filename3 = `${decision_document.meta.title}-${decision_document.meta.username}.pdf`
await saveBufferToDisk(decision_document.binary, filename3)
})
// expect(organization._id).toEqual(saved.insertedId)
it('сохранение данных индивидуального предпринимателя', async () => {
const entrepreneurData: ExternalEntrepreneurData = {
username: 'entrepreneur',
first_name: 'John',
last_name: 'Doe',
middle_name: 'Middle',
birthdate: '2023-04-01',
phone: '+1234567890',
email: 'john.doe@example.com',
full_address: 'переулок правды д. 1',
country: 'Russia',
city: 'Moscow',
details: {
inn: '0987654321',
ogrn: '0987654321098',
},
bank_account: {
account_number: '40817810099910004312',
currency: 'RUB',
card_number: '0987654321098765',
bank_name: 'Example Bank',
details: {
bik: '098765432',
corr: '30101810400000000225',
kpp: '098765432',
},
},
}
// Object.keys(organizationData).forEach((field) => {
// expect(organization[field]).toBeDefined()
// })
// })
const saved = await generator.save('entrepreneur', entrepreneurData)
console.log(saved)
const entrepreneur = await generator.get('entrepreneur', { username: entrepreneurData.username }) as any
console.log(entrepreneur)
expect(entrepreneur._id).toEqual(saved.insertedId)
// it('генерируем заявление на вступление юридического лица', async () => {
// const document: IGeneratedDocument = await generator.generate({
// code: 'registrator',
// action: 'joincoop',
// coopname: 'voskhod',
// username: 'exampleorg',
// lang: 'ru',
// signature: signatureExample,
// })
Object.keys(entrepreneurData).forEach((field) => {
expect(entrepreneur[field]).toBeDefined()
})
})
// const filename1 = `${document.meta.title}-${document.meta.username}.pdf`
// await saveBufferToDisk(document.binary, filename1)
it('генерируем заявление на вступление индивидуального предпринимателя', async () => {
const document: IGeneratedDocument = await generator.generate({
code: 'registrator',
action: 'joincoop',
coopname: 'voskhod',
username: 'entrepreneur',
lang: 'ru',
signature: signatureExample,
})
// const regenerated_document: IGeneratedDocument = await generator.generate({
// ...document.meta,
// })
const filename1 = `${document.meta.title}-${document.meta.username}.pdf`
await saveBufferToDisk(document.binary, filename1)
// const filename2 = `regenerated-${document.meta.title}-${document.meta.username}.pdf`
// await saveBufferToDisk(regenerated_document.binary, filename2)
const regenerated_document: IGeneratedDocument = await generator.generate({
...document.meta,
})
// expect(document.meta).toEqual(regenerated_document.meta)
// expect(document.hash).toEqual(regenerated_document.hash)
const filename2 = `regenerated-${document.meta.title}-${document.meta.username}.pdf`
await saveBufferToDisk(regenerated_document.binary, filename2)
// const document_from_disk1 = await loadBufferFromDisk(filename1)
// const document_from_disk2 = await loadBufferFromDisk(filename2)
expect(document.meta).toEqual(regenerated_document.meta)
expect(document.hash).toEqual(regenerated_document.hash)
// const hash1 = calculateSha256(document_from_disk1)
// const hash2 = calculateSha256(document_from_disk2)
const document_from_disk1 = await loadBufferFromDisk(filename1)
const document_from_disk2 = await loadBufferFromDisk(filename2)
// // console.log('hash1: ', hash1)
// // console.log('hash2: ', hash2)
// // console.log(document)
const hash1 = calculateSha256(document_from_disk1)
const hash2 = calculateSha256(document_from_disk2)
// expect(hash1).toEqual(hash2)
// console.log('hash1: ', hash1)
// console.log('hash2: ', hash2)
// console.log(document)
// const decision_document: IGeneratedDocument = await generator.generate({
// code: 'registrator',
// action: 'joincoopdec',
// coopname: 'voskhod',
// username: 'exampleorg',
// lang: 'ru',
// decision_id: 2,
// })
expect(hash1).toEqual(hash2)
// const filename3 = `${decision_document.meta.title}-${decision_document.meta.username}.pdf`
// await saveBufferToDisk(decision_document.binary, filename3)
// })
const decision_document: IGeneratedDocument = await generator.generate({
code: 'registrator',
action: 'joincoopdec',
coopname: 'voskhod',
username: 'entrepreneur',
lang: 'ru',
decision_id: 3,
})
// it('сохранение данных индивидуального предпринимателя', async () => {
// const entrepreneurData: ExternalEntrepreneurData = {
// username: 'entrepreneur',
// first_name: 'John',
// last_name: 'Doe',
// middle_name: 'Middle',
// birthdate: '2023-04-01',
// phone: '+1234567890',
// email: 'john.doe@example.com',
// full_address: 'переулок правды д. 1',
// country: 'Russia',
// city: 'Moscow',
// details: {
// inn: '0987654321',
// ogrn: '0987654321098',
// },
// bank_account: {
// account_number: '40817810099910004312',
// currency: 'RUB',
// card_number: '0987654321098765',
// bank_name: 'Example Bank',
// details: {
// bik: '098765432',
// corr: '30101810400000000225',
// kpp: '098765432',
// },
// },
// }
const filename3 = `${decision_document.meta.title}-${decision_document.meta.username}.pdf`
await saveBufferToDisk(decision_document.binary, filename3)
})
// const saved = await generator.save('entrepreneur', entrepreneurData)
// console.log(saved)
// const entrepreneur = await generator.get('entrepreneur', { username: entrepreneurData.username }) as any
// console.log(entrepreneur)
// expect(entrepreneur._id).toEqual(saved.insertedId)
// Object.keys(entrepreneurData).forEach((field) => {
// expect(entrepreneur[field]).toBeDefined()
// })
// })
// it('генерируем заявление на вступление индивидуального предпринимателя', async () => {
// const document: IGeneratedDocument = await generator.generate({
// code: 'registrator',
// action: 'joincoop',
// coopname: 'voskhod',
// username: 'entrepreneur',
// lang: 'ru',
// signature: signatureExample,
// })
// const filename1 = `${document.meta.title}-${document.meta.username}.pdf`
// await saveBufferToDisk(document.binary, filename1)
// const regenerated_document: IGeneratedDocument = await generator.generate({
// ...document.meta,
// })
// const filename2 = `regenerated-${document.meta.title}-${document.meta.username}.pdf`
// await saveBufferToDisk(regenerated_document.binary, filename2)
// expect(document.meta).toEqual(regenerated_document.meta)
// expect(document.hash).toEqual(regenerated_document.hash)
// const document_from_disk1 = await loadBufferFromDisk(filename1)
// const document_from_disk2 = await loadBufferFromDisk(filename2)
// const hash1 = calculateSha256(document_from_disk1)
// const hash2 = calculateSha256(document_from_disk2)
// // console.log('hash1: ', hash1)
// // console.log('hash2: ', hash2)
// // console.log(document)
// expect(hash1).toEqual(hash2)
// const decision_document: IGeneratedDocument = await generator.generate({
// code: 'registrator',
// action: 'joincoopdec',
// coopname: 'voskhod',
// username: 'entrepreneur',
// lang: 'ru',
// decision_id: 3,
// })
// const filename3 = `${decision_document.meta.title}-${decision_document.meta.username}.pdf`
// await saveBufferToDisk(decision_document.binary, filename3)
// })
})
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.21](https://github.com/coopenomics/cooptypes/compare/cooptypes@1.0.20...cooptypes@1.0.21) (2024-08-25)
**Note:** Version bump only for package cooptypes
## [1.0.20](https://github.com/coopenomics/cooptypes/compare/cooptypes@1.0.20-alpha.1...cooptypes@1.0.20) (2024-08-25)
**Note:** Version bump only for package cooptypes
## [1.0.19](https://github.com/coopenomics/cooptypes/compare/cooptypes@1.0.18...cooptypes@1.0.19) (2024-08-13)
**Note:** Version bump only for package cooptypes
+4 -4
View File
@@ -68,7 +68,7 @@ api.getTableRows(
})
```
Те же параметры scope, table, code могут быть использованы для получения информации из модуля [COOPARSER](https://github.com/copenomics/cooparser). Последнее используется, когда необходимо получить исторические данные и нет необходимости проверять их актуальность по наличию таблиц в блокчейне. Однако, таблицы в блокчейне необходимо всегда проверять перед отправкой любой транзакции действия. Нельзя полагаться на данные из парсера при подготовке транзакции действия.
Те же параметры scope, table, code могут быть использованы для получения информации из модуля [COOPARSER](https://github.com/coopenomics/cooparser). Последнее используется, когда необходимо получить исторические данные и нет необходимости проверять их актуальность по наличию таблиц в блокчейне. Однако, таблицы в блокчейне необходимо всегда проверять перед отправкой любой транзакции действия. Нельзя полагаться на данные из парсера при подготовке транзакции действия.
### Транзакция действий
Состояние любого смарт-контракта может изменяться только с помощью действий. Для того, чтобы совершить действия, необходимо сформировать и отправить транзакцию с помощью библиотеки eosjs или альтернатив.
@@ -113,7 +113,7 @@ const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), te
## Лицензия
[MIT](./LICENSE) License © 2024-PRESENT [CBS VOSKHOD](https://github.com/copenomics)
[MIT](./LICENSE) License © 2024-PRESENT [CBS VOSKHOD](https://github.com/coopenomics)
<!-- Badges -->
@@ -123,7 +123,7 @@ const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), te
[npm-downloads-href]: https://npmjs.com/package/cooptypes
[bundle-src]: https://img.shields.io/bundlephobia/minzip/cooptypes?style=flat&colorA=080f12&colorB=1fa669&label=minzip
[bundle-href]: https://bundlephobia.com/result?p=cooptypes
[license-src]: https://img.shields.io/github/license/copenomics/cooptypes.svg?style=flat&colorA=080f12&colorB=1fa669
[license-href]: https://github.com/copenomics/cooptypes/blob/main/LICENSE
[license-src]: https://img.shields.io/github/license/coopenomics/cooptypes.svg?style=flat&colorA=080f12&colorB=1fa669
[license-href]: https://github.com/coopenomics/cooptypes/blob/main/LICENSE
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
[jsdocs-href]: https://www.jsdocs.io/package/cooptypes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "cooptypes",
"type": "module",
"version": "1.0.19",
"version": "1.0.21",
"description": "_description_",
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
"license": "MIT",
@@ -0,0 +1,15 @@
import * as Permissions from '../../../common/permissions'
import type * as Registrator from '../../../interfaces/registrator'
import { Actors } from '../../../common'
export const authorizations = [{ permissions: [Permissions.active, Permissions.special], actor: Actors._admin }] as const
/**
* Имя действия
*/
export const actionName = 'delcoop'
/**
* @interface
*/
export type IDeleteCooperative = Registrator.IDelcoop
@@ -55,3 +55,15 @@ export * as Init from './init'
* @private
*/
export * as AddUser from './addUser'
/**
* Действие изменения статуса подключенного кооператива.
* @private
*/
export * as SetCoopStatus from './setCoopStatus'
/**
* Удаление кооператива из реестра подключений
* @private
*/
export * as DeleteCooperative from './deleteCooperative'
@@ -0,0 +1,15 @@
import * as Permissions from '../../../common/permissions'
import type * as Registrator from '../../../interfaces/registrator'
import { Actors } from '../../../common'
export const authorizations = [{ permissions: [Permissions.active, Permissions.special], actor: Actors._admin }] as const
/**
* Имя действия
*/
export const actionName = 'stcoopstatus'
/**
* @interface
*/
export type ISetCoopStatus = Registrator.IStcoopstatus
@@ -0,0 +1,21 @@
import * as Permissions from '../../../../common/permissions'
import type * as Soviet from '../../../../interfaces/soviet'
import { Actors } from '../../../../common'
/**
* Действие выполняется за подписью {@link Actors._admin | администратора}.
*/
export const authorizations = [
{ permissions: [Permissions.active, Permissions.special], actor: Actors._admin },
] as const
/**
* Имя действия
*/
export const actionName = 'cnfrmindoc'
/**
* @interface
* Действие подтверждает приём заявления администратором
*/
export type IConfirmIncomeDocument = Soviet.ICnfrmindoc
@@ -0,0 +1,21 @@
import * as Permissions from '../../../../common/permissions'
import type * as Soviet from '../../../../interfaces/soviet'
import { Actors } from '../../../../common'
/**
* Действие выполняется за подписью {@link Actors._admin | администратора}.
*/
export const authorizations = [
{ permissions: [Permissions.active, Permissions.special], actor: Actors._admin },
] as const
/**
* Имя действия
*/
export const actionName = 'declnindoc'
/**
* @interface
* Действие отклоняет заявление пайщика администратором
*/
export type IDeclineIncomeDocument = Soviet.IDeclnindoc
@@ -23,3 +23,13 @@ export * as SetRights from './setRights'
* @private
*/
export * as Init from './init'
/**
* Действие подтверждения приёма заявления пайщика
*/
export * as ConfirmIncomeDocument from './confirmIncomeDocument'
/**
* Действие отклонения приёма заявления пайщика
*/
export * as DeclineIncomeDocument from './declineIncomeDocument'
@@ -16,6 +16,6 @@ export const actionName = 'createprog'
/**
* @interface
* Действие редактирует целевую потребительскую программу маркетплейса.
* Действие редактирует целевую потребительскую программу.
*/
export type ICreateMarketProgram = Soviet.ICreateprog
export type ICreateProgram = Soviet.ICreateprog
@@ -1,14 +1,19 @@
/**
* Действие создаёт целевую потребительскую программу маркетплейса.
* Действие создаёт целевую потребительскую маркетплейса.
*/
export * as CreateMarketProgram from './createMarketProgram'
export * as CreateProgram from './createProgram'
/**
* Действие редактирует целевую потребительскую программу маркетплейса.
*/
export * as EditMarketProgram from './editMarketProgram'
export * as EditProgram from './editProgram'
/**
* Действие отключает целевую потребительскую программу маркетплейса.
*/
export * as DisableMarketProgram from './disableMarketProgram'
export * as DisableProgram from './disableProgram'
/**
* Действие отправки заявления на присоединение к ЦПП Кооператива
*/
export * as JoinProgram from './joinProgram'
@@ -0,0 +1,20 @@
import * as Permissions from '../../../../common/permissions'
import type * as Soviet from '../../../../interfaces/soviet'
import { Actors } from '../../../../common'
/**
* Действие выполняется за подписью любого {@link Actors._username | пользователя}.
*/
export const authorizations = [
{ permissions: [Permissions.active], actor: Actors._username },
] as const
/**
* Имя действия
*/
export const actionName = 'joinprog'
/**
* Действие отправки заявления на присоединение к ЦПП кооператива
*/
export type IJoinProgram = Soviet.IJoinprog
@@ -0,0 +1,17 @@
import type * as Soviet from '../../../interfaces/soviet'
import { Actors } from '../../../common'
/**
* Имя таблицы
*/
export const tableName = 'indocuments'
/**
* Таблица хранится в {@link Actors._coopname | области памяти кооператива}.
*/
export const scope = Actors._coopname
/**
* @interface
*/
export type IIncomeDocument = Soviet.IIndocument
@@ -39,9 +39,9 @@ export * as Decisions from './decisions'
export * as JoinCoops from './joinCoops'
/**
* Таблица хранит целевые потребительские программы контракта маркетплейса.
* Таблица хранит целевые потребительские программы.
*/
export * as MarketPrograms from './marketPrograms'
export * as Programs from './programs'
/**
* Таблица хранит информацию о пайщиках.
@@ -57,3 +57,8 @@ export * as ProgramWallets from './programWallets'
* Таблица содержит сводный баланс пайщиков кооператива.
*/
export * as Wallets from './wallets'
/**
* Таблица содержит заявления пайщиков кооператива, которые ожидают приёма, но не требуют решения совета.
*/
export * as IncomeDocuments from './incomeDocuments'
@@ -15,4 +15,4 @@ export const scope = Actors._coopname
* @interface
* Таблица хранит публичную часть реестра пайщиков кооператива.
*/
export type IParticipants = Soviet.IParticipants
export type IParticipants = Soviet.IParticipant
@@ -4,7 +4,7 @@ import { Actors } from '../../../common'
/**
* Имя таблицы
*/
export const tableName = 'progcomarket'
export const tableName = 'programs'
/**
* Таблица хранится в {@link Actors._coopname | области памяти кооператива}.
@@ -15,4 +15,4 @@ export const scope = Actors._coopname
* @interface
* Таблица хранит целевые потребительские программы контракта маркетплейса.
*/
export type IMarketPrograms = Soviet.IProgcomarket
export type IProgram = Soviet.IProgram
@@ -72,6 +72,14 @@ export interface IComplexAgenda extends IAgenda {
documents: IComplexDocument
}
export interface IGetResponse<T> {
results: T[]
page: number
limit: number
totalResults: number
totalPages: number
}
/**
* Общий интерфейс для генерации/регенерации документа
*/
@@ -92,10 +100,9 @@ export interface IGenerateJoinCoopDecision extends IGenerate {
decision_id: number
}
export interface IGetResponse<T> {
results: T[]
page: number
limit: number
totalResults: number
totalPages: number
/** Интерфейс генерации документа для присоединения к программе ЦПП */
export interface IGenerateJoinProgram extends IGenerate {
registry_id: number
protocol_number: string
protocol_day_month_year: string
}
@@ -13,6 +13,8 @@ export interface ICountsBase {
}
export interface ICreatedraft {
scope: IName
username: IName
registry_id: IUint64
lang: IName
title: string
@@ -23,25 +25,37 @@ export interface ICreatedraft {
}
export interface ICreatetrans {
scope: IName
username: IName
draft_id: IUint64
lang: IName
data: string
}
export interface IDeldraft {
scope: IName
username: IName
draft_id: IUint64
}
export interface IDeltrans {
scope: IName
username: IName
translate_id: IUint64
}
export interface IEdittrans {
scope: IName
username: IName
translate_id: IUint64
data: string
}
export interface IMigrate {
}
export interface INewid {
scope: IName
id: IUint64
}
@@ -69,6 +69,13 @@ export interface ICooperative {
org_registration: IAsset
org_initial: IAsset
org_minimum: IAsset
status: IName
created_at: ITimePointSec
}
export interface IDelcoop {
registrator: IName
coopname: IName
}
export interface IDocument {
@@ -114,7 +121,6 @@ export interface IOrgData {
export interface IRegcoop {
registrator: IName
coopname: IName
username: IName
params: IOrgData
}
@@ -125,6 +131,12 @@ export interface IReguser {
type: IName
}
export interface IStcoopstatus {
coopname: IName
username: IName
status: IName
}
export interface IUpdateaccnt {
username: IName
account_to_change: IName
+94 -10
View File
@@ -24,6 +24,7 @@ export interface IAddprogbal {
export interface IAddress {
id: IUint64
coopname: IName
braname: IName
data: IAddressData
}
@@ -54,6 +55,16 @@ export interface IAddstaff {
position_title: string
}
export interface IAdduser {
coopname: IName
username: IName
type: IName
created_at: ITimePointSec
initial: IAsset
minimum: IAsset
spread_initial: boolean
}
export interface IAuthorize {
coopname: IName
chairman: IName
@@ -129,6 +140,13 @@ export interface IChanges {
return_product_decision_id: IUint64
}
export interface ICnfrmindoc {
coopname: IName
registrator: IName
username: IName
indoc_id: IUint64
}
export interface ICounts extends ICountsBase {
}
@@ -141,21 +159,35 @@ export interface ICountsBase {
export interface ICreaddress {
coopname: IName
chairman: IName
braname: IName
data: IAddressData
}
export interface ICreateboard {
coopname: IName
chairman: IName
username: IName
type: IName
members: IBoardMember[]
name: string
description: string
}
export interface ICreateprog {
export interface ICreatebranch {
coopname: IName
chairman: IName
braname: IName
name: string
description: string
authorizer: IName
trusted: IName[]
}
export interface ICreateprog {
coopname: IName
username: IName
program_type: IName
draft_registry_id: IUint64
hash_of_conditions: IChecksum256
title: string
announce: string
description: string
@@ -164,6 +196,7 @@ export interface ICreateprog {
calculation_type: IName
fixed_membership_contribution: IAsset
membership_percent_fee: IUint64
meta: string
}
export interface IDecision {
@@ -183,15 +216,29 @@ export interface IDecision {
created_at: ITimePointSec
}
export interface IDeclnindoc {
coopname: IName
registrator: IName
username: IName
indoc_id: IUint64
comment: string
}
export interface IDeladdress {
coopname: IName
chairman: IName
address_id: IUint64
}
export interface IDeletebranch {
coopname: IName
chairman: IName
braname: IName
}
export interface IDisableprog {
coopname: IName
id: IUint64
program_id: IUint64
}
export interface IDisautomate {
@@ -211,18 +258,33 @@ export interface IDocument {
export interface IEditaddress {
coopname: IName
chairman: IName
braname: IName
address_id: IUint64
data: IAddressData
}
export interface IEditbranch {
coopname: IName
chairman: IName
braname: IName
name: string
description: string
authorizer: IName
trusted: IName[]
}
export interface IEditprog {
coopname: IName
id: IUint64
username: IName
program_id: IUint64
draft_registry_id: IUint64
hash_of_conditions: IChecksum256
title: string
announce: string
description: string
preview: string
images: string
meta: string
}
export interface IExec {
@@ -231,9 +293,6 @@ export interface IExec {
decision_id: IUint64
}
export interface IFix {
}
export interface IFundwithdraw {
coopname: IName
username: IName
@@ -242,6 +301,15 @@ export interface IFundwithdraw {
document: IDocument
}
export interface IIndocument {
id: IUint64
coopname: IName
username: IName
type: IName
secondary_id: IUint64
document: IDocument
}
export interface IInit {
}
@@ -258,6 +326,16 @@ export interface IJoincoops {
notice: string
}
export interface IJoinprog {
coopname: IName
username: IName
document: IDocument
program_id: IUint64
}
export interface IMigrate {
}
export interface INewact {
coopname: IName
username: IName
@@ -309,7 +387,7 @@ export interface IOnewallet {
minimum: IAsset
}
export interface IParticipants {
export interface IParticipant {
username: IName
created_at: ITimePointSec
last_update: ITimePointSec
@@ -321,9 +399,12 @@ export interface IParticipants {
type: IName
}
export interface IProgcomarket {
export interface IProgram {
id: IUint64
coopname: IName
program_type: IName
draft_registry_id: IUint64
hash_of_conditions: IChecksum256
is_active: boolean
title: string
announce: string
@@ -334,6 +415,8 @@ export interface IProgcomarket {
calculation_type: IName
membership_percent_fee: IUint64
fixed_membership_contribution: IAsset
start_at: ITimePointSec
expired_at: ITimePointSec
}
export interface IProgwallet {
@@ -342,6 +425,7 @@ export interface IProgwallet {
program_id: IUint64
username: IName
available: IAsset
document: IDocument
}
export interface IRecieved {
@@ -402,7 +486,7 @@ export interface IUnblockbal {
export interface IUpdateboard {
coopname: IName
chairman: IName
username: IName
board_id: IUint64
members: IBoardMember[]
name: string
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.0.25](https://github.com/copenomics/coop-notificator/compare/coop-notificator@0.0.24...coop-notificator@0.0.25) (2024-08-25)
**Note:** Version bump only for package coop-notificator
## [0.0.24](https://github.com/copenomics/coop-notificator/compare/coop-notificator@0.0.24-alpha.1...coop-notificator@0.0.24) (2024-08-25)
**Note:** Version bump only for package coop-notificator
## [0.0.23](https://github.com/copenomics/coop-notificator/compare/coop-notificator@0.0.22...coop-notificator@0.0.23) (2024-08-13)
**Note:** Version bump only for package coop-notificator
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "coop-notificator",
"type": "module",
"version": "0.0.23",
"version": "0.0.25",
"private": true,
"packageManager": "pnpm@9.1.1",
"description": "_description_",
+2 -2
View File
@@ -5,10 +5,10 @@
"editor.tabCompletion": "onlySnippets",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": ["source.fixAll.eslint"],
"eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
"eslint.validate": ["javascript", "typescript", "vue"],
"typescript.tsdk": "node_modules/typescript/lib",
"i18n-ally.localesPaths": ["src/i18n"],
"typescript.format.enable": true,
"typescript.format.indentSwitchCase": false,
"typescript.validate.enable": true
"typescript.validate.enable": true,
}
+32
View File
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.1.38](https://github.com/coopenomics/monocoop/compare/terminal@0.1.37...terminal@0.1.38) (2024-08-25)
**Note:** Version bump only for package terminal
## [0.1.37](https://github.com/coopenomics/monocoop/compare/terminal@0.1.36...terminal@0.1.37) (2024-08-25)
**Note:** Version bump only for package terminal
## [0.1.36](https://github.com/coopenomics/monocoop/compare/terminal@0.1.35...terminal@0.1.36) (2024-08-25)
**Note:** Version bump only for package terminal
## [0.1.35](https://github.com/coopenomics/monocoop/compare/terminal@0.1.35-alpha.1...terminal@0.1.35) (2024-08-25)
**Note:** Version bump only for package terminal
## [0.1.34](https://github.com/coopenomics/monocoop/compare/terminal@0.1.33...terminal@0.1.34) (2024-08-13)
**Note:** Version bump only for package terminal
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "terminal",
"version": "0.1.34",
"version": "0.1.38",
"description": "A Terminal Project",
"productName": "Terminal App",
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
+5 -1
View File
@@ -1,5 +1,7 @@
<template lang='pug'>
router-view(v-if="isLoaded")
div
router-view(v-if="isLoaded")
RootPopup
</template>
<script setup lang="ts">
@@ -13,6 +15,8 @@ import { Cookies, LocalStorage, QSpinner, useQuasar } from 'quasar';
import { COOPNAME } from 'src/shared/config';
import { useCardStore } from './providers/card/store';
import { RootPopup } from 'src/widgets/Desktop/RootPopup';
const $q = useQuasar()
const router = useRouter()
@@ -33,6 +33,10 @@ export default route(async function (/* { store, ssrContext } */) {
const { initWallet } = useCardStore()
await initWallet()
const currentUser = useCurrentUserStore();
const session = useSessionStore();
console.log('on load desktops', currentUser)
await desktops.loadDesktops()
await desktops.setActiveDesktop(desktops.defaultDesktopHash)
@@ -63,13 +67,8 @@ export default route(async function (/* { store, ssrContext } */) {
from: RouteLocationNormalizedGeneric,
next: any
) => {
console.log('on router before')
desktops.healthCheck()
const { initWallet } = useCardStore()
await initWallet()
const currentUser = useCurrentUserStore();
const session = useSessionStore();
/** проверяем установлено ли приложение и не переход ли это на страницу установки */
if (desktops.health?.status === 'install' && to.name !== 'install') {
@@ -2,12 +2,12 @@ import layout from 'src/pages/_layouts/default.vue';
import index from 'src/pages/index.vue';
import blank from 'src/pages/blank/blank.vue';
import permissionDenied from 'src/pages/_layouts/permissionDenied.vue';
import { SignUpPage } from 'src/pages/SignUp';
import { SignInPage } from 'src/pages/SignIn';
import { SignUpPage } from 'src/pages/Registrator/SignUp';
import { SignInPage } from 'src/pages/Registrator/SignIn';
import { RouteRecordRaw } from 'vue-router';
import { InstallCooperativePage } from 'src/pages/Install';
import { LostKeyPage } from 'src/pages/Auth/LostKey/ui';
import { ResetKeyPage } from 'src/pages/Auth/ResetKey';
import { InstallCooperativePage } from 'src/pages/Installer';
import { LostKeyPage } from 'src/pages/Registrator/LostKey/ui';
import { ResetKeyPage } from 'src/pages/Registrator/ResetKey';
const baseRoutes = [
@@ -18,7 +18,7 @@ div.menu-container
q-icon(:name="isDark ? 'brightness_7' : 'brightness_3'").q-pt-xs.btn-icon
span.btn-font {{ isDark ? 'светлая' : 'тёмная' }}
q-btn(v-ripple flat class="cursor-pointer btn-menu" @click="logout")
q-btn(flat class="cursor-pointer btn-menu" @click="logout")
q-icon( color="red" name="logout").q-pt-xs.btn-icon
div.btn-font Выход
@@ -29,7 +29,7 @@ import { computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useQuasar } from 'quasar'
import { COOPNAME } from 'src/shared/config'
import { useLogoutUser } from 'src/features/User/Logout'
import { useLogoutUser } from 'src/features/Registrator/Logout'
import { FailAlert } from 'src/shared/api'
import { useCurrentUserStore } from 'src/entities/User'
import { type IRoute } from 'src/entities/Desktop/model/types'
@@ -22,6 +22,7 @@ import { ChangeCooperativeContributions } from 'src/widgets/Cooperative/Contribu
import { ChangeCooperativeContacts } from 'src/widgets/Cooperative/Contacts';
import { UserSettingsPage } from 'src/pages/User/SettingsPage';
import { ListOfParticipantsPage } from 'src/pages/Cooperative/ListOfParticipants';
import { UnionPageListOfCooperatives } from 'src/pages/Union/ListOfCooperatives';
export const manifest = {
'name': 'UserDesktop',
@@ -42,6 +43,7 @@ export const manifest = {
title: 'Удостоверение',
icon: '',
roles: [],
programs: ['wallet']
},
path: 'identity',
name: 'user-identity',
@@ -180,7 +182,17 @@ export const manifest = {
]
},
{
meta: {
title: 'Подключения',
icon: 'fas fa-link',
roles: ['chairman', 'member'],
},
path: '/:coopname/connections',
name: 'connections',
component: markRaw(UnionPageListOfCooperatives),
},
// {
@@ -3,20 +3,20 @@ import { ContractsList, TablesList } from 'src/shared/config';
import {
IAddressesData,
IAdministratorData,
ICoopMarketProgramData,
ILoadCoopMarketPrograms,
ICoopProgramData,
ILoadCoopPrograms,
ILoadCooperativeAddresses,
} from '../model';
import {Cooperative, FundContract, RegistratorContract } from 'cooptypes';
import {Cooperative, FundContract, RegistratorContract, SovietContract } from 'cooptypes';
async function loadMarketPrograms(
params: ILoadCoopMarketPrograms
): Promise<ICoopMarketProgramData[]> {
async function loadPrograms(
params: ILoadCoopPrograms
): Promise<ICoopProgramData[]> {
return (await fetchTable(
ContractsList.Soviet,
SovietContract.contractName.production,
params.coopname,
TablesList.CoopMarketPrograms
)) as ICoopMarketProgramData[];
SovietContract.Tables.Programs.tableName
)) as ICoopProgramData[];
}
async function loadAdmins(coopname: string): Promise<IAdministratorData[]> {
@@ -94,7 +94,7 @@ async function loadCooperativeAddresses(
}
export const api = {
loadMarketPrograms,
loadPrograms,
loadCooperativeAddresses,
loadPublicCooperativeData,
loadAdmins,
@@ -1,10 +1,10 @@
import { defineStore } from 'pinia';
import { Ref, ref } from 'vue';
import { Ref, ref, ComputedRef, computed } from 'vue';
import { api } from '../api';
import {
IAddressesData,
ICoopMarketProgramData,
ILoadCoopMarketPrograms,
ICoopProgramData,
ILoadCoopPrograms,
ILoadCooperativeAddresses,
IAdministratorData,
} from './types';
@@ -16,14 +16,14 @@ interface ICooperativeStore {
// методы
loadFunds: (coopname: string) => Promise<void>;
loadAddresses: (params: ILoadCooperativeAddresses) => Promise<void>;
loadMarketPrograms: (params: ILoadCoopMarketPrograms) => Promise<void>;
loadPrograms: (params: ILoadCoopPrograms) => Promise<void>;
loadPrivateCooperativeData: () => Promise<void>;
loadContacts: () => Promise<void>;
loadPublicCooperativeData: (coopname: string) => Promise<void>;
loadAdmins: (coopname: string) => Promise<void>;
// данные
admins: Ref<IAdministratorData[]>;
marketPrograms: Ref<ICoopMarketProgramData[]>;
programs: Ref<ICoopProgramData[]>;
addresses: Ref<IAddressesData[]>;
contacts: Ref<Cooperative.Model.IContacts | undefined>
publicCooperativeData: Ref<RegistratorContract.Tables.Cooperatives.ICooperative | undefined>;
@@ -32,12 +32,14 @@ interface ICooperativeStore {
coopWallet: Ref<FundContract.Tables.CoopWallet.ICoopWallet | undefined>
accumulationFunds: Ref<FundContract.Tables.AccumulatedFunds.IAccumulatedFund[]>
expenseFunds: Ref<FundContract.Tables.ExpensedFunds.IExpensedFund[]>
governSymbol: ComputedRef<string>
}
export const useCooperativeStore = defineStore(
namespace,
(): ICooperativeStore => {
const marketPrograms = ref([] as ICoopMarketProgramData[]);
const programs = ref([] as ICoopProgramData[]);
const addresses = ref([] as IAddressesData[]);
const admins = ref([] as IAdministratorData[]);
const publicCooperativeData = ref<RegistratorContract.Tables.Cooperatives.ICooperative>();
@@ -46,6 +48,13 @@ export const useCooperativeStore = defineStore(
const accumulationFunds = ref<FundContract.Tables.AccumulatedFunds.IAccumulatedFund[]>([])
const expenseFunds = ref<FundContract.Tables.ExpensedFunds.IExpensedFund[]>([])
const governSymbol = computed(() => {
if (publicCooperativeData.value) {
const [, symbol] = publicCooperativeData.value.initial.split(' ')
return symbol
} else return ''
})
const contacts = ref<Cooperative.Model.IContacts>()
const loadFunds = async(coopname: string) : Promise<void> => {
@@ -74,10 +83,10 @@ export const useCooperativeStore = defineStore(
);
};
const loadMarketPrograms = async (
params: ILoadCoopMarketPrograms
const loadPrograms = async (
params: ILoadCoopPrograms
): Promise<void> => {
marketPrograms.value = await api.loadMarketPrograms(params);
programs.value = await api.loadPrograms(params);
};
const loadAddresses = async (
@@ -92,19 +101,19 @@ export const useCooperativeStore = defineStore(
return {
loadFunds,
loadMarketPrograms,
loadPrograms,
loadAddresses,
loadContacts,
loadPublicCooperativeData,
loadPrivateCooperativeData,
marketPrograms,
programs,
addresses,
contacts,
privateCooperativeData,
publicCooperativeData,
loadAdmins,
admins,
governSymbol,
coopWallet,
accumulationFunds,
expenseFunds
@@ -1,11 +1,11 @@
import { SovietContract } from 'cooptypes';
import { IUser } from 'src/shared/lib/types/user';
export type ICoopMarketProgramData =
SovietContract.Tables.MarketPrograms.IMarketPrograms;
export type ICoopProgramData =
SovietContract.Tables.Programs.IProgram;
export type IAddressesData = SovietContract.Tables.Addresses.IAddress;
export interface ILoadCoopMarketPrograms {
export interface ILoadCoopPrograms {
coopname: string;
}
@@ -1,10 +1,17 @@
import { defineStore } from 'pinia';
import { reactive } from 'vue';
import { IIndividualData } from 'src/shared/lib/types/user/IUserData';
import { Ref, ref } from 'vue';
interface data {
id: number,
role: string,
type: 'individual',
individual_data: IIndividualData
}
interface IInstallCooperative {
data: {
wif: string
}
is_finish: Ref<boolean>
soviet: Ref<data[]>
}
const namespace = 'install';
@@ -13,12 +20,12 @@ export const useInstallCooperativeStore = defineStore(
namespace,
(): IInstallCooperative => {
const data = reactive({
wif: ''
})
const soviet = ref([])
const is_finish = ref(false)
return {
data
soviet,
is_finish
}
}, {
persist: true,
@@ -0,0 +1,2 @@
export * from './ui'
export * from './model'
@@ -0,0 +1 @@
export * from './store'
@@ -0,0 +1,159 @@
import { defineStore } from 'pinia';
import { reactive } from 'vue';
import { IGeneratedAccount } from 'src/shared/lib/types/user';
import { IUserData } from 'src/shared/lib/types/user/IUserData';
const namespace = 'registrator';
function clearObjectValues(obj: any): any {
for (const key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
clearObjectValues(obj[key]); // рекурсивный вызов
} else if (typeof obj[key] === 'string' && obj[key] !== '') {
obj[key] = '';
} else if (typeof obj[key] === 'boolean') {
obj[key] = false;
}
}
return obj;
}
export const useRegistratorStore = defineStore(
namespace,
() => {
const state = reactive({
step: 1,
role: 'user',
email: '',
account: { username: '', private_key: '', public_key: '' } as IGeneratedAccount,
userData: {
type: 'individual',
individual_data: {
first_name: '',
last_name: '',
middle_name: '',
birthdate: '',
full_address: '',
phone: '',
email: '',
},
organization_data: {
type: 'coop', // или другой тип, если нужно
is_cooperative: false,
short_name: '',
full_name: '',
represented_by: {
first_name: '',
last_name: '',
middle_name: '',
position: '',
based_on: '',
},
country: 'Russia', // или 'Other'
city: '',
full_address: '',
phone: '',
email: '',
details: {
inn: '',
ogrn: '',
},
bank_account: {
currency: 'RUB', // или 'Other'
card_number: undefined,
bank_name: '',
account_number: '',
details: {
bik: '',
corr: '',
kpp: '',
},
},
},
entrepreneur_data: {
first_name: '',
last_name: '',
middle_name: '',
birthdate: '',
phone: '',
email: '',
country: 'Russia', // или 'Other'
city: '',
full_address: '',
details: {
inn: '',
ogrn: '',
},
bank_account: {
currency: 'RUB', // или 'Other'
card_number: undefined,
bank_name: '',
account_number: '',
details: {
bik: '',
corr: '',
kpp: '',
},
},
},
} as IUserData,
signature: '',
inLoading: false,
agreements: {
condidential: false,
digital_signature: false,
wallet: false,
ustav: false,
user: false,
self_paid: false,
},
statement: {
hash: '',
meta: {},
public_key: '',
signature: '',
},
payment: {
provider: 'yookassa',
details: {
token: '',
url: '',
},
},
is_paid: false,
});
const clearAddUserState = () => reactive({
spread_initial: false,
created_at: '',
initial: 0,
minimum: 0,
org_initial: 0,
org_minimum: 0
})
const addUserState = clearAddUserState()
const clearUserData = () => {
state.step = 1
state.email = ''
state.account = clearObjectValues(state.account);
state.userData = clearObjectValues(state.userData);
state.payment.provider = 'yookassa'
}
return {
state,
addUserState,
clearUserData,
clearAddUserState
};
},
{
persist: true,
}
);
@@ -0,0 +1 @@
export * from '../../../shared/ui/UserDataForm/UserDataForm'
@@ -4,7 +4,7 @@ import { computed, ComputedRef, Ref, ref } from 'vue';
import { Session } from '@wharfkit/session';
import { WalletPluginPrivateKey } from '@wharfkit/wallet-plugin-privatekey';
import { FailAlert, readBlockchain } from 'src/shared/api';
import { CHAIN_ID, CHAIN_URL } from 'src/shared/config';
import { CHAIN_ID, CHAIN_URL, SYSTEM_TOKEN } from 'src/shared/config';
import { PrivateKey, Serializer } from '@wharfkit/antelope';
import { GetInfoResult } from 'eosjs/dist/eosjs-rpc-interfaces';
@@ -64,6 +64,7 @@ export const useSessionStore = defineStore('session', (): ISessionStore => {
chain: {
id: CHAIN_ID,
url: CHAIN_URL,
systemToken: SYSTEM_TOKEN
},
walletPlugin: new WalletPluginPrivateKey(
globalStore.wif as PrivateKey
@@ -0,0 +1 @@
export * from './store'
@@ -0,0 +1,19 @@
import { RegistratorContract } from 'cooptypes'
import { defineStore } from 'pinia'
const namespace = 'union'
export const useUnionStore = defineStore(
namespace,
() => {
const coops = [] as RegistratorContract.Tables.Cooperatives.ICooperative[]
return {
coops
}
},
{
persist: false
}
)
@@ -1,16 +1,6 @@
import { RegistratorContract, Cooperative } from 'cooptypes';
import { RegistratorContract } from 'cooptypes';
import { AccountResult } from 'eosjs/dist/eosjs-rpc-interfaces';
export type IEntrepreneurData = Cooperative.Users.IEntrepreneurData;
export type IIndividualData = Cooperative.Users.IIndividualData;
export type IOrganizationData = Cooperative.Users.IOrganizationData;
export interface IUserData {
type: 'individual' | 'entrepreneur' | 'organization';
entrepreneur_data?: IEntrepreneurData;
individual_data?: IIndividualData;
organization_data?: IOrganizationData;
}
import { IEntrepreneurData, IIndividualData, IOrganizationData } from 'src/shared/lib/types/user/IUserData';
export interface ILoadPrivateProfile {
coopname: string;
@@ -28,7 +18,7 @@ export interface IPrivateProfile {
export interface IUserAccountData {
username: string;
status: 'created' | 'joined' | 'payed' | 'registered' | 'active' | 'blocked';
status: 'created' | 'joined' | 'payed' | 'registered' | 'active' | 'blocked' | 'failed';
is_registered: boolean;
type: 'individual' | 'entrepreneur' | 'organization';
public_key: string;
@@ -12,7 +12,7 @@ import {
IDepositData,
IWithdrawData,
IProgramWalletData,
ICoopMarketProgramData,
ICoopProgramData,
ExtendedProgramWalletData,
IGetPaymentMethods,
IGetResponsePaymentMethodData,
@@ -28,6 +28,7 @@ import {
ILoadUserProgramWallets,
ILoadUserWithdraws,
} from '../model';
import { SovietContract } from 'cooptypes';
async function loadSingleUserWalletData(
params: ILoadSingleUserWallet
@@ -121,15 +122,15 @@ async function loadUserProgramWalletsData(
params: ILoadUserProgramWallets
): Promise<ExtendedProgramWalletData[]> {
const programs = (await fetchTable(
ContractsList.Soviet,
SovietContract.contractName.production,
params.coopname,
TablesList.CoopMarketPrograms
)) as ICoopMarketProgramData[];
SovietContract.Tables.Programs.tableName
)) as ICoopProgramData[];
const program_wallets = (await fetchTable(
ContractsList.Soviet,
SovietContract.contractName.production,
params.coopname,
TablesList.ProgramWallets,
SovietContract.Tables.ProgramWallets.tableName,
params.username,
params.username,
LimitsList.None,
@@ -24,9 +24,9 @@ interface IWalletStore {
withdraws: Ref<IWithdrawData[]>;
methods: Ref<IPaymentMethodData[]>;
update: (params: ILoadUserWallet) => Promise<void>;
loadUserWalet: (params: ILoadUserWallet) => Promise<void>;
//TODO move to Features
//TODO move to features
createDeposit: (params: ICreateDeposit) => Promise<IPaymentOrder>;
createWithdraw: (params: ICreateWithdraw) => Promise<void>;
}
@@ -45,16 +45,17 @@ export const useWalletStore = defineStore(namespace, (): IWalletStore => {
const program_wallets = ref<ExtendedProgramWalletData[]>([]);
const methods = ref<IPaymentMethodData[]>([]);
const createEmptyWallet = (): IWalletData => ({
username: '',
coopname: '',
available: `0.0000 ${CURRENCY}`,
blocked: `0.0000 ${CURRENCY}`,
minimum: `0.0000 ${CURRENCY}`,
});
const loadUserWalet = async (params: ILoadUserWallet) => {
const createEmptyWallet = (): IWalletData => ({
username: '',
coopname: '',
available: `0.0000 ${CURRENCY}`,
blocked: `0.0000 ${CURRENCY}`,
minimum: `0.0000 ${CURRENCY}`,
});
const update = async (params: ILoadUserWallet) => {
try {
const data = await Promise.all([
api.loadSingleUserWalletData(params),
@@ -90,7 +91,7 @@ export const useWalletStore = defineStore(namespace, (): IWalletStore => {
deposits,
withdraws,
methods,
update,
loadUserWalet,
createDeposit,
createWithdraw,
};
@@ -2,12 +2,13 @@ import { SovietContract, GatewayContract } from 'cooptypes';
export type IProgramWalletData =
SovietContract.Tables.ProgramWallets.IProgramWallet;
export type ICoopMarketProgramData =
SovietContract.Tables.MarketPrograms.IMarketPrograms;
export type ICoopProgramData =
SovietContract.Tables.Programs.IProgram;
export type ExtendedProgramWalletData = IProgramWalletData & {
program_type: string;
program_details: ICoopMarketProgramData; // | или другие типы будущих программ
program_details: ICoopProgramData; // | или другие типы будущих программ
};
export type IDepositData = GatewayContract.Tables.Deposits.IDeposits;
+3 -2
View File
@@ -20,7 +20,8 @@ declare module 'vue-router' {
// Расширяем интерфейс RouteMeta, добавляя новые свойства
interface RouteMeta {
roles?: string[];
// title: string
// icon: string
programs?: string[]
title: string
icon: string
}
}
@@ -1,16 +0,0 @@
<template lang="pug">
q-btn(@click="next" color="primary" :disabled="!wif").q-mt-md продолжить
</template>
<script lang="ts" setup>
import { useInstallCooperativeStore } from 'src/entities/Installer/model';
import { computed } from 'vue';
const install = useInstallCooperativeStore()
const wif = computed(() => install.data.wif)
const next = () => {
console.log('on next feature')
}
</script>
@@ -1 +0,0 @@
export {default as SetInstallKeyButton} from './SetInstallKeyButton.vue'
@@ -0,0 +1,13 @@
import type { IInstall } from 'coopback';
import { sendPOST } from 'src/shared/api';
async function install(data: IInstall): Promise<void> {
const response = await sendPOST('/v1/mono/install', data);
return response;
}
export const api = {
install
}
@@ -1,10 +1,12 @@
import { useInstallCooperativeStore } from 'src/entities/Installer/model'
import { api } from '../api'
import { IInstall } from 'coopback'
export const useInstallCooperative = () => {
const store = useInstallCooperativeStore()
async function install() {
console.log('install', store.data)
async function install(data: IInstall) {
await api.install(data)
}
return {
@@ -0,0 +1,68 @@
<template lang="pug">
form(@submit.prevent="submit").full-width
q-input(
v-model="email"
label="Введите электронную почту"
color="primary"
hint=""
outlined
class="full-width"
autocorrect="off"
autocapitalize="off"
autocomplete="off"
spellcheck="false"
).q-mt-lg
q-input(
v-model="privateKey"
label="Введите ключ доступа"
color="primary"
hint=""
outlined
class="full-width"
type="password"
autocorrect="off"
autocapitalize="off"
autocomplete="off"
spellcheck="false")
q-btn(
type="submit"
label="Войти"
class="full-width"
color="primary"
:loading="loading"
:disable="!privateKey")
</template>
<script lang="ts" setup>
import { useInstallCooperativeStore } from 'src/entities/Installer/model';
import { useCurrentUserStore } from 'src/entities/User';
import { useLoginUser } from 'src/features/Registrator/LoginUser';
import { FailAlert } from 'src/shared/api';
import { COOPNAME } from 'src/shared/config';
import { useGlobalStore } from 'src/shared/store';
import { ref } from 'vue';
const email = ref('')
const privateKey = ref('')
const loading = ref(false)
const currentUser = useCurrentUserStore()
const globalStore = useGlobalStore()
const submit = async () => {
loading.value = true
try {
const { login } = useLoginUser()
await login(email.value, privateKey.value)
await currentUser.loadProfile(globalStore.username, COOPNAME)
loading.value = false
} catch (e: any) {
loading.value = false
FailAlert(e.message)
}
}
</script>
@@ -0,0 +1 @@
export {default as RequestKeyForm} from './RequestKeyForm.vue'
@@ -0,0 +1,63 @@
<template lang="pug">
div(v-if="installStore")
div(v-for="(member,index) in installStore.soviet" v-bind:key="member.id")
q-card(style="margin-bottom: 50px;")
q-badge(v-if="member.role=='chairman'" style="position: absolute; top: -15px;" label="Председатель совета" color="black")
q-badge(v-if="member.role=='member'" style="position: absolute; top: -15px;" label="Член совета" color="black")
q-btn(style="position: absolute; top: -20px; right: 0px;" flat v-if="member.role != 'chairman'" @click="del(member.id)" icon="close" dense size="sm" round)
p {{ installStore.soviet[index] }}
IndividualDataForm(v-model:userData="installStore.soviet[index]")
template(#top)
q-input(filled v-model="installStore.soviet[index].individual_data.email" label="Электронная почта")
div.flex.justify-around
q-btn(@click="add" color="primary" icon="add") добавить члена
q-btn(@click="next" color="primary" icon="done") завершить
</template>
<script lang="ts" setup>
import { useInstallCooperativeStore } from 'src/entities/Installer/model';
const installStore = useInstallCooperativeStore()
import { IndividualDataForm } from 'src/shared/ui/UserDataForm/IndividualDataForm';
import type { IIndividualData } from 'src/shared/lib/types/user/IUserData';
import { FailAlert, SuccessAlert } from 'src/shared/api';
import { useDesktopStore } from 'src/entities/Desktop/model';
import { useInstallCooperative } from '../../model';
installStore.is_finish = false
const add = () => {
let role = 'chairman'
if (installStore.soviet.length > 0)
role = 'member'
installStore.soviet.push({id: Date.now(), role, type: 'individual', individual_data: {} as IIndividualData})
}
const del = (id: number) => {
installStore.soviet = installStore.soviet.filter(el => el.id !== id)
}
const next = async () => {
const forInstall = installStore.soviet.map(el => ({role: el.role as 'chairman' | 'member', individual_data: el.individual_data}))
try {
const {install} = useInstallCooperative()
await install(forInstall)
useDesktopStore().healthCheck()
installStore.is_finish = true
SuccessAlert('Установка произведена успешно')
} catch(e: any){
FailAlert(e.message)
}
}
if (installStore.soviet.length == 0)
add()
</script>
@@ -0,0 +1 @@
export {default as SetSovietForm} from './SetSovietForm.vue'

Some files were not shown because too many files have changed in this diff Show More