Compare commits

..

212 Commits

Author SHA1 Message Date
Alex Ant 6a450e2ac6 some steps 2025-07-03 17:58:45 +05:00
Alex Ant 9fc87a705f bug: meet service improve 2025-07-02 13:27:31 +05:00
Alex Ant 305864c1ed chore(release): publish 2025-07-02 12:16:36 +05:00
Alex Ant ad83d9cc77 fix: meet сервис на отправку уведомления о повторном собрании 2025-07-02 11:58:51 +05:00
Alex Ant 226c7f9473 chore(release): publish 2025-07-01 21:03:01 +05:00
Alex Ant 137d1ca8a4 migration 2025-07-01 20:31:21 +05:00
Alex Ant 59744e9d23 добавлены анимации для входа и выхода меню, улучшена логика рендеринга. Обновлены стили и добавлен ключ для перерендера при смене маршрутов. Исправлены мелкие недочеты в других компонентах. 2025-07-01 16:46:33 +05:00
Alex Ant ac8836628e chore(release): publish 2025-07-01 16:04:01 +05:00
Alex Ant 1f649c8951 Упрощен компонент ShadowHtml: удалена проверка на клиентскую среду, добавлены логи для отладки, обновлено состояние миграции с изменением тестового файла. 2025-07-01 15:45:10 +05:00
Alex Ant 310468fb69 Исправлено название типа платежа "Возврат средств" на "Возврат взноса" в PaymentDomainEntity. 2025-07-01 13:36:13 +05:00
Alex Ant 7f782e0a92 Рефакторинг пользователя в сессии на фронте, правки визуального отображения всех страниц, управление исходящими платежами в шлюзе, возврат паевого взноса в кошельке. 2025-07-01 13:34:46 +05:00
Alex Ant d0c9f8bffc Новая архитектура для входящих и исходящих платежей 2025-06-26 20:20:58 +05:00
Alex Ant 60a35f6f76 returnByMoneyDecision Document 2025-06-25 20:34:12 +05:00
Alex Ant a3a2923751 Добавляем шаблон заявления на возврат паевого взноса с ЦК 2025-06-24 16:18:34 +05:00
Alex Ant 32e6a45f05 chore(release): publish 2025-06-24 09:07:26 +05:00
Alex Ant 59665c6df4 fix navigation guard bug 2025-06-24 08:50:05 +05:00
Alex Ant d23b4e3aac поле ввода для поиска пайщика и извлечения его username 2025-06-23 20:56:07 +05:00
Alex Ant 20897cf199 search by private account 2025-06-23 13:30:34 +05:00
Alex Ant 0b57232606 Корректное удаление кооперативного участка. Общее собранее уполномоченных. Правки title шаблонов. 2025-06-19 12:09:10 +05:00
Alex Ant 1bd8f003f7 chore(release): publish 2025-06-19 10:00:51 +05:00
Alex Ant fcb614cd90 Правка сообщений с ошибками на фронте, расширение шаблонов общих собраний на повторяемость. 2025-06-19 09:41:41 +05:00
Alex Ant 1c376c003a chore(release): publish 2025-06-14 21:27:59 +05:00
Alex Ant a433ceaf1d FATALITY BUG FIX 2025-06-14 21:26:41 +05:00
Alex Ant 850478b7f7 Revert "откатываем функционал"
This reverts commit 8484a14905.
2025-06-14 20:28:02 +05:00
Alex Ant 11a891392e update workflow #2 2025-06-14 17:56:14 +05:00
Alex Ant 7930ef8ef6 workflow fix 2025-06-14 16:09:22 +05:00
Alex Ant 8484a14905 откатываем функционал 2025-06-14 13:40:01 +05:00
Alex Ant e7a0968b94 fix hash router 2025-06-14 11:07:35 +05:00
Alex Ant 87241b2de0 rollback 2025-06-14 09:07:57 +05:00
Alex Ant 4a5fb2af8b chore(release): publish 2025-06-13 20:45:38 +05:00
Alex Ant b9acc67818 update 2025-06-13 20:18:34 +05:00
Alex Ant 5be9fa6ae8 update 2025-06-13 20:15:39 +05:00
Alex Ant e0f8d6a64c back to hash routing 2025-06-13 19:48:36 +05:00
Alex Ant 2276ab396e update 2025-06-13 19:20:02 +05:00
Alex Ant 9de84afc29 looking for bug 2025-06-13 17:08:27 +05:00
Alex Ant 747e567666 enable test mode 2025-06-13 16:15:50 +05:00
Alex Ant 675376079e Обновлено использование индекса cooperatives в shared_registrator.hpp, добавлено новое действие delmeet в meet для удаления собраний. Исправлены проверки на наличие активных пайщиков и добавлено форматирование ссылок в компонентах голосования и повестки. Обновлены формы создания и перезапуска собраний для поддержки новых требований. 2025-06-13 13:26:32 +05:00
Alex Ant 1fa0cee816 Добавлено использование функции parseLinks для форматирования ссылок в контексте и решениях в компонентах повестки и голосования. Упрощен код за счет удаления дублирующей функции parseLinks из компонентов. 2025-06-12 20:26:43 +05:00
Alex Ant 6a7f71eb5a Добавлено форматирование ссылок в повестке собрания. Реализована функция для преобразования текста с ссылками в HTML-формат. Исправлено отображение контекста повестки. 2025-06-12 20:22:33 +05:00
Alex Ant 6bda6948bf Добавлено новое поле 'level' в интерфейсы и DTO для обработки собраний, обновлены адаптеры для поддержки этого поля. Пофиксена проблема с Float на проценте кворума. 2025-06-12 20:14:55 +05:00
Alex Ant abb43b4221 fix count 2025-06-12 19:17:45 +05:00
Alex Ant 4193c45205 подсчитываем количество активных пайщиков в кооперативах 2025-06-12 15:47:27 +05:00
Alex Ant 36eb50fef9 meet fix 2025-06-12 15:45:12 +05:00
Alex Ant ad0ebf82ee добавлено действие migrate в meet и созданы миграции на добавление новых шаблонов 2025-06-12 14:56:42 +05:00
Alex Ant 54d55e288f release 2025-06-12 11:13:51 +05:00
Alex Ant 9fb51b00bd Добавлены новые зависимости moment-timezone и @novu/js, обновлены версии существующих пакетов. Внесены изменения в модули и сервисы для поддержки новых функциональностей, включая адаптеры для расширений и обработку уведомлений. Реализована логика работы с временными зонами и обновлены интерфейсы для работы с аккаунтами и собраниями. 2025-06-11 21:39:13 +05:00
Alex Ant d56dcc153a Добавлены новые поля для ответов голосования в схемы и DTO, а также обновлены интерфейсы и типы для поддержки голосования на собраниях. Реализована логика обработки ответов и обновлены компоненты для работы с новыми данными. Добавлена поддержка часового пояса в форматирование дат. 2025-06-10 14:14:44 +05:00
Alex Ant d9f421acbd Обновлены компоненты рабочего стола: добавлены маршруты по умолчанию для рабочих столов "participant" и "soviet", реализована логика выбора рабочего стола на основе прав пользователя и сохраненного выбора. Также добавлены новые методы для навигации и сохранения состояния рабочего стола. Исправлены ошибки в компонентах и улучшена верстка. 2025-06-09 17:54:33 +05:00
Alex Ant 01ec687ba0 almost works 2025-06-09 15:27:03 +05:00
Alex Ant 0ee1efac4e add exampleData 2025-06-03 13:12:35 +05:00
Alex Ant fbf9d514a0 update 2025-06-03 10:54:14 +05:00
Alex Ant be7a9e9e3a update 2025-06-02 23:15:51 +05:00
Alex Ant bc3b3f701f update cooptypes and factory 2025-06-02 23:00:32 +05:00
Alex Ant 0d8be7a489 Добавлена поддержка часового пояса в компоненты создания и перезапуска собраний. Обновлены метки для отображения времени с учетом часового пояса. Добавлены зависимости moment-timezone и обновлены конфигурации окружения. 2025-05-30 22:54:22 +05:00
Alex Ant 2fdeaed3a0 Поправлена верстка. Обновлены компоненты для отображения новых данных о вопросах и результатах голосования. Изменен SDK для корректной мульти-подписи документа. 2025-05-30 21:42:07 +05:00
Alex Ant 13481d8f95 Добавлены поля для председателя и секретаря в интерфейсы и DTO собраний, а также обновлены соответствующие селекторы и агрегаты документов. Введены сертификаты для председателя и секретаря, обновлены зависимости и исправлены ссылки на информацию о пользователях в документах. 2025-05-23 17:48:52 +05:00
Alex Ant f4b87baa2b Добавлены новые типы сертификатов пользователей (EntrepreneurCertificate, IndividualCertificate, OrganizationCertificate, RepresentedByCertificate) и обновлены соответствующие DTO и интерфейсы. Обновлены зависимости в модулях и исправлены ссылки на информацию о подписантах в документах. 2025-05-23 14:14:56 +05:00
Alex Ant a337dbceb8 expandableDocument for meet 2025-05-23 10:49:03 +05:00
Alex Ant 04592a9908 meet aggregation DTO 2025-05-22 17:51:29 +05:00
Alex Ant 9d204ba496 chore(release): publish 2025-05-14 16:16:51 +05:00
Alex Ant 64dd48b408 повторная миграция соглашений 2025-05-14 15:41:34 +05:00
Alex Ant 515a374f86 chore(release): publish 2025-05-14 12:45:52 +05:00
Alex Ant ddae8d6a53 Обновлен changelog для версии v2025.5.14. 2025-05-14 12:22:46 +05:00
Alex Ant 6e87047e1d Добавлена поддержка смены темы (светлая/темная) с сохранением в localStorage, обновлены соответствующие компоненты и стили. Исправлено отображение данных участников в таблицах. 2025-05-14 12:12:00 +05:00
Alex Ant 62e13853c5 Добавлено поле аккаунта в тип Payment и обновлены соответствующие сущности и DTO, а также интерфейс для отображения ФИО плательщика. 2025-05-13 18:15:21 +05:00
Alex Ant a09959d751 chore(release): publish 2025-05-13 14:56:31 +05:00
Alex Ant e2678df443 factory bugs fix 2025-05-13 10:19:44 +05:00
Alex Ant fedec69e44 fix bug on dinamic import 2025-05-13 09:10:04 +05:00
Alex Ant 4ccf2c743c процесс голосования через подпись номера решения 2025-05-12 10:41:37 +05:00
Alex Ant 418d43af58 almost done 2025-05-09 17:31:41 +05:00
Alex Ant 869a75f080 SDK компилируется 2025-05-07 08:23:59 +05:00
Alex Ant c7bc2d1a20 Merge branch 'dev' into document2 2025-05-05 18:56:04 +05:00
Alex Ant 3ea4cd6d73 chore(release): publish 2025-05-05 18:55:34 +05:00
Alex Ant 6a955737e0 update version 2 2025-05-05 18:55:01 +05:00
Alex Ant 51bf49b063 update version 2025-05-05 18:53:25 +05:00
Alex Ant 12468b16c8 Merge branch 'testnet' 2025-05-05 18:50:23 +05:00
Alex Ant 5ebd28d181 откатываем новую таблицу кооперативов 2025-05-05 18:49:08 +05:00
Alex Ant defe482ccd контракты скомпилировались 2025-05-05 18:46:44 +05:00
Alex Ant e99d141f28 before contract migrate 2025-05-05 17:25:56 +05:00
Alex Ant aa0a6731de chore(release): publish 2025-05-05 12:53:42 +05:00
Alex Ant 46f7f10dce coop migration 2025-05-05 12:28:54 +05:00
Alex Ant 552333faf6 chore(release): publish 2025-05-05 11:17:29 +05:00
Alex Ant e23589d4d3 Функционал миграций по версиям с интеграцией блокчейна и двух баз данных 2025-05-04 14:17:27 +05:00
Alex Ant 104b08e1ba chore(release): publish 2025-05-04 12:42:52 +05:00
Alex Ant 1b81cfc0a9 fix workflow #2 2025-05-04 12:42:23 +05:00
Alex Ant 6e51433ae9 update publish workflow 2025-05-04 12:39:52 +05:00
Alex Ant 421f356987 update version 2025-05-04 12:37:53 +05:00
Alex Ant abd9f1931d chore(release): publish 2025-05-04 12:32:16 +05:00
Alex Ant 2b87034abb fix workflows 2025-05-04 12:26:07 +05:00
Alex Ant 8d7c919332 chore(release): publish 2025-05-04 12:08:16 +05:00
Alex Ant 4785ea2886 publish workflow 2025-05-04 12:07:22 +05:00
Alex Ant 4daa06dac1 Обновление структуры signature_info: добавлен идентификатор подписи. Исправлено условие фильтрации истекших решений в ChairmanPlugin. 2025-05-04 11:40:00 +05:00
Alex Ant abc253f47d create document2 format 2025-05-04 11:02:25 +05:00
Alex Ant 5fea2f8f34 chore(release): publish 2025-05-03 16:19:40 +05:00
Alex Ant c29e224f2f Дефолтные конфиги для расширений, фиксы визуалов, микросервис отмены вопроса с повестки 2025-05-03 15:56:08 +05:00
Alex Ant b930543c2b chore(release): publish 2025-05-02 10:40:41 +05:00
Alex Ant 2768d72e90 update 2025-05-01 22:51:07 +05:00
Alex Ant 8ccefe8fac update 2025-05-01 22:46:58 +05:00
Alex Ant c93e59908d update 2025-05-01 22:29:40 +05:00
Alex Ant 22f0fd8a10 update 2025-05-01 22:28:01 +05:00
Alex Ant 8e17d96529 update 2025-05-01 22:23:56 +05:00
Alex Ant 494a164ee8 update 2025-05-01 22:21:00 +05:00
Alex Ant ee28ae1719 update 2025-05-01 22:17:07 +05:00
Alex Ant 3266061359 update 2025-05-01 22:13:38 +05:00
Alex Ant f69d849c4f update lock-file 2025-05-01 21:57:50 +05:00
Alex Ant 2628120e35 update 2025-05-01 21:54:59 +05:00
Alex Ant edf7d9ab62 docs #2 2025-05-01 21:52:49 +05:00
Alex Ant 2095e448e5 docs 2025-05-01 21:50:39 +05:00
Alex Ant beff507f4a Удалены отладочные логи из функций входа и выхода пользователя, а также обновлен способ проверки переменных окружения в функции работы с IndexedDB. 2025-05-01 18:23:56 +05:00
Alex Ant bf4fbfabac update 2025-05-01 16:46:36 +05:00
Alex Ant 2f1d88a74c Добавлены отладочные логи в функции входа и выхода пользователя, а также обновлен способ загрузки переменных окружения в конфигурации Quasar для режима разработки. 2025-05-01 16:00:45 +05:00
Alex Ant b444004f4a Удалены отладочные логи из функции получения переменных окружения и обновлен middleware для инъекции переменных окружения в браузер с использованием ssrMiddleware. 2025-05-01 14:33:41 +05:00
Alex Ant 6862f2881a update 2025-05-01 13:42:00 +05:00
Alex Ant 73afcabee2 Изменен способ определения переменных окружения в конфигурации Quasar: теперь они устанавливаются только для клиентской стороны, если режим не SSR. 2025-05-01 13:27:05 +05:00
Alex Ant b4168a4053 update 2025-05-01 11:34:33 +05:00
Alex Ant 1fe14d5811 update 2025-05-01 11:22:00 +05:00
Alex Ant 89e5c97ef8 update 2025-05-01 11:12:30 +05:00
Alex Ant 258b8304ff update 2025-05-01 11:01:19 +05:00
Alex Ant 69fe9c1348 update 2025-05-01 10:31:01 +05:00
Alex Ant fa4af94fa0 update 2025-05-01 10:29:53 +05:00
Alex Ant 2ac84a6910 update 2025-05-01 10:27:41 +05:00
Alex Ant 3f79cf9a1b update 2025-05-01 10:24:33 +05:00
Alex Ant c155605ca8 update 2025-05-01 09:59:02 +05:00
Alex Ant 80a94f79da update 2025-05-01 09:51:43 +05:00
Alex Ant 89ba6cb356 update 2025-05-01 09:41:37 +05:00
Alex Ant c7bd0326ba Обновление Dockerfile: замена команды установки зависимостей на принудительную, улучшение структуры образа. Изменение конфигурации GitHub Actions для отключения кеширования и упрощения сборки образов. 2025-05-01 09:36:57 +05:00
Alex Ant 2c551a0d9e Оптимизация Dockerfile: добавление этапа сборки для зависимостей, упрощение копирования файлов и улучшение структуры образа. Обновление конфигурации GitHub Actions для сборки и публикации образов с использованием Docker Buildx. 2025-04-30 21:49:16 +05:00
Alex Ant ba103a969e Добавление шагов для отладки в GitHub Actions: вывод последних коммитов, текущей ветки и содержимого компонентов. Обновление комментариев и улучшение сборки образов без кеша. 2025-04-30 21:32:51 +05:00
Alex Ant 0d9177f98f update 2025-04-30 21:29:50 +05:00
Alex Ant 60c32be299 update 2025-04-30 20:54:13 +05:00
Alex Ant 83c107b8b2 Добавление middleware для инъекции переменных окружения в window.__ENV__ и рефакторинг функции получения переменных окружения с учетом различных сред (SSR, SPA). Теперь переменные окружения экспортируются через единую функцию getEnv(). 2025-04-30 20:53:02 +05:00
Alex Ant b6d582fb2c Обновление конфигурации проекта: замена использования переменных окружения на новый модуль env, упрощение Dockerfile, улучшение сборки контейнеров и исправление мелких ошибок в компонентах. 2025-04-30 20:30:42 +05:00
Alex Ant a5818bdc53 update 2025-04-30 18:37:23 +05:00
Alex Ant de0fe5465f update 2025-04-30 18:00:07 +05:00
Alex Ant d43b188a30 update 2025-04-30 17:47:08 +05:00
Alex Ant bfb2be2a72 update 2025-04-30 17:45:28 +05:00
Alex Ant 73c2cd9cb3 update 2025-04-30 17:35:42 +05:00
Alex Ant 61cfc442ef update 2025-04-30 17:33:58 +05:00
Alex Ant 0ed04c2c27 update 2025-04-30 17:29:37 +05:00
Alex Ant 6773509ede update 2025-04-30 17:17:55 +05:00
Alex Ant acd86df785 update 2025-04-30 17:05:31 +05:00
Alex Ant c554b167b3 update 2025-04-30 16:53:55 +05:00
Alex Ant 18cf7b61e3 print env 2025-04-30 16:47:47 +05:00
Alex Ant e42b396a68 VITE_ prefix 2025-04-30 16:39:33 +05:00
Alex Ant c47e61d42a правки SSR проблема рендиринга 2025-04-30 15:55:07 +05:00
Alex Ant 92559370fa modify quasar conf 2025-04-30 12:49:12 +05:00
Alex Ant c3a2ec46b3 update 2025-04-30 11:32:47 +05:00
Alex Ant fe55d23e65 хук на деплой 2025-04-30 10:29:59 +05:00
Alex Ant b0d4f5d542 Добавление сборки и публикации нового Docker-образа для приложения @coopenomics/desktop в workflow. Обновление конфигурации сборки контейнеров. 2025-04-29 23:23:13 +05:00
Alex Ant be48f7a158 Обновление Dockerfile для упрощения сборки с использованием lerna. Добавление новых прокси-файлов для модулей @dicebear/core, @dicebear/collection и email-regex. Обновление зависимостей в package.json и pnpm-lock.yaml. Изменение конфигурации Quasar для оптимизации работы с новыми модулями. 2025-04-29 23:21:10 +05:00
Alex Ant 83bd744100 update workflow 2025-04-29 21:49:48 +05:00
Alex Ant ff1615f7b1 workflow initialization 2025-04-29 21:40:51 +05:00
Alex Ant 696e1a0d2c Merge branch 'main' into dev 2025-04-29 16:32:03 +05:00
Alex Ant 397670473a chore(release): publish 2025-04-29 16:27:09 +05:00
Alex Ant cab8061bc3 Merge branch 'testnet' 2025-04-29 16:21:40 +05:00
Alex Ant 3c2b9bcb4c update script 2025-04-29 16:21:22 +05:00
Alex Ant 7a274b7ab1 update templates 2025-04-29 16:17:58 +05:00
Alex Ant e524244bab Добавление нового поля 'type' в сущность Payment и соответствующие изменения в DTO, схемах и селекторах. Обновление логики обновления статусов платежей с учетом нового поля. Исправление параметров в методах для получения заказов. 2025-04-29 13:36:04 +05:00
Alex Ant 14ecaf259a Добавление нового поля 'coop' в интерфейс Model и обновление схемы валидации для SelectBranchStatement. Обновление логики комбинирования данных в классе Factory для включения данных о кооперативе. Комментарии в стилях инпутов переведены в закомментированный вид. 2025-04-29 12:25:08 +05:00
Alex Ant 749c13dc91 Обновление скриптов публикации и логики миграции. Изменены команды для публикации на продакшн, добавлен новый скрипт publish-prod.sh. Обновлена логика удаления кандидатов в функции миграции и исправлены ссылки на индексы кандидатов в confirmreg.cpp. 2025-04-29 11:05:03 +05:00
Alex Ant ab2ee4cc92 lerna update 2025-04-29 10:16:02 +05:00
Alex Ant 2907352d61 disable meet for temp 2025-04-29 10:11:14 +05:00
Alex Ant 390b995eb6 Добавление новых скриптов для развертывания и обновление интерфейсов для обработки голосования на общем собрании. Обновлены типы данных в интерфейсах и DTO, добавлены новые методы для генерации документов и улучшения функционала. Удалены устаревшие интерфейсы и компоненты, улучшена структура кода для повышения эффективности. 2025-04-28 23:55:55 +05:00
Alex Ant 24b3dd3c60 Удаление устаревших интерфейсов и таблиц, связанных с кошельками. Обновление логики обработки платежей и интерфейсов для работы с новыми типами данных. Улучшение структуры компонентов и интерфейсов для более эффективного взаимодействия с API. Обновление стилей и компонентов пользовательского интерфейса для улучшения визуального восприятия. 2025-04-26 17:14:22 +05:00
Alex Ant 55444a4b72 Обновление интерфейсов и DTO для работы с документами и собраниями. Добавлены новые поля и типы данных, улучшена обработка документов в сервисах. Удалены устаревшие селекторы и обновлены существующие для соответствия новым требованиям. Исправлены типы данных в селекторах и добавлены новые экспорты. 2025-04-25 23:44:32 +05:00
Alex Ant 76854207a7 Сейчас будем переводить сервис документов на агрегатор. Обновление интерфейсов и DTO для обработки документов. Изменены типы полей в интерфейсах DocumentPackageDomainInterface, DocumentRepository и DocumentDomainService для поддержки значений null. Добавлены проверки на наличие данных в DocumentDomainEntity и улучшена обработка документов в DocumentDomainService. Обновлены методы для работы с документами в API и хранилище. 2025-04-23 19:03:18 +05:00
Alex Ant 4fcd700e39 Первичная мобильная верстка страниц стола совета 2025-04-23 12:39:23 +05:00
Alex Ant 05dfcced1b Обновление конфигурации и добавление тестового режима для собраний. Изменен порт для state-history-endpoint, добавлен флаг TEST_MODE в контракте meet, обновлены проверки дат открытия и закрытия собраний. Обновлены интерфейсы и DTO для обработки новых типов данных и улучшения функционала. 2025-04-22 23:23:09 +05:00
Alex Ant 931c366907 Добавление функционала для генерации бюллетеней голосования на общем собрании. Обновлены интерфейсы и DTO для обработки новых типов документов, добавлены методы для генерации бюллетеней и голосования. Исправлены типы данных для идентификаторов вопросов повестки. 2025-04-21 20:29:12 +05:00
Alex Ant 71d35b74d7 Добавление новых методов для подписания решений председателем и секретарем на общем собрании. Удален метод закрытия собрания, обновлены интерфейсы и DTO для обработки новых типов документов и действий. 2025-04-21 16:44:27 +05:00
Alex Ant 21fac5c7df Добавление новых типов и методов для работы с собраниями в модуле общих собраний. Реализованы методы получения данных о собраниях, обновлены интерфейсы и DTO для обработки информации о голосованиях и документах собраний. 2025-04-20 16:41:20 +05:00
Alex Ant 0ba9d55081 Добавление новых входных типов и методов для получения данных о собраниях в модуле общих собраний. Реализованы методы getMeet и getMeets, а также обновлены интерфейсы и DTO для обработки данных. 2025-04-20 12:56:42 +05:00
Alex Ant b5b388e95d Обновление документации и DTO для модуля общих собраний. Добавлены описания для полей в DTO, улучшена структура и добавлены новые типы данных для обработки информации о собраниях и голосованиях. 2025-04-20 11:59:29 +05:00
Alex Ant 9c643395b3 Добавление модуля общих собраний и расширение DTO для документов, включая новые интерфейсы и классы для обработки документов собраний и решений. 2025-04-20 11:39:27 +05:00
Alex Ant b989074170 meet module & extends all documents DTOs 2025-04-18 15:27:35 +05:00
Alex Ant 261f010a49 update release script 2025-04-16 22:03:36 +05:00
Alex Ant af46867939 update releases script 2025-04-16 22:02:08 +05:00
Alex Ant be2355e5c5 generate changelog releases 2025-04-16 21:42:37 +05:00
Alex Ant 8b4a20ed3f make Templates correct 2025-04-16 20:08:50 +05:00
Alex Ant 1ab1e1d3c5 move templates #1 2025-04-16 20:08:24 +05:00
Alex Ant c9aab02aab wtf?! 2025-04-16 20:06:49 +05:00
Alex Ant 0643604778 add meet contract, cooptypes and empty documents templates 2025-04-16 19:58:49 +05:00
Alex Ant fe79f3ff98 desktop bug fixs 2025-04-15 15:57:55 +05:00
Alex Ant f919a14927 remove Env.ts file from desktop and move params to .env 2025-04-15 12:27:29 +05:00
Alex Ant dda389ad75 fix system contract action name 2025-04-15 10:27:53 +05:00
Alex Ant aa42864029 fix contracts build 2025-04-15 10:14:07 +05:00
Alex Ant 41bb17224a coopStore release 2025-04-11 18:29:07 +05:00
Alex Ant fd6f628c43 refactoring desktop 2025-04-10 11:40:14 +05:00
Alex Ant 28ca615d96 claim -> result, result -> assignment 2025-04-06 12:56:55 +05:00
Alex Ant 76203a88d8 before make refactoring 2025-04-06 11:25:29 +05:00
Alex Ant aa891adddf shared actions 2025-04-05 11:36:06 +05:00
Alex Ant ecdac6fff9 loan contract 2025-04-03 18:52:53 +05:00
Alex Ant bcba24ea5e contracts refactoring 2025-04-03 09:36:48 +05:00
Alex Ant 44b1f423cc appStore & medusa component & capital contract (start rework) 2025-03-28 18:42:28 +05:00
Alex Ant 85cc7361d7 refactoring participant widget to page 2025-03-27 19:14:02 +05:00
Alex Ant e5e28ff652 chore(release): publish 2025-03-27 18:13:33 +05:00
Alex Ant 4957182480 update mutation simplification 2025-03-27 17:30:31 +05:00
Alex Ant 84927e943a make participants editable 2025-03-27 14:32:23 +05:00
Alex Ant 0d06114f00 change decision dto and logout on some auth problems 2025-03-26 22:18:12 +05:00
Alex Ant 2654760e16 Merge pull request #201 from coopenomics/kamilocean/sprint-4
Kamilocean/sprint 4
2025-03-26 20:09:37 +03:00
Alex Ant d02e7ba2be README.md for cleos wallet 2025-03-26 18:27:05 +05:00
Alex Ant e18fd94336 make cleos separated component 2025-03-26 18:19:52 +05:00
Alex Ant 03e2410556 make cleos wallet accessable 2025-03-26 13:08:04 +05:00
Alex Ant 0f1f34f621 make unnesassary result 2025-03-26 11:42:05 +05:00
Alex Ant c08473618f some updates on contracts and tests 2025-03-22 13:58:51 +05:00
Alex Ant 3b4fb195bb update 2025-03-21 17:58:33 +05:00
Alex Ant 827eb10cc2 Merge branch 'dev' into TSK-900 2025-03-19 10:58:53 +05:00
Alex Ant 6e7c60de6e Создание кошелька при регистрации участника 2025-03-19 10:58:20 +05:00
kamilocean 54a4449e0b Merge branch 'dev' into kamilocean/sprint-4 2025-03-17 16:07:50 +03:00
Ilia Smirnov a6011f5d46 Merged readme fixes 2025-03-17 12:52:02 +03:00
Ilia Smirnov a1300e2b3c Merge branch 'dev' of github.com:coopenomics/mono into TSK-878 2025-03-17 12:49:40 +03:00
Alex Ant 8f58672403 Merge pull request #217 from coopenomics/dacom-dark-sun/sprint-4
Спринт-4 | dacom-dark-sun
2025-03-17 09:57:34 +03:00
515 changed files with 4543 additions and 32435 deletions
-8
View File
@@ -1,8 +0,0 @@
---
description:
globs:
alwaysApply: true
---
ВАЖНО!!! Мы работаем в МОНО-репозитории pnpm, любая установка пакетов производится ЧЕРЕЗ ФИЛЬТР компонента в корне: pnpm add glob --filter notificator2.
ВАЖНО!!! НИКОГДА НЕ ЗАПУСКАЙ ПРИЛОЖЕНИЕ ИЛИ ЕГО СБОРКУ!!! Просто отчитайся что всё сделал.
+3
View File
@@ -1,6 +1,9 @@
---
description:
globs:
alwaysApply: true
---
# DESKTOP
- Пишем код фронтенда в архитектуре Feature Sliced Design (FSD).
-62
View File
@@ -1,62 +0,0 @@
---
description:
globs:
alwaysApply: false
---
Файл [main.py](mdc:monocoop/monocoop/monocoop/components/docs/main.py) автоматически генерит ссылки на документацию SDK и GraphQL, которые формируются и публикуются автоматически. При создании документации к методам всегда применяй ссылки на SDK и GraphQL по форме:
{{ get_sdk_doc("Mutations", "Accounts", "RegisterAccount") }} | {{ get_graphql_doc("Mutation.registerAccount") }}
### 🎯 Основные паттерны использования
**1. Стандартная структура для методов API:**
```markdown
## Название действия
{{ get_sdk_doc("Namespace", "Module", "Method") }} | {{ get_graphql_doc("Type.methodName") }}
{{ get_typedoc_input("Namespace.Module.Method") }}
Результат:
{{ get_typedoc_definition("Namespace.Module.Method", "IOutput") }}
```
**2. Описание + пример (для сложных методов):**
```markdown
{{ get_typedoc_desc("Namespace.Module.Method") }}
{{ get_typedoc_input("Namespace.Module.Method") }}
```
**3. Ссылки на типы данных:**
```markdown
У каждого аккаунта есть объект {{ get_graphql_definition("Account") }} в GraphQL-API
```
### 🔧 Макросы и их применение
| Макрос | Назначение | Пример использования |
|--------|------------|---------------------|
| `get_sdk_doc` | Ссылка на SDK документацию | `{{ get_sdk_doc("Mutations", "Payments", "CreateDeposit") }}` |
| `get_graphql_doc` | Ссылка на GraphQL операцию | `{{ get_graphql_doc("Query.getAccount") }}` |
| `get_graphql_definition` | Ссылка на GraphQL тип | `{{ get_graphql_definition("Account") }}` |
| `get_class_doc` | Ссылка на класс/метод SDK | `{{ get_class_doc("Document", "sign") }}` |
| `get_typedoc_input` | **Полный пример** TypeScript вызова | `{{ get_typedoc_input("Mutations.Auth.Login") }}` |
| `get_typedoc_definition` | **Структура интерфейса** | `{{ get_typedoc_definition("Mutations.Auth.Login", "IOutput") }}` |
| `get_typedoc_desc` | Описание + примеры | `{{ get_typedoc_desc("Mutations.Auth.Login") }}` |
| `get_typedoc_value` | Значение константы | `{{ get_typedoc_value("Constants.API_VERSION") }}` |
### 📝 Правила оформления
**ОБЯЗАТЕЛЬНО:**
- Всегда используй `get_typedoc_input` для демонстрации **КАК вызывать** метод
- Всегда используй `get_typedoc_definition` для показа **ЧТО возвращается**
- Комбинируй SDK и GraphQL ссылки через ` | `: `{{ get_sdk_doc(...) }} | {{ get_graphql_doc(...) }}`
**ЖЕЛАТЕЛЬНО:**
- Для сложных методов добавляй `get_typedoc_desc` в начало
- Используй `get_graphql_definition` для ссылок на типы данных в тексте
- Группируй связанные операции в одном разделе
**ФОРМАТ ССЫЛОК:**
- SDK: `"Namespace", "Module", "Method"` (3 аргумента)
- GraphQL: `"Type.methodName"` (точка между типом и методом)
- Определения: просто имя типа `"TypeName"`
+2 -25
View File
@@ -76,14 +76,7 @@ jobs:
echo "CMD [\"pnpm\", \"-F\", \"coop-notificator\", \"run\", \"start\"]" >> Dockerfile.notificator
docker build -t dicoop/notificator:${{ env.DOCKER_TAG }} -f Dockerfile.notificator .
docker push dicoop/notificator:${{ env.DOCKER_TAG }}
- name: Build notifications image
run: |
echo "FROM dicoop/mono-base:${{ env.DOCKER_TAG }}" > Dockerfile.notifications
echo "CMD [\"pnpm\", \"-F\", \"@coopenomics/notifications\", \"run\", \"sync\"]" >> Dockerfile.notifications
docker build -t dicoop/notifications:${{ env.DOCKER_TAG }} -f Dockerfile.notifications .
docker push dicoop/notifications:${{ env.DOCKER_TAG }}
# Отправка хука для деплоя
- name: Trigger deployment webhook
if: ${{ success() }}
@@ -103,20 +96,4 @@ jobs:
curl -X POST ${{ vars.TESTNET_WEBHOOK_URL }} \
-H 'Content-Type: application/json' \
-d '${{ env.DOCKER_TAG }}'
fi
# Уведомление в Telegram об успехе
- name: Telegram notify success
if: ${{ success() }}
run: |
curl -s -X POST https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage \
-d chat_id=${{ secrets.TELEGRAM_CHAT_ID }} \
-d text="✅ [GITHUB MONO] Успешная сборка контейнеров: $GITHUB_REPOSITORY ($GITHUB_REF) [${{ env.DOCKER_TAG }}]"
# Уведомление в Telegram об ошибке
- name: Telegram notify failure
if: ${{ failure() }}
run: |
curl -s -X POST https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage \
-d chat_id=${{ secrets.TELEGRAM_CHAT_ID }} \
-d text="❌ [GITHUB MONO] Ошибка при сборке контейнеров: $GITHUB_REPOSITORY ($GITHUB_REF) [${{ env.DOCKER_TAG }}]"
fi
-3
View File
@@ -5,6 +5,3 @@ blockchain-data/
scripts/changelog-prompt.md
scripts/changelog-release.md
scripts/release-info.md
components/docs/docs/sdk
dist/
.env
+7 -47
View File
@@ -3,57 +3,17 @@
"editor.guides.bracketPairs": true,
"editor.tabCompletion": "onlySnippets",
"editor.defaultFormatter": "esbenp.prettier-vscode",
// "editor.formatOnSave": true,
// "editor.codeActionsOnSave": {
// "source.addMissingImports.ts": "explicit",
// "source.fixAll.ts": "explicit",
// "source.fixAll.eslint": "explicit"
// },
"eslint.run": "onType",
"eslint.validate": ["javascript", "typescript", "vue"],
"i18n-ally.localesPaths": ["src/i18n"],
"typescript.format.enable": true,
"typescript.format.indentSwitchCase": false,
"typescript.validate.enable": true,
"notebook.defaultFormatter": "Vue.volar",
// Оптимизация для монорепозитория
"typescript.preferences.useAliasesForRenames": false,
"typescript.preferences.include": false,
"typescript.disableAutomaticTypeAcquisition": true,
"typescript.preferences.includePackageJsonAutoImports": "off",
"typescript.suggest.autoImports": true,
"typescript.suggest.paths": true,
"typescript.updateImportsOnFileMove.enabled": "always",
"typescript.workspaceSymbols.scope": "currentProject",
// Настройки для снижения нагрузки
"files.watcherExclude": {
"**/node_modules/**": true,
"**/dist/**": true,
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/*/**": true,
"**/.cache/**": true,
"**/.quasar/**": true,
"**/*.tsbuildinfo": true
},
"search.exclude": {
"**/node_modules": true,
"**/dist": true,
"**/.cache": true,
"**/.quasar": true,
"**/*.tsbuildinfo": true
},
"files.exclude": {
"**/.cache": true,
"**/*.tsbuildinfo": true,
"**/node_modules/.cache": true
},
// TypeScript server настройки
"typescript.tsserver.maxTsServerMemory": 8192,
"typescript.tsserver.watchOptions": {
"excludeFiles": [
"**/node_modules/**/*",
"**/dist/**/*",
"**/.cache/**/*"
]
}
"notebook.defaultFormatter": "Vue.volar"
}
-129
View File
@@ -1,129 +0,0 @@
# 📋 Резюме создания компонентов Notifications
## ✅ Что создано
### 1. 📚 Библиотека `@monocoop/notifications`
**Расположение:** `components/notifications/`
**Функции:**
- ✅ Типизированные интерфейсы для workflow с Zod
- ✅ Builder паттерн для создания workflow
- ✅ Базовые шаблоны для email, in-app, push, SMS
- ✅ Автоматическая конвертация Zod схем в JSON Schema для Novu
- ✅ Экспорт всех workflow для использования в других пакетах
**Структура:**
```
src/
├── types/ # Базовые типы и интерфейсы
├── base/ # Утилиты и настройки по умолчанию
├── workflows/ # Папки с workflow
│ └── welcome/ # Пример приветственного workflow
└── index.ts # Главный экспорт
```
### 2. 🚀 NestJS приложение `@monocoop/notificator2`
**Расположение:** `components/notificator2/`
**Функции:**
- ✅ Автоматический upsert всех workflow в Novu при запуске
- ✅ RESTful API для триггера уведомлений
- ✅ Типизированная валидация payload
- ✅ Health check endpoints
- ✅ Использует библиотеку notifications для типов
**API Endpoints:**
- `GET /api/notifications/health` - Health check
- `GET /api/notifications/workflows` - Список workflow
- `POST /api/notifications/trigger` - Универсальный триггер
- `POST /api/notifications/trigger/welcome` - Триггер welcome workflow
- `POST /api/notifications/workflows/upsert-all` - Принудительный upsert
## 🔧 Как использовать
### 1. Настройка библиотеки notifications
```bash
cd components/notifications
pnpm install # или npm install
pnpm build # для компиляции TypeScript
```
### 2. Настройка notificator2
```bash
cd components/notificator2
pnpm install # или npm install
# Настройка окружения
cp .env.example .env
# Добавить NOVU_API_KEY в .env
# Запуск
pnpm start:dev
```
### 3. Добавление нового workflow
**В библиотеке notifications:**
```typescript
// components/notifications/src/workflows/order/order-workflow.ts
export const orderWorkflow = WorkflowBuilder
.create<OrderPayload>()
.name('Order Confirmation')
.workflowId('order-confirmation')
.payloadSchema(orderPayloadSchema)
.addSteps([...])
.build();
```
**Регистрация в index.ts:**
```typescript
// components/notifications/src/workflows/index.ts
import { orderWorkflow } from './order';
export const allWorkflows = [
welcomeWorkflow,
orderWorkflow, // ← добавить новый workflow
];
```
### 4. Использование API
**Триггер welcome workflow:**
```bash
curl -X POST http://localhost:3000/api/notifications/trigger/welcome \
-H "Content-Type: application/json" \
-d '{
"subscriberId": "user-123",
"email": "user@example.com",
"payload": {
"userName": "Иван Иванов",
"userEmail": "user@example.com",
"age": 25
}
}'
```
## 🎯 Преимущества архитектуры
1. **Типобезопасность** - Zod схемы обеспечивают валидацию на уровне TypeScript и runtime
2. **Разделение ответственности** - Библиотека содержит только типы, сервер - логику
3. **Расширяемость** - Легко добавлять новые workflow
4. **Автоматизация** - Workflow автоматически синхронизируются с Novu
5. **Переиспользование** - Типы можно использовать в других частях системы
## 🔄 Workflow при запуске
1. **Запуск notificator2**
2. **Чтение всех workflow из библиотеки**
3. **Проверка существования в Novu**
4. **Создание/обновление workflow**
5. **Готов к приёму запросов на триггеры**
## 📁 Структура как в testFramework2.ts
Вся логика из `testFramework2.ts` была перенесена в structured архитектуру:
-`buildWorkflowData``WorkflowBuilder`
-`baseSteps``createEmailStep`, `createInAppStep`, etc.
-`upsertWorkflow``NovuService.upsertWorkflow`
-`triggerWorkflow``NovuService.triggerWorkflow`
- ✅ Типизация payload → Zod схемы + TypeScript типы
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@coopenomics/boot",
"type": "module",
"version": "2025.7.23-1",
"version": "2025.7.2",
"private": true,
"packageManager": "pnpm@9.0.6",
"description": "",
-5
View File
@@ -65,11 +65,6 @@ export default [
path: path.resolve(process.cwd(), '../contracts/build/contracts/fund'),
target: 'fund',
},
{
name: 'ledger',
path: path.resolve(process.cwd(), '../contracts/build/contracts/ledger'),
target: 'ledger',
},
{
name: 'contributor',
path: path.resolve(process.cwd(), '../contracts/build/contracts/contributor'),
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@coopenomics/cleos",
"version": "2025.7.23-1",
"version": "2025.7.2",
"private": true,
"description": "",
"scripts": {
BIN
View File
Binary file not shown.
@@ -1,4 +0,0 @@
---
alwaysApply: true
---
Длинна типа name не должна превышать 12 символов и не должна содержать специальных знаков.
-1
View File
@@ -30,7 +30,6 @@ macro(add_contract_build name)
endmacro()
# Добавляем все контракты
add_contract_build(ledger)
add_contract_build(meet)
add_contract_build(loan)
add_contract_build(wallet)
Binary file not shown.
-1
View File
@@ -6,7 +6,6 @@
#include "src/addaccum.cpp"
#include "src/addcirculate.cpp"
#include "src/addexpense.cpp"
#include "src/accumfee.cpp"
#include "src/addinitial.cpp"
#include "src/authorize.cpp"
#include "src/delfund.cpp"
+2 -5
View File
@@ -44,10 +44,10 @@ class [[eosio::contract(FUND)]] fund : public eosio::contract {
eosio::name type, uint64_t fund_id);
// атомарные транзакции фондового кошелька
// паевой фонд
// паевый фонд
[[eosio::action]] void addcirculate(
eosio::name coopname,
eosio::asset quantity); /// < добавить сумму в паевой фонд
eosio::asset quantity); /// < добавить сумму в паевый фонд
[[eosio::action]] void subcirculate(
eosio::name coopname,
eosio::asset quantity,
@@ -65,9 +65,6 @@ class [[eosio::contract(FUND)]] fund : public eosio::contract {
[[eosio::action]] void addexpense(eosio::name coopname, uint64_t fund_id,
eosio::asset quantity);
// добавить членский взнос на накопительный счет кооператива для дальнейшего управления
[[eosio::action]] void accumfee(eosio::name coopname, eosio::asset quantity);
//счет вступительных взносов
[[eosio::action]] void addinitial(eosio::name coopname,
eosio::asset quantity);
@@ -1,23 +0,0 @@
/**
* @brief Атомарный метод добавления членского взноса на накопительный счет кооператива.
* Минует процесс spreadamount и добавляет средства напрямую на accumulative_expense_account
* для дальнейшего управления кооперативом (распределение по фондам или использование на расходы).
*
* @param coopname Имя кооператива
* @param quantity Сумма членского взноса
*/
[[eosio::action]] void fund::accumfee(eosio::name coopname, eosio::asset quantity) {
name payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
auto cooperative = get_cooperative_or_fail(coopname);
coopwallet_index coopwallet(_fund, coopname.value);
auto wal = coopwallet.find(0);
eosio::check(wal != coopwallet.end(), "Кошелёк кооператива не найден");
// Добавление членского взноса на накопительный счет кооператива
coopwallet.modify(wal, payer, [&](auto &w) {
w.accumulative_expense_account.available += quantity;
});
}
@@ -1,8 +1,8 @@
// атомарные транзакции фондового кошелька
// паевой счет
// паевый счет
[[eosio::action]] void fund::addcirculate(
eosio::name coopname,
eosio::asset quantity) /// < добавить сумму в паевой фонд
eosio::asset quantity) /// < добавить сумму в паевый фонд
{
name payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
@@ -1,10 +0,0 @@
cmake_minimum_required(VERSION 3.5)
# Проект
project(ledger)
find_package(cdt)
# Добавление контракта
add_contract(ledger ledger ledger.cpp)
target_compile_definitions(ledger PUBLIC IS_TESTNET=${IS_TESTNET})
@@ -1,17 +0,0 @@
#include "ledger.hpp"
#include <ctime>
#include <eosio/transaction.hpp>
#include "src/common/add.cpp"
#include "src/common/sub.cpp"
#include "src/common/transfer.cpp"
#include "src/common/block.cpp"
#include "src/common/unblock.cpp"
#include "src/common/writeoff.cpp"
#include "src/common/writeoffcnsl.cpp"
#include "src/writeoff/create.cpp"
#include "src/writeoff/auth.cpp"
#include "src/writeoff/complete.cpp"
#include "src/writeoff/decline.cpp"
#include "src/migrate/migrate.cpp"
@@ -1,51 +0,0 @@
#include <eosio/asset.hpp>
#include <eosio/contract.hpp>
#include <eosio/crypto.hpp>
#include <eosio/eosio.hpp>
#include <eosio/multi_index.hpp>
#include <eosio/system.hpp>
#include <eosio/time.hpp>
#include "../lib/common.hpp"
using namespace eosio;
/**
* @ingroup public_contracts
* @brief Контракт ledger для управления бухгалтерской книгой кооператива
* @details Обеспечивает ведение счетов согласно стандартам кооперативной отчетности
* Счета создаются автоматически при первом пополнении и удаляются при обнулении всех балансов
*/
class [[eosio::contract(LEDGER)]] ledger : public eosio::contract {
public:
ledger(eosio::name receiver, eosio::name code,
eosio::datastream<const char *> ds)
: eosio::contract(receiver, code, ds) {}
void apply(uint64_t receiver, uint64_t code, uint64_t action);
[[eosio::action]] void migrate();
// Операции со счетами (common процесс)
[[eosio::action]] void add(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
[[eosio::action]] void sub(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
[[eosio::action]] void transfer(eosio::name coopname, uint64_t from_account_id, uint64_t to_account_id, eosio::asset quantity, std::string comment);
// Операции блокировки/разблокировки средств
[[eosio::action]] void block(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
[[eosio::action]] void unblock(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
// Атомарная операция списания
[[eosio::action]] void writeoff(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
// Атомарная операция отмены списания
[[eosio::action]] void writeoffcnsl(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
// Операции процесса списания через совет (writeoff процесс)
[[eosio::action]] void create(eosio::name coopname, eosio::name username, uint64_t account_id, eosio::asset quantity, std::string reason, document2 document, checksum256 writeoff_hash);
[[eosio::action]] void auth(eosio::name coopname, checksum256 writeoff_hash);
// Коллбэки от gateway
[[eosio::action]] void complete(eosio::name coopname, checksum256 writeoff_hash);
[[eosio::action]] void decline(eosio::name coopname, checksum256 writeoff_hash, std::string reason);
};
@@ -1,43 +0,0 @@
/**
* @brief Пополнение счета с автоматическим созданием если не существует
* @param actor - кто предоставляет авторизацию
* @param coopname - имя кооператива
* @param account_id - идентификатор счета
* @param quantity - сумма пополнения
* @param comment - комментарий к операции
*/
[[eosio::action]]
void ledger::add(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::name payer = coopname;
if (!has_auth(coopname)) {
payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
}
eosio::check(quantity.is_valid(), "Некорректная сумма");
eosio::check(quantity.amount > 0, "Сумма должна быть положительной");
eosio::check(quantity.symbol == _root_govern_symbol, "Некорректный символ валюты");
laccounts_index accounts(_ledger, coopname.value);
auto account_iter = accounts.find(account_id);
if (account_iter == accounts.end()) {
// Счет не существует - создаем автоматически, получая имя из ACCOUNT_MAP
std::string account_name = Ledger::get_account_name_by_id(account_id);
eosio::check(account_name != "Неизвестный счет", "Счет с таким ID не предусмотрен в плане счетов");
// Создаем новый счет
accounts.emplace(payer, [&](auto& acc) {
acc.id = account_id;
acc.name = account_name;
acc.available = quantity;
acc.blocked = eosio::asset(0, _root_govern_symbol);
acc.writeoff = eosio::asset(0, _root_govern_symbol);
});
} else {
// Счет существует - пополняем available
accounts.modify(account_iter, payer, [&](auto& acc) {
acc.available += quantity;
});
}
}
@@ -1,31 +0,0 @@
/**
* @brief Блокировка средств на счете (перенос из available в blocked)
* @param coopname - имя кооператива
* @param account_id - идентификатор счета
* @param quantity - сумма блокировки
* @param comment - комментарий к операции
*/
[[eosio::action]]
void ledger::block(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::name payer = coopname;
if (!has_auth(coopname)) {
payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
}
eosio::check(quantity.is_valid(), "Некорректная сумма");
eosio::check(quantity.amount > 0, "Сумма должна быть положительной");
eosio::check(quantity.symbol == _root_govern_symbol, "Некорректный символ валюты");
laccounts_index accounts(_ledger, coopname.value);
auto account_iter = accounts.find(account_id);
eosio::check(account_iter != accounts.end(), "Счет не найден");
// Проверяем достаточность доступных средств
eosio::check(account_iter->available >= quantity, "Недостаточно доступных средств для блокировки");
// Переносим средства из available в blocked
accounts.modify(account_iter, payer, [&](auto& acc) {
acc.available -= quantity;
acc.blocked += quantity;
});
}
@@ -1,38 +0,0 @@
/**
* @brief Списание со счета
* @param actor - кто предоставляет авторизацию
* @param coopname - имя кооператива
* @param account_id - идентификатор счета
* @param quantity - сумма списания
* @param comment - комментарий к операции
*/
[[eosio::action]]
void ledger::sub(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::name payer = coopname;
if (!has_auth(coopname)) {
payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
}
eosio::check(quantity.is_valid(), "Некорректная сумма");
eosio::check(quantity.amount > 0, "Сумма должна быть положительной");
eosio::check(quantity.symbol == _root_govern_symbol, "Некорректный символ валюты");
laccounts_index accounts(_ledger, coopname.value);
auto account_iter = accounts.find(account_id);
eosio::check(account_iter != accounts.end(), "Счет не найден");
// Проверяем достаточность доступных средств
eosio::check(account_iter->available >= quantity, "Недостаточно доступных средств для списания");
// Обновляем баланс счета
accounts.modify(account_iter, payer, [&](auto& acc) {
acc.available -= quantity;
});
// Проверяем и удаляем счет если он полностью пуст
if (account_iter->is_empty()) {
accounts.erase(account_iter);
}
}
@@ -1,61 +0,0 @@
/**
* @brief Перевод средств между счетами
* @param coopname - имя кооператива
* @param from_account_id - идентификатор счета списания
* @param to_account_id - идентификатор счета зачисления
* @param quantity - сумма перевода
* @param comment - комментарий к операции
*/
[[eosio::action]]
void ledger::transfer(eosio::name coopname, uint64_t from_account_id, uint64_t to_account_id, eosio::asset quantity, std::string comment) {
eosio::name payer = coopname;
if (!has_auth(coopname)) {
payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
}
eosio::check(quantity.is_valid(), "Некорректная сумма");
eosio::check(quantity.amount > 0, "Сумма должна быть положительной");
eosio::check(quantity.symbol == _root_govern_symbol, "Некорректный символ валюты");
eosio::check(from_account_id != to_account_id, "Счета списания и зачисления должны отличаться");
laccounts_index accounts(_ledger, coopname.value);
// Проверяем счет списания
auto from_account_iter = accounts.find(from_account_id);
eosio::check(from_account_iter != accounts.end(), "Счет списания не найден");
eosio::check(from_account_iter->available >= quantity, "Недостаточно доступных средств для перевода");
// Проверяем счет зачисления или создаем его
auto to_account_iter = accounts.find(to_account_id);
// Списываем с источника
accounts.modify(from_account_iter, payer, [&](auto& acc) {
acc.available -= quantity;
});
if (to_account_iter == accounts.end()) {
// Счет получателя не существует - создаем автоматически
std::string account_name = Ledger::get_account_name_by_id(to_account_id);
eosio::check(account_name != "Неизвестный счет", "Счет получателя с таким ID не предусмотрен в плане счетов");
accounts.emplace(payer, [&](auto& acc) {
acc.id = to_account_id;
acc.name = account_name;
acc.available = quantity;
acc.blocked = eosio::asset(0, _root_govern_symbol);
acc.writeoff = eosio::asset(0, _root_govern_symbol);
});
} else {
// Зачисляем на получателя
accounts.modify(to_account_iter, payer, [&](auto& acc) {
acc.available += quantity;
});
}
// Проверяем и удаляем счет источника если он полностью пуст
if (from_account_iter->is_empty()) {
accounts.erase(from_account_iter);
}
}
@@ -1,31 +0,0 @@
/**
* @brief Разблокировка средств на счете (перенос из blocked в available)
* @param coopname - имя кооператива
* @param account_id - идентификатор счета
* @param quantity - сумма разблокировки
* @param comment - комментарий к операции
*/
[[eosio::action]]
void ledger::unblock(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::name payer = coopname;
if (!has_auth(coopname)) {
payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
}
eosio::check(quantity.is_valid(), "Некорректная сумма");
eosio::check(quantity.amount > 0, "Сумма должна быть положительной");
eosio::check(quantity.symbol == _root_govern_symbol, "Некорректный символ валюты");
laccounts_index accounts(_ledger, coopname.value);
auto account_iter = accounts.find(account_id);
eosio::check(account_iter != accounts.end(), "Счет не найден");
// Проверяем достаточность заблокированных средств
eosio::check(account_iter->blocked >= quantity, "Недостаточно заблокированных средств для разблокировки");
// Переносим средства из blocked в available
accounts.modify(account_iter, payer, [&](auto& acc) {
acc.blocked -= quantity;
acc.available += quantity;
});
}
@@ -1,31 +0,0 @@
/**
* @brief Атомарная операция списания - перевод заблокированных средств в списанные
* @param coopname - имя кооператива
* @param account_id - идентификатор счета
* @param quantity - сумма списания
* @param comment - комментарий к операции
*/
[[eosio::action]]
void ledger::writeoff(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::name payer = coopname;
if (!has_auth(coopname)) {
payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
}
eosio::check(quantity.is_valid(), "Некорректная сумма");
eosio::check(quantity.amount > 0, "Сумма должна быть положительной");
eosio::check(quantity.symbol == _root_govern_symbol, "Некорректный символ валюты");
laccounts_index accounts(_ledger, coopname.value);
auto account_iter = accounts.find(account_id);
eosio::check(account_iter != accounts.end(), "Счет не найден");
// Проверяем достаточность заблокированных средств
eosio::check(account_iter->blocked >= quantity, "Недостаточно заблокированных средств для списания");
// Атомарно переводим средства из blocked в writeoff
accounts.modify(account_iter, payer, [&](auto& acc) {
acc.blocked -= quantity;
acc.writeoff += quantity;
});
}
@@ -1,32 +0,0 @@
/**
* @brief Атомарная операция отмены списания - перевод списанных средств обратно в заблокированные
* @param coopname - имя кооператива
* @param account_id - идентификатор счета
* @param quantity - сумма отмены списания
* @param comment - комментарий к операции
*/
[[eosio::action]]
void ledger::writeoffcnsl(eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::name payer = coopname;
if (!has_auth(coopname)) {
payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
}
eosio::check(quantity.is_valid(), "Некорректная сумма");
eosio::check(quantity.amount > 0, "Сумма должна быть положительной");
eosio::check(quantity.symbol == _root_govern_symbol, "Некорректный символ валюты");
laccounts_index accounts(_ledger, coopname.value);
auto account_iter = accounts.find(account_id);
eosio::check(account_iter != accounts.end(), "Счет не найден");
// Проверяем достаточность списанных средств
eosio::check(account_iter->writeoff >= quantity, "Недостаточно списанных средств для отмены списания");
// Атомарно переводим средства из writeoff в blocked
accounts.modify(account_iter, payer, [&](auto& acc) {
acc.writeoff -= quantity;
acc.blocked += quantity;
});
}
@@ -1,50 +0,0 @@
/**
* @brief Миграция данных из контракта fund
* Переносит данные из фондов fund в счета ledger
* Теперь счета создаются только при наличии средств для переноса
*/
void ledger::migrate(){
require_auth(_ledger);
// Получаем все кооперативы
cooperatives2_index coops(_registrator, _registrator.value);
for (auto coop_iter = coops.begin(); coop_iter != coops.end(); ++coop_iter) {
eosio::name coopname = coop_iter->username;
// Проверяем что счета еще не инициализированы
laccounts_index accounts(_ledger, coopname.value);
auto existing = accounts.begin();
if (existing != accounts.end()) {
continue; // Пропускаем уже мигрированные кооперативы
}
// Мигрируем данные из fund контракта
// Читаем кошелек кооператива
coopwallet_index coopwallets(_fund, coopname.value);
auto wallet_iter = coopwallets.find(0); // ID всегда 0
if (wallet_iter != coopwallets.end()) {
// Паевой фонд (circulating_account) -> счет 80 (SHARE_FUND)
if (wallet_iter->circulating_account.available.amount > 0) {
Ledger::add(_ledger, coopname, Ledger::accounts::SHARE_FUND,
wallet_iter->circulating_account.available,
"Миграция: перенос паевого фонда из fund контракта");
}
// Вступительные взносы (initial_account) -> счет 861 (ENTRANCE_FEES)
if (wallet_iter->initial_account.available.amount > 0) {
Ledger::add(_ledger, coopname, Ledger::accounts::ENTRANCE_FEES,
wallet_iter->initial_account.available,
"Миграция: перенос вступительных взносов из fund контракта");
}
// Накопительный счет членских взносов (accumulative_expense_account) -> счет 86 (TARGET_RECEIPTS)
if (wallet_iter->accumulative_expense_account.available.amount > 0) {
Ledger::add(_ledger, coopname, Ledger::accounts::TARGET_RECEIPTS,
wallet_iter->accumulative_expense_account.available,
"Миграция: перенос накопительного счета членских взносов из fund контракта");
}
}
}
}
@@ -1,37 +0,0 @@
/**
* @brief Авторизация операции после положительного решения совета
* @param coopname - имя кооператива
* @param writeoff_hash - хэш операции списания
*/
[[eosio::action]]
void ledger::auth(eosio::name coopname, checksum256 writeoff_hash) {
require_auth(_soviet);
auto writeoff_opt = Ledger::get_writeoff_by_hash(writeoff_hash);
eosio::check(writeoff_opt.has_value(), "Операция не найдена");
auto writeoff = writeoff_opt.value();
eosio::check(writeoff.coopname == coopname, "Неверный кооператив");
eosio::check(writeoff.status == "pending"_n, "Операция уже обработана");
// Обновляем статус операции
writeoffs_index writeoffs(_ledger, _ledger.value);
auto writeoff_iter = writeoffs.find(writeoff.id);
writeoffs.modify(writeoff_iter, _soviet, [&](auto& w) {
w.status = "approved"_n;
});
// Отправляем запрос на создание исходящего платежа в gateway через интерфейс
Action::send<createoutpay_interface>(
_gateway,
"createoutpay"_n,
_ledger,
coopname,
writeoff.username,
writeoff_hash,
writeoff.quantity,
_ledger, // callback_contract
"complete"_n, // confirm_callback
"decline"_n // decline_callback
);
}
@@ -1,33 +0,0 @@
/**
* @brief Коллбэк при успешном завершении платежа
* @param coopname - имя кооператива
* @param writeoff_hash - хэш операции списания
*/
[[eosio::action]]
void ledger::complete(eosio::name coopname, checksum256 writeoff_hash) {
require_auth(_gateway);
auto writeoff_opt = Ledger::get_writeoff_by_hash(writeoff_hash);
eosio::check(writeoff_opt.has_value(), "Операция не найдена");
auto writeoff = writeoff_opt.value();
eosio::check(writeoff.coopname == coopname, "Неверный кооператив");
eosio::check(writeoff.status == "approved"_n, "Операция не одобрена");
// Обновляем статус операции
writeoffs_index writeoffs(_ledger, _ledger.value);
auto writeoff_iter = writeoffs.find(writeoff.id);
writeoffs.modify(writeoff_iter, _gateway, [&](auto& w) {
w.status = "paid"_n;
});
// Списываем средства со счета
laccounts_index accounts(_ledger, coopname.value);
auto account_iter = accounts.find(writeoff.account_id);
eosio::check(account_iter != accounts.end(), "Счет не найден");
accounts.modify(account_iter, _gateway, [&](auto& acc) {
acc.blocked -= writeoff.quantity;
acc.writeoff += writeoff.quantity;
});
}
@@ -1,73 +0,0 @@
/**
* @brief Создание заявления в совет для списания средств
* @param coopname - имя кооператива
* @param username - инициатор заявления
* @param account_id - идентификатор счета для списания
* @param quantity - сумма списания
* @param reason - обоснование списания
* @param document - документ обоснования
* @param writeoff_hash - внешний хэш операции списания
*/
[[eosio::action]]
void ledger::create(eosio::name coopname, eosio::name username, uint64_t account_id, eosio::asset quantity, std::string reason, document2 document, checksum256 writeoff_hash) {
require_auth(coopname);
eosio::check(quantity.is_valid(), "Некорректная сумма");
eosio::check(quantity.amount > 0, "Сумма должна быть положительной");
eosio::check(quantity.symbol == _root_govern_symbol, "Некорректный символ валюты");
eosio::check(reason.length() > 0, "Обоснование должно быть от 1 символа");
// Проверяем что кооператив существует
cooperatives2_index coops(_registrator, _registrator.value);
auto coop_iter = coops.find(coopname.value);
eosio::check(coop_iter != coops.end(), "Кооператив не найден");
// Проверяем что счет существует
laccounts_index accounts(_ledger, coopname.value);
auto account_iter = accounts.find(account_id);
eosio::check(account_iter != accounts.end(), "Счет не найден");
// Проверяем достаточность средств
eosio::check(account_iter -> available >= quantity, "Недостаточно средств на счету");
// Проверяем уникальность writeoff_hash
auto existing_writeoff = Ledger::get_writeoff_by_hash(writeoff_hash);
eosio::check(!existing_writeoff.has_value(), "Операция с таким хэшем уже существует");
// Создаем операцию ожидающую решения совета
auto operation_id = get_global_id_in_scope(_ledger, _ledger, "writeoffs"_n);
writeoffs_index writeoffs(_ledger, _ledger.value);
writeoffs.emplace(username, [&](auto& op) {
op.id = operation_id;
op.coopname = coopname;
op.username = username;
op.account_id = account_id;
op.quantity = quantity;
op.reason = reason;
op.document = document;
op.writeoff_hash = writeoff_hash;
op.status = "pending"_n;
});
// Создаем агенду в совете через Action::send
Action::send<createagenda_interface>(
_soviet,
"createagenda"_n,
username,
coopname,
username,
get_valid_soviet_action("ledgerwthd"_n), // тип решения
writeoff_hash,
_ledger, // callback_contract
"auth"_n, // confirm_callback
"decline"_n, // decline_callback
document,
reason
);
// Блокируем средства на счету
std::string comment = "Служебная записка отправлена в совет для списания средств со счета " + account_iter->name + " на сумму " + quantity.to_string();
Ledger::block(coopname, coopname, account_id, quantity, comment);
}
@@ -1,22 +0,0 @@
/**
* @brief Коллбэк при отклонении платежа или решения совета
* @param coopname - имя кооператива
* @param writeoff_hash - хэш операции списания
* @param reason - причина отклонения
*/
[[eosio::action]]
void ledger::decline(eosio::name coopname, checksum256 writeoff_hash, std::string reason) {
// Может быть вызван от _soviet (отклонение решения) или _gateway (отклонение платежа)
eosio::check(has_auth(_soviet) || has_auth(_gateway), "Недостаточно прав для отклонения операции");
auto writeoff_opt = Ledger::get_writeoff_by_hash(writeoff_hash);
eosio::check(writeoff_opt.has_value(), "Операция не найдена");
auto writeoff = writeoff_opt.value();
eosio::check(writeoff.coopname == coopname, "Неверный кооператив");
// Обновляем статус операции
writeoffs_index writeoffs(_ledger, _ledger.value);
auto writeoff_iter = writeoffs.find(writeoff.id);
writeoffs.erase(writeoff_iter);
}
+6 -6
View File
@@ -164,10 +164,10 @@ struct org_data {
std::string announce; ///< Анонс
std::string description; ///< Описание
eosio::asset initial; ///< Вступительный взнос физического лица / ип
eosio::asset minimum; ///< Минимальный паевой взнос физического лица / ип
eosio::asset minimum; ///< Минимальный паевый взнос физического лица / ип
eosio::asset org_initial; ///< Вступительный взнос юридического лица
eosio::asset org_minimum; ///< Минимальный паевой взнос юридического лица
eosio::asset org_minimum; ///< Минимальный паевый взнос юридического лица
};
@@ -192,11 +192,11 @@ struct [[eosio::table, eosio::contract(REGISTRATOR)]] cooperative {
eosio::asset registration; ///< Регистрационный взнос физического лица / ип
eosio::asset initial; ///< Вступительный членский взнос физического лица / ип
eosio::asset minimum; ///< Минимальный паевой взнос физического лица / ип
eosio::asset minimum; ///< Минимальный паевый взнос физического лица / ип
eosio::binary_extension<eosio::asset> org_registration; ///< Регистрационный взнос юридического лица
eosio::binary_extension<eosio::asset> org_initial; ///< Вступительный членский взнос юридического лица
eosio::binary_extension<eosio::asset> org_minimum; ///< Минимальный паевой взнос юридического лица
eosio::binary_extension<eosio::asset> org_minimum; ///< Минимальный паевый взнос юридического лица
eosio::binary_extension<eosio::name> status; ///< Статус процесса подключения
eosio::binary_extension<eosio::time_point_sec> created_at; ///< Дата поступления заявки на подключение (pending | ... | active | blocked)
@@ -303,11 +303,11 @@ struct [[eosio::table, eosio::contract(REGISTRATOR)]] cooperative2 {
eosio::asset registration; ///< Регистрационный взнос физического лица / ип
eosio::asset initial; ///< Вступительный членский взнос физического лица / ип
eosio::asset minimum; ///< Минимальный паевой взнос физического лица / ип
eosio::asset minimum; ///< Минимальный паевый взнос физического лица / ип
eosio::binary_extension<eosio::asset> org_registration; ///< Регистрационный взнос юридического лица
eosio::binary_extension<eosio::asset> org_initial; ///< Вступительный членский взнос юридического лица
eosio::binary_extension<eosio::asset> org_minimum; ///< Минимальный паевой взнос юридического лица
eosio::binary_extension<eosio::asset> org_minimum; ///< Минимальный паевый взнос юридического лица
eosio::binary_extension<eosio::name> status; ///< Статус процесса подключения
eosio::binary_extension<eosio::time_point_sec> created_at; ///< Дата поступления заявки на подключение (pending | ... | active | blocked)
-15
View File
@@ -76,21 +76,6 @@ struct [[eosio::table, eosio::contract(BRANCH)]] coobranch {
bool is_account_in_trusted(const eosio::name& account) const {
return std::find(trusted.begin(), trusted.end(), account) != trusted.end();
}
/**
* @brief Проверяет права доступа пользователя к данному кооперативному участку
* @param username Имя пользователя для проверки
* @return true если пользователь имеет права доступа, false в противном случае
*/
bool is_user_authorized(const eosio::name& username) const {
// Проверяем является ли пользователь доверенным лицом (trustee)
if (trustee == username) {
return true;
}
// Проверяем находится ли пользователь в списке доверенных (trusted)
return is_account_in_trusted(username);
}
};
typedef eosio::multi_index<"branches"_n, coobranch,
+153 -1
View File
@@ -1,5 +1,157 @@
#pragma once
// Структуры exchange_params и request перенесены в shared_marketplace.hpp
/**
\ingroup public_tables
\brief Параметры заявки на обмен.
*
* Эта структура предоставляет набор данных, которые требуются для создания или обновления заявки на обмен в контракте "marketplace".
*
* @details Следующие параметры определяют заявку:
* - username: Имя пользователя, инициирующего или обновляющего заявку.
* - parent_id: Идентификатор родительской заявки (если есть).
* - coopname: Имя кооператива.
* - units: Количество частей (штук) товара или услуги для обмена.
* - unit_cost: Цена за единицу (штуку) товара или услуги, выраженная в определенном формате asset.
* - data: Содержит дополнительные данные, специфичные для заявки (например, условия обмена).
* - meta: Метаданные, предоставляющие дополнительную информацию о заявке (например, описание товара или условия обмена).
*/
struct exchange_params {
eosio::name username; /*!< Имя пользователя, инициирующего или обновляющего заявку */
uint64_t parent_id; /*!< Идентификатор родительской заявки */
uint64_t program_id; /*!< Идентификатор программы */
eosio::name coopname; /*!< Имя кооператива */
uint64_t units; /*!< Количество частей (штук) товара или услуги */
eosio::asset unit_cost; /*!< Цена за единицу (штуку) товара или услуги */
uint64_t product_lifecycle_secs; /*!< Время жизни продукта, заявляемое поставщиком */
std::optional<document2> document; /*!< Сопутствующий подписанный документ на взнос или возврат взноса */
std::string data; /*!< Дополнительные данные, специфичные для заявки */
std::string meta; /*!< Метаданные о заявке */
};
/**
* @brief Таблица обменов для контракта "marketplace"
* @ingroup public_tables
* Эта таблица используется для хранения информации об обменных заявках в системе.
*
* @param id Идентификатор обмена, используемый как первичный ключ
* @param parent_id Идентификатор родительской заявки (если есть)
* @param type Тип обмена (покупка, продажа и т.д.)
* @param status Статус обмена (например, "опубликовано", "на модерации" и т.д.)
* @param username Имя пользователя, создавшего заявку
* @param token_contract Имя контракта токена
* @param unit_cost Цена за единицу товара в заявке
* @param remain_units Оставшееся количество товара
* @param blocked_units Заблокированное количество товара
* @param delivered_units Количество доставленного товара
* @param data Дополнительные данные, связанные с заявкой
* @param meta Метаданные заявки
*
* Дополнительные индексы по status, type и parent_id позволяют искать заявки по этим полям.
*
* Пример использования:
* @code
* requests_index exchange(_me, coopname.value);
* auto exchange_order = exchange.find(id);
* @endcode
*/
struct [[eosio::table, eosio::contract(MARKETPLACE)]] request {
uint64_t id; /*!< идентификатор обмена */
uint64_t parent_id; /*!< идентификатор родительской заявки */
uint64_t program_id; /*!< идентификатор программы */
eosio::name coopname; /*!< имя аккаунта кооператива */
eosio::name type; /*!< тип обмена */
eosio::name status; /*!< статус обмена */
eosio::name username; /*!< имя аккаунта владельца заявки */
eosio::name parent_username; /*!< имя аккаунта владельца объявления */
eosio::name token_contract; /*!< имя контракта токена */
eosio::asset unit_cost;/*!< себестоимость единицы товара от поставщика */
eosio::asset supplier_amount; /*!< сумма взноса поставщика */
eosio::asset total_cost; /*!< сумма взноса заказчика */
eosio::asset membership_fee; /*!< членский взнос заказчика */
uint64_t remain_units; /*!< оставшееся количество товара */
uint64_t blocked_units; /*!< заблокированное количество товара */
uint64_t delivered_units; /*!< количество доставленного товара */
std::string data; /*!< дополнительные данные */
std::string meta; /*!< метаданные заявки */
eosio::name money_contributor;
eosio::name product_contributor;
document2 contribute_product_statement;
document2 return_product_statement;
uint64_t contribution_product_decision_id;
document2 contribution_product_authorization;
uint64_t return_product_decision_id;
document2 return_product_authorization;
document2 product_contribution_act_validation;
document2 product_contribution_act;
document2 product_recieve_act;
document2 product_recieve_act_validation;
uint64_t product_lifecycle_secs;
uint64_t cancellation_fee; //up to 100
eosio::asset cancellation_fee_amount;
eosio::time_point_sec created_at;
eosio::time_point_sec accepted_at;
eosio::time_point_sec supplied_at;
eosio::time_point_sec delivered_at;
eosio::time_point_sec recieved_at;
eosio::time_point_sec completed_at;
eosio::time_point_sec declined_at;
eosio::time_point_sec disputed_at;
eosio::time_point_sec canceled_at;
// eosio::time_point_sec expired_at;
eosio::time_point_sec warranty_delay_until;
eosio::time_point_sec deadline_for_receipt;
bool is_warranty_return = false;
uint64_t warranty_return_id;
uint64_t primary_key() const { return id; } /*!< return id - primary_key */
uint64_t by_coop() const {return coopname.value;} /*!< кооператив */
uint64_t by_status() const { return status.value; } /*!< индекс по статусу */
uint64_t by_program() const { return program_id; } /*!< индекс по программе */
uint64_t by_type() const { return type.value; } /*!< индекс по типу */
uint64_t by_parent() const { return parent_id; } /*!< индекс по родительскому ID */
uint64_t by_username() const { return username.value;} /*!< индекс по имени аккаунта */
uint64_t by_parent_username() const { return parent_username.value;} /*!< индекс по имени аккаунта владельца объявления */
uint64_t by_created() const { return created_at.sec_since_epoch();}
uint64_t by_completed() const { return completed_at.sec_since_epoch();}
uint64_t by_declined() const { return declined_at.sec_since_epoch();}
uint64_t by_canceled() const { return canceled_at.sec_since_epoch();}
uint64_t by_warranty_id() const { return warranty_return_id;}
// uint64_t by_expired() const { return expired_at.sec_since_epoch();}
};
typedef eosio::multi_index<
"requests"_n, request,
eosio::indexed_by<"bycoop"_n, eosio::const_mem_fun<request, uint64_t, &request::by_coop>>,
eosio::indexed_by<"bystatus"_n, eosio::const_mem_fun<request, uint64_t, &request::by_status>>,
eosio::indexed_by<"bytype"_n, eosio::const_mem_fun<request, uint64_t, &request::by_type>>,
eosio::indexed_by<"byprogram"_n, eosio::const_mem_fun<request, uint64_t, &request::by_program>>,
eosio::indexed_by<"byparent"_n, eosio::const_mem_fun<request, uint64_t, &request::by_parent>>,
eosio::indexed_by<"byusername"_n, eosio::const_mem_fun<request, uint64_t, &request::by_username>>,
eosio::indexed_by<"bypausername"_n, eosio::const_mem_fun<request, uint64_t, &request::by_parent_username>>,
eosio::indexed_by<"bycreated"_n, eosio::const_mem_fun<request, uint64_t, &request::by_created>>,
eosio::indexed_by<"bycompleted"_n, eosio::const_mem_fun<request, uint64_t, &request::by_completed>>,
eosio::indexed_by<"bydeclined"_n, eosio::const_mem_fun<request, uint64_t, &request::by_declined>>,
eosio::indexed_by<"bycanceled"_n, eosio::const_mem_fun<request, uint64_t, &request::by_canceled>>,
eosio::indexed_by<"bywarrantyid"_n, eosio::const_mem_fun<request, uint64_t, &request::by_warranty_id>>
// eosio::indexed_by<"byexpired"_n, eosio::const_mem_fun<request, uint64_t, &request::by_expired>>
>
requests_index; /*!< Тип мультииндекса для таблицы обменов */
+1 -12
View File
@@ -1,17 +1,9 @@
#include <eosio/eosio.hpp>
#include <eosio/asset.hpp>
#include <eosio/symbol.hpp>
#include <eosio/system.hpp>
#include <eosio/crypto.hpp>
#include <eosio/transaction.hpp>
#include <eosio/permission.hpp>
#include "consts.hpp"
#include "registry.hpp"
#include "utils.hpp"
#include "drafts.hpp"
#include "shared_document.hpp"
#include "accounts.hpp"
#include "changes.hpp"
#include "coops.hpp"
#include "counts.hpp"
#include "permissions.hpp"
@@ -25,13 +17,10 @@
#include "shared_actions.hpp"
#include "shared_soviet.hpp"
#include "shared_wallet.hpp"
#include "shared_fund.hpp"
#include "shared_gateway.hpp"
#include "shared_ledger.hpp"
#include "shared_approver.hpp"
#include "shared_registrator.hpp"
#include "shared_loan.hpp"
#include "shared_branch.hpp"
#include "shared_marketplace.hpp"
#include "approves.hpp"
#include "debts.hpp"
+3 -15
View File
@@ -93,7 +93,7 @@ static constexpr eosio::name _result_action = "result"_n;
//program_types
static constexpr eosio::name _wallet_program = "wallet"_n;
static constexpr eosio::name _marketplace_program = "marketplace"_n;
static constexpr eosio::name _sosedi_program = "cooplace"_n;
static constexpr eosio::name _source_program = "source"_n;
static constexpr eosio::name _capital_program = "capital"_n;
@@ -117,18 +117,11 @@ static const std::set<eosio::name> soviet_actions = {
//WALLET
"createwthd"_n, //создать заявление на возврат паевого взноса
//LEDGER
"ledgerwthd"_n, //заявление на списание со счета через ledger
//MARKETPLACE
"authoffs2c"_n, //заявление на взнос имуществом
"authoffc2r"_n, //заявление на возврат паевого взноса имуществом
};
//program_ids
static constexpr uint64_t _wallet_program_id = 1;
static constexpr uint64_t _marketplace_program_id = 2;
static constexpr uint64_t _sosedi_program_id = 2;
static constexpr uint64_t _capital_program_id = 3;
static constexpr int64_t REWARD_SCALE = 100000000; ///< Масштабный коэффициент для вознаграждений (1e8).
@@ -150,10 +143,7 @@ static constexpr int64_t REWARD_SCALE = 100000000; ///< Масштабный к
#define CAPITAL "capital"
#define WALLET "wallet"
#define LOAN "loan"
#define LEDGER "ledger"
#define MEET "meet"
#define LEDGER "ledger"
/**
* @ingroup public_consts
* @{
@@ -174,7 +164,6 @@ static constexpr int64_t REWARD_SCALE = 100000000; ///< Масштабный к
static constexpr eosio::name _branch = "branch"_n;
static constexpr eosio::name _loan = "loan"_n;
static constexpr eosio::name _meet = "meet"_n;
static constexpr eosio::name _ledger = "ledger"_n;
static constexpr eosio::name _power_account = "eosio.power"_n;
static constexpr eosio::name _saving_account = "eosio.saving"_n;
@@ -199,8 +188,7 @@ static constexpr int64_t REWARD_SCALE = 100000000; ///< Масштабный к
"eosio.msig"_n,
"eosio.wrap"_n,
"eosio.power"_n,
"eosio.saving"_n,
"ledger"_n
"eosio.saving"_n
// Добавьте остальные стандартные или пользовательские контракты по необходимости
};
+1 -1
View File
@@ -165,7 +165,7 @@ struct [[eosio::table, eosio::contract(SOVIET)]] participant {
eosio::name status; //accepted | blocked
bool is_initial = true; ///< флаг, указывающий, внесен ли регистрационный взнос.
bool is_minimum = true; ///< флаг, указывающий, внесен ли минимальный паевой взнос.
bool is_minimum = true; ///< флаг, указывающий, внесен ли минимальный паевый взнос.
bool has_vote = true; ///< флаг, указывающий, имеет ли член право голоса.
eosio::binary_extension<eosio::name> type; ///< individual | entrepreneur | organization
-2
View File
@@ -30,8 +30,6 @@ struct document2 {
// Версия стандарта документа
std::string version;
// uint64_t template_id; ///< было бы удобно но этого нет
// Хэши
eosio::checksum256 hash; // общий хэш (doc_hash + meta_hash)
eosio::checksum256 doc_hash; // хэш содержимого документа
+5 -5
View File
@@ -6,7 +6,7 @@
struct [[eosio::table, eosio::contract(SOVIET)]] program {
uint64_t id; /*!< идентификатор обмена */
uint64_t draft_id; ///< Ссылка на шаблон условий
eosio::name program_type; /*!< тип кооперативной программы (wallet | market | capital) */
eosio::name program_type; /*!< тип кооперативной программы (wallet | market | ...) */
eosio::name coopname; /*!< имя аккаунта кооператива */
bool is_active;
@@ -17,9 +17,9 @@ struct [[eosio::table, eosio::contract(SOVIET)]] program {
std::string images;
std::string meta;
eosio::name calculation_type; /*!< LEGACY тип настройки платежей по программе ( absolute | relative | free ) */
uint64_t membership_percent_fee; /*!< LEGACY процент комиссии со взноса */
eosio::asset fixed_membership_contribution; /*!< LEGACY Членский взнос */
eosio::name calculation_type; /*!< тип настройки платежей по программе ( absolute | relative | free ) */
uint64_t membership_percent_fee; /*!< процент комиссии со взноса */
eosio::asset fixed_membership_contribution; /*!< Членский взнос */
eosio::time_point_sec start_at; /*!< Время открытия */
eosio::time_point_sec expired_at; /*!< Временное ограничение */
@@ -120,7 +120,7 @@ struct ProgramInfo {
static const std::map<eosio::name, ProgramInfo> program_map = {
{_wallet_program, {1, 1}}, // program_id = 1, draft_id = 1
{_marketplace_program, {2, 699}}, // program_id = 2, draft_id = 699
{_sosedi_program, {2, 699}}, // program_id = 2, draft_id = 699
{_source_program, {3, 0}}, // program_id = 3, draft_id = 0
{_capital_program, {4, 1000}} // program_id = 4, draft_id = 1000
};
@@ -1,62 +0,0 @@
namespace Document {
/**
* @brief Проверяет, что переданный документ соответствует ожидаемому шаблону
* @param document Документ для проверки
* @param expected_registry_id Ожидаемый идентификатор шаблона
*/
inline void validate_registry_id(document2 document, uint64_t expected_registry_id) {
uint64_t registry_id = extract_registry_id_from_meta(document.meta);
eosio::check(registry_id == expected_registry_id, "Передан неверный шаблон документа");
}
/*!
* \brief Структура именованного документа
*/
struct named_document {
name name; /*!< имя документа (до 12 символов) */
document2 document; /*!< сам документ */
};
/**
* @brief Добавить документ с проверкой длины имени
* @param docs Вектор документов
* @param name Имя документа
* @param doc Документ
*/
inline void add_document(std::vector<named_document>& docs, const name& name, const document2& doc) {
docs.push_back({name, doc});
}
/**
* @brief Найти документ по имени
* @param docs Вектор документов
* @param name Имя для поиска
* @param found_doc Найденный документ (выходной параметр)
* @return true если документ найден
*/
inline bool find_document(const std::vector<named_document>& docs, const name& name, document2& found_doc) {
for (const auto& nd : docs) {
if (nd.name == name) {
found_doc = nd.document;
return true;
}
}
return false;
}
/**
* @brief Проверить наличие документа
* @param docs Вектор документов
* @param name Имя для поиска
* @return true если документ найден
*/
inline bool has_document(const std::vector<named_document>& docs, const name& name) {
for (const auto& nd : docs) {
if (nd.name == name) {
return true;
}
}
return false;
}
}
@@ -1,3 +0,0 @@
namespace Fund {
}
@@ -1,369 +0,0 @@
#pragma once
/**
* @brief Структура бухгалтерского счета
*/
struct [[eosio::table, eosio::contract(LEDGER)]] laccount {
uint64_t id; ///< Идентификатор счета
std::string name; ///< Название счета
eosio::asset available; ///< Доступные средства (было allocation)
eosio::asset blocked; ///< Заблокированные средства
eosio::asset writeoff; ///< Списанные средства
uint64_t primary_key() const { return id; }
/**
* @brief Проверяет, пуст ли счет (все балансы равны нулю)
*/
bool is_empty() const {
return available.amount == 0 && blocked.amount == 0 && writeoff.amount == 0;
}
/**
* @brief Получает общий баланс счета
*/
eosio::asset get_total() const {
return available + blocked + writeoff;
}
/**
* @brief Получает всего доступных + заблокированных средств (без списанных)
*/
eosio::asset get_balance() const {
return available + blocked;
}
};
/**
* @brief Типы индексов для таблиц ledger
*/
typedef eosio::multi_index<"accounts"_n, laccount> laccounts_index;
/**
* @brief Структура для операций ожидающих решения совета
*/
struct [[eosio::table, eosio::contract(LEDGER)]] writeoff_op {
uint64_t id; ///< Идентификатор операции
eosio::name coopname; ///< Имя кооператива
eosio::name username; ///< Инициатор операции
uint64_t account_id; ///< Счет для операции
eosio::asset quantity; ///< Сумма операции
std::string reason; ///< Обоснование
document2 document; ///< Документ обоснования
checksum256 writeoff_hash; ///< Хэш операции списания
eosio::name status; ///< Статус: pending, approved, declined, paid
uint64_t primary_key() const { return id; }
uint64_t by_coop() const { return coopname.value; }
checksum256 by_hash() const { return writeoff_hash; }
};
typedef eosio::multi_index<"writeoffs"_n, writeoff_op,
eosio::indexed_by<"bycoop"_n, eosio::const_mem_fun<writeoff_op, uint64_t, &writeoff_op::by_coop>>,
eosio::indexed_by<"byhash"_n, eosio::const_mem_fun<writeoff_op, checksum256, &writeoff_op::by_hash>>
> writeoffs_index;
/**
* @brief Класс Ledger для интеграции с ledger контрактом
*/
class Ledger {
public:
/**
* @brief Валидные действия ledger для интеграции с другими контрактами
*/
static const std::set<eosio::name> ledger_actions;
/**
* @brief Проверка корректности действия ledger
*/
static eosio::name get_valid_ledger_action(const eosio::name& action);
/**
* @brief Проверка корректности символа валюты для операций ledger
*/
static void check_ledger_symbol(const eosio::asset& amount);
/**
* @brief Проверка положительности суммы для операций ledger
*/
static void check_positive_amount(const eosio::asset& amount);
// Основные операции
static void add(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
static void sub(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
static void transfer(eosio::name actor, eosio::name coopname, uint64_t from_account_id, uint64_t to_account_id, eosio::asset quantity, std::string comment);
// Операции блокировки/разблокировки
static void block(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
static void unblock(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
// Атомарные операции списания
static void writeoff(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
static void writeoffcnsl(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment);
// Специализированные методы для членских взносов
static void add_membership_fee(eosio::name actor, eosio::name coopname, eosio::asset quantity, std::string comment);
static void sub_membership_fee(eosio::name actor, eosio::name coopname, eosio::asset quantity, std::string comment);
static void block_membership_fee(eosio::name actor, eosio::name coopname, eosio::asset quantity, std::string comment);
static void unblock_membership_fee(eosio::name actor, eosio::name coopname, eosio::asset quantity, std::string comment);
/**
* @brief Получает операцию списания по хэшу
*/
static std::optional<writeoff_op> get_writeoff_by_hash(const checksum256 &writeoff_hash);
/**
* @brief Получает название счета по его ID из ACCOUNT_MAP
*/
static std::string get_account_name_by_id(uint64_t account_id);
/**
* @brief Константы счетов
*/
struct accounts {
// Денежные средства
static constexpr uint64_t CASH = 50; // Касса
static constexpr uint64_t BANK_ACCOUNT = 51; // Расчетный счет
// Расчеты с пайщиками
static constexpr uint64_t MEMBER_SETTLEMENTS = 75; // Расчеты с пайщиками по внесению/возврату паевых взносов
static constexpr uint64_t MEMBER_DEBT = 751; // Задолженность пайщиков по внесению взносов в паевой фонд
static constexpr uint64_t INCOME_ACCRUALS = 752; // Начисление доходов участникам от предпринимательской деятельности ПО (кооперативные выплаты)
// Паевой фонд
static constexpr uint64_t SHARE_FUND = 80; // Паевой фонд (складочный капитал)
// Расчеты с пайщиками (дебиторами и кредиторами)
static constexpr uint64_t MEMBER_FEES = 761; // По членским взносам
static constexpr uint64_t PROPERTY_TRANSFER = 762; // По передаче имущества для некоммерческой деятельности
static constexpr uint64_t OTHER_SETTLEMENTS = 763; // Другие расчеты
// Расчеты по займам
static constexpr uint64_t LOANS_ISSUED = 583; // Расчеты по выданным займам
static constexpr uint64_t LOAN_INTEREST = 911; // Внесение процентов за пользование займами
// Финансовые вложения из средств ПО
static constexpr uint64_t FINANCIAL_INVESTMENTS = 58; // Финансовые вложения из средств ПО
static constexpr uint64_t SHARES_AND_STAKES = 581; // Доли, паи и акции в организациях, где участвует ПО
static constexpr uint64_t SECURITIES = 582; // Облигации (государственные ценные бумаги)
// Расчеты с дебиторами и кредиторами
static constexpr uint64_t DEBTORS_CREDITORS = 76; // Расчеты с дебиторами и кредиторами
// Запасы, затраты, расчеты, собственные средства
static constexpr uint64_t FIXED_ASSETS = 1; // Основные средства
static constexpr uint64_t INTANGIBLE_ASSETS = 4; // Нематериальные активы
static constexpr uint64_t MATERIALS_GOODS = 10; // Материалы, товары
static constexpr uint64_t MAIN_PRODUCTION = 20; // Основное производство
static constexpr uint64_t NON_PROFIT_ACTIVITY = 201; // Некоммерческая деятельность
static constexpr uint64_t GENERAL_EXPENSES = 26; // Общехозяйственные расходы (содержание ПО)
static constexpr uint64_t RESERVES = 63; // Резервы по сомнительным долгам
static constexpr uint64_t LONG_TERM_LOANS = 67; // Расчеты по долгосрочным кредитам и займам
static constexpr uint64_t TAXES_FEES = 68; // Расчеты с бюджетом по налогам и сборам
static constexpr uint64_t SOCIAL_INSURANCE = 69; // Расчеты по социальному страхованию и обеспечению
static constexpr uint64_t SALARY = 70; // Заработная плата
static constexpr uint64_t ACCOUNTABLE_PERSONS = 71; // Расчеты с подотчетными лицами
static constexpr uint64_t ADDITIONAL_CAPITAL = 83; // Добавочный капитал
static constexpr uint64_t FUNDS_PO_1 = 831; // Фонды ПО (вариант пополнения фондов ПО)
static constexpr uint64_t CURRENT_YEAR_PROFIT = 841; // Нераспределенная прибыль (убыток) отчетного года
static constexpr uint64_t PREVIOUS_YEARS_PROFIT = 842; // Нераспределенная прибыль (непокрытый убыток) прошлых лет
static constexpr uint64_t FUNDS_PO_2 = 843; // Фонды ПО (вариант пополнения фондов ПО)
static constexpr uint64_t UNDISTRIBUTED_PROFIT = 84; // Нераспределенная прибыль (непокрытый убыток)
static constexpr uint64_t TARGET_RECEIPTS = 86; // Целевые поступления
static constexpr uint64_t ENTRANCE_FEES = 861; // Вступительные взносы
static constexpr uint64_t RESERVE_FUND = 862; // Резервный фонд
static constexpr uint64_t INDIVISIBLE_FUND = 863; // Неделимый фонд
static constexpr uint64_t ECONOMIC_ACTIVITY_FUND = 864; // Фонд обеспечения хозяйственной деятельности
static constexpr uint64_t MUTUAL_SECURITY_FUND = 865; // Фонд взаимного обеспечения
static constexpr uint64_t DEVELOPMENT_FUND = 866; // Фонд развития потребительской кооперации
static constexpr uint64_t OTHER_INCOME_EXPENSES = 91; // Прочие доходы и расходы
static constexpr uint64_t FUTURE_EXPENSES_RESERVE = 96; // Резерв предстоящих расходов
static constexpr uint64_t FUTURE_INCOME = 98; // Доходы будущих периодов
static constexpr uint64_t FREE_RECEIPT = 981; // Безвозмездное получение имущества
};
};
/**
* @brief Карта счетов для инициализации бухгалтерской книги
* СОХРАНЯЕМ - используется для получения названий при автосоздании счетов
*/
static const std::vector<std::tuple<uint64_t, std::string>> ACCOUNT_MAP = {
{Ledger::accounts::FIXED_ASSETS, "Основные средства"},
{Ledger::accounts::INTANGIBLE_ASSETS, "Нематериальные активы"},
{Ledger::accounts::MATERIALS_GOODS, "Материалы, товары"},
{Ledger::accounts::MAIN_PRODUCTION, "Основное производство"},
{Ledger::accounts::NON_PROFIT_ACTIVITY, "Некоммерческая деятельность"},
{Ledger::accounts::GENERAL_EXPENSES, "Общехозяйственные расходы"},
{Ledger::accounts::CASH, "Касса"},
{Ledger::accounts::BANK_ACCOUNT, "Расчетный счет"},
{Ledger::accounts::RESERVES, "Резервы по сомнительным долгам"},
{Ledger::accounts::LONG_TERM_LOANS, "Расчеты по долгосрочным кредитам и займам"},
{Ledger::accounts::TAXES_FEES, "Расчеты с бюджетом по налогам и сборам"},
{Ledger::accounts::SOCIAL_INSURANCE, "Расчеты по социальному страхованию и обеспечению"},
{Ledger::accounts::SALARY, "Заработная плата"},
{Ledger::accounts::ACCOUNTABLE_PERSONS, "Расчеты с подотчетными лицами"},
{Ledger::accounts::MEMBER_SETTLEMENTS, "Расчеты с пайщиками по внесению/возврату паевых взносов"},
{Ledger::accounts::SHARE_FUND, "Паевой фонд (складочный капитал)"},
{Ledger::accounts::ADDITIONAL_CAPITAL, "Добавочный капитал"},
{Ledger::accounts::TARGET_RECEIPTS, "Целевые поступления"},
{Ledger::accounts::OTHER_INCOME_EXPENSES, "Прочие доходы и расходы"},
{Ledger::accounts::FUTURE_EXPENSES_RESERVE, "Резерв предстоящих расходов"},
{Ledger::accounts::FUTURE_INCOME, "Доходы будущих периодов"},
{Ledger::accounts::SHARES_AND_STAKES, "Доли, паи и акции в организациях"},
{Ledger::accounts::SECURITIES, "Облигации (государственные ценные бумаги)"},
{Ledger::accounts::LOANS_ISSUED, "Расчеты по выданным займам"},
{Ledger::accounts::MEMBER_DEBT, "Задолженность пайщиков по внесению взносов в паевой фонд"},
{Ledger::accounts::INCOME_ACCRUALS, "Начисление доходов участникам от предпринимательской деятельности ПО"},
{Ledger::accounts::MEMBER_FEES, "По членским взносам"},
{Ledger::accounts::PROPERTY_TRANSFER, "По передаче имущества для некоммерческой деятельности"},
{Ledger::accounts::OTHER_SETTLEMENTS, "Другие расчеты"},
{Ledger::accounts::DEBTORS_CREDITORS, "Расчеты с дебиторами и кредиторами"},
{Ledger::accounts::ENTRANCE_FEES, "Вступительные взносы"},
{Ledger::accounts::FUNDS_PO_1, "Фонды ПО (вариант пополнения фондов ПО)"},
{Ledger::accounts::CURRENT_YEAR_PROFIT, "Нераспределенная прибыль (убыток) отчетного года"},
{Ledger::accounts::PREVIOUS_YEARS_PROFIT, "Нераспределенная прибыль (непокрытый убыток) прошлых лет"},
{Ledger::accounts::FUNDS_PO_2, "Фонды ПО (вариант пополнения фондов ПО)"},
{Ledger::accounts::UNDISTRIBUTED_PROFIT, "Нераспределенная прибыль (непокрытый убыток)"},
{Ledger::accounts::RESERVE_FUND, "Резервный фонд"},
{Ledger::accounts::INDIVISIBLE_FUND, "Неделимый фонд"},
{Ledger::accounts::ECONOMIC_ACTIVITY_FUND, "Фонд обеспечения хозяйственной деятельности"},
{Ledger::accounts::MUTUAL_SECURITY_FUND, "Фонд взаимного обеспечения"},
{Ledger::accounts::DEVELOPMENT_FUND, "Фонд развития потребительской кооперации"},
{Ledger::accounts::LOAN_INTEREST, "Внесение процентов за пользование займами"},
{Ledger::accounts::FINANCIAL_INVESTMENTS, "Финансовые вложения из средств ПО"},
{Ledger::accounts::FREE_RECEIPT, "Безвозмездное получение имущества"}
};
// Реализация статических методов класса Ledger
const std::set<eosio::name> Ledger::ledger_actions = {
"add"_n, // пополнение счета
"sub"_n, // списание со счета
"transfer"_n, // перевод между счетами
"block"_n, // блокировка средств
"unblock"_n, // разблокировка средств
"writeoff"_n, // атомарное списание средств
"writeoffcnsl"_n, // атомарная отмена списания
"create"_n, // создание заявления на списание
"auth"_n, // авторизация списания
"complete"_n, // завершение операции
"decline"_n // отклонение операции
};
inline eosio::name Ledger::get_valid_ledger_action(const eosio::name& action) {
eosio::check(ledger_actions.contains(action), "Недопустимое имя действия ledger");
return action;
}
inline void Ledger::check_ledger_symbol(const eosio::asset& amount) {
eosio::check(amount.symbol == _root_govern_symbol, "Некорректный символ валюты для операций ledger");
}
inline void Ledger::check_positive_amount(const eosio::asset& amount) {
eosio::check(amount.is_valid(), "Некорректная сумма");
eosio::check(amount.amount > 0, "Сумма должна быть положительной");
}
inline std::string Ledger::get_account_name_by_id(uint64_t account_id) {
for (const auto& account_data : ACCOUNT_MAP) {
if (std::get<0>(account_data) == account_id) {
return std::get<1>(account_data);
}
}
return "Неизвестный счет";
}
inline void Ledger::add(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::action(
eosio::permission_level{actor, "active"_n},
_ledger,
get_valid_ledger_action("add"_n),
std::make_tuple(coopname, account_id, quantity, comment)
).send();
}
inline void Ledger::sub(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::action(
eosio::permission_level{actor, "active"_n},
_ledger,
get_valid_ledger_action("sub"_n),
std::make_tuple(coopname, account_id, quantity, comment)
).send();
}
inline void Ledger::transfer(eosio::name actor, eosio::name coopname, uint64_t from_account_id, uint64_t to_account_id, eosio::asset quantity, std::string comment) {
eosio::action(
eosio::permission_level{actor, "active"_n},
_ledger,
get_valid_ledger_action("transfer"_n),
std::make_tuple(coopname, from_account_id, to_account_id, quantity, comment)
).send();
}
inline void Ledger::block(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::action(
eosio::permission_level{actor, "active"_n},
_ledger,
get_valid_ledger_action("block"_n),
std::make_tuple(coopname, account_id, quantity, comment)
).send();
}
inline void Ledger::unblock(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::action(
eosio::permission_level{actor, "active"_n},
_ledger,
get_valid_ledger_action("unblock"_n),
std::make_tuple(coopname, account_id, quantity, comment)
).send();
}
inline void Ledger::writeoff(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::action(
eosio::permission_level{actor, "active"_n},
_ledger,
get_valid_ledger_action("writeoff"_n),
std::make_tuple(coopname, account_id, quantity, comment)
).send();
}
inline void Ledger::writeoffcnsl(eosio::name actor, eosio::name coopname, uint64_t account_id, eosio::asset quantity, std::string comment) {
eosio::action(
eosio::permission_level{actor, "active"_n},
_ledger,
get_valid_ledger_action("writeoffcnsl"_n),
std::make_tuple(coopname, account_id, quantity, comment)
).send();
}
inline void Ledger::add_membership_fee(eosio::name actor, eosio::name coopname, eosio::asset quantity, std::string comment) {
add(actor, coopname, accounts::TARGET_RECEIPTS, quantity, comment);
}
inline void Ledger::sub_membership_fee(eosio::name actor, eosio::name coopname, eosio::asset quantity, std::string comment) {
sub(actor, coopname, accounts::TARGET_RECEIPTS, quantity, comment);
}
inline void Ledger::block_membership_fee(eosio::name actor, eosio::name coopname, eosio::asset quantity, std::string comment) {
block(actor, coopname, accounts::TARGET_RECEIPTS, quantity, comment);
}
inline void Ledger::unblock_membership_fee(eosio::name actor, eosio::name coopname, eosio::asset quantity, std::string comment) {
unblock(actor, coopname, accounts::TARGET_RECEIPTS, quantity, comment);
}
inline std::optional<writeoff_op> Ledger::get_writeoff_by_hash(const checksum256 &writeoff_hash) {
writeoffs_index writeoffs(_ledger, _ledger.value);
auto hash_idx = writeoffs.get_index<"byhash"_n>();
auto op_iter = hash_idx.find(writeoff_hash);
if (op_iter == hash_idx.end()) {
return std::nullopt;
}
return *op_iter;
}
@@ -1,321 +0,0 @@
#pragma once
// Сигнатуры для callback действий marketplace
#define AUTH_SIGNATURE eosio::name coopname, checksum256 request_hash, document2 authorization
using auth_interface = void(AUTH_SIGNATURE);
namespace Marketplace {
/**
* @brief Сегмент поставки - унифицированная структура для работы с документами
* @ingroup public_tables
*
* Сегмент представляет собой путь поставки от пайщика в кооператив или из кооператива до пайщика
*
* Типы сегментов:
* - "contribute" - сегмент поставки имущества в кооператив
* - "return" - сегмент возврата имущества из кооператива
* - "wreturn" - сегмент возврата по гарантии (от заказчика в кооператив)
* - "wsupply" - сегмент выдачи по гарантии (из кооператива поставщику)
*/
struct [[eosio::table, eosio::contract(MARKETPLACE)]] segment {
uint64_t id; /*!< идентификатор сегмента */
uint64_t request_id; /*!< идентификатор заявки, к которой относится сегмент */
eosio::name type; /*!< тип сегмента: "contribute", "return", "wreturn", "wsupply" */
eosio::name status; /*!< статус сегмента */
document2 convert_in; /*!< заявление на конвертацию из кошелька */
document2 statement; /*!< заявление/документ на взнос или возврат */
uint64_t decision_id; /*!< идентификатор решения */
document2 authorization; /*!< документ авторизации */
document2 act1; /*!< акт приёма-передачи */
document2 act2; /*!< акт приёма-передачи */
document2 convert_out; /*!< заявление на конвертацию в кошелек */
// Документы транспортировки
document2 transport_act_1; /*!< акт товарно-транспортной накладной - передача имущества на транспортировку */
document2 transport_act_2; /*!< акт товарно-транспортной накладной - прием имущества водителем */
document2 transport_act_3; /*!< акт товарно-транспортной накладной - доставка до КУ получателя */
document2 transport_act_4; /*!< акт товарно-транспортной накладной - прием имущества председателем КУ */
eosio::name coopactor; /*!< представитель кооператива, который действует в этом сегменте */
eosio::name username; /*!< пользователь, который действует в этом сегменте */
eosio::name driver_username; /*!< водитель-пайщик, который принимает имущество на транспортировку */
eosio::name receive_from_driver_coopactor; /*!< председатель КУ, который принимает имущество от водителя */
eosio::time_point_sec created_at;
eosio::time_point_sec updated_at;
uint64_t primary_key() const { return id; }
uint64_t by_request() const { return request_id; }
uint64_t by_type() const { return type.value; }
uint64_t by_status() const { return status.value; }
};
typedef eosio::multi_index<
"segments"_n, segment,
eosio::indexed_by<"byrequest"_n, eosio::const_mem_fun<segment, uint64_t, &segment::by_request>>,
eosio::indexed_by<"bytype"_n, eosio::const_mem_fun<segment, uint64_t, &segment::by_type>>,
eosio::indexed_by<"bystatus"_n, eosio::const_mem_fun<segment, uint64_t, &segment::by_status>>
> segments_index;
/**
* @brief Перевозка имущества - объединение нескольких заявок в одну транспортную накладную
* @ingroup public_tables
*
* Перевозка представляет собой процесс транспортировки множества единиц имущества
* в рамках одной товарно-транспортной накладной от одного кооперативного участка
* к одному или нескольким получателям.
*
* Статусы перевозки:
* - "loading" - идет загрузка товаров в перевозку
* - "transit" - перевозка в пути (товары загружены и подписана накладная)
* - "arrived" - перевозка прибыла, ожидает подтверждения получателя
* - "completed" - все товары из перевозки переданы получателям
*/
struct [[eosio::table, eosio::contract(MARKETPLACE)]] shipment {
uint64_t id; /*!< идентификатор перевозки */
checksum256 hash; /*!< внешний идентификатор перевозки */
eosio::name coopname; /*!< имя кооператива */
eosio::name driver_username; /*!< водитель-пайщик */
eosio::name source_braname; /*!< КУ отправителя */
eosio::name destination_braname; /*!< КУ назначения (может быть промежуточный) */
eosio::name status; /*!< статус перевозки */
std::vector<checksum256> request_hashes; /*!< массив хэшей заявок в перевозке */
std::vector<Document::named_document> documents; /*!< именованные документы перевозки */
eosio::time_point_sec created_at; /*!< время создания перевозки */
eosio::time_point_sec loaded_at; /*!< время завершения загрузки */
eosio::time_point_sec delivered_at; /*!< время доставки */
eosio::time_point_sec completed_at; /*!< время завершения перевозки */
uint64_t primary_key() const { return id; }
checksum256 by_hash() const { return hash; }
uint64_t by_coop() const { return coopname.value; }
uint64_t by_driver() const { return driver_username.value; }
uint64_t by_source() const { return source_braname.value; }
uint64_t by_destination() const { return destination_braname.value; }
uint64_t by_status() const { return status.value; }
uint64_t by_created() const { return created_at.sec_since_epoch(); }
};
typedef eosio::multi_index<
"shipments"_n, shipment,
eosio::indexed_by<"byhash"_n, eosio::const_mem_fun<shipment, checksum256, &shipment::by_hash>>,
eosio::indexed_by<"bycoop"_n, eosio::const_mem_fun<shipment, uint64_t, &shipment::by_coop>>,
eosio::indexed_by<"bydriver"_n, eosio::const_mem_fun<shipment, uint64_t, &shipment::by_driver>>,
eosio::indexed_by<"bysource"_n, eosio::const_mem_fun<shipment, uint64_t, &shipment::by_source>>,
eosio::indexed_by<"bydest"_n, eosio::const_mem_fun<shipment, uint64_t, &shipment::by_destination>>,
eosio::indexed_by<"bystatus"_n, eosio::const_mem_fun<shipment, uint64_t, &shipment::by_status>>,
eosio::indexed_by<"bycreated"_n, eosio::const_mem_fun<shipment, uint64_t, &shipment::by_created>>
> shipments_index;
/**
* @brief Таблица обменов для контракта "marketplace"
* @ingroup public_tables
*/
struct [[eosio::table, eosio::contract(MARKETPLACE)]] request {
uint64_t id; /*!< идентификатор обмена */
checksum256 hash; /*!< хэш заявки */
eosio::name coopname; /*!< имя аккаунта кооператива */
eosio::name type; /*!< тип обмена: orderoffer или offerorder */
eosio::name status; /*!< статус обмена */
eosio::name username; /*!< имя аккаунта владельца заявки */
eosio::name braname; /*!< имя кооперативного участка */
eosio::name warehouse; /*!< имя КУ где хранится имущество */
eosio::name token_contract; /*!< имя контракта токена */
eosio::name receiver_braname; /*!< КУ заказчика для получения товара */
eosio::name supplier_braname; /*!< КУ поставщика для отправки товара */
eosio::asset unit_cost;/*!< себестоимость единицы товара от поставщика */
eosio::asset base_cost; /*!< базовая стоимость заявки */
eosio::asset membership_fee_amount; /*!< членский взнос заказчика */
eosio::asset total_cost; /*!< общая сумма заявки */
uint64_t units; /*!< количество единиц товара */
std::string meta; /*!< метаданные заявки */
eosio::name money_contributor; /*!< имя аккаунта, который вносит средства */
eosio::name product_contributor; /*!< имя аккаунта, который передаёт товар */
std::vector<Document::named_document> documents; /*!< именованные документы заявки */
uint64_t product_lifecycle_secs; // жизненный цикл продукта
uint64_t warranty_period_secs; // гарантийный срок в секундах
eosio::asset cancellation_fee_amount; // сумма штрафа за отмену заявки
eosio::time_point_sec warranty_delay_until;
eosio::time_point_sec deadline_for_receipt;
bool is_warranty_return = false;
uint64_t warranty_return_id;
eosio::time_point_sec created_at;
eosio::time_point_sec accepted_at;
eosio::time_point_sec supplied_at;
eosio::time_point_sec delivered_at;
eosio::time_point_sec received_at;
eosio::time_point_sec completed_at;
eosio::time_point_sec declined_at;
eosio::time_point_sec disputed_at;
eosio::time_point_sec canceled_at;
uint64_t primary_key() const { return id; }
uint64_t by_coop() const {return coopname.value;}
uint64_t by_status() const { return status.value; }
uint64_t by_type() const { return type.value; }
checksum256 by_hash() const { return hash; }
uint64_t by_username() const { return username.value;}
uint64_t by_created() const { return created_at.sec_since_epoch();}
uint64_t by_completed() const { return completed_at.sec_since_epoch();}
uint64_t by_declined() const { return declined_at.sec_since_epoch();}
uint64_t by_canceled() const { return canceled_at.sec_since_epoch();}
uint64_t by_warranty_id() const { return warranty_return_id;}
// Логические геттеры для получения актуальных ролей
eosio::name get_money_contributor() const {
return is_warranty_return ? product_contributor : money_contributor;
}
eosio::name get_product_contributor() const {
return is_warranty_return ? money_contributor : product_contributor;
}
// Геттеры для понимания ролей в контексте текущей операции
eosio::name get_payer() const {
return get_money_contributor();
}
eosio::name get_supplier() const {
return get_product_contributor();
}
// Специальные геттеры для гарантийного возврата
// Возвращают участников в контексте процесса возврата брака
/**
* @brief Получить пайщика, который возвращает товар в гарантийном возврате
* Это тот, кто изначально получил товар и теперь возвращает его как брак
*/
eosio::name get_product_backer() const {
return money_contributor;
}
/**
* @brief Получить поставщика брака в гарантийном возврате
* Это тот, кто изначально поставил товар и теперь получает его обратно как брак
*/
eosio::name get_defective_supplier() const {
return product_contributor;
}
};
typedef eosio::multi_index<
"requests"_n, request,
eosio::indexed_by<"bycoop"_n, eosio::const_mem_fun<request, uint64_t, &request::by_coop>>,
eosio::indexed_by<"bystatus"_n, eosio::const_mem_fun<request, uint64_t, &request::by_status>>,
eosio::indexed_by<"bytype"_n, eosio::const_mem_fun<request, uint64_t, &request::by_type>>,
eosio::indexed_by<"byhash"_n, eosio::const_mem_fun<request, checksum256, &request::by_hash>>,
eosio::indexed_by<"byusername"_n, eosio::const_mem_fun<request, uint64_t, &request::by_username>>,
eosio::indexed_by<"bycreated"_n, eosio::const_mem_fun<request, uint64_t, &request::by_created>>,
eosio::indexed_by<"bycompleted"_n, eosio::const_mem_fun<request, uint64_t, &request::by_completed>>,
eosio::indexed_by<"bydeclined"_n, eosio::const_mem_fun<request, uint64_t, &request::by_declined>>,
eosio::indexed_by<"bycanceled"_n, eosio::const_mem_fun<request, uint64_t, &request::by_canceled>>,
eosio::indexed_by<"bywarrantyid"_n, eosio::const_mem_fun<request, uint64_t, &request::by_warranty_id>>
> requests_index;
static const std::set<eosio::name> marketplace_callback_actions = {
"authoffs2c"_n, // авторизация сегмента contribute для направления OFFER → ORDER
"authoffc2r"_n, // авторизация сегмента return для направления OFFER → ORDER
"authordcont"_n, // авторизация сегмента contribute для направления ORDER → OFFER
"authordret"_n, // авторизация сегмента return для направления ORDER → OFFER
"declineacc"_n, // отклонение принятия заявки
};
inline eosio::name get_valid_marketplace_action(const eosio::name& action) {
eosio::check(marketplace_callback_actions.contains(action), "Недопустимое имя действия marketplace");
return action;
}
// Вспомогательные функции для поиска заявок по хэшу
static std::optional<request> get_request_by_hash(eosio::name coopname, checksum256 request_hash) {
requests_index requests(_marketplace, coopname.value);
auto idx = requests.get_index<"byhash"_n>();
auto req = idx.find(request_hash);
if (req != idx.end()) {
return *req;
}
return std::nullopt;
}
// Вспомогательные функции для поиска перевозок по хэшу
static std::optional<shipment> get_shipment_by_hash(eosio::name coopname, checksum256 shipment_hash) {
shipments_index shipments(_marketplace, coopname.value);
auto idx = shipments.get_index<"byhash"_n>();
auto ship = idx.find(shipment_hash);
if (ship != idx.end()) {
return *ship;
}
return std::nullopt;
}
static request get_request_by_hash_or_fail(eosio::name coopname, checksum256 request_hash, const std::string& error_msg = "Заявка не найдена по хэшу") {
auto request_opt = get_request_by_hash(coopname, request_hash);
eosio::check(request_opt.has_value(), error_msg);
return *request_opt;
}
static shipment get_shipment_by_hash_or_fail(eosio::name coopname, checksum256 shipment_hash, const std::string& error_msg = "Перевозка не найдена по хэшу") {
auto shipment_opt = get_shipment_by_hash(coopname, shipment_hash);
eosio::check(shipment_opt.has_value(), error_msg);
return *shipment_opt;
}
/*!
* \brief Константы для имен документов маркетплейса (максимум 12 символов)
*/
namespace DocumentNames {
static constexpr const name RETURN_STMT = "returnstmt"_n; // заявление на возврат имущества
static constexpr const name CONVERT_FROM = "convertfrom"_n; // заявление на конвертацию из кошелька
static constexpr const name CONVERT_TO = "convertto"_n; // заявление на конвертацию в кошелек
static constexpr const name CONTRIB_STMT = "contribstmt"_n; // заявление на имущественный паевой взнос
static constexpr const name CONTRIB_AUTH = "contribauth"_n; // авторизация взноса
static constexpr const name RETURN_AUTH = "returnauth"_n; // авторизация возврата
static constexpr const name RECEIVE_ACT = "receiveact"_n; // акт получения
static constexpr const name RECEIVE_ACT_CONF = "receiveconf"_n; // подтверждение акта получения
static constexpr const name TRANSPORT1 = "transport1"_n; // акт транспортировки 1 (УСТАРЕВШИЙ)
static constexpr const name TRANSPORT2 = "transport2"_n; // акт транспортировки 2 (УСТАРЕВШИЙ)
static constexpr const name TRANSPORT3 = "transport3"_n; // акт транспортировки 3 (УСТАРЕВШИЙ)
static constexpr const name TRANSPORT4 = "transport4"_n; // акт транспортировки 4 (УСТАРЕВШИЙ)
static constexpr const name SUPPLY_ACT = "supplyact"_n; // акт поставки
static constexpr const name SUPPLY_ACT_CONF = "supplyconf"_n; // подтверждение акта поставки
static constexpr const name SHIPMENT_ACT = "shipmentact"_n; // товарно-транспортная накладная
static constexpr const name DELIVERY_ACT = "deliveryact"_n; // акт доставки (УСТАРЕВШИЙ)
// Документы новой системы перевозок
static constexpr const name SHIPMENT_SEND_ACT = "shsendact"_n; // акт передачи от отправителя
static constexpr const name SHIPMENT_LOADING_ACT = "shloadact"_n; // акт приёма водителем
static constexpr const name SHIPMENT_ARRIVE_ACT = "sharriveact"_n; // акт прибытия/доставки на склад, подписанный водителем
static constexpr const name SHIPMENT_RECV_ACT = "shrecvact"_n; // акт приёма на складе получателем
// Документы гарантийного возврата
static constexpr const name WDISPUTE = "wdispute"_n; // претензия на гарантийный возврат
static constexpr const name WRETURN_AUTH = "wreturnauth"_n; // авторизация гарантийного возврата
static constexpr const name WSUPPLY_AUTH = "wsupplyauth"_n; // авторизация гарантийной выдачи
static constexpr const name WRETURN_ACT = "wreturnact"_n; // акт гарантийного возврата
static constexpr const name WOFFER_ACT = "wofferact"_n; // акт предложения товара поставщику
static constexpr const name WACCEPT_ACT = "wacceptact"_n; // акт принятия/отказа поставщика
}
} // namespace Marketplace
+92 -101
View File
@@ -4,94 +4,26 @@
using completewthd_interface = void(COMPLETEWTHD_SIGNATURE);
using declinewthd_interface = void(DECLINEWTHD_SIGNATURE);
static const std::set<eosio::name> wallet_callback_actions = {
"authwthd"_n, // авторизация возврата паевого взноса
"declinewthd"_n, // отклонение возврата паевого взноса
"completewthd"_n, // завершение возврата паевого взноса
};
namespace Wallet {
class Wallet {
public:
/**
* @ingroup public_tables
* @brief Таблица `deposits` отслеживает депозиты в контракте WALLET.
*/
struct [[eosio::table, eosio::contract(WALLET)]] deposit {
uint64_t id; /*!< Уникальный идентификатор записи ввода */
eosio::name coopname; /*!< Имя аккаунта кооператива, в контексте которого совершается депозит */
eosio::name username; /*!< Имя аккаунта пользователя, совершившего ввод */
checksum256 deposit_hash; ///< Хэш входящего платежа
eosio::asset quantity; /*!< Количество средств во внутренней валюте */
eosio::name status; /*!< Статус ввода */
eosio::time_point_sec created_at = current_time_point(); ///< Время истечения срока давности
uint64_t primary_key() const { return id; } /*!< Возвращает id как первичный ключ */
uint64_t by_username() const { return username.value; } /*!< Индекс по имени пользователя */
checksum256 by_hash() const { return deposit_hash; } /*!< Индекс по хэшу платежа */
uint64_t by_status() const { return status.value; } /*!< Индекс по статусу вводу */
uint64_t by_created() const { return created_at.sec_since_epoch(); }
static const std::set<eosio::name> wallet_callback_actions = {
"authwthd"_n, // авторизация возврата паевого взноса
"declinewthd"_n, // отклонение возврата паевого взноса
"completewthd"_n, // завершение возврата паевого взноса
};
typedef eosio::multi_index<
"deposits"_n, deposit,
eosio::indexed_by<"byhash"_n, eosio::const_mem_fun<deposit, checksum256, &deposit::by_hash>>,
eosio::indexed_by<"byusername"_n, eosio::const_mem_fun<deposit, uint64_t, &deposit::by_username>>,
eosio::indexed_by<"bystatus"_n, eosio::const_mem_fun<deposit, uint64_t, &deposit::by_status>>,
eosio::indexed_by<"bycreated"_n, eosio::const_mem_fun<deposit, uint64_t, &deposit::by_created>>
> deposits_index;
/**
* @ingroup public_tables
* @brief Таблица `withdraws` отслеживает операции вывода средств в контракте WALLET.
*/
struct [[eosio::table, eosio::contract(WALLET)]] withdraw {
uint64_t id; /*!< Уникальный идентификатор записи вывода */
eosio::name username; /*!< Имя пользователя, осуществляющего вывод средств */
eosio::name coopname; /*!< Имя аккаунта кооператива, в рамках которого осуществляется вывод */
checksum256 withdraw_hash; /*!< Идентификатор возврата */
eosio::name status; /*!< Статус операции вывода */
eosio::asset quantity; /*!< Количество средств для вывода во внутренней валюте */
document2 statement; /*!< Заявление на возврат */
document2 approved_statement; /*!< Предварительно-принятое заявление */
document2 authorization; /*!< Решение совета */
eosio::time_point_sec created_at = current_time_point(); ///< Время истечения срока давности
uint64_t primary_key() const { return id; } /*!< Возвращает id как первичный ключ */
checksum256 by_hash() const { return withdraw_hash; } ///< Индекс по хэшу задачи.
uint64_t by_username() const { return username.value; } /*!< Индекс по имени пользователя */
uint64_t by_status() const { return status.value; } /*!< Индекс по статусу операции вывода */
uint64_t by_created() const { return created_at.sec_since_epoch(); }
};
typedef eosio::multi_index<
"withdraws"_n, withdraw,
eosio::indexed_by<"byusername"_n, eosio::const_mem_fun<withdraw, uint64_t, &withdraw::by_username>>,
eosio::indexed_by<"byhash"_n, const_mem_fun<withdraw, checksum256, &withdraw::by_hash>>,
eosio::indexed_by<"bystatus"_n, eosio::const_mem_fun<withdraw, uint64_t, &withdraw::by_status>>,
eosio::indexed_by<"bycreated"_n, eosio::const_mem_fun<withdraw, uint64_t, &withdraw::by_created>>
> withdraws_index; /*!< Мультииндекс для доступа и манипуляции данными таблицы `withdraws` */
static eosio::name get_valid_wallet_action(const eosio::name& action) {
inline eosio::name get_valid_wallet_action(const eosio::name& action) {
eosio::check(wallet_callback_actions.contains(action), "Недопустимое имя действия wallet");
return action;
}
static void validate_asset(const eosio::asset& amount) {
inline void validate_asset(const eosio::asset& amount) {
check(amount.symbol == _root_govern_symbol, "Invalid token symbol");
check(amount.is_valid(), "Invalid asset");
check(amount.amount > 0, "Amount must be positive");
}
static void add_available_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo) {
inline void add_available_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo) {
auto program = get_program_or_fail(coopname, get_program_id(program_type));
action(
@@ -103,7 +35,7 @@ public:
}
static void sub_available_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo) {
inline void sub_available_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo) {
auto program = get_program_or_fail(coopname, get_program_id(program_type));
action(
@@ -114,7 +46,7 @@ public:
).send();
}
static void add_blocked_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo) {
inline void add_blocked_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo) {
auto program = get_program_or_fail(coopname, get_program_id(program_type));
action(
@@ -132,7 +64,7 @@ public:
).send();
}
static void sub_blocked_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo) {
inline void sub_blocked_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo) {
auto program = get_program_or_fail(coopname, get_program_id(program_type));
action(
@@ -150,7 +82,7 @@ public:
).send();
}
static void block_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo){
inline void block_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo){
auto program = get_program_or_fail(coopname, get_program_id(program_type));
action(
@@ -161,7 +93,7 @@ public:
).send();
}
static void unblock_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo){
inline void unblock_funds(eosio::name contract, eosio::name coopname, eosio::name username, eosio::asset amount, eosio::name program_type, std::string memo){
auto program = get_program_or_fail(coopname, get_program_id(program_type));
action(
@@ -171,10 +103,17 @@ public:
std::make_tuple(coopname, username, program.id, amount, memo)
).send();
}
inline void pay_membership_fee(name contract, name coopname, name username, name amount, eosio::name program_type, std::string memo) {
auto program = get_program_or_fail(coopname, get_program_id(program_type));
static void pay_membership_fee(name contract, name coopname, name username, eosio::asset amount, uint64_t program_id, std::string memo) {
auto program = get_program_or_fail(coopname, program_id);
action(
permission_level{ contract, "active"_n },
_soviet,
"subbal"_n,
std::make_tuple(coopname, username, program.id, amount, false, memo)
).send();
action(
permission_level{ contract, "active"_n },
_soviet,
@@ -184,20 +123,37 @@ public:
}
static void unpay_membership_fee(name contract, name coopname, name username, eosio::asset amount, uint64_t program_id, std::string memo) {
auto program = get_program_or_fail(coopname, program_id);
/**
* @ingroup public_tables
* @brief Таблица `deposits` отслеживает депозиты в контракте WALLET.
*/
struct [[eosio::table, eosio::contract(WALLET)]] deposit {
uint64_t id; /*!< Уникальный идентификатор записи ввода */
eosio::name coopname; /*!< Имя аккаунта кооператива, в контексте которого совершается депозит */
eosio::name username; /*!< Имя аккаунта пользователя, совершившего ввод */
checksum256 deposit_hash; ///< Хэш входящего платежа
eosio::asset quantity; /*!< Количество средств во внутренней валюте */
eosio::name status; /*!< Статус ввода */
action(
permission_level{ contract, "active"_n },
_soviet,
"submemberfee"_n,
std::make_tuple(coopname, username, program.id, amount, memo)
).send();
}
eosio::time_point_sec created_at = current_time_point(); ///< Время истечения срока давности
uint64_t primary_key() const { return id; } /*!< Возвращает id как первичный ключ */
uint64_t by_username() const { return username.value; } /*!< Индекс по имени пользователя */
checksum256 by_hash() const { return deposit_hash; } /*!< Индекс по хэшу платежа */
uint64_t by_status() const { return status.value; } /*!< Индекс по статусу вводу */
uint64_t by_created() const { return created_at.sec_since_epoch(); }
};
static std::optional<deposit> get_deposit(eosio::name coopname, const checksum256 &hash) {
typedef eosio::multi_index<
"deposits"_n, deposit,
eosio::indexed_by<"byhash"_n, eosio::const_mem_fun<deposit, checksum256, &deposit::by_hash>>,
eosio::indexed_by<"byusername"_n, eosio::const_mem_fun<deposit, uint64_t, &deposit::by_username>>,
eosio::indexed_by<"bystatus"_n, eosio::const_mem_fun<deposit, uint64_t, &deposit::by_status>>,
eosio::indexed_by<"bycreated"_n, eosio::const_mem_fun<deposit, uint64_t, &deposit::by_created>>
> deposits_index;
inline std::optional<deposit> get_deposit(eosio::name coopname, const checksum256 &hash) {
deposits_index primary_index(_wallet, coopname.value);
auto secondary_index = primary_index.get_index<"byhash"_n>();
@@ -207,7 +163,41 @@ public:
}
return *itr;
};
}
/**
* @ingroup public_tables
* @brief Таблица `withdraws` отслеживает операции вывода средств в контракте WALLET.
*/
struct [[eosio::table, eosio::contract(WALLET)]] withdraw {
uint64_t id; /*!< Уникальный идентификатор записи вывода */
eosio::name username; /*!< Имя пользователя, осуществляющего вывод средств */
eosio::name coopname; /*!< Имя аккаунта кооператива, в рамках которого осуществляется вывод */
checksum256 withdraw_hash; /*!< Идентификатор возврата */
eosio::name status; /*!< Статус операции вывода */
eosio::asset quantity; /*!< Количество средств для вывода во внутренней валюте */
document2 statement; /*!< Заявление на возврат */
document2 approved_statement; /*!< Предварительно-принятое заявление */
document2 authorization; /*!< Решение совета */
eosio::time_point_sec created_at = current_time_point(); ///< Время истечения срока давности
uint64_t primary_key() const { return id; } /*!< Возвращает id как первичный ключ */
checksum256 by_hash() const { return withdraw_hash; } ///< Индекс по хэшу задачи.
uint64_t by_username() const { return username.value; } /*!< Индекс по имени пользователя */
uint64_t by_status() const { return status.value; } /*!< Индекс по статусу операции вывода */
uint64_t by_created() const { return created_at.sec_since_epoch(); }
};
typedef eosio::multi_index<
"withdraws"_n, withdraw,
eosio::indexed_by<"byusername"_n, eosio::const_mem_fun<withdraw, uint64_t, &withdraw::by_username>>,
eosio::indexed_by<"byhash"_n, const_mem_fun<withdraw, checksum256, &withdraw::by_hash>>,
eosio::indexed_by<"bystatus"_n, eosio::const_mem_fun<withdraw, uint64_t, &withdraw::by_status>>,
eosio::indexed_by<"bycreated"_n, eosio::const_mem_fun<withdraw, uint64_t, &withdraw::by_created>>
> withdraws_index; /*!< Мультииндекс для доступа и манипуляции данными таблицы `withdraws` */
/**
@@ -216,7 +206,7 @@ public:
* @param hash Хэш возврата.
* @return `std::optional<withdraw>` - найденное действие или `std::nullopt`, если его нет.
*/
static std::optional<withdraw> get_withdraw(eosio::name coopname, const checksum256 &hash) {
inline std::optional<withdraw> get_withdraw(eosio::name coopname, const checksum256 &hash) {
withdraws_index primary_index(_wallet, coopname.value);
auto secondary_index = primary_index.get_index<"byhash"_n>();
@@ -226,6 +216,7 @@ public:
}
return *itr;
};
};
}
}
-40
View File
@@ -57,44 +57,4 @@ uint64_t generate() {
}
return seed;
}
std::string checksum256_to_hex(const eosio::checksum256& hash) {
auto hash_bytes = hash.extract_as_byte_array();
std::string hash_hex;
for (const auto& byte : hash_bytes) {
char hex_char[3];
sprintf(hex_char, "%02x", byte);
hash_hex += hex_char;
}
return hash_hex;
}
uint64_t extract_registry_id_from_meta(const std::string& meta_json) {
// Ищем "registry_id": и извлекаем число после двоеточия
std::string search_key = "\"registry_id\":";
size_t pos = meta_json.find(search_key);
eosio::check(pos != std::string::npos, "registry_id not found in meta");
// Перемещаемся после двоеточия
pos += search_key.length();
// Ищем первую цифру
while (pos < meta_json.length() && (meta_json[pos] < '0' || meta_json[pos] > '9')) {
pos++;
}
eosio::check(pos < meta_json.length(), "registry_id value not found");
// Собираем цифры
uint64_t result = 0;
while (pos < meta_json.length() && meta_json[pos] >= '0' && meta_json[pos] <= '9') {
result = result * 10 + (meta_json[pos] - '0');
pos++;
}
eosio::check(result > 0, "invalid registry_id value");
return result;
}
+11 -2
View File
@@ -11,8 +11,17 @@
### Структуры
- `balance`: Описывает баланс пользователя.
- `requests`: Описывает информацию об обмене.
- `requests_params`: Параметры обмена, включая имя пользователя, контракт, количество единиц, цену за штуку и дополнительные данные и метаданные.
- `exchange`: Описывает информацию об обмене.
- `exchange_params`: Параметры обмена, включая имя пользователя, контракт, количество единиц, цену за штуку и дополнительные данные и метаданные.
### Действия
Контракт включает в себя следующие действия:
- **Действия обмена**: `offer`, `order`, `complete`, `decline`, `accept`.
- **Административные действия**: `moderate`, `prohibit`, `unpublish`, `publish`.
- **Действия авторизации**: `authorize`.
- **Прочие действия**: `newid` (используется для возврата информации из контракта), `update`, `addpieces`.
## Использование
@@ -1,37 +1,38 @@
#include "marketplace.hpp"
#include <eosio/transaction.hpp>
#include "src/accept.cpp"
#include "src/addunits.cpp"
#include "src/authorize.cpp"
#include "src/cancel.cpp"
#include "src/change.cpp"
#include "src/complete.cpp"
#include "src/decline.cpp"
#include "src/delivered.cpp"
#include "src/dispute.cpp"
#include "src/moderate.cpp"
#include "src/offer.cpp"
#include "src/order.cpp"
#include "src/prohibit.cpp"
#include "src/publish.cpp"
#include "src/recieve.cpp"
#include "src/recievecnfrm.cpp"
#include "src/supply.cpp"
#include "src/supplycnfrm.cpp"
#include "src/unpublish.cpp"
#include "src/update.cpp"
// Процесс поставки по заявкам orderoffer
#include "src/deliver_on_offer/orderoffer.cpp"
#include "src/deliver_on_offer/accept.cpp"
#include "src/deliver_on_offer/authcontrib.cpp"
#include "src/deliver_on_offer/authreturn.cpp"
#include "src/deliver_on_offer/declineacc.cpp"
#include "src/deliver_on_offer/supply.cpp"
#include "src/deliver_on_offer/supplcnf.cpp"
#include "src/deliver_on_offer/delivered.cpp"
#include "src/deliver_on_offer/receive.cpp"
#include "src/deliver_on_offer/receivecnf.cpp"
#include "src/deliver_on_offer/complete.cpp"
#include "src/deliver_on_offer/decline.cpp"
#include "src/deliver_on_offer/cancel.cpp"
// Новая система перевозок
#include "src/shipment/createship.cpp"
#include "src/shipment/signbydriver.cpp"
#include "src/shipment/arrived.cpp"
#include "src/shipment/receiveshipm.cpp"
#include "src/shipment/retransport.cpp"
// Диспуты
#include "src/dispute_on_offer/dispute.cpp"
#include "src/dispute_on_offer/wauthorize.cpp"
#include "src/dispute_on_offer/wreturn.cpp"
#include "src/dispute_on_offer/woffer.cpp"
#include "src/dispute_on_offer/waccept.cpp"
/**
* @brief Пустой метод регистрации нового идентификатора
* @ingroup public_actions
* Этот метод используется для возврата информации из контракта.
* @param id идентификатор
* @param type тип идентификатора
*/
[[eosio::action]] void marketplace::newid(uint64_t id, eosio::name type) {
require_auth(_marketplace);
};
[[eosio::action]] void marketplace::migrate(){
// require_auth(_marketplace);
}
require_auth(_marketplace);
}
@@ -8,8 +8,6 @@
#include "../lib/common.hpp"
using namespace Marketplace;
/**
* \ingroup public_contracts
* @brief Класс `marketplace` предоставляет функционал кооперативного маркетплейса, позволяя пользователям
@@ -17,28 +15,12 @@ using namespace Marketplace;
* центральной точкой для всех операций обмена в рамках кооперативной экосистемы.
*
* Основные функции класса:
* - Создание и управление заявками типа orderoffer (заказчик поставщик).
* - Создание и управление заявками на обмен, включая предложения и заказы.
* - Операции обновления, принятия, отказа и завершения обменных операций.
* - Модерация и управление публикацией заявок на обмен.
* - Административные функции, такие как создание идентификаторов и авторизация операций.
*
* ## Процесс поставки orderoffer:
*
* 1. **orderoffer** - заказчик создает заявку с документами на возврат и конвертацию, средства блокируются
* 2. **accept** - поставщик принимает заявку и предоставляет документы на взнос и конвертацию
* 3. **authcontrib/authreturn** - совет авторизует оба заявления раздельно
* 4. **supply** **supplcnf** - поставка товара и подтверждение председателем КУ
* 5. **deliver1** **deliver2** **deliver3** **deliver4** - этапы транспортировки
* 6. **receive** **receivecnf** - получение товара заказчиком
* 7. **complete** - завершение поставки после гарантийного периода
*
* ## Документооборот:
*
* Все документы сохраняются в векторе `std::vector<document2> documents` в заявке.
* Каждый этап процесса добавляет необходимые документы в этот вектор.
*
* \note Контракт маркетплейса является центральной точкой экономической активности на платформе.
* \note Система упрощена для работы с одной заявкой вместо двух встречных.
*/
class [[eosio::contract(MARKETPLACE)]] marketplace : public eosio::contract {
@@ -47,47 +29,54 @@ public:
eosio::datastream<const char *> ds)
: eosio::contract(receiver, code, ds) {}
void apply(uint64_t receiver, uint64_t code, uint64_t action);
[[eosio::action]] void migrate();
// ... определение методов контракта ...
//marketplace.cpp
[[eosio::action]] void newid(uint64_t id, eosio::name type);
// Действия для создания заявок
[[eosio::action]] void orderoffer(eosio::name coopname, eosio::name receiver_braname, eosio::name username, checksum256 hash, uint64_t units, eosio::asset unit_cost, uint32_t product_lifecycle_secs, uint32_t warranty_period_secs, eosio::asset membership_fee_amount, eosio::asset cancellation_fee_amount, document2 product_return_statement, document2 convert_in, std::string meta);
//soviet.cpp
[[eosio::action]] void authorize(eosio::name coopname, uint64_t exchange_id, uint64_t contribution_product_decision_id, document2 contribution_product_authorization, uint64_t return_product_decision_id, document2 return_product_authorization);
static void cancel_request(eosio::name coopname, eosio::name username, checksum256 request_hash);
// Статические методы для отклонения заявок
static void decline_request(eosio::name coopname, const request& change);
//change.cpp
[[eosio::action]] void offer(const exchange_params& params);
[[eosio::action]] void order(const exchange_params& params);
// Методы для направления заявок
[[eosio::action]] void accept(eosio::name coopname, eosio::name supplier_braname, eosio::name username, checksum256 request_hash, document2 convert_out, document2 return_document);
[[eosio::action]] void authcontrib(eosio::name coopname, checksum256 request_hash, document2 authorization);
[[eosio::action]] void authreturn(eosio::name coopname, checksum256 request_hash, document2 authorization);
[[eosio::action]] void declineacc(eosio::name coopname, checksum256 hash, std::string reason);
[[eosio::action]] void supply(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 act);
[[eosio::action]] void supplcnf(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 act);
static void create(eosio::name type, const exchange_params& params);
static void create_parent(eosio::name type, const exchange_params& params);
static void create_child(eosio::name type, const exchange_params& params);
static void cancel_parent(eosio::name coopname, eosio::name username, uint64_t exchange_id);
static void cancel_child(eosio::name coopname, eosio::name username, uint64_t exchange_id);
[[eosio::action]] void accept(eosio::name coopname, eosio::name username, uint64_t exchange_id, document2 document);
[[eosio::action]] void decline(eosio::name coopname, eosio::name username, uint64_t exchange_id, std::string meta);
[[eosio::action]] void supplycnfrm(eosio::name coopname, eosio::name username, uint64_t exchange_id, document2 document);
[[eosio::action]] void supply(eosio::name coopname, eosio::name username, uint64_t exchange_id, document2 document);
[[eosio::action]] void delivered(eosio::name coopname, eosio::name username, uint64_t exchange_id);
[[eosio::action]] void recieve(eosio::name coopname, eosio::name username, uint64_t exchange_id, document2 document);
[[eosio::action]] void recievecnfrm(eosio::name coopname, eosio::name username, uint64_t exchange_id, document2 document);
[[eosio::action]] void dispute(eosio::name coopname, eosio::name username, uint64_t exchange_id, document2 document);
// Новая система перевозок
[[eosio::action]] void createship(eosio::name coopname, checksum256 hash, eosio::name driver_username, eosio::name source_braname, eosio::name destination_braname, std::vector<checksum256> request_hashes, document2 transport_act_sender);
[[eosio::action]] void signbydriver(eosio::name coopname, checksum256 hash, document2 transport_act_driver);
[[eosio::action]] void arrived(eosio::name coopname, checksum256 hash, document2 transport_act_delivery);
[[eosio::action]] void receiveshipm(eosio::name coopname, checksum256 hash, document2 warehouse_receipt_act);
[[eosio::action]] void retransport(eosio::name coopname, checksum256 completed_hash, eosio::name new_driver_username, eosio::name source_braname, eosio::name new_destination_braname, std::vector<checksum256> request_hashes, document2 transport_act_sender);
[[eosio::action]] void complete(eosio::name coopname, eosio::name username, uint64_t exchange_id);
[[eosio::action]] void cancel(eosio::name coopname, eosio::name username, uint64_t exchange_id);
// Доставка заказчику
[[eosio::action]] void delivered(eosio::name coopname, eosio::name username, checksum256 request_hash);
[[eosio::action]] void receive(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document);
[[eosio::action]] void receivecnf(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document);
[[eosio::action]] void complete(eosio::name coopname, eosio::name username, checksum256 request_hash);
[[eosio::action]] void decline(eosio::name coopname, eosio::name username, checksum256 request_hash, std::string meta);
[[eosio::action]] void cancel(eosio::name coopname, eosio::name username, checksum256 request_hash);
// Методы для работы с диспутом (гарантийный возврат)
[[eosio::action]] void dispute(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document);
[[eosio::action]] void wauthorize(eosio::name coopname, checksum256 request_hash, uint64_t wreturn_decision_id, document2 wreturn_authorization, uint64_t wsupply_decision_id, document2 wsupply_authorization);
[[eosio::action]] void wreturn(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document);
[[eosio::action]] void woffer(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document);
[[eosio::action]] void waccept(eosio::name coopname, eosio::name username, checksum256 request_hash, bool accept, document2 document);
[[eosio::action]] void update(eosio::name coopname, eosio::name username, uint64_t exchange_id, uint64_t remain_units, eosio::asset unit_cost, std::string data, std::string meta);
[[eosio::action]] void addunits(eosio::name coopname, eosio::name username, uint64_t exchange_id, uint64_t units);
//admins.cpp
[[eosio::action]] void moderate(eosio::name coopname, eosio::name username, uint64_t exchange_id, uint64_t cancellation_fee);
[[eosio::action]] void prohibit(eosio::name coopname, eosio::name username, uint64_t exchange_id, std::string meta);
[[eosio::action]] void unpublish(eosio::name coopname, eosio::name username, uint64_t exchange_id);
[[eosio::action]] void publish(eosio::name coopname, eosio::name username, uint64_t exchange_id);
struct [[eosio::table, eosio::contract("marketplace")]] balances : balances_base {};
struct [[eosio::table, eosio::contract("marketplace")]] counts : counts_base {};
};
@@ -1,90 +0,0 @@
/**
\ingroup public_actions
\brief Принятие заявки поставщиком.
@details Поставщик принимает заявку orderoffer на поставку имущества и предоставляет необходимые документы.
@param coopname Имя кооператива
@param supplier_braname Имя кооперативного участка поставщика
@param username Имя поставщика
@param request_hash Хэш заявки
@param convert_out Заявление на конвертацию
@param product_contribution_statement Заявление на имущественный паевой взнос
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::accept(eosio::name coopname, eosio::name supplier_braname, eosio::name username, checksum256 request_hash, document2 convert_out, document2 product_contribution_statement) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "active"_n, "Только активная заявка может быть принята");
eosio::check(change.type == "orderoffer"_n, "Метод accept применим только к заявкам типа orderoffer");
// Проверяем существование кооперативного участка поставщика
get_branch_or_fail(coopname, supplier_braname);
// Проверяем подписи документов
verify_document_or_fail(convert_out);
verify_document_or_fail(product_contribution_statement);
// Валидируем документы по registry_id (пока что нули)
Document::validate_registry_id(convert_out, 0);
Document::validate_registry_id(product_contribution_statement, 0);
// Получаем первоначальный документ возврата из заявки по имени
document2 initial_return_statement;
bool found = Document::find_document(change.documents, DocumentNames::RETURN_STMT, initial_return_statement);
eosio::check(found, "В заявке отсутствует заявление на возврат имущества");
// Обновляем заявку
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
o.status = "accepted"_n;
o.accepted_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
o.product_contributor = username;
o.supplier_braname = supplier_braname;
// Добавляем новые документы с именами
Document::add_document(o.documents, DocumentNames::CONVERT_TO, convert_out);
Document::add_document(o.documents, DocumentNames::CONTRIB_STMT, product_contribution_statement);
});
// Используем хэш заявки как идентификатор пакета решений
checksum256 agenda_hash = change.hash;
// Отправляем ПЕРВЫЙ вопрос в совет - по заявлению на имущественный паевой взнос
Action::send<createagenda_interface>(
_soviet,
"createagenda"_n,
_marketplace,
coopname,
username,
get_valid_soviet_action("authcontrib"_n), // авторизация взноса имуществом
agenda_hash,
_marketplace,
Marketplace::get_valid_marketplace_action("authcontrib"_n),
"declineacc"_n,
product_contribution_statement,
std::string("")
);
// Отправляем ВТОРОЙ вопрос в совет - по заявлению на возврат имущества
Action::send<createagenda_interface>(
_soviet,
"createagenda"_n,
_marketplace,
coopname,
username,
get_valid_soviet_action("authreturn"_n), // авторизация возврата имуществом
agenda_hash,
_marketplace,
Marketplace::get_valid_marketplace_action("authreturn"_n),
"declineacc"_n,
initial_return_statement,
std::string("")
);
};
@@ -1,45 +0,0 @@
/**
\ingroup public_actions
\brief Авторизация заявления на имущественный паевой взнос советом кооператива.
@details Совет кооператива авторизует заявление на имущественный паевой взнос.
@param coopname Имя кооператива
@param request_hash Хэш заявки
@param authorization Документ авторизации от совета
@note Авторизация требуется от аккаунта: @p _soviet
**/
[[eosio::action]] void marketplace::authcontrib(eosio::name coopname, checksum256 request_hash, document2 authorization) {
require_auth(_soviet);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "accepted"_n, "Только принятая заявка может быть авторизована");
// Проверяем подпись документа
verify_document_or_fail(authorization);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(authorization, 0);
// Обновляем заявку
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
// Добавляем документ авторизации взноса с именем
Document::add_document(o.documents, DocumentNames::CONTRIB_AUTH, authorization);
// Проверяем, есть ли уже оба документа авторизации
bool has_contrib_auth = Document::has_document(o.documents, DocumentNames::CONTRIB_AUTH);
bool has_return_auth = Document::has_document(o.documents, DocumentNames::RETURN_AUTH);
// Если получили оба документа авторизации, переводим в статус authorized
if (has_contrib_auth && has_return_auth) {
o.status = "authorized"_n;
}
});
};
@@ -1,45 +0,0 @@
/**
\ingroup public_actions
\brief Авторизация заявления на возврат имущества советом кооператива.
@details Совет кооператива авторизует заявление на возврат имущества.
@param coopname Имя кооператива
@param request_hash Хэш заявки
@param authorization Документ авторизации от совета
@note Авторизация требуется от аккаунта: @p _soviet
**/
[[eosio::action]] void marketplace::authreturn(eosio::name coopname, checksum256 request_hash, document2 authorization) {
require_auth(_soviet);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "accepted"_n, "Только принятая заявка может быть авторизована");
// Проверяем подпись документа
verify_document_or_fail(authorization);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(authorization, 0);
// Обновляем заявку
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
// Добавляем документ авторизации возврата с именем
Document::add_document(o.documents, DocumentNames::RETURN_AUTH, authorization);
// Проверяем, есть ли уже оба документа авторизации
bool has_contrib_auth = Document::has_document(o.documents, DocumentNames::CONTRIB_AUTH);
bool has_return_auth = Document::has_document(o.documents, DocumentNames::RETURN_AUTH);
// Если получили оба документа авторизации, переводим в статус authorized
if (has_contrib_auth && has_return_auth) {
o.status = "authorized"_n;
}
});
};
@@ -1,61 +0,0 @@
/**
\ingroup public_actions
\brief Отмена заявки пользователем.
@details Пользователь может отменить свою заявку с учетом комиссии за отмену.
@param coopname Имя кооператива
@param username Имя пользователя
@param request_hash Хэш заявки
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::cancel(eosio::name coopname, eosio::name username, checksum256 request_hash) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
// Проверяем права доступа
eosio::check(change.username == username || change.product_contributor == username, "Недостаточно прав доступа");
// Ограничения отмены
eosio::check(change.status != "completed"_n, "Нельзя отменить завершенную заявку");
eosio::check(change.status != "canceled"_n, "Заявка уже отменена");
eosio::check(change.status != "declined"_n, "Нельзя отменить отклоненную заявку");
// Поставщик не может отменить заявку после поставки
if ((change.money_contributor != username && change.product_contributor != username) ||
(change.product_contributor == username && (change.status == "supplied1"_n || change.status == "supplied2"_n ||
change.status == "delivered"_n || change.status == "received1"_n || change.status == "received2"_n))) {
eosio::check(false, "Поставщик не может отменить заявку после поставки");
}
std::string memo = "Отмена заявки №" + std::to_string(change.id);
// Возвращаем средства заказчику с учетом комиссии за отмену
if (username == change.money_contributor) {
eosio::asset return_amount = change.total_cost - change.cancellation_fee_amount;
// Списываем заблокированные средства
Wallet::sub_blocked_funds(_marketplace, coopname, change.money_contributor, change.total_cost, _marketplace_program, memo);
// Возвращаем средства в кошелёк
Wallet::add_available_funds(_marketplace, coopname, change.money_contributor, return_amount, _wallet_program, memo);
// Направляем комиссию в фонд членских взносов
if (change.cancellation_fee_amount.amount > 0) {
// Wallet::add_member_fee(_marketplace, coopname, change.username, _marketplace_program_id, change.cancellation_fee_amount, memo);
}
}
// Удаляем заявку из системы
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для удаления");
requests.erase(change_itr);
};
@@ -1,40 +0,0 @@
/**
\ingroup public_actions
\brief Завершение поставки.
@details После истечения гарантийной задержки происходит завершение поставки.
@param coopname Имя кооператива
@param username Имя пользователя
@param request_hash Хэш заявки
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::complete(eosio::name coopname, eosio::name username, checksum256 request_hash) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "received"_n, "Завершение возможно только после статуса received");
eosio::check(eosio::time_point_sec(eosio::current_time_point()) >= change.warranty_delay_until, "Гарантийная задержка ещё не истекла");
// Проводки по кошельку
std::string memo = "Завершение поставки для заказа №" + std::to_string(change.id);
// Поставщик - списываем заблокированный баланс и начисляем в кошелёк
Wallet::sub_blocked_funds(_marketplace, coopname, change.product_contributor, change.base_cost, _marketplace_program, memo);
Wallet::add_available_funds(_marketplace, coopname, change.product_contributor, change.base_cost, _wallet_program, memo);
// Членские взносы (если больше нуля)
if (change.membership_fee_amount.amount > 0) {
// Wallet::add_member_fee(_marketplace, coopname, change.username, _marketplace_program_id, change.membership_fee_amount, memo);
}
// Удаляем заявку из системы
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для удаления");
requests.erase(change_itr);
};
@@ -1,39 +0,0 @@
/**
\ingroup public_actions
\brief Отклонение заявки.
@details Отклонение заявки с указанием причины.
@param coopname Имя кооператива
@param username Имя пользователя
@param request_hash Хэш заявки
@param meta Причина отклонения
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::decline(eosio::name coopname, eosio::name username, checksum256 request_hash, std::string meta) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "active"_n || change.status == "accepted"_n, "Можно отклонить только активную или принятую заявку");
std::string memo = "Отклонение заявки №" + std::to_string(change.id) + ": " + meta;
// Возвращаем средства заказчику если они были заблокированы
if (change.status == "active"_n && change.money_contributor != ""_n) {
// Списываем заблокированные средства
Wallet::sub_blocked_funds(_marketplace, coopname, change.money_contributor, change.total_cost, _marketplace_program, memo);
// Возвращаем средства в кошелёк
Wallet::add_available_funds(_marketplace, coopname, change.money_contributor, change.total_cost, _wallet_program, memo);
}
// Удаляем заявку из системы
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для удаления");
requests.erase(change_itr);
};
@@ -1,62 +0,0 @@
/**
\ingroup public_actions
\brief Отклонение принятия заявки советом (declineacc).
@details Данный метод вызывается советом когда заявление на конвертацию, возврат или взнос отклоняется.
После рефакторинга работаем только с одной заявкой orderoffer.
@param coopname Имя кооператива
@param request_hash Хэш заявки, которая должна быть отменена
@param reason Причина отклонения
@note Авторизация требуется от аккаунта: @p _soviet
*/
[[eosio::action]] void marketplace::declineacc(eosio::name coopname, checksum256 request_hash, std::string reason) {
require_auth(_soviet);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
// Если заявка не найдена, ничего не делаем (возможно уже удалена)
if (!change_opt.has_value()) {
print("Заявка уже удалена или не найдена. Кооператив: ", coopname, ", причина: ", reason);
return;
}
auto change = change_opt.value();
// Логирование отклонения
print("Отклонение заявления советом. Заявка ID: ", change.id, ", причина: ", reason);
// Отклоняем заявку
decline_request(coopname, change);
}
/**
* @brief Статический метод для отклонения заявки (используется советом)
*/
void marketplace::decline_request(eosio::name coopname, const request& change) {
requests_index requests(_marketplace, coopname.value);
// Проверяем, что заявка все еще существует
auto change_itr = requests.find(change.id);
if (change_itr == requests.end()) {
return; // Заявка уже удалена
}
std::string memo = "Отклонение заявления советом по программе №" + std::to_string(_marketplace_program_id) + " для заявки ID: " + std::to_string(change.id);
// Возвращаем средства заказчику если они были заблокированы
if (change.type == "orderoffer"_n && change.total_cost.amount > 0 && change.money_contributor != ""_n) {
// Списываем заблокированные средства с маркетплейса
Wallet::sub_blocked_funds(_marketplace, coopname, change.money_contributor, change.total_cost, _marketplace_program, memo);
// Возвращаем средства в кошелёк
Wallet::add_available_funds(_marketplace, coopname, change.money_contributor, change.total_cost, _wallet_program, memo);
}
// Удаляем заявку из системы
requests.erase(change_itr);
}
@@ -1,35 +0,0 @@
/**
\ingroup public_actions
\brief Перевод заявки в статус готово к выдаче.
@details Председатель КУ переводит заявку в статус delivered независимо от транспортировки.
Используется когда транспортировка между КУ не нужна или имущество уже находится на складе.
Просто перевод статуса без дополнительных документов.
@param coopname Имя кооператива
@param username Имя пользователя (может быть поставщиком или заказчиком)
@param request_hash Хэш заявки
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::delivered(eosio::name coopname, eosio::name username, checksum256 request_hash) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
// Проверяем что заявка в подходящем статусе (после поставки или перемещения со склада)
eosio::check(change.status == "supplied2"_n || change.status == "shiprecvd"_n, "Перевод в статус delivered возможен только после поставки (supplied2) или после получения на склад (shiprecvd)");
// Обновляем заявку - просто перевод статуса
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
o.status = "delivered"_n;
o.delivered_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
// Устанавливаем крайний срок получения (3 дня)
o.deadline_for_receipt = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch() + 3 * 24 * 60 * 60);
});
};
@@ -1,110 +0,0 @@
/**
\ingroup public_actions
\brief Создать заявку orderoffer - заказчик создает заявку на поставку товара от поставщика.
*
* Данный метод позволяет заказчику создать заявку на поставку товара от поставщика.
* Заявка содержит всю информацию о товаре, стоимости, документах и сразу блокирует средства заказчика.
*
* @param coopname Имя кооператива
* @param receiver_braname Имя кооперативного участка заказчика для получения товара
* @param username Имя заказчика
* @param hash Хэш заявки (уникальный идентификатор)
* @param units Количество единиц товара
* @param unit_cost Цена за единицу товара
* @param product_lifecycle_secs Время жизни продукта
* @param warranty_period_secs Гарантийный срок в секундах
* @param membership_fee_amount Сумма членского взноса
* @param cancellation_fee_amount Сумма комиссии за отмену заявки
* @param product_return_statement Заявление на возврат паевого взноса имуществом
* @param convert_in Заявление на конвертацию из кошелька в маркетплейс
* @param meta Метаданные о заявке
*
* @note Авторизация требуется от аккаунта: @p coopname
*/
[[eosio::action]] void marketplace::orderoffer(eosio::name coopname, eosio::name receiver_braname, eosio::name username, checksum256 hash, uint64_t units, eosio::asset unit_cost, uint32_t product_lifecycle_secs, uint32_t warranty_period_secs, eosio::asset membership_fee_amount, eosio::asset cancellation_fee_amount, document2 product_return_statement, document2 convert_in, std::string meta) {
require_auth(coopname);
// Проверяем, что заявка с таким хэшем не существует
auto existing_request = get_request_by_hash(coopname, hash);
eosio::check(!existing_request.has_value(), "Заявка с таким хэшем уже существует");
// Проверяем, что символ токена совпадает с символом токена кооператива
auto coop = get_cooperative_or_fail(coopname);
eosio::check(unit_cost.symbol == coop.initial.symbol, "Неверный символ токена");
eosio::check(membership_fee_amount.symbol == coop.initial.symbol, "Неверный символ токена для членского взноса");
eosio::check(cancellation_fee_amount.symbol == coop.initial.symbol, "Неверный символ токена для комиссии отмены");
eosio::check(units > 0, "Количество единиц в заявке должно быть больше нуля");
eosio::check(unit_cost.amount >= 0, "Цена не может быть отрицательной");
eosio::check(membership_fee_amount.amount >= 0, "Членский взнос не может быть отрицательным");
eosio::check(cancellation_fee_amount.amount >= 0, "Комиссия за отмену не может быть отрицательной");
// Проверяем, что пользователь является пайщиком кооператива
get_participant_or_fail(coopname, username);
// Проверяем существование кооперативного участка заказчика
get_branch_or_fail(coopname, receiver_braname);
// Проверяем существование программы маркетплейса
auto program = get_program_or_fail(coopname, _marketplace_program_id);
// Гарантийный срок возврата должен быть установлен
eosio::check(product_lifecycle_secs > 0, "Гарантийный срок возврата для имущества должен быть установлен");
eosio::check(warranty_period_secs > 0, "Гарантийный срок должен быть больше нуля");
// Проводим проверку подписи документов
verify_document_or_fail(product_return_statement);
verify_document_or_fail(convert_in);
// Валидируем документы по registry_id (пока что нули как просил пользователь)
Document::validate_registry_id(product_return_statement, 0);
Document::validate_registry_id(convert_in, 0);
// Рассчитываем стоимость
eosio::asset base_cost = unit_cost * units;
eosio::asset total_cost = base_cost + membership_fee_amount;
// Проверяем что комиссия за отмену не превышает общую стоимость
eosio::check(cancellation_fee_amount <= total_cost, "Комиссия за отмену не может превышать общую стоимость заявки");
requests_index requests(_marketplace, coopname.value);
uint64_t request_id = get_global_id(_marketplace, "requests"_n);
std::string memo = "Начало поставки по программе №" + std::to_string(_marketplace_program_id) + " с ID: " + std::to_string(request_id);
// Создаем вектор именованных документов
std::vector<Document::named_document> documents;
Document::add_document(documents, DocumentNames::RETURN_STMT, product_return_statement);
Document::add_document(documents, DocumentNames::CONVERT_FROM, convert_in);
requests.emplace(_marketplace, [&](auto &i) {
i.id = request_id;
i.hash = hash;
i.type = "orderoffer"_n;
i.username = username;
i.coopname = coopname;
i.status = "active"_n;
i.units = units;
i.unit_cost = unit_cost;
i.base_cost = base_cost;
i.membership_fee_amount = membership_fee_amount;
i.total_cost = total_cost;
i.product_lifecycle_secs = product_lifecycle_secs;
i.warranty_period_secs = warranty_period_secs;
i.money_contributor = username;
i.meta = meta;
i.created_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
i.cancellation_fee_amount = cancellation_fee_amount;
i.receiver_braname = receiver_braname;
i.documents = documents;
});
// Конвертируем и блокируем средства заказчика
std::string convert_memo = "Конвертация средств из ЦПП 'Цифровой Кошелёк' в ЦПП 'Маркетплейс' для заказа №" + std::to_string(request_id);
Wallet::sub_available_funds(_marketplace, coopname, username, total_cost, _wallet_program, convert_memo);
// Добавляем средства на ЦПП маркетплейса
Wallet::add_available_funds(_marketplace, coopname, username, total_cost, _marketplace_program, convert_memo);
// Блокируем средства на программе маркетплейса
Wallet::block_funds(_marketplace, coopname, username, total_cost, _marketplace_program, memo);
};
@@ -1,39 +0,0 @@
/**
\ingroup public_actions
\brief Получение товара заказчиком.
@details Заказчик приходит на КУ для получения имущества. Председатель КУ подписывает акт и передаёт имущество заказчику.
@param coopname Имя кооператива
@param username Имя заказчика
@param request_hash Хэш заявки
@param document Акт получения имущества
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::receive(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "delivered"_n, "Получение возможно только после статуса delivered");
eosio::check(change.money_contributor == username, "Недостаточно прав доступа");
// Проверяем подпись документа
verify_document_or_fail(document);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(document, 0);
// Обновляем заявку
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
o.status = "received1"_n;
// Добавляем акт получения с именем
Document::add_document(o.documents, DocumentNames::RECEIVE_ACT, document);
});
};
@@ -1,51 +0,0 @@
/**
\ingroup public_actions
\brief Подтверждение получения заказчиком.
@details Заказчик подтверждает факт получения имущества второй подписью акта приёма-передачи.
@param coopname Имя кооператива
@param username Имя заказчика
@param request_hash Хэш заявки
@param document Акт подтверждения получения
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::receivecnf(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "received1"_n, "Подтверждение возможно только после статуса received1");
eosio::check(change.money_contributor == username, "Недостаточно прав доступа");
// Проверяем подпись документа
verify_document_or_fail(document);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(document, 0);
// Обновляем заявку
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
o.status = "received2"_n;
o.received_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
// Устанавливаем время окончания гарантийной задержки
o.warranty_delay_until = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch() + change.warranty_period_secs);
// Добавляем акт подтверждения с именем
Document::add_document(o.documents, DocumentNames::RECEIVE_ACT_CONF, document);
});
// Проводки по кошельку
std::string memo = "Подтверждение получения для заказа №" + std::to_string(change.id);
// Паевой фонд - уменьшаем циркуляцию
Ledger::sub(_marketplace, coopname, Ledger::accounts::SHARE_FUND, change.base_cost, memo);
// Заказчик - списываем заблокированный баланс
Wallet::sub_blocked_funds(_marketplace, coopname, change.money_contributor, change.total_cost, _marketplace_program, memo);
};
@@ -1,50 +0,0 @@
/**
\ingroup public_actions
\brief Подтверждение поставки председателем КУ.
@details Председатель кооперативного участка или доверенное им лицо подтверждает факт поставки имущества.
@param coopname Имя кооператива
@param username Имя представителя кооператива
@param request_hash Хэш заявки
@param act Акт подтверждения поставки
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::supplcnf(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 act) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "supplied1"_n, "Поставка должна быть подтверждена после статуса supplied1");
// Проверяем подпись документа
verify_document_or_fail(act);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(act, 0);
// Обновляем заявку
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
o.status = "supplied2"_n;
o.warehouse = change.supplier_braname; // Ставим имущество на склад КУ приёма
o.supplied_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
// Добавляем акт подтверждения с именем
Document::add_document(o.documents, DocumentNames::SUPPLY_ACT_CONF, act);
});
// Проводки по кошельку
std::string memo = "Подтверждение поставки для заказа №" + std::to_string(change.id);
// Паевой фонд - увеличиваем циркуляцию
Ledger::add(_marketplace, coopname, Ledger::accounts::SHARE_FUND, change.total_cost, memo);
// Поставщик - начисляем и блокируем средства
Wallet::add_available_funds(_marketplace, coopname, change.product_contributor, change.base_cost, _marketplace_program, memo);
Wallet::block_funds(_marketplace, coopname, change.product_contributor, change.base_cost, _marketplace_program, memo);
};
@@ -1,40 +0,0 @@
/**
\ingroup public_actions
\brief Поставка имущества в кооператив.
@details Поставщик поставляет имущество на указанный кооперативный участок и предоставляет подписанный акт приёма-передачи.
@param coopname Имя кооператива
@param username Имя поставщика
@param request_hash Хэш заявки
@param act Акт поставки имущества
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::supply(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 act) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "authorized"_n, "Только авторизованная заявка может быть поставлена");
eosio::check(change.product_contributor == username, "Недостаточно прав доступа");
// Проверяем подпись документа
verify_document_or_fail(act);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(act, 0);
// Обновляем заявку
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
o.status = "supplied1"_n;
o.supplied_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
// Добавляем акт поставки с именем
Document::add_document(o.documents, DocumentNames::SUPPLY_ACT, act);
});
};
@@ -1,56 +0,0 @@
# Система гарантийного возврата (диспут)
## Обзор
Новая система диспута работает через создание дополнительных сегментов в рамках существующей пары заявок, а не через создание новых заявок.
## Типы сегментов диспута
- **wreturn** - сегмент возврата товара от заказчика в кооператив
- **wsupply** - сегмент выдачи товара из кооператива поставщику
## Процесс диспута
### 1. Открытие диспута (`dispute`)
- Заказчик подает претензию с документом
- Создаются два новых сегмента: `wreturn` и `wsupply`
- Статус заявки меняется на `disputed`
### 2. Авторизация диспута (`wauthorize`)
- Совет авторизует принятие товара от заказчика
- Совет авторизует последующую выдачу товара поставщику
- Статус заявки меняется на `wauthorized`
### 3. Возврат товара (`wreturn`)
- Заказчик возвращает товар в кооператив
- Председатель принимает товар и подписывает акт
- Статус заявки меняется на `wreturned`
### 4. Предложение товара поставщику (`woffer`)
- Кооператив предлагает поставщику забрать товар
- Создается акт передачи
- Статус заявки меняется на `woffered`
### 5. Принятие решения поставщиком (`waccept`)
- Поставщик может принять товар (`accept=true`) или отказаться (`accept=false`)
- При принятии: статус становится `wcompleted`
- При отказе: статус становится `wdeclined`
## Статусы заявок диспута
- **disputed** - диспут открыт
- **wauthorized** - диспут авторизован советом
- **wreturned** - товар возвращен в кооператив
- **woffered** - товар предложен поставщику
- **wcompleted** - поставщик принял товар, диспут завершен
- **wdeclined** - поставщик отказался от товара, диспут завершен
## Статусы сегментов
- **created** - сегмент создан
- **statement** - документ/заявление предоставлено
- **authorized** - авторизовано советом
- **returned** - товар возвращен в кооператив
- **offered** - товар предложен поставщику
- **accepted** - поставщик принял товар
- **declined** - поставщик отказался от товара
@@ -1,61 +0,0 @@
/**
\ingroup public_actions
\brief Открытие гарантийного спора по заявке.
@details Заказчик может открыть спор после получения товара, если есть проблемы с качеством или соответствием.
Создается претензия, которая сохраняется в документах заявки.
@param coopname Имя кооператива
@param username Имя заказчика, открывающего спор
@param request_hash Хэш заявки, по которой открывается спор
@param document Документ с описанием претензии
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::dispute(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document){
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.type == "orderoffer"_n, "Спор может быть открыт только по заявке orderoffer");
eosio::check(change.username == username, "Только заказчик может открыть спор");
eosio::check(change.is_warranty_return == false, "Нельзя открыть спор на спор");
eosio::check(change.status == "received"_n || change.status == "completed"_n, "Спор можно открыть только после получения товара");
// Проверяем подпись документа
verify_document_or_fail(document);
// Обновляем статус заявки на "disputed" и добавляем документ с претензией
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &e){
e.status = "disputed"_n;
e.disputed_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
e.is_warranty_return = true;
Document::add_document(e.documents, Marketplace::DocumentNames::WDISPUTE, document);
});
// Используем хэш заявки как идентификатор пакета решений
checksum256 agenda_hash = change.hash;
// Отправляем заявление на гарантийный возврат в совет
Action::send<createagenda_interface>(
_soviet,
"createagenda"_n,
_marketplace,
coopname,
username,
get_valid_soviet_action("mpwreturn"_n),
agenda_hash,
_marketplace,
Marketplace::get_valid_marketplace_action("wauthorize"_n),
"wdecline"_n,
document,
std::string("")
);
}
@@ -1,48 +0,0 @@
/**
\ingroup public_actions
\brief Принятие или отказ поставщика от товара в рамках гарантийного возврата
@details Поставщик может принять товар (accept=true) или отказаться от него (accept=false).
При принятии товар передается поставщику и диспут завершается.
При отказе товар остается у кооператива и диспут завершается.
@param coopname Имя кооператива
@param username Имя поставщика
@param request_hash Хэш заявки с диспутом
@param accept Принимает ли поставщик товар (true/false)
@param document Документ с решением поставщика
@note Авторизация требуется от аккаунта: @p coopname
*/
[[eosio::action]] void marketplace::waccept(eosio::name coopname, eosio::name username, checksum256 request_hash, bool accept, document2 document) {
require_auth(coopname);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "woffered"_n, "Товар должен быть предложен поставщику");
eosio::check(change.product_contributor == username, "Только поставщик может принять решение о товаре");
// Проверяем подпись документа
verify_document_or_fail(document);
requests_index requests(_marketplace, coopname.value);
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
if (accept) {
// Поставщик принимает товар
requests.modify(change_itr, _marketplace, [&](auto &ch) {
ch.status = "wcompleted"_n;
Document::add_document(ch.documents, Marketplace::DocumentNames::WACCEPT_ACT, document);
});
} else {
// Поставщик отказывается от товара
requests.modify(change_itr, _marketplace, [&](auto &ch) {
ch.status = "wdeclined"_n;
Document::add_document(ch.documents, Marketplace::DocumentNames::WACCEPT_ACT, document);
});
}
}
@@ -1,34 +0,0 @@
/**
\ingroup public_actions
\brief Авторизация гарантийного возврата советом
@details Совет авторизует принятие товара от заказчика и его последующую выдачу поставщику
@param coopname Имя кооператива
@param request_hash Хэш заявки с диспутом
@param wreturn_decision_id Идентификатор решения по принятию товара
@param wreturn_authorization Документ авторизации принятия товара
@param wsupply_decision_id Идентификатор решения по выдаче товара поставщику
@param wsupply_authorization Документ авторизации выдачи товара
@note Авторизация требуется от аккаунта: @p _soviet
*/
[[eosio::action]] void marketplace::wauthorize(eosio::name coopname, checksum256 request_hash, uint64_t wreturn_decision_id, document2 wreturn_authorization, uint64_t wsupply_decision_id, document2 wsupply_authorization) {
require_auth(_soviet);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "disputed"_n, "Заявка должна быть в статусе диспута");
// Обновляем статус заявки и добавляем документы авторизации
requests_index requests(_marketplace, coopname.value);
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _soviet, [&](auto &o) {
o.status = "wauthorized"_n;
Document::add_document(o.documents, Marketplace::DocumentNames::WRETURN_AUTH, wreturn_authorization);
Document::add_document(o.documents, Marketplace::DocumentNames::WSUPPLY_AUTH, wsupply_authorization);
});
};
@@ -1,40 +0,0 @@
/**
\ingroup public_actions
\brief Предложение товара поставщику в рамках гарантийного возврата
@details Кооператив предлагает поставщику забрать товар, возвращенный заказчиком.
Создается предложение с актом передачи.
@param coopname Имя кооператива
@param username Имя председателя, предлагающего товар
@param request_hash Хэш заявки с диспутом
@param document Акт передачи товара поставщику
@note Авторизация требуется от аккаунта: @p coopname
*/
[[eosio::action]] void marketplace::woffer(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document) {
require_auth(coopname);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "wreturned"_n, "Товар может быть предложен только после возврата в кооператив");
auto soviet = get_board_by_type_or_fail(coopname, "soviet"_n);
auto chairman = soviet.get_chairman();
eosio::check(username == chairman, "Недостаточно прав доступа для предложения товара");
// Проверяем подпись документа
verify_document_or_fail(document);
// Обновляем статус заявки и добавляем акт предложения товара
requests_index requests(_marketplace, coopname.value);
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &ch) {
ch.status = "woffered"_n;
Document::add_document(ch.documents, Marketplace::DocumentNames::WOFFER_ACT, document);
});
}
@@ -1,40 +0,0 @@
/**
\ingroup public_actions
\brief Возврат товара от заказчика в кооператив
@details Заказчик возвращает товар в кооператив в рамках гарантийного возврата.
Председатель принимает товар и подписывает акт приёма.
@param coopname Имя кооператива
@param username Имя председателя, принимающего товар
@param request_hash Хэш заявки с диспутом
@param document Акт приёма товара от заказчика
@note Авторизация требуется от аккаунта: @p coopname
*/
[[eosio::action]] void marketplace::wreturn(eosio::name coopname, eosio::name username, checksum256 request_hash, document2 document) {
require_auth(coopname);
requests_index requests(_marketplace, coopname.value);
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "wauthorized"_n, "Товар может быть возвращен только по авторизованному диспуту");
auto soviet = get_board_by_type_or_fail(coopname, "soviet"_n);
auto chairman = soviet.get_chairman();
eosio::check(username == chairman, "Недостаточно прав доступа для принятия возврата");
// Проверяем подпись документа
verify_document_or_fail(document);
// Обновляем статус заявки и добавляем акт приёма возврата
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &ch) {
ch.status = "wreturned"_n;
Document::add_document(ch.documents, Marketplace::DocumentNames::WRETURN_ACT, document);
});
}
@@ -1,35 +0,0 @@
/**
\ingroup public_actions
\brief Перевозка прибыла в место назначения.
@details Перевозка переходит в статус arrived и ожидает подписи получателя.
@param coopname Имя кооператива
@param hash Идентификатор перевозки
@param transport_act_delivery Акт доставки подписанный водителем
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::arrived(eosio::name coopname, checksum256 hash, document2 transport_act_delivery) {
require_auth(coopname);
// Проверяем что перевозка существует
auto shipment = Marketplace::get_shipment_by_hash_or_fail(coopname, hash, "Перевозка не найдена");
eosio::check(shipment.status == "transit"_n, "Подписывать акт доставки можно только для перевозки в статусе transit");
// Проверяем подпись документа
verify_document_or_fail(transport_act_delivery, { shipment.driver_username });
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(transport_act_delivery, 0);
// Обновляем перевозку - добавляем третий акт
shipments_index shipments(_marketplace, coopname.value);
auto hash_index = shipments.get_index<"byhash"_n>();
auto shipment_itr = hash_index.find(hash);
hash_index.modify(shipment_itr, _marketplace, [&](auto &s) {
s.status = "arrived"_n; // Новый статус - прибыл, ожидает приёма получателем
Document::add_document(s.documents, DocumentNames::SHIPMENT_ARRIVE_ACT, transport_act_delivery);
s.delivered_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
});
};
@@ -1,71 +0,0 @@
/**
\ingroup public_actions
\brief Создание новой перевозки с массивом заявок.
@details Создает новую перевозку от одного КУ к другому с указанием водителя и массива заявок.
Представитель КУ отправления подписывает первый акт приёма-передачи.
Заявки остаются на складе до получения подписи от водителя.
@param coopname Имя кооператива
@param hash Внешний идентификатор перевозки
@param driver_username Имя водителя-пайщика
@param source_braname КУ отправителя
@param destination_braname КУ назначения
@param request_hashes Массив хэшей заявок для перевозки
@param transport_act_sender Акт приёма-передачи от представителя КУ отправления
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::createship(eosio::name coopname, checksum256 hash, eosio::name driver_username, eosio::name source_braname, eosio::name destination_braname, std::vector<checksum256> request_hashes, document2 transport_act_sender) {
require_auth(coopname);
// Проверяем что КУ отправителя и назначения разные
eosio::check(source_braname != destination_braname, "КУ отправителя и назначения не могут совпадать");
// Проверяем что есть хотя бы одна заявка
eosio::check(!request_hashes.empty(), "Должна быть указана хотя бы одна заявка");
// Проверяем что перевозка с таким hash не существует
auto existing_shipment = Marketplace::get_shipment_by_hash(coopname, hash);
eosio::check(!existing_shipment.has_value(), "Перевозка с таким идентификатором уже существует");
// Проверяем подпись документа
verify_document_or_fail(transport_act_sender);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(transport_act_sender, 0);
requests_index requests(_marketplace, coopname.value);
// Проверяем все заявки но НЕ снимаем их со склада (это будет при signbydriver)
for (auto& request_hash : request_hashes) {
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "supplied2"_n || change.status == "shiprecvd"_n || change.status == "delivered"_n, "Перевозить можно только заявки в статусе supplied2, shiprecvd или delivered");
eosio::check(change.type == "orderoffer"_n, "Перевозить можно только заявки типа orderoffer");
eosio::check(change.warehouse == source_braname, "Заявка должна находиться на складе КУ отправителя");
}
// Получаем новый ID для перевозки
uint64_t next_shipment_id = get_global_id_in_scope(_marketplace, coopname, "shipments"_n);
// Создаем новую перевозку
shipments_index shipments(_marketplace, coopname.value);
shipments.emplace(_marketplace, [&](auto &s) {
s.id = next_shipment_id;
s.hash = hash;
s.coopname = coopname;
s.driver_username = driver_username;
s.source_braname = source_braname;
s.destination_braname = destination_braname;
s.status = "loading"_n;
s.request_hashes = request_hashes;
// Добавляем первый документ
Document::add_document(s.documents, DocumentNames::SHIPMENT_SEND_ACT, transport_act_sender);
s.created_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
});
};
@@ -1,55 +0,0 @@
/**
\ingroup public_actions
\brief Приём имущества на склад по накладной.
@details Представитель КУ получения принимает имущество на склад по накладной.
Все заявки из перевозки переходят в статус delivered и ставятся на склад КУ получения.
Объект перевозки удаляется.
@param coopname Имя кооператива
@param hash Идентификатор перевозки
@param warehouse_receipt_act Акт приёма на склад подписанный получателем
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::receiveshipm(eosio::name coopname, checksum256 hash, document2 warehouse_receipt_act) {
require_auth(coopname);
// Проверяем что перевозка существует
auto shipment = Marketplace::get_shipment_by_hash_or_fail(coopname, hash, "Перевозка не найдена");
eosio::check(shipment.status == "arrived"_n, "Принимать имущество на склад можно только для перевозки в статусе arrived");
// Проверяем подпись документа
verify_document_or_fail(warehouse_receipt_act);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(warehouse_receipt_act, 0);
requests_index requests(_marketplace, coopname.value);
// Обновляем все заявки из перевозки - ставим их на склад получения
for (auto& request_hash : shipment.request_hashes) {
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
// Обновляем заявку
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
o.status = "shiprecvd"_n; // Доставка получена
o.warehouse = shipment.destination_braname; // Ставим на склад КУ получения
o.delivered_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
// Устанавливаем крайний срок получения (3 дня)
o.deadline_for_receipt = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch() + 3 * 24 * 60 * 60);
// Добавляем акт приёма на складе получателем
Document::add_document(o.documents, DocumentNames::SHIPMENT_RECV_ACT, warehouse_receipt_act);
});
}
// Удаляем объект перевозки после завершения
shipments_index shipments(_marketplace, coopname.value);
auto hash_index = shipments.get_index<"byhash"_n>();
auto shipment_itr = hash_index.find(hash);
hash_index.erase(shipment_itr);
};
@@ -1,66 +0,0 @@
/**
\ingroup public_actions
\brief Промежуточная передача товаров между складами.
@details Создает новую перевозку для доставленных заявок, позволяя передать все товары
из текущего склада в другое место назначения с новым водителем.
@param coopname Имя кооператива
@param completed_hash Внешний идентификатор новой перевозки
@param new_driver_username Имя нового водителя-пайщика
@param source_braname КУ с которого забираем товары
@param new_destination_braname Новый КУ назначения
@param request_hashes Массив хэшей заявок для переотправки
@param transport_act_sender Акт передачи от текущего склада
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::retransport(eosio::name coopname, checksum256 completed_hash, eosio::name new_driver_username, eosio::name source_braname, eosio::name new_destination_braname, std::vector<checksum256> request_hashes, document2 transport_act_sender) {
require_auth(coopname);
// Проверяем что есть хотя бы одна заявка
eosio::check(!request_hashes.empty(), "Должна быть указана хотя бы одна заявка");
// Проверяем что перевозка с таким hash не существует
auto existing_shipment = Marketplace::get_shipment_by_hash(coopname, completed_hash);
eosio::check(!existing_shipment.has_value(), "Перевозка с таким идентификатором уже существует");
// Проверяем подпись документа
verify_document_or_fail(transport_act_sender);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(transport_act_sender, 0);
requests_index requests(_marketplace, coopname.value);
// Проверяем все заявки но НЕ снимаем их со склада (это будет при signbydriver)
for (auto& request_hash : request_hashes) {
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.status == "delivered"_n, "Переотправлять можно только доставленные заявки");
eosio::check(change.warehouse == source_braname, "Заявка должна находиться на указанном складе");
}
// Получаем новый ID для перевозки
uint64_t next_shipment_id = get_global_id_in_scope(_marketplace, coopname, "shipments"_n);
// Создаем новую перевозку
shipments_index shipments(_marketplace, coopname.value);
shipments.emplace(_marketplace, [&](auto &s) {
s.id = next_shipment_id;
s.hash = completed_hash;
s.coopname = coopname;
s.driver_username = new_driver_username;
s.source_braname = source_braname;
s.destination_braname = new_destination_braname;
s.status = "loading"_n;
s.request_hashes = request_hashes;
// Добавляем первый документ
Document::add_document(s.documents, DocumentNames::SHIPMENT_SEND_ACT, transport_act_sender);
s.created_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
});
};
@@ -1,55 +0,0 @@
/**
\ingroup public_actions
\brief Подпись акта приёма-передачи водителем.
@details Водитель подписывает акт приёма имущества на транспортировку.
Все заявки снимаются со склада отправления.
Перевозка переходит в статус transit.
@param coopname Имя кооператива
@param hash Идентификатор перевозки
@param transport_act_driver Акт приёма-передачи подписанный водителем
@note Авторизация требуется от аккаунта: @p coopname
**/
[[eosio::action]] void marketplace::signbydriver(eosio::name coopname, checksum256 hash, document2 transport_act_driver) {
require_auth(coopname);
// Проверяем что перевозка существует
auto shipment = Marketplace::get_shipment_by_hash_or_fail(coopname, hash, "Перевозка не найдена");
eosio::check(shipment.status == "loading"_n, "Подписывать акт водитель может только для перевозки в статусе loading");
// Проверяем подпись документа
verify_document_or_fail(transport_act_driver);
// Валидируем документ по registry_id (пока что ноль)
Document::validate_registry_id(transport_act_driver, 0);
requests_index requests(_marketplace, coopname.value);
// Снимаем все заявки со склада отправления
for (auto& request_hash : shipment.request_hashes) {
auto change_opt = Marketplace::get_request_by_hash(coopname, request_hash);
eosio::check(change_opt.has_value(), "Заявка не найдена");
auto change = change_opt.value();
eosio::check(change.warehouse == shipment.source_braname, "Заявка должна находиться на складе КУ отправителя");
// Снимаем заявку со склада
auto change_itr = requests.find(change.id);
eosio::check(change_itr != requests.end(), "Заявка не найдена для обновления");
requests.modify(change_itr, _marketplace, [&](auto &o){
o.warehouse = ""_n; // Снимаем со склада
});
}
// Обновляем перевозку
shipments_index shipments(_marketplace, coopname.value);
auto hash_index = shipments.get_index<"byhash"_n>();
auto shipment_itr = hash_index.find(hash);
hash_index.modify(shipment_itr, _marketplace, [&](auto &s) {
s.status = "transit"_n;
Document::add_document(s.documents, DocumentNames::SHIPMENT_LOADING_ACT, transport_act_driver);
s.loaded_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
});
};
@@ -1,19 +1,24 @@
// eosio::asset minimum = deposit -> quantity == cooperative.registration ? cooperative.minimum : cooperative.org_minimum.value();
// eosio::asset initial = deposit -> quantity == cooperative.registration ? cooperative.initial : cooperative.org_initial.value();
eosio::asset minimum = deposit -> quantity == cooperative.registration ? cooperative.minimum : cooperative.org_minimum.value();
eosio::asset initial = deposit -> quantity == cooperative.registration ? cooperative.initial : cooperative.org_initial.value();
// Fund::sub_circulating_funds(_gateway, coopname, minimum, true);
action(
permission_level{ _gateway, "active"_n},
_fund,
"subcirculate"_n,
std::make_tuple(coopname, minimum, true)
).send();
// //вычесть вступительную сумму из фонда
// action(
// permission_level{ _gateway, "active"_n},
// _fund,
// "subinitial"_n,
// std::make_tuple(coopname, initial)
// ).send();
//вычесть вступительную сумму из фонда
action(
permission_level{ _gateway, "active"_n},
_fund,
"subinitial"_n,
std::make_tuple(coopname, initial)
).send();
// action (
// permission_level{ _gateway, "active"_n},
// _soviet,
// "cancelreg"_n,
// std::make_tuple(coopname, deposit -> username, memo)
// ).send();
action (
permission_level{ _gateway, "active"_n},
_soviet,
"cancelreg"_n,
std::make_tuple(coopname, deposit -> username, memo)
).send();
@@ -15,7 +15,7 @@
* - устанавливаем дату вступления
* - фиксируем принятый взнос в реестре взносов
* 4. fund::addcirculate (добавляем минимальный взнос)
* 5. fund::addinitial (добавляем вступительный взнос в кошелек кооператива)
* 5. fund::spreadamount? (опционально распределяем вступительный взнос по фондам)
* )
* )
* )
@@ -78,10 +78,20 @@
});
Ledger::add(_registrator, coopname, Ledger::accounts::SHARE_FUND, minimum, "Паевой взнос при регистрации пайщика");
action(
permission_level{ _registrator, "active"_n},
_fund,
"addcirculate"_n,
std::make_tuple(coopname, minimum)
).send();
if (spread_initial) {
Ledger::add(_registrator, coopname, Ledger::accounts::ENTRANCE_FEES, initial, "Вступительный взнос при регистрации пайщика");
action(
permission_level{ _registrator, "active"_n},
_fund,
"addinitial"_n,
std::make_tuple(coopname, initial)
).send();
}
eosio::name braname = ""_n;
@@ -35,9 +35,19 @@ void registrator::confirmreg(eosio::name coopname, checksum256 registration_hash
).send();
//добавляем
Ledger::add(_registrator, coopname, Ledger::accounts::SHARE_FUND, candidate -> minimum, "Паевой взнос при подтверждении регистрации");
action(
permission_level{ _registrator, "active"_n},
_fund,
"addcirculate"_n,
std::make_tuple(coopname, candidate -> minimum)
).send();
Ledger::add(_registrator, coopname, Ledger::accounts::ENTRANCE_FEES, candidate -> initial, "Вступительный взнос при подтверждении регистрации");
action(
permission_level{ _registrator, "active"_n},
_fund,
"addinitial"_n,
std::make_tuple(coopname, candidate -> initial)
).send();
// Увеличиваем счетчик активных пайщиков
cooperatives2_index cooperatives(_registrator, _registrator.value);
+3 -2
View File
@@ -50,6 +50,9 @@
#include "src/fund/fundwithdraw.cpp"
#include "src/marketplace/change.cpp"
#include "src/marketplace/recieved.cpp"
#include "src/participant/addparticipant.cpp"
#include "src/participant/block.cpp"
#include "src/participant/cancelreg.cpp"
@@ -69,8 +72,6 @@
#include "src/wallet/addbal.cpp"
#include "src/wallet/addmemberfee.cpp"
#include "src/wallet/submemberfee.cpp"
#include "src/wallet/blockbal.cpp"
#include "src/wallet/openprogwall.cpp"
#include "src/wallet/subbal.cpp"
+7 -1
View File
@@ -115,6 +115,12 @@ public:
[[eosio::action]] void cancelvote(eosio::name coopname, eosio::name member, uint64_t decision_id);
//marketplace.cpp
[[eosio::action]] void change(eosio::name coopname, eosio::name parent_username, eosio::name username, uint64_t exchange_id, eosio::name money_contributor, eosio::name product_contributor);
[[eosio::action]] void recieved (eosio::name coopname, uint64_t exchange_id);
static void change_effect(eosio::name executer, eosio::name coopname, uint64_t decision_id, uint64_t batch_id);
//programs.cpp
[[eosio::action]] void createprog(eosio::name coopname, eosio::name username, eosio::name type, std::string title, std::string announce, std::string description, std::string preview, std::string images, eosio::name calculation_type, eosio::asset fixed_membership_contribution, uint64_t membership_percent_fee, bool is_can_coop_spend_share_contributions, std::string meta);
[[eosio::action]] void editprog(eosio::name coopname, eosio::name username, uint64_t program_id, uint64_t draft_id, std::string title, std::string announce, std::string description, std::string preview, std::string images, std::string meta);
@@ -143,7 +149,7 @@ public:
[[eosio::action]] void blockbal(eosio::name coopname, eosio::name username, uint64_t program_id, eosio::asset quantity, std::string memo);
[[eosio::action]] void unblockbal(eosio::name coopname, eosio::name username, uint64_t program_id, eosio::asset quantity, std::string memo);
[[eosio::action]] void addmemberfee(eosio::name coopname, eosio::name username, uint64_t program_id, eosio::asset quantity, std::string memo);
[[eosio::action]] void submemberfee(eosio::name coopname, eosio::name username, uint64_t program_id, eosio::asset quantity, std::string memo);
//addresses.cpp
[[eosio::action]] void creaddress(eosio::name coopname, eosio::name chairman, eosio::name braname, address_data data);
@@ -19,7 +19,9 @@ void soviet::exec(eosio::name executer, eosio::name coopname, uint64_t decision_
eosio::check(decision != decisions.end(),"Решение не найдено в оперативной памяти");
eosio::check(decision -> authorized == true, "Только авторизованное решение может быть исполнено");
if (decision -> type == _withdraw_action){//операция возврата паевого взноса из кошелька (вывод)
if (decision -> type == _change_action){//операция взноса-возврата взноса в маркетплейсе
soviet::change_effect(executer, coopname, decision->id, decision->batch_id);
} else if (decision -> type == _withdraw_action){//операция возврата паевого взноса из кошелька (вывод)
soviet::withdraw_effect(executer, coopname, decision->id, decision->batch_id);
} else if (decision -> type == _afund_withdraw_action) {//операция использования фонда накопления
soviet::subaccum_effect(executer, coopname, decision->id, decision->batch_id);
@@ -5,7 +5,7 @@
* Система позволяет установить дату регистрации участника, которая будет соответствовать дате уплаты им минимального и вступительного взносов.
* Если spread_initial установлен в false, то сумма вступительного взноса не распределяется среди фондов. Тогда система считает, что учет распределения вступительного взноса произошел за её пределами.
* Если spread_initial установлен в true, то сумма вступительного взноса распределяется по фондам согласно правилам распределения кооператива в контракте fund.
* Минимальный паевой взнос всегда добавляется в кошелёк пайщика и отмечается в статистике оборотного фонда кооператива.
* Минимальный паевый взнос всегда добавляется в кошелёк пайщика и отмечается в статистике оборотного фонда кооператива.
*
* @param[in] coopname The coopname
* @param[in] username The username
@@ -15,9 +15,9 @@ void soviet::unblock(eosio::name coopname, eosio::name admin, eosio::name userna
eosio::asset initial = participant -> type.value() == "organization"_n ? cooperative.org_initial.value() : cooperative.initial;
// if (is_registration == true) {
// eosio::check(!participant -> is_minimum && !participant -> is_initial, "Пайщик уже совершил вступительный и минимальный паевой взносы");
// eosio::check(!participant -> is_minimum && !participant -> is_initial, "Пайщик уже совершил вступительный и минимальный паевый взносы");
// //добавить мин паевой взнос в паевой фонд
// //добавить мин паевый взнос в паевой фонд
// action(
// permission_level{ _gateway, "active"_n},
// _fund,
@@ -45,8 +45,8 @@ void soviet::voteagainst(
require_auth(username);
}
// // Проверка соответствия ID решения
// eosio::check(signed_at <= eosio::current_time_point(), "Время подписи не может быть в будущем");
// Проверка соответствия ID решения
eosio::check(signed_at <= eosio::current_time_point(), "Время подписи не может быть в будущем");
// Проверка подписи
assert_recover_key(signed_hash, signature, public_key);
@@ -47,7 +47,7 @@ void soviet::votefor(
eosio::check(version == "1.0.0", "Неверная версия");
// Проверка соответствия ID решения
// eosio::check(signed_at <= eosio::current_time_point(), "Время подписи не может быть в будущем");
eosio::check(signed_at <= eosio::current_time_point(), "Время подписи не может быть в будущем");
// Проверка подписи
assert_recover_key(signed_hash, signature, public_key);
@@ -1,7 +1,6 @@
void soviet::addmemberfee(eosio::name coopname, eosio::name username, uint64_t program_id, eosio::asset quantity, std::string memo){
name payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
eosio::check(has_auth(_marketplace) || has_auth(_soviet), "Недостаточно прав доступа");
auto cooperative = get_cooperative_or_fail(coopname);
programs_index programs(_soviet, coopname.value);
@@ -14,12 +13,12 @@ void soviet::addmemberfee(eosio::name coopname, eosio::name username, uint64_t p
progwallets_index progwallets(_soviet, coopname.value);
auto wallet = progwallets.find(exist_wallet.id);
progwallets.modify(wallet, payer, [&](auto &p) {
progwallets.modify(wallet, _soviet, [&](auto &p) {
p.membership_contribution = p.membership_contribution.value_or(asset(0, quantity.symbol)) + quantity;
});
// Обновляем агрегированный баланс в самой программе (program_id)
programs.modify(prg, payer, [&](auto &p){
programs.modify(prg, _soviet, [&](auto &p){
p.membership_contributions = p.membership_contributions.value_or(asset(0, quantity.symbol)) + quantity;
});
}
@@ -1,31 +0,0 @@
void soviet::submemberfee(eosio::name coopname, eosio::name username, uint64_t program_id, eosio::asset quantity, std::string memo){
name payer = check_auth_and_get_payer_or_fail(contracts_whitelist);
auto cooperative = get_cooperative_or_fail(coopname);
programs_index programs(_soviet, coopname.value);
auto prg = programs.find(program_id);
eosio::check(prg != programs.end(), "Программа с указанным program_id не найдена");
auto participant = get_participant_or_fail(coopname, username);
auto exist_wallet = get_user_program_wallet_or_fail(coopname, username, program_id);
progwallets_index progwallets(_soviet, coopname.value);
auto wallet = progwallets.find(exist_wallet.id);
// Проверяем, что текущий баланс не станет меньше нуля
auto current_contribution = wallet->membership_contribution.has_value() ? wallet->membership_contribution.value() : asset(0, quantity.symbol);
eosio::check(current_contribution >= quantity, "Недостаточно средств для списания членского взноса");
progwallets.modify(wallet, payer, [&](auto &p) {
p.membership_contribution = current_contribution - quantity;
});
// Обновляем агрегированный баланс в самой программе (program_id)
auto current_program_contributions = prg->membership_contributions.has_value() ? prg->membership_contributions.value() : asset(0, quantity.symbol);
eosio::check(current_program_contributions >= quantity, "Недостаточно средств в программе для списания");
programs.modify(prg, payer, [&](auto &p){
p.membership_contributions = current_program_contributions - quantity;
});
}
@@ -11,11 +11,15 @@ void wallet::completedpst(eosio::name coopname, checksum256 deposit_hash) {
auto deposit = deposits.find(exist_deposit -> id);
auto participant = get_participant_or_fail(coopname, deposit -> username);
Wallet::add_available_funds(_wallet, coopname, deposit -> username, deposit ->quantity, _wallet_program, std::string("Паевой взнос в ЦПП 'Цифровой Кошелёк'"));
std::string memo = "Паевой взнос по целевой потребительской программе 'Цифровой Кошелёк'";
Wallet::add_available_funds(_wallet, coopname, deposit -> username, deposit ->quantity, _wallet_program, memo);
Ledger::add(_wallet, coopname, Ledger::accounts::SHARE_FUND, deposit -> quantity, memo);
action(
permission_level{ _wallet, "active"_n},
_fund,
"addcirculate"_n,
std::make_tuple(coopname, deposit -> quantity)
).send();
//оповещаем пользователя
require_recipient(deposit -> username);
@@ -9,7 +9,12 @@ void wallet::completewthd(COMPLETEWTHD_SIGNATURE) {
eosio::check(withdraw -> status == "authorized"_n, "Только принятые заявления на вывод могут быть обработаны");
Ledger::sub(_wallet, coopname, Ledger::accounts::SHARE_FUND, withdraw -> quantity, "Уменьшение паевого фонда при возврате паевого взноса");
action(
permission_level{ _wallet, "active"_n},
_fund,
"subcirculate"_n,
std::make_tuple(coopname, withdraw -> quantity, false)
).send();
std::string memo_in = "Возврат части паевого взноса по ЦПП 'Цифровой Кошелёк'";
Wallet::sub_blocked_funds(_wallet, coopname, withdraw -> username, withdraw -> quantity, _wallet_program, memo_in);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@coopenomics/contracts",
"version": "2025.7.23-1",
"version": "2025.7.2",
"private": true,
"scripts": {
"build:all": "./build-all.sh",
+59 -72
View File
@@ -7,7 +7,6 @@ export type IPublicKey = string
export type ISignature = string
export type ITimePointSec = string
export type IInt64 = number | string
export type IUint32 = number
export type IUint64 = number | string
export type IFloat64 = number
@@ -30,7 +29,7 @@ export interface IAllocate {
export interface IApprovecmmt {
coopname: IName
commit_hash: IChecksum256
empty_document: IDocument2
empty_document: IDocument
}
export interface IApprovecnvrt {
@@ -38,13 +37,13 @@ export interface IApprovecnvrt {
application: IName
approver: IName
convert_hash: IChecksum256
approved_statement: IDocument2
approved_statement: IDocument
}
export interface IApprovedebt {
coopname: IName
debt_hash: IChecksum256
approved_statement: IDocument2
approved_statement: IDocument
}
export interface IApproveexpns {
@@ -52,7 +51,7 @@ export interface IApproveexpns {
application: IName
approver: IName
expense_hash: IChecksum256
approved_statement: IDocument2
approved_statement: IDocument
}
export interface IApproveinvst {
@@ -60,7 +59,7 @@ export interface IApproveinvst {
application: IName
approver: IName
invest_hash: IChecksum256
approved_statement: IDocument2
approved_statement: IDocument
}
export interface IApprovereg {
@@ -69,7 +68,7 @@ export interface IApprovereg {
approver: IName
project_hash: IChecksum256
username: IName
approved_agreement: IDocument2
approved_agreement: IDocument
}
export interface IApproverslt {
@@ -77,7 +76,7 @@ export interface IApproverslt {
application: IName
approver: IName
result_hash: IChecksum256
approved_statement: IDocument2
approved_statement: IDocument
}
export interface IApprovewthd1 {
@@ -85,7 +84,7 @@ export interface IApprovewthd1 {
application: IName
approver: IName
withdraw_hash: IChecksum256
approved_return_statement: IDocument2
approved_return_statement: IDocument
}
export interface IApprovewthd2 {
@@ -93,7 +92,7 @@ export interface IApprovewthd2 {
application: IName
approver: IName
withdraw_hash: IChecksum256
approved_return_statement: IDocument2
approved_return_statement: IDocument
}
export interface IApprovewthd3 {
@@ -101,7 +100,7 @@ export interface IApprovewthd3 {
application: IName
approver: IName
withdraw_hash: IChecksum256
approved_return_statement: IDocument2
approved_return_statement: IDocument
}
export interface IAssignment {
@@ -145,37 +144,37 @@ export interface IAuthor {
export interface IAuthrslt {
coopname: IName
result_hash: IChecksum256
decision: IDocument2
decision: IDocument
}
export interface ICapauthexpns {
coopname: IName
expense_hash: IChecksum256
authorization: IDocument2
authorization: IDocument
}
export interface ICapauthinvst {
coopname: IName
invest_hash: IChecksum256
authorization: IDocument2
authorization: IDocument
}
export interface ICapauthwthd1 {
coopname: IName
withdraw_hash: IChecksum256
authorization: IDocument2
authorization: IDocument
}
export interface ICapauthwthd2 {
coopname: IName
withdraw_hash: IChecksum256
authorization: IDocument2
authorization: IDocument
}
export interface ICapauthwthd3 {
coopname: IName
withdraw_hash: IChecksum256
authorization: IDocument2
authorization: IDocument
}
export interface ICapitalist {
@@ -189,7 +188,7 @@ export interface ICapitalist {
export interface ICapregcontr {
coopname: IName
contributor_id: IUint64
authorization: IDocument2
authorization: IDocument
}
export interface ICommit {
@@ -220,9 +219,9 @@ export interface IContributor {
project_hash: IChecksum256
status: IName
created_at: ITimePointSec
agreement: IDocument2
approved_agreement: IDocument2
authorization: IDocument2
agreement: IDocument
approved_agreement: IDocument
authorization: IDocument
invested: IAsset
convert_percent: IUint64
contributed_hours: IUint64
@@ -247,7 +246,7 @@ export interface IConvert {
username: IName
status: IName
convert_amount: IAsset
convert_statement: IDocument2
convert_statement: IDocument
created_at: ITimePointSec
}
@@ -275,7 +274,7 @@ export interface ICreatecnvrt {
username: IName
assignment_hash: IChecksum256
convert_hash: IChecksum256
convert_statement: IDocument2
convert_statement: IDocument
}
export interface ICreatedebt {
@@ -285,7 +284,7 @@ export interface ICreatedebt {
debt_hash: IChecksum256
amount: IAsset
repaid_at: ITimePointSec
statement: IDocument2
statement: IDocument
}
export interface ICreateexpnse {
@@ -297,7 +296,7 @@ export interface ICreateexpnse {
fund_id: IUint64
amount: IAsset
description: string
statement: IDocument2
statement: IDocument
}
export interface ICreateinvest {
@@ -307,7 +306,7 @@ export interface ICreateinvest {
project_hash: IChecksum256
invest_hash: IChecksum256
amount: IAsset
statement: IDocument2
statement: IDocument
}
export interface ICreateproj {
@@ -329,7 +328,7 @@ export interface ICreatewthd1 {
assignment_hash: IChecksum256
withdraw_hash: IChecksum256
amount: IAsset
return_statement: IDocument2
return_statement: IDocument
}
export interface ICreatewthd2 {
@@ -339,7 +338,7 @@ export interface ICreatewthd2 {
project_hash: IChecksum256
withdraw_hash: IChecksum256
amount: IAsset
return_statement: IDocument2
return_statement: IDocument
}
export interface ICreatewthd3 {
@@ -349,7 +348,7 @@ export interface ICreatewthd3 {
project_hash: IChecksum256
withdraw_hash: IChecksum256
amount: IAsset
return_statement: IDocument2
return_statement: IDocument
}
export interface ICreator {
@@ -385,16 +384,16 @@ export interface IDebt {
project_hash: IChecksum256
repaid_at: ITimePointSec
amount: IAsset
statement: IDocument2
approved_statement: IDocument2
authorization: IDocument2
statement: IDocument
approved_statement: IDocument
authorization: IDocument
memo: string
}
export interface IDebtauthcnfr {
coopname: IName
debt_hash: IChecksum256
decision: IDocument2
decision: IDocument
}
export interface IDebtpaycnfrm {
@@ -435,13 +434,11 @@ export interface IDiallocate {
amount: IAsset
}
export interface IDocument2 {
version: string
export interface IDocument {
hash: IChecksum256
doc_hash: IChecksum256
meta_hash: IChecksum256
public_key: IPublicKey
signature: ISignature
meta: string
signatures: ISignatureInfo[]
}
export interface IExpense {
@@ -456,9 +453,9 @@ export interface IExpense {
fund_id: IUint64
amount: IAsset
description: string
expense_statement: IDocument2
approved_statement: IDocument2
authorization: IDocument2
expense_statement: IDocument
approved_statement: IDocument
authorization: IDocument
spended_at: ITimePointSec
}
@@ -512,8 +509,8 @@ export interface IInvest {
amount: IAsset
status: IName
invested_at: ITimePointSec
invest_statement: IDocument2
approved_statement: IDocument2
invest_statement: IDocument
approved_statement: IDocument
}
export interface IProgramWithdraw {
@@ -523,8 +520,8 @@ export interface IProgramWithdraw {
username: IName
status: IName
amount: IAsset
return_statement: IDocument2
approved_return_statement: IDocument2
return_statement: IDocument
approved_return_statement: IDocument
created_at: ITimePointSec
}
@@ -574,8 +571,8 @@ export interface IProjectWithdraw {
username: IName
status: IName
amount: IAsset
return_statement: IDocument2
approved_return_statement: IDocument2
return_statement: IDocument
approved_return_statement: IDocument
created_at: ITimePointSec
}
@@ -583,7 +580,7 @@ export interface IPushrslt {
coopname: IName
application: IName
result_hash: IChecksum256
statement: IDocument2
statement: IDocument
}
export interface IRefreshprog {
@@ -607,7 +604,7 @@ export interface IRegcontrib {
convert_percent: IUint64
rate_per_hour: IAsset
created_at: ITimePointSec
agreement: IDocument2
agreement: IDocument
}
export interface IResult {
@@ -629,11 +626,11 @@ export interface IResult {
total_amount: IAsset
available_for_return: IAsset
available_for_convert: IAsset
result_statement: IDocument2
approved_statement: IDocument2
authorization: IDocument2
act1: IDocument2
act2: IDocument2
result_statement: IDocument
approved_statement: IDocument
authorization: IDocument
act1: IDocument
act2: IDocument
}
export interface IResultWithdraw {
@@ -645,12 +642,12 @@ export interface IResultWithdraw {
username: IName
status: IName
amount: IAsset
contribution_statement: IDocument2
return_statement: IDocument2
approved_contribution_statement: IDocument2
approved_return_statement: IDocument2
authorized_contribution_statement: IDocument2
authorized_return_statement: IDocument2
contribution_statement: IDocument
return_statement: IDocument
approved_contribution_statement: IDocument
approved_return_statement: IDocument
authorized_contribution_statement: IDocument
authorized_return_statement: IDocument
created_at: ITimePointSec
}
@@ -659,7 +656,7 @@ export interface ISetact1 {
application: IName
username: IName
commit_hash: IChecksum256
act: IDocument2
act: IDocument
}
export interface ISetact2 {
@@ -667,23 +664,13 @@ export interface ISetact2 {
application: IName
username: IName
commit_hash: IChecksum256
act: IDocument2
act: IDocument
}
export interface ISettledebt {
coopname: IName
}
export interface ISignatureInfo {
id: IUint32
signed_hash: IChecksum256
signer: IName
public_key: IPublicKey
signature: ISignature
signed_at: ITimePointSec
meta: string
}
export interface IStartdistrbn {
coopname: IName
application: IName
@@ -1,129 +0,0 @@
// Generated by eosio-abi2ts 1.2.2 - eosio::abi/1.2
export type IAsset = string
export type IName = string
export type IChecksum256 = string
export type IPublicKey = string
export type ISignature = string
export type ITimePointSec = string
export type IUint32 = number
export type IUint64 = number | string
export interface IAdd {
coopname: IName
account_id: IUint64
quantity: IAsset
comment: string
}
export interface IAuth {
coopname: IName
writeoff_hash: IChecksum256
}
export interface IBlock {
coopname: IName
account_id: IUint64
quantity: IAsset
comment: string
}
export interface IComplete {
coopname: IName
writeoff_hash: IChecksum256
}
export interface ICreate {
coopname: IName
username: IName
account_id: IUint64
quantity: IAsset
reason: string
document: IDocument2
writeoff_hash: IChecksum256
}
export interface IDecline {
coopname: IName
writeoff_hash: IChecksum256
reason: string
}
export interface IDocument2 {
version: string
hash: IChecksum256
doc_hash: IChecksum256
meta_hash: IChecksum256
meta: string
signatures: ISignatureInfo[]
}
export interface ILaccount {
id: IUint64
name: string
available: IAsset
blocked: IAsset
writeoff: IAsset
}
export interface IMigrate {
}
export interface ISignatureInfo {
id: IUint32
signed_hash: IChecksum256
signer: IName
public_key: IPublicKey
signature: ISignature
signed_at: ITimePointSec
meta: string
}
export interface ISub {
coopname: IName
account_id: IUint64
quantity: IAsset
comment: string
}
export interface ITransfer {
coopname: IName
from_account_id: IUint64
to_account_id: IUint64
quantity: IAsset
comment: string
}
export interface IUnblock {
coopname: IName
account_id: IUint64
quantity: IAsset
comment: string
}
export interface IWriteoff {
coopname: IName
account_id: IUint64
quantity: IAsset
comment: string
}
export interface IWriteoffOp {
id: IUint64
coopname: IName
username: IName
account_id: IUint64
quantity: IAsset
reason: string
document: IDocument2
writeoff_hash: IChecksum256
status: IName
}
export interface IWriteoffcnsl {
coopname: IName
account_id: IUint64
quantity: IAsset
comment: string
}
@@ -9,24 +9,27 @@ export type ITimePointSec = string
export type IUint32 = number
export type IUint64 = number | string
export interface IAcceptoff {
export interface IAccept {
coopname: IName
username: IName
request_hash: IChecksum256
convert_out: IDocument2
return_document: IDocument2
exchange_id: IUint64
document: IDocument2
}
export interface IAuthoffc2r {
export interface IAddunits {
coopname: IName
request_hash: IChecksum256
authorization: IDocument2
username: IName
exchange_id: IUint64
units: IUint64
}
export interface IAuthoffs2c {
export interface IAuthorize {
coopname: IName
request_hash: IChecksum256
authorization: IDocument2
exchange_id: IUint64
contribution_product_decision_id: IUint64
contribution_product_authorization: IDocument2
return_product_decision_id: IUint64
return_product_authorization: IDocument2
}
export interface IBalances extends IBalancesBase {
@@ -41,26 +44,13 @@ export interface IBalancesBase {
export interface ICancel {
coopname: IName
username: IName
request_hash: IChecksum256
exchange_id: IUint64
}
export interface IChildorder {
coopname: IName
braname: IName
username: IName
hash: IChecksum256
parent_hash: IChecksum256
units: IUint64
unit_cost: IAsset
statement: IDocument2
convert_in: IDocument2
meta: string
}
export interface ICompleteoff {
export interface IComplete {
coopname: IName
username: IName
request_hash: IChecksum256
exchange_id: IUint64
}
export interface ICounts extends ICountsBase {
@@ -72,51 +62,23 @@ export interface ICountsBase {
value: IUint64
}
export interface IDeclineacc {
coopname: IName
hash: IChecksum256
reason: string
}
export interface IDeclineoff {
export interface IDecline {
coopname: IName
username: IName
request_hash: IChecksum256
exchange_id: IUint64
meta: string
}
export interface IDeliveroff1 {
export interface IDelivered {
coopname: IName
username: IName
request_hash: IChecksum256
transport_act_1: IDocument2
}
export interface IDeliveroff2 {
coopname: IName
username: IName
request_hash: IChecksum256
transport_act_2: IDocument2
}
export interface IDeliveroff3 {
coopname: IName
username: IName
request_hash: IChecksum256
transport_act_3: IDocument2
}
export interface IDeliveroff4 {
coopname: IName
username: IName
request_hash: IChecksum256
transport_act_4: IDocument2
exchange_id: IUint64
}
export interface IDispute {
coopname: IName
username: IName
request_hash: IChecksum256
exchange_id: IUint64
document: IDocument2
}
@@ -129,99 +91,116 @@ export interface IDocument2 {
signatures: ISignatureInfo[]
}
export interface IMigrate {
}
export interface IParentoffer {
coopname: IName
braname: IName
export interface IExchangeParams {
username: IName
hash: IChecksum256
parent_id: IUint64
program_id: IUint64
coopname: IName
units: IUint64
unit_cost: IAsset
product_lifecycle_secs: IUint32
warranty_period_secs: IUint32
membership_fee_amount: IAsset
cancellation_fee_amount: IAsset
product_lifecycle_secs: IUint64
document?: IDocument2
data: string
meta: string
}
export interface IRecvcnfoff {
export interface IMigrate {
}
export interface IModerate {
coopname: IName
username: IName
request_hash: IChecksum256
exchange_id: IUint64
cancellation_fee: IUint64
}
export interface INewid {
id: IUint64
type: IName
}
export interface IOffer {
params: IExchangeParams
}
export interface IOrder {
params: IExchangeParams
}
export interface IProhibit {
coopname: IName
username: IName
exchange_id: IUint64
meta: string
}
export interface IPublish {
coopname: IName
username: IName
exchange_id: IUint64
}
export interface IRecieve {
coopname: IName
username: IName
exchange_id: IUint64
document: IDocument2
}
export interface IRecvoff {
export interface IRecievecnfrm {
coopname: IName
username: IName
request_hash: IChecksum256
exchange_id: IUint64
document: IDocument2
}
export interface IRequest {
id: IUint64
hash: IChecksum256
parent_id: IUint64
parent_hash: IChecksum256
program_id: IUint64
coopname: IName
type: IName
status: IName
username: IName
parent_username: IName
braname: IName
token_contract: IName
unit_cost: IAsset
base_cost: IAsset
membership_fee_amount: IAsset
supplier_amount: IAsset
total_cost: IAsset
remaining_units: IUint64
membership_fee: IAsset
remain_units: IUint64
blocked_units: IUint64
supplied_units: IUint64
delivered_units: IUint64
data: string
meta: string
money_contributor: IName
product_contributor: IName
contribute_product_statement: IDocument2
return_product_statement: IDocument2
contribution_product_decision_id: IUint64
contribution_product_authorization: IDocument2
return_product_decision_id: IUint64
return_product_authorization: IDocument2
product_contribution_act_validation: IDocument2
product_contribution_act: IDocument2
product_recieve_act: IDocument2
product_recieve_act_validation: IDocument2
product_lifecycle_secs: IUint64
warranty_period_secs: IUint64
cancellation_fee: IUint64
cancellation_fee_amount: IAsset
warranty_delay_until: ITimePointSec
deadline_for_receipt: ITimePointSec
is_warranty_return: boolean
warranty_return_id: IUint64
created_at: ITimePointSec
accepted_at: ITimePointSec
supplied_at: ITimePointSec
delivered_at: ITimePointSec
received_at: ITimePointSec
recieved_at: ITimePointSec
completed_at: ITimePointSec
declined_at: ITimePointSec
disputed_at: ITimePointSec
canceled_at: ITimePointSec
}
export interface ISegment {
id: IUint64
request_id: IUint64
type: IName
status: IName
convert_in: IDocument2
statement: IDocument2
decision_id: IUint64
authorization: IDocument2
act1: IDocument2
act2: IDocument2
convert_out: IDocument2
transport_act_1: IDocument2
transport_act_2: IDocument2
transport_act_3: IDocument2
transport_act_4: IDocument2
coopactor: IName
username: IName
driver_username: IName
receive_from_driver_coopactor: IName
created_at: ITimePointSec
updated_at: ITimePointSec
warranty_delay_until: ITimePointSec
deadline_for_receipt: ITimePointSec
is_warranty_return: boolean
warranty_return_id: IUint64
}
export interface ISignatureInfo {
@@ -234,51 +213,33 @@ export interface ISignatureInfo {
meta: string
}
export interface ISupplcnfoff {
export interface ISupply {
coopname: IName
username: IName
request_hash: IChecksum256
act2: IDocument2
}
export interface ISupplyoff {
coopname: IName
username: IName
request_hash: IChecksum256
act1: IDocument2
}
export interface ITest {
}
export interface IWaccept {
coopname: IName
username: IName
request_hash: IChecksum256
accept: boolean
exchange_id: IUint64
document: IDocument2
}
export interface IWauthorize {
coopname: IName
request_hash: IChecksum256
wreturn_decision_id: IUint64
wreturn_authorization: IDocument2
wsupply_decision_id: IUint64
wsupply_authorization: IDocument2
}
export interface IWoffer {
export interface ISupplycnfrm {
coopname: IName
username: IName
request_hash: IChecksum256
exchange_id: IUint64
document: IDocument2
}
export interface IWreturn {
export interface IUnpublish {
coopname: IName
username: IName
request_hash: IChecksum256
document: IDocument2
exchange_id: IUint64
}
export interface IUpdate {
coopname: IName
username: IName
exchange_id: IUint64
remain_units: IUint64
unit_cost: IAsset
data: string
meta: string
}
+3 -25
View File
@@ -7,7 +7,6 @@ export type ISignature = string
export type ITimePointSec = string
export type IUint32 = number
export type IUint64 = number | string
export type IFloat64 = number
export interface IAuthmeet {
coopname: IName
@@ -33,11 +32,6 @@ export interface IDeclmeet {
reason: string
}
export interface IDelmeet {
coopname: IName
meet_id: IUint64
}
export interface IDocument2 {
version: string
hash: IChecksum256
@@ -47,19 +41,11 @@ export interface IDocument2 {
signatures: ISignatureInfo[]
}
export interface IGmnotify {
coopname: IName
hash: IChecksum256
username: IName
notification: IDocument2
}
export interface IMeet {
id: IUint64
hash: IChecksum256
coopname: IName
type: IName
level: IName
initiator: IName
presider: IName
secretary: IName
@@ -67,10 +53,9 @@ export interface IMeet {
created_at: ITimePointSec
open_at: ITimePointSec
close_at: ITimePointSec
notified_users: IName[]
quorum_percent: IFloat64
quorum_percent: IUint64
signed_ballots: IUint64
current_quorum_percent: IFloat64
current_quorum_percent: IUint64
cycle: IUint64
quorum_passed: boolean
proposal: IDocument2
@@ -85,19 +70,13 @@ export interface IMeetPoint {
decision: string
}
export interface IMigrate {
}
export interface INewgdecision {
coopname: IName
presider: IName
secretary: IName
hash: IChecksum256
results: IQuestionResult[]
signed_ballots: IUint64
quorum_percent: IFloat64
quorum_percent: IUint64
quorum_passed: boolean
decision: IDocument2
}
export interface IQuestion {
@@ -131,7 +110,6 @@ export interface IQuestionResult {
export interface IRestartmeet {
coopname: IName
hash: IChecksum256
new_hash: IChecksum256
newproposal: IDocument2
new_open_at: ITimePointSec
new_close_at: ITimePointSec
@@ -44,18 +44,6 @@ export interface ICandidate {
minimum: IAsset
}
export interface ICandidateLegacy {
username: IName
coopname: IName
braname: IName
status: IName
created_at: ITimePointSec
statement: IDocument
registration_hash: IChecksum256
initial: IAsset
minimum: IAsset
}
export interface IChangekey {
coopname: IName
changer: IName
@@ -112,7 +100,6 @@ export interface ICooperative2 {
status: IName$
created_at: ITimePointSec$
document: IDocument2$
active_participants_count: IUint64$
}
export interface ICreatebranch {
@@ -132,11 +119,6 @@ export interface IDeclinereg {
reason: string
}
export interface IDecparticpnt {
coopname: IName
username: IName
}
export interface IDelcoop {
registrator: IName
coopname: IName
+7 -39
View File
@@ -452,14 +452,7 @@ export interface INewact {
coopname: IName
username: IName
action: IName
package: IChecksum256
document: IDocument2
}
export interface INewagreement {
coopname: IName
username: IName
type: IName
hash: IChecksum256
document: IDocument2
}
@@ -467,37 +460,22 @@ export interface INewdecision {
coopname: IName
username: IName
action: IName
package: IChecksum256
hash: IChecksum256
document: IDocument2
}
export interface INewdeclined {
coopname: IName
username: IName
package: IChecksum256
hash: IChecksum256
document: IDocument2
}
export interface INewlink {
coopname: IName
username: IName
action: IName
package: IChecksum256
document: IDocument2
}
export interface INewpackage {
coopname: IName
username: IName
action: IName
package: IChecksum256
}
export interface INewresolved {
coopname: IName
username: IName
action: IName
package: IChecksum256
hash: IChecksum256
document: IDocument2
}
@@ -505,7 +483,7 @@ export interface INewsubmitted {
coopname: IName
username: IName
action: IName
package: IChecksum256
hash: IChecksum256
document: IDocument2
}
@@ -665,25 +643,15 @@ export interface IValidate {
}
export interface IVoteagainst {
version: string
coopname: IName
username: IName
member: IName
decision_id: IUint64
signed_at: ITimePointSec
signed_hash: IChecksum256
signature: ISignature
public_key: IPublicKey
}
export interface IVotefor {
version: string
coopname: IName
username: IName
member: IName
decision_id: IUint64
signed_at: ITimePointSec
signed_hash: IChecksum256
signature: ISignature
public_key: IPublicKey
}
export interface IWithdraw {
@@ -28,6 +28,7 @@ export interface ICompletedpst {
export interface ICompletewthd {
coopname: IName
withdraw_hash: IChecksum256
memo: string
}
export interface ICreatedpst {
+12 -7
View File
@@ -1,6 +1,12 @@
#!/bin/zsh
# Определение ассоциативных массива для zsh
declare -A contract_params_test=(
# [system]="eosio"
#[msig]="eosio.msig"
# [wrap]="eosio.wrap"
# [token]="eosio.token"
#[ano]="anotest22222"
[gateway]="gateway"
[draft]="draft"
[marketplace]="marketplace"
@@ -12,18 +18,17 @@ declare -A contract_params_test=(
[wallet]="wallet"
[loan]="loan"
[meet]="meet"
[ledger]="ledger"
)
NODE_URL="http://127.0.0.1:8888"
# Алиас для cleos через Docker
alias cleos='docker exec -it node /usr/local/bin/cleos'
rm -rf ./generated/*
# Генерация TypeScript типов из ABI для каждого контракта
for contract in "${(@k)contract_params_test}"; do
abi_contract="${contract_params_test[$contract]}"
curl -s -X POST "$NODE_URL/v1/chain/get_abi" \
-H "Content-Type: application/json" \
-d "{\"account_name\": \"$abi_contract\"}" \
| jq '.abi' \
| eosio-abi2ts -e "./generated/${contract}.ts" -p I -n 2
cleos get abi "$abi_contract" | eosio-abi2ts -e "./generated/${contract}.ts" -p I -n 2
done
#cp -r types/* ../../cooptypes/src/interfaces
+28
View File
@@ -0,0 +1,28 @@
#!/bin/zsh
declare -A contract_params_test=(
[gateway]="gateway"
[draft]="draft"
[marketplace]="marketplace"
[soviet]="soviet"
[registrator]="registrator"
[fund]="fund"
[branch]="branch"
[capital]="capital"
[wallet]="wallet"
[loan]="loan"
[meet]="meet"
)
NODE_URL="http://127.0.0.1:8888"
rm -rf ./generated/*
for contract in "${(@k)contract_params_test}"; do
abi_contract="${contract_params_test[$contract]}"
curl -s -X POST "$NODE_URL/v1/chain/get_abi" \
-H "Content-Type: application/json" \
-d "{\"account_name\": \"$abi_contract\"}" \
| jq '.abi' \
| eosio-abi2ts -e "./generated/${contract}.ts" -p I -n 2
done
+1 -7
View File
@@ -49,10 +49,4 @@ POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DATABASE=voskhod
TIMEZONE=Europe/Moscow
NOVU_APP_ID=BTaPV0bRL0dz
NOVU_BACKEND_URL=https://novu.coopenomics.world/api
NOVU_SOCKET_URL=https://novu.coopenomics.world/ws
NOVU_API_KEY=201a45fa0d7493a3d53fa309bfb01c4fd
TIMEZONE=Europe/Moscow

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