refactor(capital): канон имён ledger2 + реализован action seizecollat

Канон имён в ledger2-онтологии — самодокументирующиеся английские термины
без аббревиатур. Префикс контракта (cap) не дублировать в имени.

Переименования (старые имена — отвергнутый рабочий драфт; нигде больше
не используются):
  o.cap.dflt    → o.cap.seize    (SEIZE_COLLATERAL — изъятие обеспечения)
  o.cap.lnwoff  → o.cap.wroff    (WRITE_OFF_LOAN — списание займа)
  w.cap.coopn   → w.cap.nma      (NMA — НМА кооператива)
  capital::dfltdebt → capital::seizecollat
  state defaulted (virtual) → seized (Status::SEIZED + mark_seized)

Story 1.13 — action capital::seizecollat:
  - guard: debt.status ∈ {paid, overdue} ∧ project.status == cancelled;
  - apply o.cap.seize  (TRANSFER w.cap.gen → w.cap.nma, Дт 04 / Кт 08);
  - apply o.cap.wroff  (BURN w.cap.loan,                Дт 80 / Кт 58);
  - decrease segment.debt_amount + active_debts_count;
  - subtract project.used_for_compensation;
  - decrease contributors.debt_amount;
  - mark debt SEIZED (mark_seized);
  - inline Loan::settle_debt (loan-контракт);
  - require_recipient(username, coopname);
  - require_auth(coopname) — без подписи пайщика, без сбора совета.

Решения 2026-05-19 (Игорь Смуров / Алексей Муравьёв):
  - срок займа фикс — 1 год;
  - проводки невозврата: Дт 04 / Кт 08 + Дт 80 / Кт 58;
  - автоматизм без подписи пайщика и без сбора совета.

