Untitled
unknown
plain_text
a month ago
13 kB
3
Indexable
#include <iostream> #include <map> #include <locale.h> #include <vector> #include <sqlite3.h> // Добавляем заголовок SQLite using namespace std; // Класс для работы с базой данных class Database { private: sqlite3* db; void execute(const string& query) { char* errMsg; if(sqlite3_exec(db, query.c_str(), nullptr, nullptr, &errMsg) != SQLITE_OK) { cerr << "Ошибка SQL: " << errMsg << endl; sqlite3_free(errMsg); } } public: Database() { if(sqlite3_open("materials.db", &db) != SQLITE_OK) { cerr << "Ошибка открытия БД: " << sqlite3_errmsg(db) << endl; exit(1); } // Создаем таблицы execute( "CREATE TABLE IF NOT EXISTS Materials (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "name TEXT NOT NULL UNIQUE," "quantity INTEGER NOT NULL);" "CREATE TABLE IF NOT EXISTS Products (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "name TEXT NOT NULL UNIQUE);" "CREATE TABLE IF NOT EXISTS ProductMaterials (" "product_id INTEGER NOT NULL," "material_id INTEGER NOT NULL," "quantity INTEGER NOT NULL," "FOREIGN KEY(product_id) REFERENCES Products(id)," "FOREIGN KEY(material_id) REFERENCES Materials(id));" ); } ~Database() { sqlite3_close(db); } sqlite3* handle() { return db; } }; // Класс для управления складом class Inventory { private: Database& db; public: Inventory(Database& database) : db(database) {} void addMaterial(const string& name, int quantity) { sqlite3_stmt* stmt; const char* query = "INSERT INTO Materials (name, quantity) " "VALUES (?, COALESCE((SELECT quantity FROM Materials WHERE name = ?), 0) + ?)"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, name.c_str(), -1, SQLITE_STATIC); sqlite3_bind_int(stmt, 3, quantity); sqlite3_step(stmt); sqlite3_finalize(stmt); cout << "Добавлено " << quantity << " ед. " << name << " на склад.\n"; } bool removeMaterial(const string& name, int quantity) { sqlite3_stmt* stmt; bool success = false; const char* query = "UPDATE Materials SET quantity = quantity - ? " "WHERE name = ? AND quantity >= ?"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); sqlite3_bind_int(stmt, 1, quantity); sqlite3_bind_text(stmt, 2, name.c_str(), -1, SQLITE_STATIC); sqlite3_bind_int(stmt, 3, quantity); if(sqlite3_step(stmt) == SQLITE_DONE) { if(sqlite3_changes(db.handle()) > 0) { cout << "Списано " << quantity << " ед. " << name << " со склада.\n"; success = true; } else { cout << "Ошибка: недостаточно " << name << " на складе.\n"; } } sqlite3_finalize(stmt); return success; } void showInventory() { sqlite3_stmt* stmt; cout << "\n--- Склад ---\n"; const char* query = "SELECT name, quantity FROM Materials"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); while(sqlite3_step(stmt) == SQLITE_ROW) { cout << sqlite3_column_text(stmt, 0) << ": " << sqlite3_column_int(stmt, 1) << " ед.\n"; } cout << "--------------\n"; sqlite3_finalize(stmt); } bool hasMaterial(const string& name, int quantity) { sqlite3_stmt* stmt; bool result = false; const char* query = "SELECT quantity FROM Materials WHERE name = ?"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) { result = (sqlite3_column_int(stmt, 0) >= quantity); } sqlite3_finalize(stmt); return result; } }; // Класс для каталога продукции class ProductCatalog { private: Database& db; int getMaterialId(const string& name) { sqlite3_stmt* stmt; int id = -1; const char* query = "SELECT id FROM Materials WHERE name = ?"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) { id = sqlite3_column_int(stmt, 0); } sqlite3_finalize(stmt); return id; } public: ProductCatalog(Database& database) : db(database) {} void addProduct(const string& productName, const map<string, int>& materials) { sqlite3_stmt* stmt; const char* query = "INSERT INTO Products (name) VALUES (?)"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); sqlite3_bind_text(stmt, 1, productName.c_str(), -1, SQLITE_STATIC); sqlite3_step(stmt); int productId = sqlite3_last_insert_rowid(db.handle()); sqlite3_finalize(stmt); for(const auto& [matName, qty] : materials) { int matId = getMaterialId(matName); if(matId == -1) { cerr << "Материал " << matName << " не найден!\n"; continue; } const char* insertQuery = "INSERT INTO ProductMaterials (product_id, material_id, quantity) " "VALUES (?, ?, ?)"; sqlite3_prepare_v2(db.handle(), insertQuery, -1, &stmt, nullptr); sqlite3_bind_int(stmt, 1, productId); sqlite3_bind_int(stmt, 2, matId); sqlite3_bind_int(stmt, 3, qty); sqlite3_step(stmt); sqlite3_finalize(stmt); } cout << "Продукт " << productName << " добавлен в каталог.\n"; } void showProducts() { sqlite3_stmt* stmt; cout << "\n--- Каталог продукции ---\n"; const char* query = "SELECT p.name, m.name, pm.quantity " "FROM Products p " "JOIN ProductMaterials pm ON p.id = pm.product_id " "JOIN Materials m ON pm.material_id = m.id"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); map<string, vector<pair<string, int>>> products; while(sqlite3_step(stmt) == SQLITE_ROW) { string productName = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)); string matName = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)); int quantity = sqlite3_column_int(stmt, 2); products[productName].emplace_back(matName, quantity); } for(const auto& [name, materials] : products) { cout << name << " (нужно: "; for(const auto& [mat, qty] : materials) { cout << mat << " - " << qty << " ед., "; } cout << ")\n"; } cout << "-------------------------\n"; sqlite3_finalize(stmt); } map<string, int> getProductMaterials(const string& productName) { sqlite3_stmt* stmt; map<string, int> materials; const char* query = "SELECT m.name, pm.quantity " "FROM Products p " "JOIN ProductMaterials pm ON p.id = pm.product_id " "JOIN Materials m ON pm.material_id = m.id " "WHERE p.name = ?"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); sqlite3_bind_text(stmt, 1, productName.c_str(), -1, SQLITE_STATIC); while(sqlite3_step(stmt) == SQLITE_ROW) { string matName = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)); int quantity = sqlite3_column_int(stmt, 1); materials[matName] = quantity; } sqlite3_finalize(stmt); return materials; } bool hasProduct(const string& productName) { sqlite3_stmt* stmt; bool exists = false; const char* query = "SELECT 1 FROM Products WHERE name = ?"; sqlite3_prepare_v2(db.handle(), query, -1, &stmt, nullptr); sqlite3_bind_text(stmt, 1, productName.c_str(), -1, SQLITE_STATIC); exists = (sqlite3_step(stmt) == SQLITE_ROW); sqlite3_finalize(stmt); return exists; } }; // Основной класс системы class MaterialAccountingSystem { private: Database db; Inventory inventory; ProductCatalog catalog; public: MaterialAccountingSystem() : db(), inventory(db), catalog(db) {} void addMaterialToInventory() { string name; int quantity; cout << "Введите название материала: "; cin >> name; cout << "Введите количество: "; cin >> quantity; inventory.addMaterial(name, quantity); } void addProductToCatalog() { string productName; cout << "Введите название продукта: "; cin >> productName; map<string, int> materials; while(true) { string materialName; int materialQuantity; cout << "Введите название материала (или 'gotovo' для завершения): "; cin >> materialName; if(materialName == "gotovo") break; cout << "Введите необходимое количество: "; cin >> materialQuantity; materials[materialName] = materialQuantity; } if(materials.empty()) { cout << "Ошибка: не добавлено ни одного материала! Продукт не сохранён.\n"; } else { catalog.addProduct(productName, materials); } } void produceProduct() { string productName; cout << "Введите название продукта для производства: "; cin >> productName; if(!catalog.hasProduct(productName)) { cout << "Ошибка: продукт не найден в каталоге!\n"; return; } map<string, int> requiredMaterials = catalog.getProductMaterials(productName); for(const auto& [mat, qty] : requiredMaterials) { if(!inventory.hasMaterial(mat, qty)) { cout << "Ошибка: недостаточно материала " << mat << "!\n"; return; } } for(const auto& [mat, qty] : requiredMaterials) { inventory.removeMaterial(mat, qty); } cout << "Продукт " << productName << " успешно произведён!\n"; } void showInventory() { inventory.showInventory(); } void showProductCatalog() { catalog.showProducts(); } void menu() { while(true) { cout << "\nВыберите действие:\n" << "1. Добавить материал на склад\n" << "2. Добавить новый продукт\n" << "3. Показать склад\n" << "4. Показать каталог\n" << "5. Произвести продукт\n" << "6. Выйти\n" << "Ваш выбор: "; int choice; cin >> choice; switch(choice) { case 1: addMaterialToInventory(); break; case 2: addProductToCatalog(); break; case 3: showInventory(); break; case 4: showProductCatalog(); break; case 5: produceProduct(); break; case 6: return; default: cout << "Неверный выбор!\n"; } } } }; int main() { setlocale(LC_ALL, "RUS"); MaterialAccountingSystem system; system.menu(); return 0; }
Editor is loading...
Leave a Comment