feat(capital/state): program_expense_pool + topupprogexp
Story 1.6 эпика «Благорост» (blago issue 51F-18). Программные расходы (Story 1.5) списываются из дедикейтнутого пула, а не из аллокаций проектов. До этого коммита поля для такого пула в global_state не было. Изменения: - global_state.program_expense_pool — доступная сумма программы под расходы - global_state.program_expense_reserved — зарезервированная под approved/authorized программные расходы (Story 1.5: createprogexp резервирует, declprogexp возвращает, exppaycnfrm списывает окончательно) - State::topup_program_expense_pool / reserve_program_expense / release_program_expense / consume_program_expense — utility-функции для Story 1.5 - topupprogexp(coopname, amount) action — председатель переводит amount из global_available_invest_pool в program_expense_pool; деньги остаются на ledger2-кошельке BLAGOROST_FUND, меняется только разбивка по назначению Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @brief Пополняет пул программных расходов из общего инвестиционного пула программы.
|
||||
*
|
||||
* Программные расходы — это целевые списания «Благорост», не аллоцированные ни в один проект
|
||||
* (хозяйственные расходы программы, оплата инфраструктуры программы и т.п.). Прежде чем
|
||||
* создавать запрос на программный расход, председатель пополняет дедикейтнутый пул
|
||||
* @c program_expense_pool из общего @c global_available_invest_pool — деньги остаются
|
||||
* на том же ledger2-кошельке @c BLAGOROST_FUND, меняется только разбивка по назначению.
|
||||
*
|
||||
* @param coopname Кооператив (scope state)
|
||||
* @param amount Сумма пополнения (символ строго совпадает с программой)
|
||||
* @ingroup public_actions
|
||||
* @ingroup public_capital_actions
|
||||
*
|
||||
* @note Авторизация требуется от аккаунта: @p coopname (председатель).
|
||||
*/
|
||||
void capital::topupprogexp(name coopname, eosio::asset amount) {
|
||||
require_auth(coopname);
|
||||
|
||||
Capital::State::topup_program_expense_pool(coopname, amount);
|
||||
}
|
||||
@@ -95,6 +95,9 @@
|
||||
#include "app/debt_managment/create_debt/declinedebt.cpp"
|
||||
#include "app/debt_managment/settle_debt/settledebt.cpp"
|
||||
|
||||
// Управление программными расходами
|
||||
#include "app/expense_managment/program_expenses/topupprogexp.cpp"
|
||||
|
||||
// Управление расходами
|
||||
#include "app/expense_managment/create_expense/approveexpns.cpp"
|
||||
#include "app/expense_managment/create_expense/capauthexpns.cpp"
|
||||
|
||||
@@ -322,4 +322,7 @@ public:
|
||||
[[eosio::action]]
|
||||
void settledebt(name coopname, name username, eosio::asset amount, document2 statement);
|
||||
|
||||
[[eosio::action]]
|
||||
void topupprogexp(name coopname, eosio::asset amount);
|
||||
|
||||
};
|
||||
|
||||
@@ -39,8 +39,11 @@ namespace Capital {
|
||||
asset program_membership_distributed = asset(0, _root_govern_symbol); ///< Распределенная сумма членских взносов по программе
|
||||
double program_membership_cumulative_reward_per_share; ///< Накопительное вознаграждение на долю в членских взносах
|
||||
|
||||
asset program_expense_pool = asset(0, _root_govern_symbol); ///< Доступная сумма программы под целевые расходы (без аллокации в проекты)
|
||||
asset program_expense_reserved = asset(0, _root_govern_symbol); ///< Сумма, зарезервированная под approved/authorized программные расходы
|
||||
|
||||
config config; ///< Управляемая конфигурация контракта
|
||||
|
||||
|
||||
uint64_t primary_key() const { return coopname.value; } ///< Первичный ключ (1)
|
||||
};
|
||||
|
||||
@@ -78,7 +81,7 @@ inline global_state get_global_state(name coopname) {
|
||||
|
||||
/**
|
||||
* @brief Проверяет что контракт инициализирован.
|
||||
*
|
||||
*
|
||||
* @param coopname Имя кооператива.
|
||||
*/
|
||||
inline void is_initialized(name coopname) {
|
||||
@@ -86,6 +89,78 @@ inline void is_initialized(name coopname) {
|
||||
auto itr = global_state_inst.find(coopname.value);
|
||||
eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Пополняет пул программных расходов на @p amount из общего пула инвестиций программы.
|
||||
* Вызывается из action topupprogexp (председатель).
|
||||
*/
|
||||
inline void topup_program_expense_pool(eosio::name coopname, const asset &amount) {
|
||||
global_state_table global_state_inst(_capital, _capital.value);
|
||||
auto itr = global_state_inst.find(coopname.value);
|
||||
eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
|
||||
eosio::check(amount.is_valid() && amount.amount > 0, "Сумма пополнения должна быть положительной");
|
||||
eosio::check(itr->global_available_invest_pool >= amount,
|
||||
"Недостаточно свободных инвестиций программы для пополнения пула расходов");
|
||||
|
||||
global_state_inst.modify(itr, _capital, [&](auto &s) {
|
||||
s.global_available_invest_pool -= amount;
|
||||
s.program_expense_pool += amount;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Резервирует средства под approved/authorized программный расход:
|
||||
* program_expense_pool -= amount, program_expense_reserved += amount.
|
||||
*/
|
||||
inline void reserve_program_expense(eosio::name coopname, const asset &amount) {
|
||||
global_state_table global_state_inst(_capital, _capital.value);
|
||||
auto itr = global_state_inst.find(coopname.value);
|
||||
eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
|
||||
eosio::check(amount.is_valid() && amount.amount > 0, "Сумма резерва должна быть положительной");
|
||||
eosio::check(itr->program_expense_pool >= amount,
|
||||
"Недостаточно средств в пуле программных расходов");
|
||||
|
||||
global_state_inst.modify(itr, _capital, [&](auto &s) {
|
||||
s.program_expense_pool -= amount;
|
||||
s.program_expense_reserved += amount;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Освобождает зарезервированное при отклонении программного расхода:
|
||||
* program_expense_reserved -= amount, program_expense_pool += amount.
|
||||
*/
|
||||
inline void release_program_expense(eosio::name coopname, const asset &amount) {
|
||||
global_state_table global_state_inst(_capital, _capital.value);
|
||||
auto itr = global_state_inst.find(coopname.value);
|
||||
eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
|
||||
eosio::check(amount.is_valid() && amount.amount > 0, "Сумма освобождения должна быть положительной");
|
||||
eosio::check(itr->program_expense_reserved >= amount,
|
||||
"Зарезервированных программных расходов меньше указанной суммы");
|
||||
|
||||
global_state_inst.modify(itr, _capital, [&](auto &s) {
|
||||
s.program_expense_reserved -= amount;
|
||||
s.program_expense_pool += amount;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Окончательное списание программного расхода после exppaycnfrm:
|
||||
* program_expense_reserved -= amount. Деньги уже ушли gateway,
|
||||
* ledger2-проводка PAY_EXPENSE сделана в action подтверждения.
|
||||
*/
|
||||
inline void consume_program_expense(eosio::name coopname, const asset &amount) {
|
||||
global_state_table global_state_inst(_capital, _capital.value);
|
||||
auto itr = global_state_inst.find(coopname.value);
|
||||
eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
|
||||
eosio::check(amount.is_valid() && amount.amount > 0, "Сумма списания должна быть положительной");
|
||||
eosio::check(itr->program_expense_reserved >= amount,
|
||||
"Зарезервированных программных расходов меньше указанной суммы");
|
||||
|
||||
global_state_inst.modify(itr, _capital, [&](auto &s) {
|
||||
s.program_expense_reserved -= amount;
|
||||
});
|
||||
}
|
||||
}// namespace State
|
||||
|
||||
}// namespace Capital
|
||||
Reference in New Issue
Block a user