couponctr
unknown
c_cpp
2 years ago
6.7 kB
9
Indexable
#include "couponctr.hpp" #include <eosio/eosio.hpp> #include <string> using namespace std; using namespace eosio; /* ISSUE Questa azione permette ad un produttore di emettere un nuovo coupon. Input: Tipo del coupon ('a' valore sconto fisso, 'p' valore sconto percentuale), valore del coupon, data di scadenza, address del consumatore a cui sarà assegnato il coupon. Permessi: producerp */ [[eosio::action]] void couponctr::issue(const string coupon_type, const float coupon_value, const string expiration, const eosio::name consumer) { check(!coupon_type.compare("a") || !coupon_type.compare("p"), "Coupon type must be 'a' for absolute value or 'p' for percentage value."); std::string s(expiration); struct tm tm { }; strptime(s.c_str(), "%d-%m-%Y", &tm); time_t t = mktime(&tm); coupon_table c_t("couponctr"_n, "couponctr"_n.value); c_t.emplace("producer"_n, [&](auto &c) { c.coupon_id = c_t.available_primary_key(); c.coupon_type = coupon_type; c.producer = current_receiver(); // current_reicever returns the account which specifies the current receiver of the action c.consumer = consumer; c.creation = time(0); // current date/time based on current system c.expiration = t; c.coupon_value = coupon_value; c.isValid = true; }); } /*La funzione acquire per ora è messa da parte perché EOSIO non permette di avere un parametro di tipo 'name' come opzionale (non è possibile avere un name nullo) ed inoltre non è possibile avere overloading di azioni, per cui bisognerebbe creare un'azione extra solo per creare coupon non assegnati, questi coupon dovrebbero appartenere ad una tabella diversa e in caso di acquisto dovrebbero essere convertiti al primo tipo di coupon (quelli assegnati) e riaggiunti alla prima tabella. Conviene mantenere fede al modello o rivederlo eliminando i coupon non assegnati? Per ora io sono per la seconda opzione, i coupon non assegnati erano stati inseriti per rendere il modello più generale possibile, però nel pratico difficilmente verrebbero implementati. [[eosio::action]] void couponctr::acquire(const uint64_t coupon_id, const name consumer) { coupon_table c_t("couponctr"_n, "couponctr"_n.value); auto c_itr = c_t.find(coupon_id); check(c_itr != c_t.end(), "Coupon ID not found."); require_auth(consumer); check(c_itr->consumer.value != NULL, "Coupon is already assigned."); c_t.modify(c_itr, consumer, [&](auto &c) { c.consumer = consumer; }); }*/ /* TRANSFER Azione con cui un consumatore trasferisce un proprio coupon ad un altro utente. Input: id del coupon da trasferire, address dell'utente destinatario. Permessi: consumerp */ [[eosio::action]] void couponctr::transfer(const uint64_t coupon_id, const name consumer1, const name consumer2) { coupon_table c_t("couponctr"_n, "couponctr"_n.value); auto c_itr = c_t.find(coupon_id); check(c_itr != c_t.end(), "Coupon ID not found."); check(c_itr->isValid == true, "Coupon has already been redeemed."); require_auth(consumer1); c_t.modify(c_itr, consumer1, [&](auto &c) { check (c.consumer == consumer1, "Coupon is assigned to another consumer."); c.consumer = consumer2; }); } /* INVALIDATE Azione con cui si cancella un coupon rendendolo non più valido. Input: id del coupon da cancellare Permessi: interp (intermediario)*/ [[eosio::action]] void couponctr::invalidate(const uint64_t coupon_id) { coupon_table c_t("couponctr"_n, "couponctr"_n.value); auto c_itr = c_t.find(coupon_id); check(c_itr != c_t.end(), "Coupon ID not found."); name user; if (has_auth("producer"_n)) { user = "producer"_n; } if (has_auth("intermediary"_n)) { user = "intermediary"_n; } c_t.modify(c_itr, user, [&](auto &c) { c.isValid = false; }); // c_t.erase(c_itr); la funzione erase cancella del tutto il coupon, può essere utile invece mantenerlo e dare come feedback il fatto che non sia valido } /* REDEEM Azione con cui viene riscattato un coupon. Input: id del coupon da riscattare, importo della transazione in atto. [ATTENZIONE: l'importo della transazione viene ottenuto dalla transazione in atto durante il riscatto del coupon, per ora si sottindende che ci sia un sistema che faccia sì che ciò avvenga]. Output: il nuovo importo calcolato secondo tipo e valore del coupon riscattato. Una volta riscattato un coupon non è più valido e viene cancellato. Permessi: interp (intermediario) */ [[eosio::action]] float couponctr::redeem(const uint64_t coupon_id, const float amount) { coupon_table c_t("couponctr"_n, "couponctr"_n.value); auto c_itr = c_t.find(coupon_id); check(c_itr != c_t.end(), "Coupon ID not found."); check(c_itr->isValid == true, "Coupon has already been redeemed."); /* Si verifica che il coupon corrispondente sia valido attraverso il valoredi isValid (che deve essere pari a 1) e il confronto tra la data attuale e quella riportata in expiration, che specifica la data di scadenza*/ if (c_itr->expiration < time(0)) { // Per sopperire al problema di conflitto tra la libreria time.h e alcune di eosio si stampano i due valori temporali, verrano visualizzati come pending output al momento dell'attivazione di check print("Time ", time(0)); print(" Expiration ", c_itr->expiration); invalidate(coupon_id); // struct tm *exp = localtime(&c_itr->expiration); le funzioni della libreria time.h entrano in conflitto con altre librerie di eosio // print("Coupon has expired ", std::asctime(exp)); check(c_itr->expiration > time(0), "Coupon has expired"); return amount; } print(c_itr->coupon_type); /* Il tipo di coupon 'a' corrisponde ad un coupon sconto assoluto, cioè con un valore fisso*/ if (!c_itr->coupon_type.compare("a")) { float new_amount = amount - c_itr->coupon_value; invalidate(coupon_id); return new_amount; } /* L'altro tipo di coupon possibile è contrassegnato con 'p' e corrisponde ad un coupon dal valore percentuale*/ if (!c_itr->coupon_type.compare("p")) { float new_amount = amount - (amount * c_itr->coupon_value) / 100; invalidate(coupon_id); return new_amount; } return amount; }
Editor is loading...