Compile: cdt-cpp v4.1.0 OK (warnings only Ricardian + deprecation).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
coopops
2026-05-19 18:30:47 +00:00
parent 4d6a03a142
commit ca877ab294
9 changed files with 205 additions and 74 deletions
@@ -52,11 +52,19 @@ describe('CAPITAL — расширения «Благорост» (Эпик 1)',
)
it.todo(
'Story 1.13: dfltdebt — компонент cancelled/rejected → автоматическое закрытие займа через обращение взыскания на коммиты-обеспечение: o.cap.dflt (Дт 04 / Кт 08, TRANSFER GENERATOR_FUND → COOP_NMA) + o.cap.lnwoff (Дт 80 / Кт 58, BURN LOAN_ISSUED); сегмент уменьшен на сумму займа; долг удалён; без подписи пайщика и без сбора совета'
'Story 1.13: seizecollat — компонент cancelled → автоматическое закрытие займа через изъятие коммитов-обеспечения в НМА кооператива: o.cap.seize (Дт 04 / Кт 08, TRANSFER GENERATOR_FUND → NMA) + o.cap.wroff (Дт 80 / Кт 58, BURN LOAN_ISSUED); сегмент уменьшен на сумму займа; долг → SEIZED; без подписи пайщика и без сбора совета (решение 2026-05-19)'
)
it.todo(
'Story 1.13: dfltdebt отвергается, если родительский компонент не в статусе cancelled/rejected'
'Story 1.13: seizecollat отвергается, если родительский компонент не в статусе cancelled'
)
it.todo(
'Story 1.13: seizecollat отвергается, если долг не в статусе paid/overdue'
)
it.todo(
'Story 1.13: seizecollat — глобальный contributors.debt_amount пайщика уменьшен; запись в loan.debts удалена; loan.summaries.total опущен'
)
it.todo(
@@ -0,0 +1,91 @@
/**
* @brief Закрывает заём изъятием коммитов-обеспечения в НМА кооператива.
*
* Срабатывает, когда родительский компонент проекта явно перешёл в `cancelled`:
* проект до акта-2 не дойдёт, возврат через `signact2` невозможен.
* Коммиты-обеспечение, накопленные пайщиком на сегменте проекта-компонента
* (`w.cap.gen`), изымаются в НМА кооператива (`w.cap.nma`), а обязательство
* пайщика по займу списывается. Никаких санкций к пайщику не применяется,
* совет не собирается, подпись пайщика не требуется.
*
* Двухоперационная свёртка ledger2:
* - o.cap.seize — TRANSFER w.cap.gen → w.cap.nma, Дт 04 / Кт 08.
* Зеркалит o.cap.accept, но без участия пайщика: НМА из
* обеспечения идут в имущество кооператива, а не на share
* программы пайщика.
* - o.cap.wroff — BURN w.cap.loan, Дт 80 / Кт 58.
* Закрывает финансовое вложение кооператива в пайщика.
* Зеркало o.cap.repay, но share пайщика не пополняется —
* платёж сделан имущественно через коммиты.
*
* Решение 2026-05-19 (Игорь Смуров / Алексей Муравьёв): срок займа фиксированный
* (1 год от выплаты), но при явной отмене компонента закрытие происходит
* досрочно — без ожидания due_at.
*
* @param coopname Наименование кооператива (scope)
* @param debt_hash Хеш закрываемого займа
* @ingroup public_actions
* @ingroup public_capital_actions
*
* @note Авторизация только от @p coopname. Action идёт из backend кооператива,
* отслеживающего переход компонента в `cancelled`.
*/
void capital::seizecollat(name coopname, checksum256 debt_hash) {
require_auth(coopname);
// 1. Получить долг
auto exist_debt = Capital::Debts::get_debt_or_fail(coopname, debt_hash);
// 2. Долг должен быть активным (выплачен, не погашен)
eosio::check(exist_debt.status == Capital::Debts::Status::PAID
|| exist_debt.status == Capital::Debts::Status::OVERDUE,
"Изъятие обеспечения допустимо для активного (paid) или просроченного (overdue) займа");
// 3. Guard на статус родительского компонента: только `cancelled` (отменён).
// Если компонент завершён нормально (`finalized`/`result`) — возврат идёт
// через signact2 → o.cap.repay, не сюда.
auto project = Capital::Projects::get_project_or_fail(coopname, exist_debt.project_hash);
eosio::check(project.status == Capital::Projects::Status::CANCELLED,
"Изъятие обеспечения допустимо только при cancelled статусе компонента проекта");
// 4. Сегмент пайщика на компоненте
auto exist_segment = Capital::Segments::get_segment_or_fail(coopname,
exist_debt.project_hash, exist_debt.username, "Сегмент пайщика не найден");
// 5. Контрибьютор для обновления глобального долга
auto contributor = Capital::Contributors::get_contributor(coopname, exist_debt.username);
eosio::check(contributor.has_value(), "Контрибьютор не найден");
auto memo = Capital::Memo::get_debt_memo(exist_debt.username);
// 6. o.cap.seize: TRANSFER GENERATOR_FUND → NMA, Дт 04 / Кт 08.
// Коммиты-обеспечение из «Генератора» пайщика уходят в НМА кооператива.
Ledger2::apply(_capital, coopname, operations::capital::SEIZE_COLLATERAL,
exist_debt.amount, exist_debt.username, debt_hash, memo);
// 7. o.cap.wroff: BURN LOAN_ISSUED, Дт 80 / Кт 58.
// Финансовое вложение кооператива в пайщика закрыто; share пайщика не
// пополняется — займ погашен имущественно.
Ledger2::apply(_capital, coopname, operations::capital::WRITE_OFF_LOAN,
exist_debt.amount, exist_debt.username, debt_hash, memo);
// 8. Обновить агрегаты сегмента: -debt_amount, -active_debts_count.
Capital::Segments::decrease_debt_amount(coopname, exist_segment.id, exist_debt.amount);
Capital::Segments::decrease_active_debts_count(coopname, exist_debt.project_hash, exist_debt.username);
// 9. Уменьшить used_for_compensation в проекте (зеркало createdebt).
Capital::Projects::subtract_used_for_compensation(coopname, project.id, exist_debt.amount);
// 10. Глобальный долг контрибьютора уменьшаем (как в settledebt).
Capital::Contributors::decrease_debt_amount(coopname, contributor->id, exist_debt.amount);
// 11. Запись долга → SEIZED (для аудита).
Capital::Debts::mark_seized(coopname, exist_debt.id);
// 12. Централизованный реестр в loan-контракте: уменьшаем сводную, удаляем запись.
Loan::settle_debt(_capital, coopname, exist_debt.username, debt_hash, exist_debt.amount);
// 13. Уведомить пайщика и кооператив.
require_recipient(exist_debt.username);
require_recipient(coopname);
}
@@ -95,6 +95,7 @@
#include "app/debt_managment/create_debt/debtpayretry.cpp"
#include "app/debt_managment/create_debt/declinedebt.cpp"
#include "app/debt_managment/create_debt/markdebtoverd.cpp"
#include "app/debt_managment/create_debt/seizecollat.cpp"
#include "app/debt_managment/settle_debt/settledebt.cpp"
// Управление программными расходами
@@ -328,6 +328,9 @@ public:
[[eosio::action]]
void markdebtoverd(name coopname);
[[eosio::action]]
void seizecollat(name coopname, checksum256 debt_hash);
[[eosio::action]]
void topupprogexp(name coopname, eosio::asset amount);
@@ -22,6 +22,7 @@ namespace Status {
constexpr name PAID = "paid"_n; ///< Долг выплачен пайщику, активный (ждёт погашения)
constexpr name OVERDUE = "overdue"_n; ///< Долг просрочен (now > due_at) — выставляется action markdebtoverd
constexpr name SETTLED = "settled"_n; ///< Долг полностью погашен (деньгами через settledebt либо результатом через signact2)
constexpr name SEIZED = "seized"_n; ///< Долг закрыт изъятием коммитов-обеспечения в НМА кооператива (через seizecollat при отмене родительского компонента; решение 2026-05-19)
}
/**
@@ -206,8 +207,8 @@ inline void mark_pay_declined(
* Решение 2026-05-19 (Игорь Смуров / Алексей Муравьёв): срок займа
* фиксированный — год, не привязан к календарному сроку проекта. Если
* родительский компонент явно перешёл в `cancelled/rejected` раньше — займ
* закрывается досрочно через обращение взыскания на коммиты-обеспечение
* (см. `default_debt` / o.cap.dflt + o.cap.lnwoff).
* закрывается досрочно через изъятие коммитов-обеспечения в НМА кооператива
* (см. action `capital::seizecollat`, операции o.cap.seize + o.cap.wroff).
*/
constexpr uint32_t DEFAULT_DEBT_TERM_SECONDS = 365 * 24 * 60 * 60;
@@ -296,6 +297,33 @@ inline void mark_settled(
});
}
/**
* @brief Закрывает долг как изъятый — переводит в SEIZED.
*
* Применяется в seizecollat после применения o.cap.seize + o.cap.wroff и
* декремента сегмента. Семантически зеркалит mark_settled, но не пишет
* memo о погашении: займ закрыт имущественно через коммиты-обеспечение,
* без зачисления на share пайщика. Решение 2026-05-19.
*/
inline void mark_seized(
eosio::name coopname,
uint64_t debt_id,
eosio::name payer = name{}
) {
if (payer == name{}) payer = coopname;
debts_index debts(_capital, coopname.value);
auto debt = debts.find(debt_id);
eosio::check(debt != debts.end(), "Долг не найден");
eosio::check(debt->status == Status::PAID || debt->status == Status::OVERDUE,
"Изъятие обеспечения допустимо только из статуса paid или overdue");
debts.modify(debt, payer, [&](auto &d) {
d.status = Status::SEIZED;
d.repaid_at = eosio::current_time_point();
});
}
/**
* @brief Удаляет долг
*/
@@ -1,27 +1,27 @@
# ─────────────────────────────────────────────────────────────────────────────
# Стандарт «Займ пайщику» — выдача беспроцентного целевого займа из паевого
# фонда кооператива, его возврат через акт приёма-передачи проекта либо
# обращение взыскания на коммиты-обеспечение при невозврате.
# изъятие коммитов-обеспечения в НМА кооператива при невозврате.
#
# Многоактовый процесс с авторизацией советом. Четыре операции:
# • o.cap.lend — выдача займа на момент авторизации (ISSUE → w.cap.loan, Дт 58 / Кт 51)
# • o.cap.repay — возврат займа из акта-2 (TRANSFER w.cap.loan → w.wal.share, Дт 80 / Кт 58)
# • o.cap.dflt — обращение взыскания на коммиты-обеспечение при невозврате
# (TRANSFER w.cap.gen → w.cap.coopn, Дт 04 / Кт 08; решение 2026-05-19)
# • o.cap.lnwoff — списание займа в счёт обращения взыскания
# • o.cap.seize — изъятие коммитов-обеспечения в НМА кооператива при невозврате
# (TRANSFER w.cap.gen → w.cap.nma, Дт 04 / Кт 08; решение 2026-05-19)
# • o.cap.wroff — списание займа за счёт изъятого обеспечения
# (BURN w.cap.loan, Дт 80 / Кт 58; решение 2026-05-19)
#
# Срок займа: 1 год (фиксированный). Если родительский компонент явно перешёл
# в `cancelled/rejected` раньше — займ закрывается досрочно через `dfltdebt`
# в `cancelled/rejected` раньше — займ закрывается досрочно через `seizecollat`
# без сбора совета и без подписи пайщика.
#
# Источники правды в коде:
# • cpp/capital/capital.hpp — actions
# • cpp/capital/app/debt_managment/create_debt/{createdebt,approvedebt,debtauthcnfr,debtpaycnfrm,declinedebt,debtpaydcln,markdebtoverd,dfltdebt}.cpp
# • cpp/capital/app/debt_managment/create_debt/{createdebt,approvedebt,debtauthcnfr,debtpaycnfrm,declinedebt,debtpaydcln,markdebtoverd,seizecollat}.cpp
# • cpp/capital/domain/entities/debts.hpp — DEFAULT_DEBT_TERM_SECONDS = 365 дней
# • cpp/lib/core/ledger2/operations.hpp — o.cap.lend, o.cap.repay, o.cap.dflt, o.cap.lnwoff
# • cpp/lib/core/ledger2/operations.hpp — o.cap.lend, o.cap.repay, o.cap.seize, o.cap.wroff
# • cpp/lib/core/ledger2/processes.hpp — processes::capital::DEBT
# • cpp/lib/core/ledger2/wallets.hpp — w.cap.coopn (COOP_NMA, COOPERATIVE)
# • cpp/lib/core/ledger2/wallets.hpp — w.cap.nma (NMA кооператива, COOPERATIVE)
# ─────────────────────────────────────────────────────────────────────────────
# ── Секция 1. Паспорт ───────────────────────────────────────────────────────
@@ -34,8 +34,8 @@ contract: capital
summary: >
Пайщик получает из паевого фонда кооператива беспроцентный целевой заём
на год; возврат происходит при сдаче акта-2 проекта, либо — если проект
не доведён до завершения — займ закрывается автоматически через коммиты
пайщика, переданные в обеспечение.
не доведён до завершения — займ закрывается автоматически за счёт коммитов
пайщика, переданных в обеспечение.
purpose: >
«Заём пайщику» — кооператив выдаёт пайщику беспроцентный целевой заём
из паевого фонда на год. Заявку последовательно одобряют председатель
@@ -44,7 +44,7 @@ purpose: >
на возврат не нужна. Если родительский компонент проекта явно отменён
или отклонён, займ закрывается автоматически без участия пайщика и без
сбора совета: коммиты, ранее переданные пайщиком в обеспечение по
договору ответственного хранения, переходят в имущество кооператива,
договору ответственного хранения, изымаются в НМА кооператива,
а обязательство пайщика по займу списывается. Никаких санкций к пайщику
не применяется.
roles:
@@ -101,16 +101,16 @@ actions:
Gateway отклонил исходящий платёж по займу (тех. ошибка, возврат).
Запись долга удаляется.
- name: capital::dfltdebt
human: Закрыть займ через обеспечение
- name: capital::seizecollat
human: Изъять обеспечение и закрыть займ
actor: coopname
role: closer
purpose: >
Автоматическое закрытие займа при невозврате: родительский компонент
явно перешёл в `cancelled/rejected`, проект до акта-2 не дойдёт.
Применяются две ledger2-операции — o.cap.dflt (обращение взыскания на
коммиты-обеспечение, Дт 04 / Кт 08, TRANSFER w.cap.gen → w.cap.coopn)
и o.cap.lnwoff (списание займа, Дт 80 / Кт 58, BURN w.cap.loan).
Применяются две ledger2-операции — o.cap.seize (изъятие коммитов-
обеспечения в НМА кооператива, Дт 04 / Кт 08, TRANSFER w.cap.gen →
w.cap.nma) и o.cap.wroff (списание займа, Дт 80 / Кт 58, BURN w.cap.loan).
Запись долга удаляется, сегмент пайщика уменьшается на сумму обращения,
счётчик `active_debts_count` декрементируется. Никаких санкций к
пайщику, без сбора совета и без подписи пайщика (решение 2026-05-19).
@@ -144,25 +144,25 @@ states:
Gateway подтвердил зачисление займа пайщику. Запись долга остаётся
в реестре до момента возврата через акт приёма-передачи проекта.
due_at = now + 1 год; если до этого срока компонент перешёл в
`cancelled/rejected` — займ закрывается через обращение взыскания
на обеспечение (см. defaulted).
`cancelled/rejected` — займ закрывается через изъятие обеспечения
(см. seized).
kind: normal
- name: defaulted
human: Закрыт через обеспечение
- name: seized
human: Закрыт через изъятие обеспечения
description: >
Займ закрыт автоматически через обращение взыскания на коммиты-
обеспечение пайщика (родительский компонент в `cancelled/rejected`).
В ledger2 применены o.cap.dflt (Дт 04 / Кт 08, TRANSFER w.cap.gen →
w.cap.coopn) и o.cap.lnwoff (Дт 80 / Кт 58, BURN w.cap.loan).
Запись долга удалена, коммиты-обеспечение перешли в имущество
кооператива (НМА). Решение 2026-05-19.
Займ закрыт автоматически: коммиты-обеспечение пайщика изъяты в НМА
кооператива (родительский компонент в `cancelled/rejected`). В ledger2
применены o.cap.seize (Дт 04 / Кт 08, TRANSFER w.cap.gen → w.cap.nma)
и o.cap.wroff (Дт 80 / Кт 58, BURN w.cap.loan). Запись долга удалена,
коммиты-обеспечение перешли в имущество кооператива (НМА).
Решение 2026-05-19.
kind: virtual
virtual: true
- name: removed
human: Отклонено
description: >
Заявка отклонена на одном из этапов; запись удалена, операции
o.cap.lend / o.cap.repay / o.cap.dflt / o.cap.lnwoff не создавались.
o.cap.lend / o.cap.repay / o.cap.seize / o.cap.wroff не создавались.
kind: virtual
virtual: true
@@ -223,13 +223,13 @@ transitions:
- Платёж не прошёл / отклонён Gateway.
- from: paid
to: defaulted
action: capital::dfltdebt
to: seized
action: capital::seizecollat
actor: coopname
ledger_code: o.cap.dflt
ledger_code: o.cap.seize
operations:
- o.cap.dflt
- o.cap.lnwoff
- o.cap.seize
- o.cap.wroff
guards:
- Родительский компонент проекта явно в статусе `cancelled` или `rejected`.
- У пайщика на сегменте есть коммиты, накопленные как обеспечение
@@ -289,17 +289,17 @@ scenario:
actor: gateway_operator
description: >
Платёж не прошёл / отклонён. Запись долга удаляется.
- branch: Невозврат — обращение взыскания на обеспечение
- branch: Невозврат — изъятие обеспечения
at_step: 4
action: capital::dfltdebt
action: capital::seizecollat
actor: coopname
description: >
Если родительский компонент проекта явно перешёл в `cancelled` или
`rejected` (проект до акта-2 не дойдёт), займ закрывается автоматически
через коммиты-обеспечение пайщика. Применяются две ledger2-операции:
(1) o.cap.dflt — обращение взыскания на коммиты-обеспечение (Дт 04 /
Кт 08, TRANSFER w.cap.gen → w.cap.coopn);
(2) o.cap.lnwoff — списание займа (Дт 80 / Кт 58, BURN w.cap.loan).
за счёт коммитов-обеспечения пайщика. Применяются две ledger2-операции:
(1) o.cap.seize — изъятие коммитов-обеспечения в НМА кооператива
(Дт 04 / Кт 08, TRANSFER w.cap.gen → w.cap.nma);
(2) o.cap.wroff — списание займа (Дт 80 / Кт 58, BURN w.cap.loan).
Запись долга удаляется, сегмент пайщика уменьшается на сумму
обращения, никакие документы и подписи не требуются (решение 2026-05-19).
@@ -355,34 +355,34 @@ operations:
(Кт 58), сумма зачитывается в паевой фонд (Дт 80) и появляется как
доступный остаток на SHARE_FUND_PAY пайщика.
- ledger_code: o.cap.dflt
human_name: Обращение взыскания на коммиты-обеспечение при невозврате займа
- ledger_code: o.cap.seize
human_name: Изъятие коммитов-обеспечения в НМА кооператива
wallet_op: TRANSFER
wallet_from: w.cap.gen # ЦПП «Генератор» — единый кошелёк программы у пайщика
wallet_to: w.cap.coopn # Имущество кооператива — НМА из коммитов-обеспечения
wallet_to: w.cap.nma # НМА кооператива (из коммитов-обеспечения по займам)
debit: 4 # Нематериальные активы
credit: 8 # Вложения во внеоборотные активы
amount_ref: debt.amount
triggered_by: capital::dfltdebt
triggered_by: capital::seizecollat
description: >
Родительский компонент проекта явно перешёл в `cancelled/rejected`,
проект до акта-2 не дойдёт. Коммиты-обеспечение пайщика, накопленные
на «Генераторе» (w.cap.gen), переходят в имущество кооператива (НМА).
на «Генераторе» (w.cap.gen), изымаются в НМА кооператива.
Бухгалтерская запись зеркалит o.cap.accept: Дт 04 закрывает Кт 08 на
сумму займа, но без участия пайщика — кошелёк COOP_NMA (w.cap.coopn)
сумму займа, но без участия пайщика — кошелёк NMA (w.cap.nma)
фиксирует НМА кооператива, полученные из обеспечения. Решение 2026-05-19.
- ledger_code: o.cap.lnwoff
human_name: Списание займа в счёт обращения взыскания на обеспечение
- ledger_code: o.cap.wroff
human_name: Списание займа за счёт изъятого обеспечения
wallet_op: BURN
wallet_from: w.cap.loan # Выданные пайщикам беспроцентные займы
wallet_to: ''
debit: 80 # Паевой фонд (складочный капитал)
credit: 58 # Финансовые вложения
amount_ref: debt.amount
triggered_by: capital::dfltdebt
triggered_by: capital::seizecollat
description: >
Парная к o.cap.dflt операция: закрывает обязательство пайщика по
Парная к o.cap.seize операция: закрывает обязательство пайщика по
займу. Бухгалтерская запись зеркалит o.cap.repay (Дт 80 / Кт 58), но
кошелёк w.cap.loan только сжимается (BURN) — на share пайщика ничего
не зачисляется, потому что платёж сделан имущественно через
@@ -407,7 +407,7 @@ related:
id: public_capital_rid_process
relation: affects
note: >
Альтернативная ветка `defaulted` (o.cap.dflt) уменьшает доступную
сумму коммитов на сегменте пайщика — те коммиты, что были обеспечением,
Альтернативная ветка `seized` (o.cap.seize) уменьшает доступную сумму
коммитов на сегменте пайщика — те коммиты, что были обеспечением,
переходят в имущество кооператива и более не участвуют в РИД-учёте
пайщика.
@@ -77,8 +77,8 @@ namespace operations {
inline constexpr eosio::name DROP_PREIMP = "o.cap.drppre"_n; ///< Закрытие пред-импорт-учёта при переходе на электронный учёт (Dr 80 / Cr 04, BURN PREIMP_FUND). Вызывается из capital::importcontr перед o.cap.import.
inline constexpr eosio::name LEND = "o.cap.lend"_n; ///< Выдача беспроцентного займа пайщику (Dr 58 / Cr 51, ISSUE LOAN_ISSUED).
inline constexpr eosio::name REPAY = "o.cap.repay"_n; ///< Возврат займа пайщика по акту-2 (Dr 80 / Cr 58, TRANSFER LOAN_ISSUED → SHARE_FUND_PAY).
inline constexpr eosio::name FORECLOSE = "o.cap.dflt"_n; ///< Обращение взыскания на коммиты-обеспечение при невозврате займа (Dr 04 / Cr 08, TRANSFER GENERATOR_FUND → COOP_NMA). Решение 2026-05-19.
inline constexpr eosio::name LOAN_WRITEOFF = "o.cap.lnwoff"_n; ///< Списание займа в счёт обращения взыскания (Dr 80 / Cr 58, BURN LOAN_ISSUED). Зеркало REPAY без зачисления на share пайщика. Решение 2026-05-19.
inline constexpr eosio::name SEIZE_COLLATERAL = "o.cap.seize"_n; ///< Изъятие коммитов-обеспечения в НМА кооператива при невозврате займа (Dr 04 / Cr 08, TRANSFER GENERATOR_FUND → NMA). Решение 2026-05-19.
inline constexpr eosio::name WRITE_OFF_LOAN = "o.cap.wroff"_n; ///< Списание займа за счёт изъятого обеспечения (Dr 80 / Cr 58, BURN LOAN_ISSUED). Зеркало REPAY без зачисления на share пайщика — займ погашен имущественно. Решение 2026-05-19.
inline constexpr eosio::name WITHDRAW_FROM_CAPITAL = "o.cap.wthcap"_n; ///< Возврат паевого из ЦПП «Благорост» в кошелёк пайщика (TRANSFER BLAGOROST_FUND → SHARE_FUND_PAY, без Dr/Cr).
inline constexpr eosio::name CONVERT_TO_SHARE = "o.cap.cnvshr"_n; ///< Конвертация сегмента: РИД → главный кошелёк (TRANSFER GENERATOR_FUND → SHARE_FUND_PAY, без Dr/Cr — бухпроводка уже была сделана в ACCEPT_RID).
inline constexpr eosio::name CONVERT_TO_BLAGO = "o.cap.cnvbl"_n; ///< Конвертация сегмента: РИД → ЦПП «Благорост» (TRANSFER GENERATOR_FUND → BLAGOROST_FUND, без Dr/Cr — бухпроводка уже была сделана в ACCEPT_RID).
@@ -255,27 +255,27 @@ static constexpr OperationRegistryEntry OPERATION_REGISTRY[] = {
ledger2_accounts::SHARE_FUND, ledger2_accounts::FINANCIAL_INVESTMENTS,
"Возврат беспроцентного займа пайщика по акту-2" },
// 11a. Обращение взыскания на коммиты-обеспечение при невозврате займа:
// Dr 04 / Cr 08, TRANSFER GENERATOR_FUND → COOP_NMA.
// Срабатывает автоматически из `dfltdebt`, когда родительский компонент
// перешёл в `cancelled/rejected` (решение 2026-05-19 — без сбора совета,
// без подписи пайщика). РИД-коммиты, накопленные на GENERATOR_FUND пайщика
// как обеспечение, переходят в имущество кооператива (НМА). Пара по 04
// зеркалит `o.cap.accept`, но без участия пайщика — сегмент уменьшается
// на сумму обращения, кошелёк COOP_NMA пополняется.
{ operations::capital::FORECLOSE, processes::capital::DEBT, WalletOp::TRANSFER,
ledger2_wallets::GENERATOR_FUND, ledger2_wallets::COOP_NMA,
// 11a. Изъятие коммитов-обеспечения в НМА кооператива при невозврате займа:
// Dr 04 / Cr 08, TRANSFER GENERATOR_FUND → NMA.
// Срабатывает автоматически из `capital::seizecollat`, когда родительский
// компонент перешёл в `cancelled/rejected` (решение 2026-05-19 — без сбора
// совета, без подписи пайщика). РИД-коммиты, накопленные на GENERATOR_FUND
// пайщика как обеспечение, переходят в имущество кооператива (НМА). Пара
// по 04 зеркалит `o.cap.accept`, но без участия пайщика — сегмент пайщика
// уменьшается на сумму обращения, кошелёк NMA пополняется.
{ operations::capital::SEIZE_COLLATERAL, processes::capital::DEBT, WalletOp::TRANSFER,
ledger2_wallets::GENERATOR_FUND, ledger2_wallets::NMA,
ledger2_accounts::INTANGIBLE_ASSETS, ledger2_accounts::NON_CURRENT_INVESTMENTS,
"Обращение взыскания на коммиты-обеспечение при невозврате займа" },
"Изъятие коммитов-обеспечения в НМА кооператива" },
// 11b. Списание займа в счёт обращения взыскания: Dr 80 / Cr 58, BURN LOAN_ISSUED.
// Парная к `o.cap.dflt` операция, закрывает обязательство пайщика по займу.
// 11b. Списание займа за счёт изъятого обеспечения: Dr 80 / Cr 58, BURN LOAN_ISSUED.
// Парная к `o.cap.seize` операция, закрывает обязательство пайщика по займу.
// Зеркало `o.cap.repay`, но без зачисления на share пайщика (платёж сделан
// имущественно — через коммиты-обеспечение). Решение 2026-05-19.
{ operations::capital::LOAN_WRITEOFF, processes::capital::DEBT, WalletOp::BURN,
{ operations::capital::WRITE_OFF_LOAN, processes::capital::DEBT, WalletOp::BURN,
ledger2_wallets::LOAN_ISSUED, eosio::name{},
ledger2_accounts::SHARE_FUND, ledger2_accounts::FINANCIAL_INVESTMENTS,
"Списание займа в счёт обращения взыскания на обеспечение" },
"Списание займа за счёт изъятого обеспечения" },
// 12. Подтверждение поставки: Dr 51 / Cr 80, ISSUE SHARE_FUND_PAY
{ operations::marketplace::CONFIRM_SUPPLY, processes::marketplace::REQUEST, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::SHARE_FUND_PAY,
@@ -48,7 +48,7 @@ namespace processes {
namespace capital {
inline constexpr eosio::name IMPORT = "p.cap.import"_n; ///< Оффлайн-импорт пайщика Благорост (o.cap.drppre (опц.) + o.cap.import).
inline constexpr eosio::name INVEST = "p.cap.invest"_n; ///< Инвестиция в ЦПП Благорост (wallet-only 2001→9001).
inline constexpr eosio::name DEBT = "p.cap.debt"_n; ///< Займ пайщику (o.cap.lend + o.cap.repay; альтернативная ветка невозврата — o.cap.dflt + o.cap.lnwoff, решение 2026-05-19).
inline constexpr eosio::name DEBT = "p.cap.debt"_n; ///< Займ пайщику (o.cap.lend + o.cap.repay; альтернативная ветка невозврата — o.cap.seize + o.cap.wroff, решение 2026-05-19).
inline constexpr eosio::name RID = "p.cap.rid"_n; ///< Приём РИД в паевой фонд: o.cap.commit (коммиты) + o.cap.accept (акт-2) + опц. o.cap.repay + o.cap.cnvshr/o.cap.cnvbl (финальная конвертация сегмента). Анкер процесса — result_hash.
inline constexpr eosio::name PROPERTY = "p.cap.prop"_n; ///< Приём имущественного паевого взноса (одноактовый).
inline constexpr eosio::name PREIMP = "p.cap.preimp"_n; ///< Первичный учёт РИД-взноса до перехода на электронный учёт (одноактовый, anchor = preimp register hash).
@@ -63,7 +63,7 @@ struct ledger2_wallets {
static constexpr eosio::name BLAGOROST_FUND = "w.cap.blago"_n; ///< Благорост — единый агрегированный кошелёк программы (USER_SHARED; ADR-009)
static constexpr eosio::name GENERATOR_FUND = "w.cap.gen"_n; ///< Генератор — единый агрегированный кошелёк программы (USER_SHARED; ADR-009)
static constexpr eosio::name PREIMP_FUND = "w.cap.preimp"_n; ///< Первичный учёт РИД-взносов до перехода на электронный учёт (USER_SHARED; o.cap.preimp / o.cap.drppre)
static constexpr eosio::name COOP_NMA = "w.cap.coopn"_n; ///< Имущество кооператива — НМА из коммитов-обеспечения при невозврате займа (COOPERATIVE; решение 2026-05-19)
static constexpr eosio::name NMA = "w.cap.nma"_n; ///< НМА кооператива — собственное имущество, перешедшее из коммитов-обеспечения при невозврате займа (COOPERATIVE; решение 2026-05-19)
// marketplace — выплаты
static constexpr eosio::name SUPPLIER_PAYMENTS = "w.mkt.payout"_n; ///< Выплаты поставщикам (sink RECEIVE_CONFIRM, COOPERATIVE)
@@ -113,7 +113,7 @@ inline constexpr std::array<Ledger2WalletMeta, 15> LEDGER2_WALLET_REGISTRY = {{
{ ledger2_wallets::MIN_SHARE_USED, "Использованные минимальные паевые взносы", WalletKind::COOPERATIVE },
{ ledger2_wallets::LOAN_ISSUED, "Выданные пайщикам беспроцентные займы", WalletKind::COOPERATIVE },
{ ledger2_wallets::SUPPLIER_PAYMENTS, "Выплаты поставщикам", WalletKind::COOPERATIVE },
{ ledger2_wallets::COOP_NMA, "Имущество кооператива — НМА из коммитов-обеспечения", WalletKind::COOPERATIVE },
{ ledger2_wallets::NMA, "НМА кооператива (из коммитов-обеспечения по займам)", WalletKind::COOPERATIVE },
}};
static constexpr size_t LEDGER2_WALLET_REGISTRY_SIZE = LEDGER2_WALLET_REGISTRY.size();