#pragma once #include "worker.h" #include #include class ProduceWorker : public Worker { public: explicit ProduceWorker(ConnectionPool &pool, MessageBroker &broker); ~ProduceWorker() override; protected: void run() override; private: void processProductions(); std::vector> getFinishedProductions(Database &db); bool addToInventory(Database &db, int branchId, int productId, int quantity, int quality, int userId); bool storeInStock(Database &db, int stockId, int productId, int quantity, int quality); void deleteProduction(Database &db, const std::string &productionId); void sendProductionReadyEvent(int userId, int productId, int quantity, int quality, int branchId); void addProductionToLog(int regionId, int userId, int productId, int quantity); static constexpr const char *QUERY_GET_FINISHED_PRODUCTIONS = R"( SELECT DISTINCT p.id AS production_id, p.branch_id, p.product_id, p.quantity, p.start_timestamp, pr.production_time, k.character_id, case when k2.id is not null then (k.knowledge * 2 + k2.knowledge) / 3 else k.knowledge end AS quality, br.region_id, br.falukant_user_id user_id FROM falukant_data.production p JOIN falukant_type.product pr ON p.product_id = pr.id JOIN falukant_data.branch br ON p.branch_id = br.id JOIN falukant_data.character c ON c.user_id = br.falukant_user_id JOIN falukant_data.knowledge k ON p.product_id = k.product_id AND k.character_id = c.id JOIN falukant_data.stock s ON s.branch_id = br.id LEFT JOIN falukant_data.director d on d.employer_user_id = c.user_id LEFT JOIN falukant_data.knowledge k2 on k2.character_id = d.director_character_id and k2.product_id = p.product_id WHERE p.start_timestamp + interval '1 minute' * pr.production_time <= NOW() ORDER BY p.start_timestamp; )"; static constexpr const char *QUERY_GET_AVAILABLE_STOCKS = R"( SELECT stock.id, stock.quantity AS total_capacity, ( SELECT COALESCE(SUM(inventory.quantity), 0) FROM falukant_data.inventory WHERE inventory.stock_id = stock.id ) AS filled, stock.branch_id FROM falukant_data.stock stock JOIN falukant_data.branch branch ON stock.branch_id = branch.id WHERE branch.id = $1 ORDER BY total_capacity DESC; )"; static constexpr const char *QUERY_DELETE_PRODUCTION = R"( DELETE FROM falukant_data.production WHERE id = $1; )"; static constexpr const char *QUERY_INSERT_INVENTORY = R"( INSERT INTO falukant_data.inventory (stock_id, product_id, quantity, quality, produced_at) VALUES ($1, $2, $3, $4, NOW()); )"; static constexpr const char *QUERY_INSERT_UPDATE_PRODUCTION_LOG = R"( INSERT INTO falukant_log.production ( region_id, product_id, quantity, producer_id, production_date ) VALUES ($1, $2, $3, $4, CURRENT_DATE) ON CONFLICT (producer_id, product_id, region_id, production_date) DO UPDATE SET quantity = falukant_log.production.quantity + EXCLUDED.quantity; )"; static constexpr const char *QUERY_ADD_OVERPRODUCTION_NOTIFICATION = R"( INSERT INTO falukant_log.notification (user_id, tr, shown, created_at, updated_at) VALUES($1, $2, false, now(), now()); )"; };