Untitled
unknown
plain_text
9 months ago
13 kB
6
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