COOPENOMICS  v1
Кооперативная Экономика
contributors.hpp
См. документацию.
1#pragma once
2
3#include "../core/gamification/gamification.hpp"
4
5using namespace eosio;
6using std::string;
7
8namespace Capital {
9
18 struct [[eosio::table, eosio::contract(CAPITAL)]] contributor {
19 uint64_t id;
20 name coopname;
21 name username;
22 checksum256 contributor_hash;
23 time_point_sec created_at;
24 name status;
25 std::string memo;
26 bool is_external_contract = false;
28 std::vector<checksum256> appendixes;
29
30 eosio::asset rate_per_hour = asset(0, _root_govern_symbol);
31 uint64_t hours_per_day = 0;
32 eosio::asset debt_amount = asset(0, _root_govern_symbol);
33
34 eosio::asset contributed_as_investor = asset(0, _root_govern_symbol);
35 eosio::asset contributed_as_creator = asset(0, _root_govern_symbol);
36 eosio::asset contributed_as_author = asset(0, _root_govern_symbol);
37 eosio::asset contributed_as_coordinator = asset(0, _root_govern_symbol);
38 eosio::asset contributed_as_contributor = asset(0, _root_govern_symbol);
39 eosio::asset contributed_as_propertor = asset(0, _root_govern_symbol);
40
41 // Геймификация: уровень и энергия
42 uint32_t level = 1;
43 double energy = 99.9999999999;
44 time_point_sec last_energy_update;
45
46 uint64_t primary_key() const { return id; }
47 uint64_t by_username() const { return username.value; }
48 checksum256 by_hash() const { return contributor_hash; }
49 uint64_t by_investor_rating() const { return contributed_as_investor.amount; }
50 uint64_t by_creator_rating() const { return contributed_as_creator.amount; }
51 uint64_t by_author_rating() const { return contributed_as_author.amount; }
52 uint64_t by_coordinator_rating() const { return contributed_as_coordinator.amount; }
53 uint64_t by_contributor_rating() const { return contributed_as_contributor.amount; }
54 uint64_t by_propertor_rating() const { return contributed_as_propertor.amount; }
55 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; }
56 };
57
58typedef eosio::multi_index<
59 "contributors"_n, contributor,
60 indexed_by<"byusername"_n, const_mem_fun<contributor, uint64_t, &contributor::by_username>>,
61 indexed_by<"byhash"_n, const_mem_fun<contributor, checksum256, &contributor::by_hash>>,
62 indexed_by<"byinvrate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_investor_rating>>,
63 indexed_by<"bycreatorate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_creator_rating>>,
64 indexed_by<"byauthorate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_author_rating>>,
65 indexed_by<"bycoordrate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_coordinator_rating>>,
66 indexed_by<"bycontrate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_contributor_rating>>,
67 indexed_by<"byprprate"_n, const_mem_fun<contributor, uint64_t, &contributor::by_propertor_rating>>,
68 indexed_by<"byrating"_n, const_mem_fun<contributor, uint64_t, &contributor::by_rating>>
70}// namespace Capital
71
73
80 namespace Status {
81 const eosio::name PENDING = "pending"_n;
82 const eosio::name ACTIVE = "active"_n;
83 const eosio::name IMPORT = "import"_n;
84 }
85
86 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){
87 Capital::contributor_index contributors(_capital, coopname.value);
88
89 contributors.emplace(coopname, [&](auto &c) {
90 c.id = get_global_id_in_scope(_capital, coopname, "contributors"_n);
91 c.coopname = coopname;
92 c.username = username;
93 c.contributor_hash = contributor_hash;
95 c.is_external_contract = is_external_contract;
96 c.contract = contract;
97 c.created_at = eosio::current_time_point();
98 c.rate_per_hour = rate_per_hour;
99 c.hours_per_day = hours_per_day;
100
101 // Инициализация геймификации
102 c.level = 1;
103 c.energy = 99.9999999999;
104 c.last_energy_update = eosio::current_time_point();
105 });
106 }
107
108
113 eosio::name coopname,
114 eosio::name username,
115 checksum256 contributor_hash,
116 eosio::asset contribution_amount,
117 std::string memo
118 ) {
119 Capital::contributor_index contributors(_capital, coopname.value);
120
121 contributors.emplace(coopname, [&](auto &c) {
122 c.id = get_global_id_in_scope(_capital, coopname, "contributors"_n);
123 c.coopname = coopname;
124 c.username = username;
125 c.contributor_hash = contributor_hash;
127 c.is_external_contract = true;
128 c.created_at = eosio::current_time_point();
129 c.memo = memo;
130 c.rate_per_hour = asset(0, _root_govern_symbol);
131 c.hours_per_day = 0;
132 c.contributed_as_investor = contribution_amount;
133
134 // Инициализация геймификации
135 c.level = 1;
136 c.energy = 99.9999999999;
137 c.last_energy_update = eosio::current_time_point();
138 });
139 }
140
141
145 inline void push_appendix_to_contributor(eosio::name coopname, uint64_t contributor_id, checksum256 project_hash){
146 contributor_index contributors(_capital, coopname.value);
147 auto contributor_itr = contributors.find(contributor_id);
148 eosio::check(contributor_itr != contributors.end(), "Контрибьютор не найден");
149
150 contributors.modify(contributor_itr, _capital, [&](auto &c) {
151 c.appendixes.push_back(project_hash);
152 });
153 }
154
158 inline std::optional<contributor> get_contributor(eosio::name coopname, eosio::name username) {
159 contributor_index contributors(_capital, coopname.value);
160 auto username_index = contributors.get_index<"byusername"_n>();
161
162 auto itr = username_index.find(username.value);
163 if (itr == username_index.end()) {
164 return std::nullopt;
165 }
166
167 return contributor(*itr);
168 }
169
170
171
172
176 inline std::optional<contributor> get_contributor_by_hash(eosio::name coopname, const checksum256& contributor_hash) {
177 contributor_index contributors(_capital, coopname.value);
178 auto hash_index = contributors.get_index<"byhash"_n>();
179
180 auto itr = hash_index.find(contributor_hash);
181 if (itr == hash_index.end()) {
182 return std::nullopt;
183 }
184
185 return contributor(*itr);
186}
187
188
192inline bool is_contributor_has_appendix_in_project(eosio::name coopname, const checksum256 &project_hash, uint64_t contributor_id) {
193 contributor_index contributors(_capital, coopname.value);
194 auto contributor = contributors.find(contributor_id);
195
196 if (contributor == contributors.end()) {
197 return false;
198 }
199
200 // Проверяем есть ли project_hash в векторе appendixes
201 for (const auto& appendix_project_hash : contributor->appendixes) {
202 if (appendix_project_hash == project_hash) {
203 return true;
204 }
205 }
206
207 return false;
208}
209
210
214inline std::optional<contributor> get_active_contributor_or_fail(eosio::name coopname, eosio::name username) {
215 auto contributor = get_contributor(coopname, username);
216 eosio::check(contributor.has_value(), "Исполнитель не подписывал договор УХД");
217 eosio::check(contributor -> status == Status::ACTIVE, "Договор УХД с пайщиком не активен");
218 return contributor;
219}
220
221
225inline std::optional<contributor> get_active_contributor_with_appendix_or_fail(eosio::name coopname, const checksum256 &project_hash, eosio::name username) {
226 auto contributor = get_active_contributor_or_fail(coopname, username);
227 eosio::check(is_contributor_has_appendix_in_project(coopname, project_hash, contributor->id),
228 "Пайщик не подписывал приложение к договору УХД для данного проекта");
229 return contributor;
230}
231
237inline std::optional<contributor> get_contributor_for_regshare_or_fail(eosio::name coopname, eosio::name username) {
238 auto contributor = get_contributor(coopname, username);
239 eosio::check(contributor.has_value(), "Исполнитель не подписывал договор УХД");
240 const eosio::name st = contributor->status;
241 eosio::check(st == Status::ACTIVE || st == Status::IMPORT,
242 "Договор УХД с пайщиком не в статусе active или import");
243 return contributor;
244}
245
246
247
252inline void update_contributor_ratings_from_segment(eosio::name coopname, uint64_t contributor_id, const Capital::Segments::segment& segment) {
253 Capital::contributor_index contributors(_capital, coopname.value);
254 auto contributor = contributors.find(contributor_id);
255
256 eosio::check(contributor != contributors.end(), "Контрибьютор не найден");
257
258 contributors.modify(contributor, _capital, [&](auto &c) {
259 // ВАЖНО: contributed_as_investor НЕ обновляется здесь, так как обновляется в момент инвестиции (createinvest)
260 // Это предотвращает двойное начисление для участников с несколькими ролями (инвестор+создатель/автор и т.д.)
261
262 if (segment.is_author) {
263 c.contributed_as_author += (segment.author_base + segment.author_bonus);
264 }
265
266 if (segment.is_creator) {
267 c.contributed_as_creator += (segment.creator_base + segment.creator_bonus);
268 }
269
270 if (segment.is_coordinator) {
271 c.contributed_as_coordinator += segment.coordinator_base;
272 }
273
274 if (segment.is_contributor) {
275 c.contributed_as_contributor += segment.contributor_bonus;
276 }
277
278 if (segment.is_propertor) {
279 c.contributed_as_propertor += segment.property_base;
280 }
281 });
282
283 // Обновляем геймификацию (уровень и энергию) после обновления рейтингов
284 Capital::Gamification::update_gamification_from_segment(coopname, contributor_id, segment);
285}
286
290inline void increase_debt_amount(eosio::name coopname, uint64_t contributor_id, eosio::asset amount) {
291 contributor_index contributors(_capital, coopname.value);
292 auto contributor = contributors.find(contributor_id);
293
294 eosio::check(contributor != contributors.end(), "Контрибьютор не найден");
295 //TODO: make coopname payer
296 contributors.modify(contributor, _capital, [&](auto &c) {
297 c.debt_amount += amount;
298 });
299}
300
304 inline void decrease_debt_amount(eosio::name coopname, uint64_t contributor_id, eosio::asset amount) {
305 contributor_index contributors(_capital, coopname.value);
306 auto contributor = contributors.find(contributor_id);
307
308 eosio::check(contributor != contributors.end(), "Контрибьютор не найден");
309 eosio::check(contributor->debt_amount >= amount, "Недостаточно долга для погашения");
310
311 //TODO: make coopname payer
312 contributors.modify(contributor, _capital, [&](auto &c) {
313 c.debt_amount -= amount;
314 });
315}
316
320inline void edit_contributor(eosio::name coopname, uint64_t contributor_id, eosio::asset rate_per_hour, uint64_t hours_per_day) {
321 contributor_index contributors(_capital, coopname.value);
322 auto contributor = contributors.find(contributor_id);
323
324 eosio::check(contributor != contributors.end(), "Участник не найден");
325
326 contributors.modify(contributor, coopname, [&](auto &c) {
327 c.rate_per_hour = rate_per_hour;
328 c.hours_per_day = hours_per_day;
329 });
330}
331
338inline void increase_investor_contribution(eosio::name coopname, uint64_t contributor_id, eosio::asset amount) {
339 contributor_index contributors(_capital, coopname.value);
340 auto contributor = contributors.find(contributor_id);
341
342 eosio::check(contributor != contributors.end(), "Участник не найден");
343
344 contributors.modify(contributor, _capital, [&](auto &c) {
345 c.contributed_as_investor += amount;
346 });
347}
348
356 eosio::name coopname,
357 uint64_t contributor_id,
358 eosio::asset rate_per_hour,
359 uint64_t hours_per_day,
360 bool is_external_contract,
362) {
363 contributor_index contributors(_capital, coopname.value);
364 auto contributor = contributors.find(contributor_id);
365
366 eosio::check(contributor != contributors.end(), "Участник не найден");
367 eosio::check(contributor->status == Status::IMPORT, "Участник не находится в статусе импорта");
368 eosio::check(contributor->is_external_contract == is_external_contract, "Флаг внешнего контракта не совпадает с импортированным");
369
370 contributors.modify(contributor, coopname, [&](auto &c) {
371 c.rate_per_hour = rate_per_hour;
372 c.hours_per_day = hours_per_day;
373 // Для не внешних контрактов обновляем contract
374 if (!is_external_contract) {
375 c.contract = contract;
376 }
377 c.status = Status::PENDING; // Меняем статус на PENDING для одобрения председателем
378 });
379}
380
381
382}// namespace Capital::Contributors
Контракт Contributor управляет вкладами, распределением вознаграждений и выводом средств для участник...
Definition: contributor.hpp:17
static constexpr eosio::name _capital
Definition: consts.hpp:150
static constexpr eosio::symbol _root_govern_symbol
Definition: consts.hpp:209
contract
Definition: eosio.msig_tests.cpp:977
share_type amount
Definition: eosio.token_tests.cpp:174
const eosio::name ACTIVE
Авторизован/активен
Definition: contributors.hpp:82
const eosio::name IMPORT
Импортирован, требует завершения регистрации
Definition: contributors.hpp:83
const eosio::name PENDING
Ожидает подтверждения
Definition: contributors.hpp:81
Definition: contributors.hpp:72
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:355
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:112
std::optional< contributor > get_active_contributor_with_appendix_or_fail(eosio::name coopname, const checksum256 &project_hash, eosio::name username)
Получает участника по имени аккаунта, проверяет активность и членство в проекте.
Definition: contributors.hpp:225
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:86
void push_appendix_to_contributor(eosio::name coopname, uint64_t contributor_id, checksum256 project_hash)
Добавляет project_hash в вектор appendixes у контрибьютора
Definition: contributors.hpp:145
void increase_investor_contribution(eosio::name coopname, uint64_t contributor_id, eosio::asset amount)
Увеличивает инвестиционный вклад участника
Definition: contributors.hpp:338
std::optional< contributor > get_contributor_by_hash(eosio::name coopname, const checksum256 &contributor_hash)
Получает участника по хэшу контрибьютора.
Definition: contributors.hpp:176
bool is_contributor_has_appendix_in_project(eosio::name coopname, const checksum256 &project_hash, uint64_t contributor_id)
Проверяет есть ли у контрибьютора приложение для проекта
Definition: contributors.hpp:192
void edit_contributor(eosio::name coopname, uint64_t contributor_id, eosio::asset rate_per_hour, uint64_t hours_per_day)
Обновляет параметры участника (часы в день и информацию о себе)
Definition: contributors.hpp:320
std::optional< contributor > get_contributor(eosio::name coopname, eosio::name username)
Получает участника по имени аккаунта.
Definition: contributors.hpp:158
std::optional< contributor > get_active_contributor_or_fail(eosio::name coopname, eosio::name username)
Получает участника по имени аккаунта и проверяет на активность.
Definition: contributors.hpp:214
std::optional< contributor > get_contributor_for_regshare_or_fail(eosio::name coopname, eosio::name username)
Контрибьютор, допустимый для capital::regshare без приложения к проекту. Статусы import (импорт с бал...
Definition: contributors.hpp:237
void increase_debt_amount(eosio::name coopname, uint64_t contributor_id, eosio::asset amount)
Увеличивает долг контрибьютора
Definition: contributors.hpp:290
void decrease_debt_amount(eosio::name coopname, uint64_t contributor_id, eosio::asset amount)
Увеличивает долг контрибьютора
Definition: contributors.hpp:304
void update_contributor_ratings_from_segment(eosio::name coopname, uint64_t contributor_id, const Capital::Segments::segment &segment)
Обновляет накопительные показатели контрибьютора на основе его ролей и вкладов в сегменте
Definition: contributors.hpp:252
void update_gamification_from_segment(eosio::name coopname, uint64_t contributor_id, const Capital::Segments::segment &segment)
Обновляет геймификацию (уровень и энергию) на основе вкладов из сегмента
Definition: gamification.cpp:95
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:69
Definition: eosio.msig.hpp:34
Таблица сегментов хранит данные о вкладах участника в проект.
Definition: segments.hpp:34
bool is_coordinator
Является ли участник координатором
Definition: segments.hpp:46
bool is_creator
Является ли участник создателем
Definition: segments.hpp:45
bool is_author
Является ли участник автором
Definition: segments.hpp:44
bool is_propertor
Является ли участник пропертором
Definition: segments.hpp:48
bool is_contributor
Является ли участник участником
Definition: segments.hpp:49
Таблица участников хранит данные индивидуального участника кооператива.
Definition: contributors.hpp:18
bool is_external_contract
Флаг, указывающий на внешний контракт
Definition: contributors.hpp:26
time_point_sec last_energy_update
Время последнего обновления энергии
Definition: contributors.hpp:44
std::string memo
Мемо для импортированных контрибьюторов
Definition: contributors.hpp:25
uint64_t id
ID контрибьютора (внутренний ключ)
Definition: contributors.hpp:19
uint64_t primary_key() const
Первичный ключ (1)
Definition: contributors.hpp:46
time_point_sec created_at
Время создания контрибьютора
Definition: contributors.hpp:23
uint64_t by_contributor_rating() const
Индекс по рейтингу контрибьютора (8)
Definition: contributors.hpp:53
uint64_t by_rating() const
Индекс по общему рейтингу (10)
Definition: contributors.hpp:55
name coopname
Имя кооператива
Definition: contributors.hpp:20
name status
Статус контрибьютора
Definition: contributors.hpp:24
document2 contract
Договор УХД
Definition: contributors.hpp:27
uint64_t by_propertor_rating() const
Индекс по рейтингу пропертора (9)
Definition: contributors.hpp:54
eosio::asset rate_per_hour
Ставка за час
Definition: contributors.hpp:30
uint64_t by_username() const
Индекс по имени пользователя (2)
Definition: contributors.hpp:47
uint64_t by_author_rating() const
Индекс по рейтингу автора (6)
Definition: contributors.hpp:51
uint64_t by_coordinator_rating() const
Индекс по рейтингу координатора (7)
Definition: contributors.hpp:52
uint64_t by_investor_rating() const
Индекс по рейтингу инвестора (4)
Definition: contributors.hpp:49
uint64_t by_creator_rating() const
Индекс по рейтингу создателя (5)
Definition: contributors.hpp:50
checksum256 by_hash() const
Индекс по хэшу контрибьютора (3)
Definition: contributors.hpp:48
name username
Имя пользователя
Definition: contributors.hpp:21
std::vector< checksum256 > appendixes
Вектор хэшей проектов, для которых подписаны приложения
Definition: contributors.hpp:28
eosio::asset debt_amount
Сумма долга
Definition: contributors.hpp:32
checksum256 contributor_hash
Внешний идентификатор контрибьютора
Definition: contributors.hpp:22
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:58