backend fitur produk dan transaki
This commit is contained in:
parent
244395c234
commit
f1fcbddfeb
|
|
@ -237,15 +237,26 @@ class MLService {
|
||||||
} else if (response.statusCode == 409) {
|
} else if (response.statusCode == 409) {
|
||||||
final result = jsonDecode(response.body);
|
final result = jsonDecode(response.body);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else if (response.statusCode == 400) {
|
||||||
|
final result = jsonDecode(response.body);
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'message': 'Server error: ${response.statusCode}',
|
'message': result['message'] ?? 'Bad request'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
print('Create product error - Status: ${response.statusCode}');
|
||||||
|
print('Response body: ${response.body}');
|
||||||
|
return {
|
||||||
|
'status': 'error',
|
||||||
|
'message': 'Server error: ${response.statusCode}'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Create product error: $e');
|
print('Create product exception: $e');
|
||||||
return {'status': 'error', 'message': 'Connection error: $e'};
|
return {
|
||||||
|
'status': 'error',
|
||||||
|
'message': 'Connection error: $e'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
-- Create Database and Tables for Prediksi Stok Bahan Kue
|
||||||
|
-- Run this in MySQL to setup the database
|
||||||
|
|
||||||
|
-- Create Database
|
||||||
|
CREATE DATABASE IF NOT EXISTS prediksi_stok_db;
|
||||||
|
USE prediksi_stok_db;
|
||||||
|
|
||||||
|
-- Create Products Table
|
||||||
|
CREATE TABLE IF NOT EXISTS products (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
name VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
category VARCHAR(100) NOT NULL,
|
||||||
|
price INT NOT NULL,
|
||||||
|
current_stock INT NOT NULL DEFAULT 0,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Create Transactions Table
|
||||||
|
CREATE TABLE IF NOT EXISTS transactions (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
product_name VARCHAR(255) NOT NULL,
|
||||||
|
category VARCHAR(100) NOT NULL,
|
||||||
|
quantity INT NOT NULL,
|
||||||
|
unit_price INT NOT NULL,
|
||||||
|
total_price INT NOT NULL,
|
||||||
|
transaction_date DATE NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Create Predictions Table
|
||||||
|
CREATE TABLE IF NOT EXISTS predictions (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
product_name VARCHAR(255) NOT NULL,
|
||||||
|
category VARCHAR(100) NOT NULL,
|
||||||
|
unit_price INT NOT NULL,
|
||||||
|
prediction_date DATE NOT NULL,
|
||||||
|
predicted_quantity INT NOT NULL,
|
||||||
|
raw_value FLOAT,
|
||||||
|
estimated_total_price INT,
|
||||||
|
accuracy_r2 FLOAT,
|
||||||
|
error_mae FLOAT,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Create Recipes Table
|
||||||
|
CREATE TABLE IF NOT EXISTS recipes (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
recipe_name VARCHAR(255) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Create Recipe Ingredients Table
|
||||||
|
CREATE TABLE IF NOT EXISTS recipe_ingredients (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
recipe_id INT NOT NULL,
|
||||||
|
product_name VARCHAR(255) NOT NULL,
|
||||||
|
quantity_needed FLOAT NOT NULL,
|
||||||
|
unit VARCHAR(50) NOT NULL,
|
||||||
|
FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Insert Initial Products (8 items)
|
||||||
|
INSERT INTO products (name, category, price, current_stock) VALUES
|
||||||
|
('Tepung Terigu 1kg', 'Tepung', 15000, 50),
|
||||||
|
('Telur 1kg', 'Telur', 25000, 30),
|
||||||
|
('Gula Pasir 1kg', 'Gula', 12000, 40),
|
||||||
|
('Susu Bubuk', 'Susu', 20000, 20),
|
||||||
|
('Cokelat Bubuk 250gr', 'Cokelat', 18000, 15),
|
||||||
|
('Mentega 500gr', 'Mentega', 22000, 25),
|
||||||
|
('Keju Parut 250gr', 'Keju', 28000, 10),
|
||||||
|
('Baking Powder', 'Bahan Tambahan', 8000, 35);
|
||||||
|
|
||||||
|
-- Insert Sample Recipes
|
||||||
|
INSERT INTO recipes (recipe_name, description) VALUES
|
||||||
|
('Donat', 'Resep donat lezat'),
|
||||||
|
('Roti Putih', 'Resep roti putih'),
|
||||||
|
('Kue Brownies', 'Resep brownies cokelat'),
|
||||||
|
('Kue Tart', 'Resep kue tart');
|
||||||
|
|
||||||
|
-- Insert Recipe Ingredients
|
||||||
|
-- Donat
|
||||||
|
INSERT INTO recipe_ingredients (recipe_id, product_name, quantity_needed, unit) VALUES
|
||||||
|
(1, 'Tepung Terigu 1kg', 0.5, 'kg'),
|
||||||
|
(1, 'Telur 1kg', 2, 'butir'),
|
||||||
|
(1, 'Gula Pasir 1kg', 0.1, 'kg'),
|
||||||
|
(1, 'Mentega 500gr', 0.05, 'kg'),
|
||||||
|
(1, 'Baking Powder', 0.005, 'kg');
|
||||||
|
|
||||||
|
-- Roti Putih
|
||||||
|
INSERT INTO recipe_ingredients (recipe_id, product_name, quantity_needed, unit) VALUES
|
||||||
|
(2, 'Tepung Terigu 1kg', 0.8, 'kg'),
|
||||||
|
(2, 'Telur 1kg', 3, 'butir'),
|
||||||
|
(2, 'Gula Pasir 1kg', 0.08, 'kg'),
|
||||||
|
(2, 'Mentega 500gr', 0.08, 'kg'),
|
||||||
|
(2, 'Susu Bubuk', 0.05, 'kg'),
|
||||||
|
(2, 'Baking Powder', 0.008, 'kg');
|
||||||
|
|
||||||
|
-- Kue Brownies
|
||||||
|
INSERT INTO recipe_ingredients (recipe_id, product_name, quantity_needed, unit) VALUES
|
||||||
|
(3, 'Tepung Terigu 1kg', 0.3, 'kg'),
|
||||||
|
(3, 'Cokelat Bubuk 250gr', 0.1, 'kg'),
|
||||||
|
(3, 'Telur 1kg', 4, 'butir'),
|
||||||
|
(3, 'Gula Pasir 1kg', 0.2, 'kg'),
|
||||||
|
(3, 'Mentega 500gr', 0.15, 'kg'),
|
||||||
|
(3, 'Baking Powder', 0.005, 'kg');
|
||||||
|
|
||||||
|
-- Kue Tart
|
||||||
|
INSERT INTO recipe_ingredients (recipe_id, product_name, quantity_needed, unit) VALUES
|
||||||
|
(4, 'Tepung Terigu 1kg', 0.4, 'kg'),
|
||||||
|
(4, 'Telur 1kg', 5, 'butir'),
|
||||||
|
(4, 'Gula Pasir 1kg', 0.15, 'kg'),
|
||||||
|
(4, 'Mentega 500gr', 0.2, 'kg'),
|
||||||
|
(4, 'Keju Parut 250gr', 0.1, 'kg'),
|
||||||
|
(4, 'Susu Bubuk', 0.08, 'kg');
|
||||||
|
|
||||||
|
-- Verify tables created
|
||||||
|
SELECT 'Tables created successfully!' as status;
|
||||||
|
SELECT COUNT(*) as total_products FROM products;
|
||||||
|
SELECT COUNT(*) as total_recipes FROM recipes;
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Simple backend connectivity test
|
||||||
|
Run: python test_backend.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# Change this to your backend URL
|
||||||
|
BACKEND_URL = "http://192.168.1.2:5000"
|
||||||
|
|
||||||
|
def test_health():
|
||||||
|
"""Test if backend is running"""
|
||||||
|
try:
|
||||||
|
print("\n[TEST 1] Health Check")
|
||||||
|
print(f"URL: {BACKEND_URL}/health")
|
||||||
|
response = requests.get(f"{BACKEND_URL}/health", timeout=5)
|
||||||
|
print(f"Status: {response.status_code}")
|
||||||
|
print(f"Response: {response.json()}")
|
||||||
|
return response.status_code == 200
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_get_products():
|
||||||
|
"""Test get products endpoint"""
|
||||||
|
try:
|
||||||
|
print("\n[TEST 2] Get Products")
|
||||||
|
print(f"URL: {BACKEND_URL}/products")
|
||||||
|
response = requests.get(f"{BACKEND_URL}/products", timeout=5)
|
||||||
|
print(f"Status: {response.status_code}")
|
||||||
|
data = response.json()
|
||||||
|
print(f"Total products: {data.get('total', 0)}")
|
||||||
|
if data.get('products'):
|
||||||
|
print(f"First product: {data['products'][0]}")
|
||||||
|
return response.status_code == 200
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_create_product():
|
||||||
|
"""Test create product endpoint"""
|
||||||
|
try:
|
||||||
|
print("\n[TEST 3] Create Product")
|
||||||
|
print(f"URL: {BACKEND_URL}/products")
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"name": f"Test Produk {datetime.now().strftime('%H%M%S')}",
|
||||||
|
"category": "Test",
|
||||||
|
"price": 10000,
|
||||||
|
"current_stock": 5
|
||||||
|
}
|
||||||
|
print(f"Payload: {json.dumps(payload, indent=2)}")
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
f"{BACKEND_URL}/products",
|
||||||
|
json=payload,
|
||||||
|
headers={"Content-Type": "application/json"},
|
||||||
|
timeout=5
|
||||||
|
)
|
||||||
|
print(f"Status: {response.status_code}")
|
||||||
|
print(f"Response: {response.json()}")
|
||||||
|
return response.status_code in [201, 409]
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("="*80)
|
||||||
|
print(f"Backend Connectivity Test - {BACKEND_URL}")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
tests = [
|
||||||
|
("Health Check", test_health()),
|
||||||
|
("Get Products", test_get_products()),
|
||||||
|
("Create Product", test_create_product()),
|
||||||
|
]
|
||||||
|
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("SUMMARY:")
|
||||||
|
for test_name, result in tests:
|
||||||
|
status = "✅ PASS" if result else "❌ FAIL"
|
||||||
|
print(f" {status}: {test_name}")
|
||||||
|
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
all_passed = all(result for _, result in tests)
|
||||||
|
if all_passed:
|
||||||
|
print("\n✅ Backend is working correctly!")
|
||||||
|
else:
|
||||||
|
print("\n❌ Some tests failed. Check your backend connection.")
|
||||||
Loading…
Reference in New Issue