|
|
|
@ -402,6 +402,106 @@ unsigned int Database::storeArticles(std::vector<Article*> articles)
|
|
|
|
|
return count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsigned int Database::storeSales(std::vector<std::unique_ptr<Sale>>& sales) |
|
|
|
|
{ |
|
|
|
|
int retCode{}; |
|
|
|
|
int count{}; |
|
|
|
|
sqlite3_stmt* stmt; |
|
|
|
|
|
|
|
|
|
if (sales.size() == 0) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
beginTransaction(); |
|
|
|
|
|
|
|
|
|
for (auto& sale : sales) { |
|
|
|
|
if (sale->getState() == Sale::State::NEW) { |
|
|
|
|
retCode = sqlite3_prepare_v2(db_, |
|
|
|
|
"INSERT INTO sales" |
|
|
|
|
" (id, source_no, sold_at)" |
|
|
|
|
" VALUES (:uuid, :source_no, :sold_at)", |
|
|
|
|
-1, &stmt, nullptr); |
|
|
|
|
|
|
|
|
|
if (retCode != SQLITE_OK) |
|
|
|
|
throw std::runtime_error(sqlite3_errmsg(db_)); |
|
|
|
|
|
|
|
|
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"), |
|
|
|
|
boost::uuids::to_string(sale->getUuid()).c_str(), -1, |
|
|
|
|
SQLITE_TRANSIENT); |
|
|
|
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":source_no"), |
|
|
|
|
sale->getSourceNo()); |
|
|
|
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":sold_at"), |
|
|
|
|
sale->getTimestamp().c_str(), -1, SQLITE_TRANSIENT); |
|
|
|
|
|
|
|
|
|
retCode = sqlite3_step(stmt); |
|
|
|
|
|
|
|
|
|
if (retCode != SQLITE_DONE) { |
|
|
|
|
|
|
|
|
|
std::string errMsg(sqlite3_errmsg(db_)); |
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
throw std::runtime_error(errMsg); |
|
|
|
|
} |
|
|
|
|
++count; |
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
|
|
|
|
|
for (const auto& article : sale->getArticles()) { |
|
|
|
|
retCode = sqlite3_prepare_v2(db_, |
|
|
|
|
"INSERT INTO sales_items" |
|
|
|
|
" (sale_id, article_id)" |
|
|
|
|
" VALUES (:sale_id, :article_id)", |
|
|
|
|
-1, &stmt, nullptr); |
|
|
|
|
|
|
|
|
|
if (retCode != SQLITE_OK) |
|
|
|
|
throw std::runtime_error(sqlite3_errmsg(db_)); |
|
|
|
|
|
|
|
|
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":sale_id"), |
|
|
|
|
sale->getUuidAsString().c_str(), -1, SQLITE_TRANSIENT); |
|
|
|
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":article_id"), |
|
|
|
|
article->getUuidAsString().c_str(), -1, SQLITE_TRANSIENT); |
|
|
|
|
|
|
|
|
|
retCode = sqlite3_step(stmt); |
|
|
|
|
|
|
|
|
|
if (retCode != SQLITE_DONE) { |
|
|
|
|
|
|
|
|
|
std::string errMsg(sqlite3_errmsg(db_)); |
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
throw std::runtime_error(errMsg); |
|
|
|
|
} |
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
} |
|
|
|
|
} else if (sale->getState() == Sale::State::DELETE) { |
|
|
|
|
retCode = |
|
|
|
|
sqlite3_prepare_v2(db_, "DELETE FROM sales WHERE id = :uuid", -1, &stmt, nullptr); |
|
|
|
|
|
|
|
|
|
if (retCode != SQLITE_OK) |
|
|
|
|
throw std::runtime_error(sqlite3_errmsg(db_)); |
|
|
|
|
|
|
|
|
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"), |
|
|
|
|
sale->getUuidAsString().c_str(), -1, SQLITE_TRANSIENT); |
|
|
|
|
|
|
|
|
|
retCode = sqlite3_step(stmt); |
|
|
|
|
|
|
|
|
|
if (retCode != SQLITE_DONE) { |
|
|
|
|
|
|
|
|
|
std::string errMsg(sqlite3_errmsg(db_)); |
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
throw std::runtime_error(errMsg); |
|
|
|
|
} |
|
|
|
|
++count; |
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Maybe not necessary (because of DELETE CASCADE): Delete here individual articles
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
endTransaction(); |
|
|
|
|
|
|
|
|
|
for (auto& sale : sales) { |
|
|
|
|
sale->setState(Sale::State::OK); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>>& sellers) |
|
|
|
|
{ |
|
|
|
|
int retCode{}; |
|
|
|
@ -469,5 +569,70 @@ unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>>& sellers
|
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsigned int Database::loadSales(std::vector<std::unique_ptr<Sale>>& sales, |
|
|
|
|
std::vector<std::unique_ptr<Seller>>& sellers) |
|
|
|
|
{ |
|
|
|
|
int retCode{}; |
|
|
|
|
int count{}; |
|
|
|
|
sqlite3_stmt* stmt; |
|
|
|
|
|
|
|
|
|
retCode = sqlite3_prepare_v2(db_, |
|
|
|
|
"SELECT id, source_no, sold_at" |
|
|
|
|
" FROM sales ORDER BY sold_at", |
|
|
|
|
-1, &stmt, nullptr); |
|
|
|
|
if (retCode != SQLITE_OK) |
|
|
|
|
throw std::runtime_error(sqlite3_errmsg(db_)); |
|
|
|
|
|
|
|
|
|
retCode = sqlite3_step(stmt); |
|
|
|
|
|
|
|
|
|
sales.clear(); |
|
|
|
|
|
|
|
|
|
while (retCode != SQLITE_DONE) { |
|
|
|
|
++count; |
|
|
|
|
auto sale = std::make_unique<Sale>(); |
|
|
|
|
sale->setUuidFromString(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0))); |
|
|
|
|
sale->setSourceNo(sqlite3_column_int(stmt, 1)); |
|
|
|
|
sale->setTimestamp(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2))); |
|
|
|
|
sale->setState(Sale::State::OK); |
|
|
|
|
sales.push_back(std::move(sale)); |
|
|
|
|
|
|
|
|
|
retCode = sqlite3_step(stmt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
|
|
|
|
|
for (auto& sale : sales) { |
|
|
|
|
retCode = sqlite3_prepare_v2(db_, |
|
|
|
|
"SELECT sale_id, article_id" |
|
|
|
|
" FROM sales_items" |
|
|
|
|
" WHERE sale_id = :sale_uuid", |
|
|
|
|
-1, &stmt, nullptr); |
|
|
|
|
if (retCode != SQLITE_OK) |
|
|
|
|
throw std::runtime_error(sqlite3_errmsg(db_)); |
|
|
|
|
|
|
|
|
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":sale_uuid"), |
|
|
|
|
sale->getUuidAsString().c_str(), -1, SQLITE_TRANSIENT); |
|
|
|
|
|
|
|
|
|
retCode = sqlite3_step(stmt); |
|
|
|
|
|
|
|
|
|
while (retCode != SQLITE_DONE) { |
|
|
|
|
for (auto& seller : sellers) { |
|
|
|
|
auto article = seller->getArticleByUuid( |
|
|
|
|
reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1))); |
|
|
|
|
if (article != nullptr) { |
|
|
|
|
sale->addArticle(article); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
retCode = sqlite3_step(stmt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return count; |
|
|
|
|
} |