|
COOPENOMICS
v1
Кооперативная Экономика
|
Контракт marketplace — кооперативный «Стол заказов» в режиме членских взносов.
Подробнее...
#include <marketplace.hpp>
Открытые члены | |
| marketplace (eosio::name receiver, eosio::name code, eosio::datastream< const char * > ds) | |
| void | createorder (eosio::name coopname, eosio::name orderer, checksum256 order_hash, checksum256 offer_hash, eosio::name offerer, eosio::name delivery_braname, eosio::asset quantity, eosio::asset unit_price, eosio::asset package_size, uint32_t warranty_period_secs, checksum256 batch_hash, document2 convert_statement) |
Заказчик размещает заказ на товар из каталога (Story 4.1). Один шаг ledger2: o.mkt.lock (TRANSFER w.wal.share → w.mkt.order). convert_statement — подписанное заказчиком заявление о конвертации паевого взноса в членский по программе «Стол заказов»; публикуется в реестр документов отдельным пакетом (package = hash заявления). Подробнее... | |
| void | stockorder (eosio::name coopname, eosio::name orderer, checksum256 order_hash, checksum256 offer_hash, eosio::name delivery_braname, eosio::asset quantity, eosio::asset unit_price, eosio::asset package_size, uint32_t warranty_period_secs, checksum256 batch_hash) |
Заказ из обезличенного остатка склада кооператива (requirement 76). Продавец — сам кооператив (offerer == coopname), имущество уже на счёте 10 после ранее закрытых приёмок, поэтому Order создаётся сразу в acceptcoop и идёт только через выдачу signiss1/signiss2. Этапы поставки и выплата поставщику для такого заказа не существуют. Подробнее... | |
| void | convert (eosio::name coopname, eosio::name orderer, eosio::asset amount, document2 convert_statement) |
Конвертация паевого взноса пайщика в членский кошелёк «Стола заказов» (requirement 76, заказ из остатка из членских средств). Один шаг ledger2: o.mkt.conv (TRANSFER w.wal.share → w.mkt.member, Дт 80 / Кт 86). convert_statement — подписанное заказчиком Заявление о конвертации (шаблон 1110), публикуется в реестр документов отдельным пакетом (package = hash заявления). Выполняется перед stockorder, когда членских средств пайщика не хватает на заказ из остатка (на полную сумму или только на дельту превышения над высвобождённым при замене). Подробнее... | |
| void | cancelorder (eosio::name coopname, eosio::name orderer, checksum256 order_hash) |
Заказчик отменяет заказ до акцепта (Story 4.4). Триггерит o.mkt.unlock. Заказ из остатка кооператива (offerer == coopname) отменяется и в acceptcoop — до первой подписи акта выдачи (откат оператора, requirement 76 решение 11). Подробнее... | |
| void | expireorder (eosio::name coopname, checksum256 order_hash) |
Backend закрывает Order по таймауту цикла отсечки (Story 4.3). Per-Order: o.mkt.unlock + статус active → cancelled. Backend вычисляет threshold по batch'у вне контракта; для каждого истёкшего Order'а вызывается отдельный expireorder. Подробнее... | |
| void | closeorder (eosio::name coopname, checksum256 order_hash) |
| Закрыть выданный заказ после выхода гарантийного срока: терминал жизненного цикла, запись стирается из RAM. Вызывается автоматизированной службой по расписанию; до выхода гарантийного срока, при незавершённой выплате поставщику или открытом возврате закрытие отклоняется. Подробнее... | |
| void | acceptorder (eosio::name coopname, eosio::name offerer, checksum256 order_hash) |
Поставщик акцептует один Order (Story 4.5). Без ledger2-операций — статус active → accepted. Backend проходит циклом по orders соответствующего batch'а, вызывая acceptorder per Order. Подробнее... | |
| void | declineorder (eosio::name coopname, eosio::name offerer, checksum256 order_hash) |
Поставщик отказывается от одного Order'а до акцепта (Story 4.5). Per-Order: o.mkt.unlock на total_cost + статус active → cancelled. Backend проходит циклом по orders батча, вызывая declineorder per Order. Подробнее... | |
| void | signsupp (eosio::name coopname, eosio::name offerer, checksum256 order_hash, eosio::name accept_braname, document2 act) |
Поставщик первой подписью на АПП приёмки фиксирует партию по одному Order'у (Story 5.3/5.4). Без ledger2-операций — статус accepted → supply_prepared. Параметр accept_braname указывает приёмный КУ; запись в Order. Подпись валидируется как verify_document_or_fail(act, {offerer}). Backend проходит циклом по orders батча с одинаковым act. Подробнее... | |
| void | signchair (eosio::name coopname, eosio::name signer, checksum256 order_hash, eosio::asset actual_quantity, eosio::asset actual_unit_price, document2 act) |
Председатель приёмного КУ ставит закрывающую подпись на АПП приёмки одного Order'а (Story 5.3/5.4). Per-Order: только o.mkt.purch (Дт 10 / Кт 86). Выплата поставщику (o.mkt.payout) — отдельным lazy action'ом payout после подтверждения кассиром фактического банковского перевода (E11 техдолг 598-16, Locked Decision L12). Авторизация подписи: председатель / trustee / trusted ∈ branches[o.accept_braname]. Backend проходит циклом по orders батча с одинаковым act. Подробнее... | |
| void | payout (eosio::name coopname, checksum256 order_hash) |
Инициация исходящей выплаты поставщику через контракт gateway по одному Order'у (E11 техдолг 598-16, Locked Decision L12). Per-Order: inline-вызов gateway::createoutpay с callback'ами на payconfirm / paydecline. Ledger2-операция o.mkt.payout (Дт 86 / Кт 51) применяется НЕ здесь, а в callback'е payconfirm после действия кассира. Статус Order'а не меняется; защита от двойного запроса — через order.payout_status (NONE/DECLINED → PENDING). Подробнее... | |
| void | payconfirm (eosio::name coopname, checksum256 outcome_hash) |
Callback от gateway::outcomplete — кассир подтвердил банковский перевод поставщику (E11 техдолг 598-16, Locked Decision L12). Здесь применяется o.mkt.payout (Дт 86 / Кт 51) и payout_status переходит PENDING → COMPLETED. Авторизация: _gateway. outcome_hash совпадает с order.hash (так задано при payout). Подробнее... | |
| void | paydecline (eosio::name coopname, checksum256 outcome_hash, std::string reason) |
Callback от gateway::outdecline — кассир отметил, что банковский перевод не состоялся (E11 техдолг 598-16, Locked Decision L12). Ledger2-операция НЕ применяется; обязательство Кт 86 остаётся открытым. payout_status PENDING → DECLINED; payout_decline_reason сохраняется. Авторизация: _gateway. Подробнее... | |
| void | markdown (eosio::name coopname, checksum256 order_hash, eosio::asset amount) |
| Списание уценки по заказу из остатка кооператива (requirement 76). Разница между стоимостью прибытия выданного и фактической суммой выдачи выбывает со счёта 10 в прочие расходы: o.mkt.loss (NONE, Дт 91 / Кт 10). Вместе с o.mkt.consum даёт выбытие по полной стоимости прибытия — на складе ничего не зависает. Вызывает backend после финализации выдачи (сумму считает по выданным позициям). Погашение накопленного на 91 (Дт 86 / Кт 91) — будущий процесс по образцу списания скоропорта. Подробнее... | |
| void | signiss1 (eosio::name coopname, eosio::name signer, checksum256 order_hash, document2 act) |
| Председатель КУ выдачи открывает выдачу первой подписью АПП-выдачи (Story 6.1). Без ledger2-операций — статус ready_to_receive. Авторизация: подписант ∈ branches[o.delivery_braname]. Подробнее... | |
| void | signiss2 (eosio::name coopname, eosio::name orderer, checksum256 order_hash, eosio::asset actual_quantity, eosio::asset actual_unit_price, eosio::name delivery_signer, document2 act) |
| Заказчик ставит финальную подпись АПП-выдачи (Story 6.3). Per-Order с поддержкой actual_quantity ≠ ordered (Story 6.2). Atomic: [o.mkt.unlock на разницу если actual<ordered | o.mkt.lock на разницу если actual>ordered]. Подробнее... | |
| void | setfee (eosio::name coopname, uint64_t membership_fee_percent) |
| Установка единой ставки членского взноса «Стола заказов» (requirement b6). Одна ставка на весь кооператив (HUNDR_PERCENTS = 100%); задаёт администратор. Применяется к новым заказам; в созданных заказах взнос зафиксирован полем Order.membership_fee. Подробнее... | |
| void | submretrn (eosio::name coopname, eosio::name orderer, checksum256 request_hash, checksum256 original_order_hash, eosio::asset actual_quantity, std::string reason_text, std::vector< checksum256 > photos, document2 statement) |
| Пайщик подаёт заявление на гарантийный возврат (Story 7.1). Подробнее... | |
| void | aprretrem (eosio::name coopname, eosio::name signer, eosio::name braname, checksum256 request_hash) |
Председатель удалённо одобряет очный визит (Story 7.2). Авторизация: подписант ∈ branches[braname]; параметр braname фиксирует КУ, в котором рассматривается заявление. Подробнее... | |
| void | rejretrem (eosio::name coopname, eosio::name signer, eosio::name braname, checksum256 request_hash, std::string reason) |
| Председатель удалённо отказывает (Story 7.2). Авторизация: подписант ∈ branches[braname]. Подробнее... | |
| void | accretrn (eosio::name coopname, eosio::name signer, eosio::name braname, checksum256 request_hash, document2 statement) |
Председатель принимает возврат на очном осмотре (Story 7.4). Один шаг: o.mkt.return (compensating forward к o.mkt.consum). Председатель накладывает вторую подпись на заявление пайщика (statement несёт обе подписи — пайщика и председателя), отдельного документа решения нет. Авторизация: подписант ∈ branches[braname]. Подробнее... | |
| void | rejretrn (eosio::name coopname, eosio::name signer, eosio::name braname, checksum256 request_hash, std::string reason) |
| Председатель отказывает на очном осмотре (Story 7.3). Авторизация: подписант ∈ branches[braname]. Подробнее... | |
| void | propwroff (eosio::name coopname, eosio::name proposed_by, checksum256 proposal_hash, std::vector< wroff_item > items, document2 statement, std::string meta) |
Backend выносит проект списания на повестку совета (Story 8.1). Без ledger2-операций — только создание proposal с N позициями (статус proposed) и тем же inline-вызовом ставит повестку: soviet::createagenda от permission_level{_marketplace, active} с callback_contract=marketplace, confirm_callback=onmktwoauth, decline_callback=onmktwodecl, type=mktwroff, hash=proposal_hash, statement (Заявление 1106). Проект может подаваться председателем (за подписью) либо автоматически — мост повестки целиком на контракте, без участия backend. Подробнее... | |
| void | onmktwoauth (eosio::name coopname, checksum256 hash, document2 authorization) |
Callback от soviet::exec после авторизации Протокола совета (registry 1105) председателем (Story 8.4). PROPOSED → AUTHORIZED; сохраняется authorization в wroffprops.protocol. Цикл per-item списания запускает backend через execwroff после получения этой дельты. Подробнее... | |
| void | onmktwodecl (eosio::name coopname, checksum256 hash, std::string reason) |
Callback от soviet::cancelexprd (или от любого decline-эффекта в soviet) — повестка отклонена или просрочена (Story 8.4). PROPOSED → REJECTED; reason сохраняется в wroffprops.reject_reason. Без ledger2-движений. Подробнее... | |
| void | execwroff (eosio::name coopname, eosio::name signer, checksum256 proposal_hash, uint64_t item_index) |
Backend исполняет одну позицию авторизованного проекта списания (Story 8.4). Per-item: o.mkt.wroff, items[item_index].executed = true. Когда все items исполнены, статус AUTHORIZED → EXECUTED. Подробнее... | |
| void | confirmwroff (eosio::name coopname, eosio::name signer, checksum256 proposal_hash, eosio::name braname, document2 memo) |
| Председатель кооперативного участка подтверждает фактическое списание со склада своего КУ по авторизованному советом проекту (ручной шаг стола ПВЗ). Подробнее... | |
| void | migrate () |
| Заглушка миграции — donor-таблиц нет, мигрировать нечего. Оставлена для совместимости с CMake-build и прежним ABI. Подробнее... | |
Контракт marketplace — кооперативный «Стол заказов» в режиме членских взносов.
Реализует canonical actions трёх процессов из YAML-стандартов:
propwroff (запись wroffprops::proposed) + soviet::createagenda(type=mktwroff, callback=onmktwoauth/onmktwodecl). После голосования совета и подписи Протокола (registry 1105) chairman'ом soviet::exec автоматически вызывает callback onmktwoauth (PROPOSED → AUTHORIZED, сохраняется protocol2) или onmktwodecl (PROPOSED → REJECTED). Только после AUTHORIZED backend циклом по items вызывает execwroff per-item (o.mkt.wroff на каждой позиции).Все per-batch операции на on-chain выполняются per-Order (бэкенд проходит циклом по Order'ам соответствующего batch'а, объединяя их по batch_hash). Векторов order_hashes в actions нет — это ограничение на размер транзакции в Antelope (тысячи orders в одной транзакции не пройдут).
Все ledger2-движения средств — через Ledger2::apply(_marketplace, …), никаких прямых wallet/account-операций. 13 marketplace-операций зарегистрированы в lib/core/ledger2/operations.hpp (OPERATION_REGISTRY).
Composite-операции (consum+consum2, return+return2, wroff+wroff2) — последовательные Ledger2::apply в одной транзакции Antelope (атомарность через single-action wrapper).
Авторизация подписей под актами / решениями привязана к кооперативному участку (КУ) через контракт branch и helper Branch::is_user_authorized(coopname, braname, signer) — председатель КУ может делегировать подпись доверенному лицу из coobranch.trusted[].
Источник правды по логике actions, гардам, state-переходам и операциям — три YAML-файла рядом с этим .hpp:
p.mkt.supply.standard.yamlp.mkt.return.standard.yamlp.mkt.wroff.standard.yamlDonor-actions старой клиринговой модели (FR19a, AR30) удалены вместе с соответствующими таблицами Marketplace::request/segment/shipment.
|
inline |
| void marketplace::acceptorder | ( | eosio::name | coopname, |
| eosio::name | offerer, | ||
| checksum256 | order_hash | ||
| ) |
Поставщик акцептует один Order (Story 4.5). Без ledger2-операций — статус active → accepted. Backend проходит циклом по orders соответствующего batch'а, вызывая acceptorder per Order.
Поставщик акцептует один Order (Story 4.5, p.mkt.supply).
Без ledger2-операций — статус active → accepted. Backend проходит циклом по orders соответствующего batch'а, вызывая acceptorder per Order (контракт не принимает векторов order_hash — единичные транзакции масштабируются на любой размер batch'а).
После акцепта поставщик считается обязанным доставить партию: отдельная подпись «готов отгрузить» (бывший prepship) удалена из процесса — следующий шаг сразу signsupp с актом приёмки.
Guards:
| void marketplace::accretrn | ( | eosio::name | coopname, |
| eosio::name | signer, | ||
| eosio::name | braname, | ||
| checksum256 | request_hash, | ||
| document2 | statement | ||
| ) |
Председатель принимает возврат на очном осмотре (Story 7.4). Один шаг: o.mkt.return (compensating forward к o.mkt.consum). Председатель накладывает вторую подпись на заявление пайщика (statement несёт обе подписи — пайщика и председателя), отдельного документа решения нет. Авторизация: подписант ∈ branches[braname].
Председатель принимает гарантийный возврат на очном осмотре (Story 7.4, p.mkt.return).
Compensating forward, не revert (Locked Decision L3 — AR14): новое событие в journal с прикладным полем original_consume_op_id (заполняется backend'ом в submretrn) для трассировки. Исходная o.mkt.consum в журнале НЕ модифицируется.
Терминал жизненного цикла: запись заявления стирается из RAM, история (включая со-подписанное заявление) остаётся в журнале действий. Имущество возвращается на склад КУ; средства восстанавливаются на w.mkt.member.available заказчика.
Принятие возврата оформляется второй подписью председателя на заявлении пайщика (канон двухподписных актов): на вход приходит тот же документ заявления (registry 1104) с двумя подписями — пайщика и председателя; обе проверяются, поле statement перезаписывается со-подписанной версией. Отдельного документа решения нет.
Guards:
braname) — участок выдачи исходного заказа.signer) авторизован для указанного КУ (braname).| void marketplace::aprretrem | ( | eosio::name | coopname, |
| eosio::name | signer, | ||
| eosio::name | braname, | ||
| checksum256 | request_hash | ||
| ) |
Председатель удалённо одобряет очный визит (Story 7.2). Авторизация: подписант ∈ branches[braname]; параметр braname фиксирует КУ, в котором рассматривается заявление.
Председатель удалённо одобряет очный визит (Story 7.2, p.mkt.return).
Без ledger2-операций и без документов. Процедурное действие: статус return_request pending_review → approved_for_visit фиксируется вместе с actor + blockchain_actions[at]. Подпись на документе на удалённом этапе не требуется — она нужна только при принятии возврата (accretrn).
Guards:
braname) — участок выдачи исходного заказа.signer) авторизован для указанного КУ (braname): председатель / trustee / trusted в branches[braname].| void marketplace::cancelorder | ( | eosio::name | coopname, |
| eosio::name | orderer, | ||
| checksum256 | order_hash | ||
| ) |
Заказчик отменяет заказ до акцепта (Story 4.4). Триггерит o.mkt.unlock. Заказ из остатка кооператива (offerer == coopname) отменяется и в acceptcoop — до первой подписи акта выдачи (откат оператора, requirement 76 решение 11).
Заказчик отменяет заказ / отказывается от получения позиции (Story 4.4 + удержание при отказе, p.mkt.supply).
Граница удержания — акцепт поставщиком (acceptorder). До акцепта поставщик ещё не взял обязательство и ничего не везёт — отмена бесплатна (полный возврат резерва и членского взноса). После акцепта поставщик уже принял заявку и доставляет имущество, кооператив несёт риск его оплаты — отказ пайщика удерживает 50% (тела заказа и взноса) в общий кошелёк КУ; имущество остаётся на складе КУ, вторая половина возвращается пайщику.
Guards:
| void marketplace::closeorder | ( | eosio::name | coopname, |
| checksum256 | order_hash | ||
| ) |
Закрыть выданный заказ после выхода гарантийного срока: терминал жизненного цикла, запись стирается из RAM. Вызывается автоматизированной службой по расписанию; до выхода гарантийного срока, при незавершённой выплате поставщику или открытом возврате закрытие отклоняется.
Backend закрывает выданный заказ после выхода гарантийного срока (p.mkt.supply; принцип конечного жизненного цикла RAM-записей).
Терминал жизненного цикла выданного заказа: запись стирается из RAM, история заказа (акты, выплата, гарантия) остаётся в журнале действий. Вызывается автоматизированной службой по расписанию; контракт — финальный судья условий закрытия, до их наступления закрытие отклоняется:
Guards:
| void marketplace::confirmwroff | ( | eosio::name | coopname, |
| eosio::name | signer, | ||
| checksum256 | proposal_hash, | ||
| eosio::name | braname, | ||
| document2 | memo | ||
| ) |
Председатель кооперативного участка подтверждает фактическое списание со склада своего КУ по авторизованному советом проекту (ручной шаг стола ПВЗ).
Председатель кооперативного участка подтверждает фактическое списание со склада своего КУ по авторизованному советом проекту (ручной шаг стола ПВЗ, p.mkt.wroff).
Совет лишь принимает решение о допустимости списания (proposed → authorized); фактическое выбытие имущества со склада инициирует председатель КУ, подписывая Служебную записку о списании (registry 1111). Один вызов закрывает все неисполненные позиции одного КУ (braname) за одну транзакцию: per-КУ гранулярность разбивает большой проект так, чтобы протокол поместился в лимит транзакции, и привязывает выбытие к подписи ответственного за склад.
Эффект:
braname (Дт 86 / Кт 10), как в execwroff.memo публикуется в реестр документов (make_complete_document, package = proposal_hash).Guards:
signer уполномочен для КУ braname (branches[braname].is_user_authorized) — председатель КУ или его доверенное лицо;Совет своим решением (proposed → authorized через onmktwoauth) лишь признаёт списание допустимым. Имущество физически выбывает со склада только после того, как ответственный за склад председатель КУ подпишет Служебную записку о списании (registry 1111) — это и делает данный action.
Гранулярность — по одному КУ (braname) за вызов: проект списания может охватывать несколько участков, и каждый председатель закрывает только свою часть. Все неисполненные позиции данного КУ списываются в одной транзакции (Ledger2::apply o.mkt.wroff, Дт 86 / Кт 10 — как в execwroff). Служебная записка публикуется в реестр документов в пакете процесса списания (package = proposal_hash). Исполнение последней позиции проекта (по всем КУ) стирает запись из RAM — терминал жизненного цикла.
| void marketplace::convert | ( | eosio::name | coopname, |
| eosio::name | orderer, | ||
| eosio::asset | amount, | ||
| document2 | convert_statement | ||
| ) |
Конвертация паевого взноса пайщика в членский кошелёк «Стола заказов» (requirement 76, заказ из остатка из членских средств). Один шаг ledger2: o.mkt.conv (TRANSFER w.wal.share → w.mkt.member, Дт 80 / Кт 86). convert_statement — подписанное заказчиком Заявление о конвертации (шаблон 1110), публикуется в реестр документов отдельным пакетом (package = hash заявления). Выполняется перед stockorder, когда членских средств пайщика не хватает на заказ из остатка (на полную сумму или только на дельту превышения над высвобождённым при замене).
Конвертация паевого взноса пайщика в членский кошелёк «Стола заказов» (requirement 76, заказ из остатка из членских средств).
Заказ из остатка (stockorder) фондируется ВСЕГДА из членского кошелька пайщика начисто. Этот action — отдельный шаг пополнения членского кошелька с паевого: пайщик подаёт Заявление о конвертации (шаблон 1110) с просьбой транслировать паевой взнос с программы «Цифровой кошелёк» в программу «Стол заказов». Зеркало capital::convertsegm в Благорост.
Одна ledger2-операция:
o.mkt.conv (TRANSFER w.wal.share → w.mkt.member, Дт 80 / Кт 86) — паевой переходит в целевое финансирование на членский кошелёк программы.Когда вызывается (оркестрация на backend, всё в одной транзакции с stockorder):
Guards:
| void marketplace::createorder | ( | eosio::name | coopname, |
| eosio::name | orderer, | ||
| checksum256 | order_hash, | ||
| checksum256 | offer_hash, | ||
| eosio::name | offerer, | ||
| eosio::name | delivery_braname, | ||
| eosio::asset | quantity, | ||
| eosio::asset | unit_price, | ||
| eosio::asset | package_size, | ||
| uint32_t | warranty_period_secs, | ||
| checksum256 | batch_hash, | ||
| document2 | convert_statement | ||
| ) |
Заказчик размещает заказ на товар из каталога (Story 4.1). Один шаг ledger2: o.mkt.lock (TRANSFER w.wal.share → w.mkt.order). convert_statement — подписанное заказчиком заявление о конвертации паевого взноса в членский по программе «Стол заказов»; публикуется в реестр документов отдельным пакетом (package = hash заявления).
Заказчик размещает заказ на товар (Story 4.1, p.mkt.supply шаг 1).
Одна ledger2-операция:
o.mkt.lock (TRANSFER w.wal.share → w.mkt.order пайщика на total_cost, Дт 80 / Кт 86) — резерв средств заказчика под этот Order. Паевой пайщика переходит в целевое финансирование на резерв-кошелёк.Guards (из p.mkt.supply.standard.yaml + Locked Decision L6):
get_participant_or_fail).delivery_braname существует в branches (КУ выдачи задаётся пайщиком из доступных и неизменен после создания Order'а).ledger2::walletop через assert_program_signed (cross-contract в wallet::users.programs[]) при первом TRANSFER на USER_SHARED-кошельке программы (w.mkt.order).Сообщения проверок — для прямого показа пользователю (UI ловит check'ом).
| void marketplace::declineorder | ( | eosio::name | coopname, |
| eosio::name | offerer, | ||
| checksum256 | order_hash | ||
| ) |
Поставщик отказывается от одного Order'а до акцепта (Story 4.5). Per-Order: o.mkt.unlock на total_cost + статус active → cancelled. Backend проходит циклом по orders батча, вызывая declineorder per Order.
Поставщик отказывается от одного Order'а (Story 4.5 + отказ в приёмке, p.mkt.supply).
Два случая, оба со стороны поставщика и оба без штрафа — полный возврат резерва и членского взноса заказчику (вина не его):
Per-Order: o.mkt.unlock на total_cost (TRANSFER w.mkt.order → w.mkt.member — резерв возвращается на членский «Стола заказов» заказчика) + полный возврат взноса + erase. Backend проходит циклом по неотмеченным в приёмке orders — векторов order_hash нет.
Guards:
| void marketplace::execwroff | ( | eosio::name | coopname, |
| eosio::name | signer, | ||
| checksum256 | proposal_hash, | ||
| uint64_t | item_index | ||
| ) |
Backend исполняет одну позицию авторизованного проекта списания (Story 8.4). Per-item: o.mkt.wroff, items[item_index].executed = true. Когда все items исполнены, статус AUTHORIZED → EXECUTED.
Backend исполняет одну позицию авторизованного советом проекта списания скоропорта (Story 8.4, p.mkt.wroff).
Защита от газового лимита (тысячи позиций в одной транзакции Antelope не помещаются) — backend проходит цикл и вызывает execwroff per item.
Guards:
onmktwoauth уже отработал);signer) авторизован для КУ-источника (branches[items[item_index].braname]).Per-item операция:
Вызывается ТОЛЬКО после того, как совет авторизовал проект (status = AUTHORIZED через callback onmktwoauth). Backend проходит циклом по неисполненным позициям, вызывая execwroff(proposal_hash, item_index) per item — это снимает ограничение на максимальный размер протокола.
Исполнение последней позиции (все items[i].executed == true) — терминал жизненного цикла: запись проекта стирается из RAM, история — в журнале действий и решении совета.
Подписанный советом protocol уже лежит в proposal.protocol (положен callback'ом onmktwoauth), отдельно его передавать не нужно.
| void marketplace::expireorder | ( | eosio::name | coopname, |
| checksum256 | order_hash | ||
| ) |
Backend закрывает Order по таймауту цикла отсечки (Story 4.3). Per-Order: o.mkt.unlock + статус active → cancelled. Backend вычисляет threshold по batch'у вне контракта; для каждого истёкшего Order'а вызывается отдельный expireorder.
Backend закрывает один Order по таймауту цикла отсечки заявок (Story 4.3, p.mkt.supply).
Вызывается бэкендом после расчёта по batch'у: если за время цикла Offer'а threshold не достигнут, бэкенд проходит циклом по всем active Order'ам этого batch'а и для каждого вызывает expireorder. Контракт не знает про threshold — это вычисление backend'а; on-chain — только закрытие конкретного Order'а с возвратом резерва.
Per-Order: o.mkt.unlock на total_cost (TRANSFER w.mkt.order → w.mkt.member — возврат резерва на членский «Стола заказов» заказчика) + статус active → cancelled.
Guards:
signiss2 обычным порядком либо через отдельный механизм просрочки доставки).| void marketplace::markdown | ( | eosio::name | coopname, |
| checksum256 | order_hash, | ||
| eosio::asset | amount | ||
| ) |
Списание уценки по заказу из остатка кооператива (requirement 76). Разница между стоимостью прибытия выданного и фактической суммой выдачи выбывает со счёта 10 в прочие расходы: o.mkt.loss (NONE, Дт 91 / Кт 10). Вместе с o.mkt.consum даёт выбытие по полной стоимости прибытия — на складе ничего не зависает. Вызывает backend после финализации выдачи (сумму считает по выданным позициям). Погашение накопленного на 91 (Дт 86 / Кт 91) — будущий процесс по образцу списания скоропорта.
Списание уценки по заказу из остатка кооператива (requirement 76, вопрос 4, p.mkt.supply).
Имущество остатка оприходовано на счёт 10 по цене прибытия, а выдано пайщику могло быть с уценкой. signiss2 (o.mkt.consum) закрывает Кт 10 только на фактическую сумму выдачи — без этого действия разница зависала бы на складе, которого физически уже нет. Здесь разница выбывает в прочие расходы:
o.mkt.loss (NONE, Дт 91 / Кт 10) — кошельки не двигаются, чисто бухгалтерская проводка на сумму уценки.Вместе consum + loss дают выбытие по полной стоимости прибытия. Накопленный расход на счёте 91 погашается ПОЗЖЕ отдельным процессом (Дт 86 / Кт 91) по образцу списания скоропорта через решение совета — этот шаг зафиксирован и пока не реализован.
Вызывает backend сразу после финализации выдачи: сумму уценки он считает точно по выданным складским позициям (цены прибытия у позиций одного заказа могут отличаться — FIFO-резерв), контракту эта аналитика недоступна.
Guards:
| void marketplace::migrate | ( | ) |
Заглушка миграции — donor-таблиц нет, мигрировать нечего. Оставлена для совместимости с CMake-build и прежним ABI.
| void marketplace::onmktwoauth | ( | eosio::name | coopname, |
| checksum256 | hash, | ||
| document2 | authorization | ||
| ) |
Callback от soviet::exec после авторизации Протокола совета (registry 1105) председателем (Story 8.4). PROPOSED → AUTHORIZED; сохраняется authorization в wroffprops.protocol. Цикл per-item списания запускает backend через execwroff после получения этой дельты.
Callback от soviet::exec после авторизации Протокола совета о списании скоропорта (registry 1105) председателем (Story 8.4, p.mkt.wroff).
Авторизация: контракт _soviet (require_auth(_soviet)); сигнатура соответствует authorize_action_effect в soviet — (coopname, hash, authorization).
Соглашение о сигнатуре — (coopname, hash, authorization) — задано в soviet::createagenda::authorize_action_effect. Контракт soviet зовёт marketplace::onmktwoauth от своего имени, поэтому единственно допустимая авторизация — _soviet.
Эффект:
hash.proposal.protocol.Дальнейший шаг — backend через дельту/мониторинг видит AUTHORIZED и проходит циклом execwroff per-item (см. execwroff.cpp).
| void marketplace::onmktwodecl | ( | eosio::name | coopname, |
| checksum256 | hash, | ||
| std::string | reason | ||
| ) |
Callback от soviet::cancelexprd (или от любого decline-эффекта в soviet) — повестка отклонена или просрочена (Story 8.4). PROPOSED → REJECTED; reason сохраняется в wroffprops.reject_reason. Без ledger2-движений.
Callback от soviet после отказа в Протоколе совета о списании скоропорта или истечения срока повестки (Story 8.4, p.mkt.wroff).
Сигнатура (coopname, hash, reason) соответствует DECLINE_CALLBACK_SIGNATURE в lib/core/soviet/soviet.hpp:19. Авторизация: _soviet.
Сигнатура (coopname, hash, reason) соответствует DECLINE_CALLBACK_SIGNATURE (см. cpp/lib/core/soviet/soviet.hpp:19). Контракт soviet вызывает action из cancelexprd (повестка просрочена) или вручную через decline* actions от своего имени, поэтому единственно допустимая авторизация — _soviet.
Эффект:
hash, проверяет статус PROPOSED.Без ledger2-движений.
| void marketplace::payconfirm | ( | eosio::name | coopname, |
| checksum256 | outcome_hash | ||
| ) |
Callback от gateway::outcomplete — кассир подтвердил банковский перевод поставщику (E11 техдолг 598-16, Locked Decision L12). Здесь применяется o.mkt.payout (Дт 86 / Кт 51) и payout_status переходит PENDING → COMPLETED. Авторизация: _gateway. outcome_hash совпадает с order.hash (так задано при payout).
Callback от gateway о фактическом подтверждении исходящей выплаты поставщику (E11 техдолг 598-16, Locked Decision L12, p.mkt.supply).
Inline-action отправляется контрактом gateway из gateway::outcomplete после того, как кассир в админке подтвердил реальный банковский перевод. Здесь — единственное место, где применяется бухгалтерская проводка выплаты:
Сумма — o.fact_cost (фактически принятое после отбраковки на приёмке), а не исходный o.total_cost: проводка должна совпадать с приходованием имущества (Кт 86 = fact_cost из signchair) и с реальной суммой банковского перевода.
outcome_hash приходит из gateway и равен order.hash (так его задал marketplace::payout). Поиск Order'а — по индексу byhash.
Guards:
outcome_hash.payout_status == PENDING — на NONE/COMPLETED/DECLINED callback не ждём. | void marketplace::paydecline | ( | eosio::name | coopname, |
| checksum256 | outcome_hash, | ||
| std::string | reason | ||
| ) |
Callback от gateway::outdecline — кассир отметил, что банковский перевод не состоялся (E11 техдолг 598-16, Locked Decision L12). Ledger2-операция НЕ применяется; обязательство Кт 86 остаётся открытым. payout_status PENDING → DECLINED; payout_decline_reason сохраняется. Авторизация: _gateway.
Callback от gateway об отклонении исходящей выплаты поставщику (E11 техдолг 598-16, Locked Decision L12, p.mkt.supply).
Inline-action отправляется контрактом gateway из gateway::outdecline — кассир отметил, что банковский перевод не прошёл (нет реквизитов, платёж отменён банком, ошибка ввода). Бухгалтерия не двигается — обязательство Кт 86 перед поставщиком остаётся открытым. Backend может повторно вызвать marketplace::payout после исправления реквизитов; gateway-запись по этому outcome_hash уже стёрта на outdecline, поэтому повторная инициация проходит штатно (см. payout-гард payout_status ∈ { NONE, DECLINED }).
Guards:
outcome_hash.payout_status == PENDING. | void marketplace::payout | ( | eosio::name | coopname, |
| checksum256 | order_hash | ||
| ) |
Инициация исходящей выплаты поставщику через контракт gateway по одному Order'у (E11 техдолг 598-16, Locked Decision L12). Per-Order: inline-вызов gateway::createoutpay с callback'ами на payconfirm / paydecline. Ledger2-операция o.mkt.payout (Дт 86 / Кт 51) применяется НЕ здесь, а в callback'е payconfirm после действия кассира. Статус Order'а не меняется; защита от двойного запроса — через order.payout_status (NONE/DECLINED → PENDING).
Инициация исходящей выплаты поставщику по одному Order'у через gateway (E11 техдолг 598-16, Locked Decision L12, p.mkt.supply).
Backend дёргает это действие, когда кассир в админке отметил готовность проводить выплату поставщику. Действие НЕ применяет ledger2 — оно лишь inline-вызовом регистрирует в gateway::outcomes запись типа «исходящий платёж» со статусом pending и привязанным callback'ом на marketplace. Сам Дт 86 / Кт 51 произойдёт уже в callback'е payconfirm после фактического банковского перевода (gateway::outcomplete вызывает кассир через свой стол), либо отменится в paydecline (gateway::outdecline).
Inline-вызов: gateway::createoutpay с callback_contract = _marketplace, confirm_callback = "payconfirm"_n, decline_callback = "paydecline"_n, outcome_hash = order.hash (уникальность гарантирована индексом orders).
Сумма выплаты — o.fact_cost (фактически принятое после приёмки), а НЕ o.total_cost (исходный заказ): при отбраковке части поставки на приёмке (signchair снизил факт) кооператив должен поставщику ровно принятое. fact_cost зафиксирован на приёмке (статус-гард ниже гарантирует, что приёмка уже прошла), совпадает с приходованием имущества Кт 86 и с суммой платежа в реестре платежей кооператива.
Status Order'а не меняется (выплата может идти параллельно шагам выдачи). payout_status переходит NONE/DECLINED → PENDING; declined-кейс — повторная попытка после исправления реквизитов (gateway-запись была стёрта на outdecline).
Guards:
| void marketplace::propwroff | ( | eosio::name | coopname, |
| eosio::name | proposed_by, | ||
| checksum256 | proposal_hash, | ||
| std::vector< wroff_item > | items, | ||
| document2 | statement, | ||
| std::string | meta | ||
| ) |
Backend выносит проект списания на повестку совета (Story 8.1). Без ledger2-операций — только создание proposal с N позициями (статус proposed) и тем же inline-вызовом ставит повестку: soviet::createagenda от permission_level{_marketplace, active} с callback_contract=marketplace, confirm_callback=onmktwoauth, decline_callback=onmktwodecl, type=mktwroff, hash=proposal_hash, statement (Заявление 1106). Проект может подаваться председателем (за подписью) либо автоматически — мост повестки целиком на контракте, без участия backend.
Выносит проект списания скоропорта на повестку совета (Story 8.1, p.mkt.wroff).
Без ledger2-операций. Создаётся writeoff_proposal в статусе proposed; total_amount = Σ items.amount; все items создаются с executed=false. Тем же action'ом контракт ставит повестку: inline-вызов soviet::createagenda от permission_level{_marketplace, active} (marketplace в contracts_whitelist) с type=mktwroff, hash=proposal_hash, callback_contract=_marketplace, confirm_callback=onmktwoauth, decline_callback=onmktwodecl, statement (подписанное Заявление 1106). Мост повестки целиком на контракте — backend не подписывает createagenda отдельно (кооператив не в whitelist). Списание выполняется per-item через execwroff только после callback'а onmktwoauth (status proposed → authorized).
Guards:
branches[coopname].| void marketplace::rejretrem | ( | eosio::name | coopname, |
| eosio::name | signer, | ||
| eosio::name | braname, | ||
| checksum256 | request_hash, | ||
| std::string | reason | ||
| ) |
Председатель удалённо отказывает (Story 7.2). Авторизация: подписант ∈ branches[braname].
Председатель удалённо отказывает в гарантийном возврате (Story 7.2, p.mkt.return).
Финальное решение, без ledger2-операций — терминал жизненного цикла: запись заявления стирается из RAM, причина отказа остаётся в журнале действий (аргумент reason).
Guards:
braname) — участок выдачи исходного заказа.signer) авторизован для указанного КУ (braname).| void marketplace::rejretrn | ( | eosio::name | coopname, |
| eosio::name | signer, | ||
| eosio::name | braname, | ||
| checksum256 | request_hash, | ||
| std::string | reason | ||
| ) |
Председатель отказывает на очном осмотре (Story 7.3). Авторизация: подписант ∈ branches[braname].
Председатель отказывает в гарантийном возврате на очном осмотре (Story 7.3, p.mkt.return).
Финальное решение, без ledger2-операций — терминал жизненного цикла: запись заявления стирается из RAM, причина отказа остаётся в журнале действий (аргумент reason).
Guards:
braname) — участок выдачи исходного заказа.signer) авторизован для указанного КУ (braname).| void marketplace::setfee | ( | eosio::name | coopname, |
| uint64_t | membership_fee_percent | ||
| ) |
Установка единой ставки членского взноса «Стола заказов» (requirement b6). Одна ставка на весь кооператив (HUNDR_PERCENTS = 100%); задаёт администратор. Применяется к новым заказам; в созданных заказах взнос зафиксирован полем Order.membership_fee.
Установка единой ставки членского взноса «Стола заказов» (requirement b6 «Экономика КУ»).
Ставка одна на весь кооператив — не per-КУ и не per-категория: один и тот же членский взнос вне зависимости от того, на какой кооперативный участок заказ (против спекуляций и конкуренции между участками — решение владельца 2026-06-10). Применяется к заказам, созданным ПОСЛЕ установки: в уже созданных заказах взнос зафиксирован полем Order.membership_fee.
Проценты — в долях HUNDR_PERCENTS (1000000 = 100%). Ставка 0 отключает начисление взноса.
coopname (устанавливает администратор со стола администратора). | void marketplace::signchair | ( | eosio::name | coopname, |
| eosio::name | signer, | ||
| checksum256 | order_hash, | ||
| eosio::asset | actual_quantity, | ||
| eosio::asset | actual_unit_price, | ||
| document2 | act | ||
| ) |
Председатель приёмного КУ ставит закрывающую подпись на АПП приёмки одного Order'а (Story 5.3/5.4). Per-Order: только o.mkt.purch (Дт 10 / Кт 86). Выплата поставщику (o.mkt.payout) — отдельным lazy action'ом payout после подтверждения кассиром фактического банковского перевода (E11 техдолг 598-16, Locked Decision L12). Авторизация подписи: председатель / trustee / trusted ∈ branches[o.accept_braname]. Backend проходит циклом по orders батча с одинаковым act.
Председатель приёмного КУ ставит закрывающую подпись на АПП приёмки по одному Order'у (Story 5.3/5.4, p.mkt.supply).
Per-Order — только бухгалтерская приёмка имущества:
Факт приёмки (кол-во и цена за единицу) корректируется оператором при открытии приёмки и зашивается в акт, который утверждает поставщик: привезли меньше / другого качества → принимаем со скидкой. Кооператив приходует поставщику итоговую fact_cost = actual_quantity × actual_unit_price, а не исходную o.total_cost. Резерва пайщика на приёмке нет, поэтому веток возврата/доплаты (как в signiss2) здесь не требуется — это просто итоговая стоимость к получению поставщиком.
Имущество приходуется на склад приёмного КУ (accept_braname); у кооператива возникает обязательство Кт 86 перед поставщиком. Фактическая выплата деньгами (Дт 86 / Кт 51) — отдельным lazy action'ом marketplace::payout после подтверждения кассиром реального банковского перевода (Locked Decision L12, E11 техдолг 598-16).
Status: supply_prepared → accepted_to_coop. acceptance_act_signchair сохраняется. payout_done не выставляется — это атрибут payout-действия.
Guards:
signer) авторизован для приёмного КУ — председатель, trustee либо доверенное лицо в branches[accept_braname].trusted[].| void marketplace::signiss1 | ( | eosio::name | coopname, |
| eosio::name | signer, | ||
| checksum256 | order_hash, | ||
| document2 | act | ||
| ) |
Председатель КУ выдачи открывает выдачу первой подписью АПП-выдачи (Story 6.1). Без ledger2-операций — статус ready_to_receive. Авторизация: подписант ∈ branches[o.delivery_braname].
Председатель КУ выдачи открывает выдачу первой подписью АПП-выдачи (Story 6.1, signiss1).
Без ledger2-операций. Per-Order: статус accepted_to_coop → ready_to_receive; issue_act_signiss1 сохраняется; current_warehouse_braname обновляется на delivery_braname (фиксация факта логистической передачи имущества на склад выдачи — промежуточные перемещения по заготовочным КУ контрактом не подписываются, точка хранения переходит «скачком» в этот момент). Нотификация заказчику — post-effect в backend через ParserClient.
Guards:
signer) авторизован для КУ выдачи (o.delivery_braname): председатель / trustee / trusted в branches[delivery_braname].| void marketplace::signiss2 | ( | eosio::name | coopname, |
| eosio::name | orderer, | ||
| checksum256 | order_hash, | ||
| eosio::asset | actual_quantity, | ||
| eosio::asset | actual_unit_price, | ||
| eosio::name | delivery_signer, | ||
| document2 | act | ||
| ) |
Заказчик ставит финальную подпись АПП-выдачи (Story 6.3). Per-Order с поддержкой actual_quantity ≠ ordered (Story 6.2). Atomic: [o.mkt.unlock на разницу если actual<ordered | o.mkt.lock на разницу если actual>ordered].
Заказчик закрывающей подписью АПП-выдачи получает имущество (Story 6.3, signiss2).
Per-Order атомарная транзакция с поддержкой actual_quantity ≠ ordered (Story 6.2):
1) actual == ordered: Ledger2::apply(o.mkt.consum, fact_cost) — BURN w.mkt.order, Дт 86 / Кт 10 (сжигание резерва заказа и выбытие имущества со склада через целевое финансирование).
2) actual < ordered (выдано меньше — остаток резерва возвращается): Ledger2::apply(o.mkt.unlock, ordered_cost - fact_cost) — TRANSFER w.mkt.order → w.mkt.member на разницу (остаток резерва на членский «Стола заказов»). затем — consum на fact_cost.
3) actual > ordered (доплата по факту — ТОЛЬКО с членского, паевой не трогаем): diff = fact_cost - ordered_cost проверка достаточности diff на w.mkt.member (членский «Стола заказов»). o.mkt.lockm(diff) — TRANSFER w.mkt.member → w.mkt.order (без проводки) — добор резерва на этот же Order с членского программы. Затем — consum на fact_cost. Недостающее на членском пайщик переводит ЗАРАНЕЕ отдельным Заявлением о конвертации (action convert, o.mkt.conv) — авто-конвертации паевого на выдаче нет НИГДЕ; при нехватке членского транзакция фейлится.
Status: ready_to_receive → received. actual_quantity, fact_cost, issue_act_signiss2, warranty_until заполняются.
Guards:
delivery_signer) авторизован для КУ выдачи (o.delivery_braname).| void marketplace::signsupp | ( | eosio::name | coopname, |
| eosio::name | offerer, | ||
| checksum256 | order_hash, | ||
| eosio::name | accept_braname, | ||
| document2 | act | ||
| ) |
Поставщик первой подписью на АПП приёмки фиксирует партию по одному Order'у (Story 5.3/5.4). Без ledger2-операций — статус accepted → supply_prepared. Параметр accept_braname указывает приёмный КУ; запись в Order. Подпись валидируется как verify_document_or_fail(act, {offerer}). Backend проходит циклом по orders батча с одинаковым act.
Поставщик первой подписью на АПП приёмки фиксирует партию по одному Order'у (Story 5.3/5.4, p.mkt.supply).
Без ledger2-операций (имущество физически на складе, но юридически не оприходовано до signchair). Per-Order: статус accepted → supply_prepared, параметр accept_braname указывает приёмный КУ — куда поставщик сдаёт партию. Документ acceptance_act_signsupp сохраняется (копия per Order — допустимо для on-chain).
Backend проходит циклом по orders соответствующего batch'а с одним и тем же актом, вызывая signsupp per Order — это позволяет масштабировать batch на любой размер без риска превысить лимит транзакции Antelope.
Guards:
accept_braname существует в branches[coopname].is_empty_document(acceptance_act_signsupp)). | void marketplace::stockorder | ( | eosio::name | coopname, |
| eosio::name | orderer, | ||
| checksum256 | order_hash, | ||
| checksum256 | offer_hash, | ||
| eosio::name | delivery_braname, | ||
| eosio::asset | quantity, | ||
| eosio::asset | unit_price, | ||
| eosio::asset | package_size, | ||
| uint32_t | warranty_period_secs, | ||
| checksum256 | batch_hash | ||
| ) |
Заказ из обезличенного остатка склада кооператива (requirement 76). Продавец — сам кооператив (offerer == coopname), имущество уже на счёте 10 после ранее закрытых приёмок, поэтому Order создаётся сразу в acceptcoop и идёт только через выдачу signiss1/signiss2. Этапы поставки и выплата поставщику для такого заказа не существуют.
Заказ имущества из обезличенного остатка склада кооператива (requirement 76 «Склад кооператива на КУ», p.mkt.supply).
Заказ из остатка ВСЕГДА фондируется из членского кошелька «Стола заказов» пайщика начисто (без паевого): o.mkt.lockm (тело, w.mkt.member → w.mkt.order)
convert (Заявление о конвертации). При замене непоставленного на свободный остаток высвобожденные отменой средства уже лежат в w.mkt.member — заказ создаётся без конвертации и доплаты.Продавец — сам кооператив: имущество уже принято на склад по ранее закрытым АПП приёмки (числится на счёте 10 после o.mkt.purch) и перепредлагается пайщикам после недовыдачи / отказа от излишка. Поэтому Order создаётся сразу в статусе acceptcoop — этапы поставки (acceptorder / signsupp / signchair) и выплата поставщику (payout) для него не существуют: дальше работает только штатная выдача signiss1 → signiss2 (o.mkt.consum, Дт 86 / Кт 10).
Маркер заказа из остатка — order.offerer == coopname (кооператив-продавец). По нему cancelorder разрешает отмену в acceptcoop (откат оператора до своей подписи), а payout отклоняет попытку выплаты.
Фондируется ВСЕГДА из членского кошелька «Стола заказов» пайщика начисто (без паевого), две ledger2-операции (оба кошелька на 86, без проводок):
o.mkt.lockm (TRANSFER w.mkt.member → w.mkt.order на total_cost) — тело;o.mkt.lockmf (TRANSFER w.mkt.member → w.mkt.fee на взнос) — взнос. Паевой взнос пополняет членский кошелёк ЗАРАНЕЕ отдельным действием convert (Заявление о конвертации). При замене непоставленного на свободный остаток высвобожденные отменой средства уже лежат в w.mkt.member — заказ создаётся без конвертации и без доплаты с паевого.Guards (зеркало createorder + специфика остатка):
delivery_braname существует: КУ, на складе которого лежит остаток; он же — КУ выдачи (accept_braname и current_warehouse_braname равны ему: имущество уже на месте, логистики нет).convert). | void marketplace::submretrn | ( | eosio::name | coopname, |
| eosio::name | orderer, | ||
| checksum256 | request_hash, | ||
| checksum256 | original_order_hash, | ||
| eosio::asset | actual_quantity, | ||
| std::string | reason_text, | ||
| std::vector< checksum256 > | photos, | ||
| document2 | statement | ||
| ) |
Пайщик подаёт заявление на гарантийный возврат (Story 7.1).
Пайщик подаёт заявление на гарантийный возврат (Story 7.1, p.mkt.return).
Без ledger2-операций. Создаётся return_request в pending_review; order.return_request_id ставится для двусторонней связи. Привязка к конкретному КУ не сохраняется — каждое последующее действие (aprretrem/rejretrem/accretrn/rejretrn) принимает braname параметром и валидирует его через Branch::is_user_authorized.
Guards (из p.mkt.return.standard.yaml):