COOPENOMICS  v1
Кооперативная Экономика
contributors.hpp
См. документацию.
1#pragma once
2
3
4#include "../../../lib/core/ram_payer.hpp"
5#include "../core/gamification/gamification.hpp"
6
7using namespace eosio;
8using std::string;
9
10namespace Capital {
11
20 struct [[eosio::table, eosio::contract(CAPITAL)]] contributor {
21 uint64_t id;
22 name coopname;
23 name username;
24 checksum256 contributor_hash;
25 time_point_sec created_at;
26 name status;
27 std::string memo;
28 bool is_external_contract = false;
30 std::vector<checksum256> appendixes;
31
32 eosio::asset rate_per_hour = asset(0, _root_govern_symbol);
33 uint64_t hours_per_day = 0;
34 eosio::asset debt_amount = asset(0, _root_govern_symbol);
35
36 eosio::asset contributed_as_investor = asset(0, _root_govern_symbol);
37 eosio::asset contributed_as_creator = asset(0, _root_govern_symbol);
38 eosio::asset contributed_as_author = asset(0, _root_govern_symbol);
39 eosio::asset contributed_as_coordinator = asset(0, _root_govern_symbol);
40 eosio::asset contributed_as_contributor = asset(0, _root_govern_symbol);
41 eosio::asset contributed_as_propertor = asset(0, _root_govern_symbol);
42
43 // Геймификация: уровень и энергия
44 uint32_t level = 1;
45 double energy = 99.9999999999;
46 time_point_sec last_energy_update;
47
48 uint64_t primary_key() const { return id; }
49 uint64_t by_username() const { return username.value; }
50 checksum256 by_hash() const { return contributor_hash; }
51 uint64_t by_investor_rating() const { return contributed_as_investor.amount; }
52 uint64_t by_creator_rating() const { return contributed_as_creator.amount; }
53 uint64_t by_author_rating() const { return contributed_as_author.amount; }
54 uint64_t by_coordinator_rating() const { return contributed_as_coordinator.amount; }
55 uint64_t by_contributor_rating() const { return contributed_as_contributor.amount; }
56 uint64_t by_propertor_rating() const { return contributed_as_propertor.amount; }
57 uint64_t by_rating() const { return contributed_as_investor.amount + contributed_as_creator.amount + contributed_as_author.amount + contributed_as_coordinator.amount + contributed_as_contributor.amount + contributed_as_propertor.amount; }
58 };
59
60typedef eosio::multi_index<
61 "contributors"_n, contributor,
62 indexed_by<"byusername"_n, const_mem_fun<contributor, uint64_t, &contributor::by_username>>,
63 indexed_by<"byhash"_n, const_mem_fun<contributor, checksum256, &contributor::by_hash>>,
64 indexed_by<"byinvrate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_investor_rating>>,
65 indexed_by<"bycreatorate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_creator_rating>>,
66 indexed_by<"byauthorate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_author_rating>>,
67 indexed_by<"bycoordrate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_coordinator_rating>>,
68 indexed_by<"bycontrate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_contributor_rating>>,
69 indexed_by<"byprprate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_propertor_rating>>,
70 indexed_by<"byrating"_n, const_mem_fun<contributor, uint64_t, &contributor::by_rating>>
72}// namespace Capital
73
75
82 namespace Status {
83 const eosio::name PENDING = "pending"_n;
84 const eosio::name ACTIVE = "active"_n;
85 const eosio::name IMPORT = "import"_n;
86 }
87
88 inline void create_contributor(eosio::name coopname, eosio::name username, checksum256 contributor_hash, bool is_external_contract, document2 contract, eosio::asset rate_per_hour, uint64_t hours_per_day){
89 Capital::contributor_index contributors(_capital, coopname.value);
90
91 contributors.emplace(RamPayer::of(contributors, coopname), [&](auto &c) {
92 c.id = get_global_id_in_scope(_capital, coopname, "contributors"_n);
93 c.coopname = coopname;
94 c.username = username;
95 c.contributor_hash = contributor_hash;
97 c.is_external_contract = is_external_contract;
98 c.contract = contract;
99 c.created_at = eosio::current_time_point();
100 c.rate_per_hour = rate_per_hour;
101 c.hours_per_day = hours_per_day;
102
103 // Инициализация геймификации
104 c.level = 1;
105 c.energy = 99.9999999999;
106 c.last_energy_update = eosio::current_time_point();
107 });
108 }
109
110
115 eosio::name coopname,
116 eosio::name username,
117 checksum256 contributor_hash,
118 eosio::asset contribution_amount,
119 std::string memo
120 ) {
121 Capital::contributor_index contributors(_capital, coopname.value);
122
123 contributors.emplace(RamPayer::of(contributors, coopname), [&](auto &c) {
124 c.id = get_global_id_in_scope(_capital, coopname, "contributors"_n);
125 c.coopname = coopname;
126 c.username = username;
127 c.contributor_hash = contributor_hash;
129 c.is_external_contract = true;
130 c.created_at = eosio::current_time_point();
131 c.memo = memo;
132 c.rate_per_hour = asset(0, _root_govern_symbol);
133 c.hours_per_day = 0;
134 c.contributed_as_investor = contribution_amount;
135
136 // Инициализация геймификации
137 c.level = 1;
138 c.energy = 99.9999999999;
139 c.last_energy_update = eosio::current_time_point();
140 });
141 }
142
143
147 inline void push_appendix_to_contributor(eosio::name coopname, uint64_t contributor_id, checksum256 project_hash){
148 contributor_index contributors(_capital, coopname.value);
149 auto contributor_itr = contributors.find(contributor_id);
150 eosio::check(contributor_itr != contributors.end(), "Контрибьютор не найден");
151
152 contributors.modify(contributor_itr, RamPayer::of(contributors, coopname), [&](auto &c) {
153 c.appendixes.push_back(project_hash);
154 });
155 }
156
160 inline std::optional<contributor> get_contributor(eosio::name coopname, eosio::name username) {
161 contributor_index contributors(_capital, coopname.value);
162 auto username_index = contributors.get_index<"byusername"_n>();
163
164 auto itr = username_index.find(username.value);
165 if (itr == username_index.end()) {
166 return std::nullopt;
167 }
168
169 return contributor(*itr);
170 }
171
172
173
174
178 inline std::optional<contributor> get_contributor_by_hash(eosio::name coopname, const checksum256& contributor_hash) {
179 contributor_index contributors(_capital, coopname.value);
180 auto hash_index = contributors.get_index<"byhash"_n>();
181
182 auto itr = hash_index.find(contributor_hash);
183 if (itr == hash_index.end()) {
184 return std::nullopt;
185 }
186
187 return contributor(*itr);
188}
189
190
194inline bool is_contributor_has_appendix_in_project(eosio::name coopname, const checksum256 &project_hash, uint64_t contributor_id) {
195 contributor_index contributors(_capital, coopname.value);
196 auto contributor = contributors.find(contributor_id);
197
198 if (contributor == contributors.end()) {
199 return false;
200 }
201
202 // Проверяем есть ли project_hash в векторе appendixes
203 for (const auto& appendix_project_hash : contributor->appendixes) {
204 if (appendix_project_hash == project_hash) {
205 return true;
206 }
207 }
208
209 return false;
210}
211
212
216inline std::optional<contributor> get_active_contributor_or_fail(eosio::name coopname, eosio::name username) {
217 auto contributor = get_contributor(coopname, username);
218 eosio::check(contributor.has_value(), "Исполнитель не подписывал договор УХД");
219 eosio::check(contributor -> status == Status::ACTIVE, "Договор УХД с пайщиком не активен");
220 return contributor;
221}
222
223
227inline std::optional<contributor> get_active_contributor_with_appendix_or_fail(eosio::name coopname, const checksum256 &project_hash, eosio::name username) {
228 auto contributor = get_active_contributor_or_fail(coopname, username);
229 eosio::check(is_contributor_has_appendix_in_project(coopname, project_hash, contributor->id),
230 "Пайщик не подписывал приложение к договору УХД для данного проекта");
231 return contributor;
232}
233
239inline std::optional<contributor> get_contributor_for_regshare_or_fail(eosio::name coopname, eosio::name username) {
240 auto contributor = get_contributor(coopname, username);
241 eosio::check(contributor.has_value(), "Исполнитель не подписывал договор УХД");
242 const eosio::name st = contributor->status;
243 eosio::check(st == Status::ACTIVE || st == Status::IMPORT,
244 "Договор УХД с пайщиком не в статусе active или import");
245 return contributor;
246}
247
260inline std::optional<contributor> get_contributor_for_program_invest_or_fail(eosio::name coopname, eosio::name username) {
261 auto contributor = get_contributor(coopname, username);
262 eosio::check(contributor.has_value(), "Исполнитель не подписывал договор УХД");
263 return contributor;
264}
265
266
267
272inline void update_contributor_ratings_from_segment(eosio::name coopname, uint64_t contributor_id, const Capital::Segments::segment& segment) {
273 Capital::contributor_index contributors(_capital, coopname.value);
274 auto contributor = contributors.find(contributor_id);
275
276 eosio::check(contributor != contributors.end(), "Контрибьютор не найден");
277
278 contributors.modify(contributor, RamPayer::of(contributors, coopname), [&](auto &c) {
279 // ВАЖНО: contributed_as_investor НЕ обновляется здесь, так как обновляется в момент инвестиции (createinvest)
280 // Это предотвращает двойное начисление для участников с несколькими ролями (инвестор+создатель/автор и т.д.)
281
282 if (segment.is_author) {
283 c.contributed_as_author += (segment.author_base + segment.author_bonus);
284 }
285
286 if (segment.is_creator) {
287 c.contributed_as_creator += (segment.creator_base + segment.creator_bonus);
288 }
289
290 if (segment.is_coordinator) {
291 c.contributed_as_coordinator += segment.coordinator_base;
292 }
293
294 if (segment.is_contributor) {
295 c.contributed_as_contributor += segment.contributor_bonus;
296 }
297
298 if (segment.is_propertor) {
299 c.contributed_as_propertor += segment.property_base;
300 }
301 });
302
303 // Обновляем геймификацию (уровень и энергию) после обновления рейтингов
304 Capital::Gamification::update_gamification_from_segment(coopname, contributor_id, segment);
305}
306
310inline void increase_debt_amount(eosio::name coopname, uint64_t contributor_id, eosio::asset amount) {
311 contributor_index contributors(_capital, coopname.value);
312 auto contributor = contributors.find(contributor_id);
313
314 eosio::check(contributor != contributors.end(), "Контрибьютор не найден");
315 //TODO: make coopname payer
316 contributors.modify(contributor, RamPayer::of(contributors, coopname), [&](auto &c) {
317 c.debt_amount += amount;
318 });
319}
320
324 inline void decrease_debt_amount(eosio::name coopname, uint64_t contributor_id, eosio::asset amount) {
325 contributor_index contributors(_capital, coopname.value);
326 auto contributor = contributors.find(contributor_id);
327
328 eosio::check(contributor != contributors.end(), "Контрибьютор не найден");
329 eosio::check(contributor->debt_amount >= amount, "Недостаточно долга для погашения");
330
331 //TODO: make coopname payer
332 contributors.modify(contributor, RamPayer::of(contributors, coopname), [&](auto &c) {
333 c.debt_amount -= amount;
334 });
335}
336
340inline void edit_contributor(eosio::name coopname, uint64_t contributor_id, eosio::asset rate_per_hour, uint64_t hours_per_day) {
341 contributor_index contributors(_capital, coopname.value);
342 auto contributor = contributors.find(contributor_id);
343
344 eosio::check(contributor != contributors.end(), "Участник не найден");
345
346 contributors.modify(contributor, RamPayer::of(contributors, coopname), [&](auto &c) {
347 c.rate_per_hour = rate_per_hour;
348 c.hours_per_day = hours_per_day;
349 });
350}
351
358inline void increase_investor_contribution(eosio::name coopname, uint64_t contributor_id, eosio::asset amount) {
359 contributor_index contributors(_capital, coopname.value);
360 auto contributor = contributors.find(contributor_id);
361
362 eosio::check(contributor != contributors.end(), "Участник не найден");
363
364 contributors.modify(contributor, RamPayer::of(contributors, coopname), [&](auto &c) {
365 c.contributed_as_investor += amount;
366 });
367}
368
376 eosio::name coopname,
377 uint64_t contributor_id,
378 eosio::asset rate_per_hour,
379 uint64_t hours_per_day,
380 bool is_external_contract,
381 document2 contract
382) {
383 contributor_index contributors(_capital, coopname.value);
384 auto contributor = contributors.find(contributor_id);
385
386 eosio::check(contributor != contributors.end(), "Участник не найден");
387 eosio::check(contributor->status == Status::IMPORT, "Участник не находится в статусе импорта");
388 eosio::check(contributor->is_external_contract == is_external_contract, "Флаг внешнего контракта не совпадает с импортированным");
389
390 contributors.modify(contributor, RamPayer::of(contributors, coopname), [&](auto &c) {
391 c.rate_per_hour = rate_per_hour;
392 c.hours_per_day = hours_per_day;
393 // Для не внешних контрактов обновляем contract
394 if (!is_external_contract) {
395 c.contract = contract;
396 }
397 c.status = Status::PENDING; // Меняем статус на PENDING для одобрения председателем
398 });
399}
400
401
402}// namespace Capital::Contributors
403
404// Плательщик за оперативную память строк таблицы — правило в lib/core/ram_payer.hpp.
Контракт Contributor управляет вкладами, распределением вознаграждений и выводом средств для участник...
Definition: contributor.hpp:19
static constexpr eosio::name _capital
Definition: consts.hpp:171
static constexpr eosio::symbol _root_govern_symbol
Definition: consts.hpp:236
RAM_PAYER_CLASS(Capital::contributor, contract)
contract
Definition: eosio.msig_tests.cpp:977
share_type amount
Definition: eosio.token_tests.cpp:174
const eosio::name ACTIVE
Авторизован/активен
Definition: contributors.hpp:84
const eosio::name IMPORT
Импортирован, требует завершения регистрации
Definition: contributors.hpp:85
const eosio::name PENDING
Ожидает подтверждения
Definition: contributors.hpp:83
Definition: contributors.hpp:74
std::optional< contributor > get_contributor_for_program_invest_or_fail(eosio::name coopname, eosio::name username)
Контрибьютор, допустимый для программной инвестиции (capital::createpinv). Подходит любой статус — pe...
Definition: contributors.hpp:260
void complete_imported_contributor_registration(eosio::name coopname, uint64_t contributor_id, eosio::asset rate_per_hour, uint64_t hours_per_day, bool is_external_contract, document2 contract)
Завершает регистрацию импортированного участника Обновляет импортированного участника (статус IMPORT)...
Definition: contributors.hpp:375
void import_contributor(eosio::name coopname, eosio::name username, checksum256 contributor_hash, eosio::asset contribution_amount, std::string memo)
Создаёт импортированного участника; contributed_as_investor сразу равен сумме импортируемого взноса в...
Definition: contributors.hpp:114
std::optional< contributor > get_active_contributor_with_appendix_or_fail(eosio::name coopname, const checksum256 &project_hash, eosio::name username)
Получает участника по имени аккаунта, проверяет активность и членство в проекте.
Definition: contributors.hpp:227
void create_contributor(eosio::name coopname, eosio::name username, checksum256 contributor_hash, bool is_external_contract, document2 contract, eosio::asset rate_per_hour, uint64_t hours_per_day)
Definition: contributors.hpp:88
void push_appendix_to_contributor(eosio::name coopname, uint64_t contributor_id, checksum256 project_hash)
Добавляет project_hash в вектор appendixes у контрибьютора
Definition: contributors.hpp:147
void increase_investor_contribution(eosio::name coopname, uint64_t contributor_id, eosio::asset amount)
Увеличивает инвестиционный вклад участника
Definition: contributors.hpp:358
std::optional< contributor > get_contributor_by_hash(eosio::name coopname, const checksum256 &contributor_hash)
Получает участника по хэшу контрибьютора.
Definition: contributors.hpp:178
bool is_contributor_has_appendix_in_project(eosio::name coopname, const checksum256 &project_hash, uint64_t contributor_id)
Проверяет есть ли у контрибьютора приложение для проекта
Definition: contributors.hpp:194
void edit_contributor(eosio::name coopname, uint64_t contributor_id, eosio::asset rate_per_hour, uint64_t hours_per_day)
Обновляет параметры участника (часы в день и информацию о себе)
Definition: contributors.hpp:340
std::optional< contributor > get_contributor(eosio::name coopname, eosio::name username)
Получает участника по имени аккаунта.
Definition: contributors.hpp:160
std::optional< contributor > get_active_contributor_or_fail(eosio::name coopname, eosio::name username)
Получает участника по имени аккаунта и проверяет на активность.
Definition: contributors.hpp:216
std::optional< contributor > get_contributor_for_regshare_or_fail(eosio::name coopname, eosio::name username)
Контрибьютор, допустимый для capital::regshare без приложения к проекту. Статусы import (импорт с бал...
Definition: contributors.hpp:239
void increase_debt_amount(eosio::name coopname, uint64_t contributor_id, eosio::asset amount)
Увеличивает долг контрибьютора
Definition: contributors.hpp:310
void decrease_debt_amount(eosio::name coopname, uint64_t contributor_id, eosio::asset amount)
Увеличивает долг контрибьютора
Definition: contributors.hpp:324
void update_contributor_ratings_from_segment(eosio::name coopname, uint64_t contributor_id, const Capital::Segments::segment &segment)
Обновляет накопительные показатели контрибьютора на основе его ролей и вкладов в сегменте
Definition: contributors.hpp:272
void update_gamification_from_segment(eosio::name coopname, uint64_t contributor_id, const Capital::Segments::segment &segment)
Обновляет геймификацию (уровень и энергию) на основе вкладов из сегмента
Definition: gamification.cpp:201
Definition: balances.cpp:6
eosio::multi_index< "contributors"_n, contributor, indexed_by<"byusername"_n, const_mem_fun< contributor, uint64_t, &contributor::by_username > >, indexed_by<"byhash"_n, const_mem_fun< contributor, checksum256, &contributor::by_hash > >, indexed_by<"byinvrate"_n, const_mem_fun< contributor, uint64_t, &contributor::by_investor_rating > >, indexed_by<"bycreatorate"_n, const_mem_fun< contributor, uint64_t, &contributor::by_creator_rating > >, indexed_by<"byauthorate"_n, const_mem_fun< contributor, uint64_t, &contributor::by_author_rating > >, indexed_by<"bycoordrate"_n, const_mem_fun< contributor, uint64_t, &contributor::by_coordinator_rating > >, indexed_by<"bycontrate"_n, const_mem_fun< contributor, uint64_t, &contributor::by_contributor_rating > >, indexed_by<"byprprate"_n, const_mem_fun< contributor, uint64_t, &contributor::by_propertor_rating > >, indexed_by<"byrating"_n, const_mem_fun< contributor, uint64_t, &contributor::by_rating > > > contributor_index
Definition: contributors.hpp:71
eosio::name of(const Table &table, eosio::name coopname)
Definition: ram_payer.hpp:78
Definition: eosio.msig.hpp:34
Таблица сегментов хранит данные о вкладах участника в проект.
Definition: segments.hpp:36
bool is_coordinator
Является ли участник координатором
Definition: segments.hpp:48
bool is_creator
Является ли участник создателем
Definition: segments.hpp:47
bool is_author
Является ли участник автором
Definition: segments.hpp:46
bool is_propertor
Является ли участник пропертором
Definition: segments.hpp:50
bool is_contributor
Является ли участник участником
Definition: segments.hpp:51
Таблица участников хранит данные индивидуального участника кооператива.
Definition: contributors.hpp:20
bool is_external_contract
Флаг, указывающий на внешний контракт
Definition: contributors.hpp:28
time_point_sec last_energy_update
Время последнего обновления энергии
Definition: contributors.hpp:46
std::string memo
Мемо для импортированных контрибьюторов
Definition: contributors.hpp:27
uint64_t id
ID контрибьютора (внутренний ключ)
Definition: contributors.hpp:21
uint64_t primary_key() const
Первичный ключ (1)
Definition: contributors.hpp:48
time_point_sec created_at
Время создания контрибьютора
Definition: contributors.hpp:25
uint64_t by_contributor_rating() const
Индекс по рейтингу контрибьютора (8)
Definition: contributors.hpp:55
uint64_t by_rating() const
Индекс по общему рейтингу (10)
Definition: contributors.hpp:57
name coopname
Имя кооператива
Definition: contributors.hpp:22
name status
Статус контрибьютора
Definition: contributors.hpp:26
document2 contract
Договор УХД
Definition: contributors.hpp:29
uint64_t by_propertor_rating() const
Индекс по рейтингу пропертора (9)
Definition: contributors.hpp:56
uint64_t by_username() const
Индекс по имени пользователя (2)
Definition: contributors.hpp:49
uint64_t by_author_rating() const
Индекс по рейтингу автора (6)
Definition: contributors.hpp:53
uint64_t by_coordinator_rating() const
Индекс по рейтингу координатора (7)
Definition: contributors.hpp:54
uint64_t by_investor_rating() const
Индекс по рейтингу инвестора (4)
Definition: contributors.hpp:51
uint64_t by_creator_rating() const
Индекс по рейтингу создателя (5)
Definition: contributors.hpp:52
checksum256 by_hash() const
Индекс по хэшу контрибьютора (3)
Definition: contributors.hpp:50
name username
Имя пользователя
Definition: contributors.hpp:23
std::vector< checksum256 > appendixes
Вектор хэшей проектов, для которых подписаны приложения
Definition: contributors.hpp:30
eosio::asset debt_amount
Сумма долга
Definition: contributors.hpp:34
checksum256 contributor_hash
Внешний идентификатор контрибьютора
Definition: contributors.hpp:24
Definition: document_core.hpp:27
uint64_t get_global_id_in_scope(eosio::name _me, eosio::name scope, eosio::name key)
Definition: table_counts.hpp:62