fix tampilan atau front end laporan
This commit is contained in:
parent
6ad544fb75
commit
97ceebb831
|
|
@ -372,10 +372,12 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ElevatedButton.icon(
|
child: ElevatedButton.icon(
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
Navigator.of(context).pushNamed('/transaction');
|
||||||
|
},
|
||||||
icon: const Icon(Icons.check_circle, size: 20),
|
icon: const Icon(Icons.check_circle, size: 20),
|
||||||
label: const Text(
|
label: const Text(
|
||||||
'Rekomendasi Stok',
|
'Tambah Stok',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|
@ -440,7 +442,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.shopping_cart_outlined),
|
icon: Icon(Icons.shopping_cart_outlined),
|
||||||
label: 'Stock In',
|
label: 'Stok Masuk',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.trending_up_outlined),
|
icon: Icon(Icons.trending_up_outlined),
|
||||||
|
|
|
||||||
|
|
@ -1218,7 +1218,7 @@ class _PredictionScreenState extends State<PredictionScreen> {
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.shopping_cart_outlined),
|
icon: Icon(Icons.shopping_cart_outlined),
|
||||||
label: 'Stock In',
|
label: 'Stok Masuk',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.trending_up_outlined),
|
icon: Icon(Icons.trending_up_outlined),
|
||||||
|
|
|
||||||
|
|
@ -338,7 +338,7 @@ class _ProductListScreenState extends State<ProductListScreen> with RouteAware {
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.shopping_cart_outlined),
|
icon: Icon(Icons.shopping_cart_outlined),
|
||||||
label: 'Stock In',
|
label: 'Stok Masuk',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.trending_up_outlined),
|
icon: Icon(Icons.trending_up_outlined),
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -391,7 +391,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.shopping_cart_outlined),
|
icon: Icon(Icons.shopping_cart_outlined),
|
||||||
label: 'Stock In',
|
label: 'Stok Masuk',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.trending_up_outlined),
|
icon: Icon(Icons.trending_up_outlined),
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ class _TransactionScreenState extends State<TransactionScreen> {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
'⚠️ $successCount/$totalCount Stock In berhasil. Error: $firstError',
|
'⚠️ $successCount/$totalCount Stok Masuk berhasil. Error: $firstError',
|
||||||
),
|
),
|
||||||
backgroundColor: AppColors.statusError,
|
backgroundColor: AppColors.statusError,
|
||||||
),
|
),
|
||||||
|
|
@ -80,7 +80,7 @@ class _TransactionScreenState extends State<TransactionScreen> {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
'✅ $successCount Stock In berhasil disimpan dan stok terupdate!',
|
'✅ $successCount Stok Masuk berhasil disimpan dan stok terupdate!',
|
||||||
),
|
),
|
||||||
backgroundColor: AppColors.statusSuccess,
|
backgroundColor: AppColors.statusSuccess,
|
||||||
),
|
),
|
||||||
|
|
@ -446,7 +446,7 @@ class _TransactionScreenState extends State<TransactionScreen> {
|
||||||
backgroundColor: AppColors.primaryBrown,
|
backgroundColor: AppColors.primaryBrown,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
title: Text(
|
title: Text(
|
||||||
' Stock In',
|
' Stok Masuk',
|
||||||
style: AppTextStyles.headlineLarge.copyWith(color: Colors.white),
|
style: AppTextStyles.headlineLarge.copyWith(color: Colors.white),
|
||||||
),
|
),
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
|
|
@ -765,7 +765,7 @@ class _TransactionScreenState extends State<TransactionScreen> {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
'Tanggal Stock In',
|
'Tanggal Stok Masuk',
|
||||||
style: AppTextStyles.labelLarge.copyWith(
|
style: AppTextStyles.labelLarge.copyWith(
|
||||||
color: AppColors.textPrimary,
|
color: AppColors.textPrimary,
|
||||||
),
|
),
|
||||||
|
|
@ -846,7 +846,7 @@ class _TransactionScreenState extends State<TransactionScreen> {
|
||||||
label: Text(
|
label: Text(
|
||||||
_controller.isLoading
|
_controller.isLoading
|
||||||
? 'Menyimpan...'
|
? 'Menyimpan...'
|
||||||
: 'Simpan Stock In',
|
: 'Simpan Stok Masuk',
|
||||||
style: AppTextStyles.labelLarge,
|
style: AppTextStyles.labelLarge,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -857,7 +857,7 @@ class _TransactionScreenState extends State<TransactionScreen> {
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
],
|
],
|
||||||
Text(
|
Text(
|
||||||
'Riwayat Stock In (${_controller.transactions.length})',
|
'Riwayat Stok Masuk (${_controller.transactions.length})',
|
||||||
style: AppTextStyles.headlineSmall.copyWith(
|
style: AppTextStyles.headlineSmall.copyWith(
|
||||||
color: AppColors.textPrimary,
|
color: AppColors.textPrimary,
|
||||||
),
|
),
|
||||||
|
|
@ -876,7 +876,7 @@ class _TransactionScreenState extends State<TransactionScreen> {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
'Belum ada Stock In',
|
'Belum ada Stok Masuk',
|
||||||
style: AppTextStyles.bodyMedium.copyWith(
|
style: AppTextStyles.bodyMedium.copyWith(
|
||||||
color: AppColors.textSecondary,
|
color: AppColors.textSecondary,
|
||||||
),
|
),
|
||||||
|
|
@ -987,7 +987,7 @@ class _TransactionScreenState extends State<TransactionScreen> {
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.shopping_cart_outlined),
|
icon: Icon(Icons.shopping_cart_outlined),
|
||||||
label: 'Stock In',
|
label: 'Stok Masuk',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.trending_up_outlined),
|
icon: Icon(Icons.trending_up_outlined),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ class MLService {
|
||||||
// API URL - Change based on environment
|
// API URL - Change based on environment
|
||||||
// Untuk emulator Android: 10.0.2.2
|
// Untuk emulator Android: 10.0.2.2
|
||||||
// Untuk device fisik: 192.168.x.x atau 127.0.0.1 kalau local
|
// Untuk device fisik: 192.168.x.x atau 127.0.0.1 kalau local
|
||||||
static const String baseUrl = 'http://10.103.65.129:5000';
|
static const String baseUrl = 'http://192.168.18.30:5000';
|
||||||
|
|
||||||
static const int timeoutSeconds = 30;
|
static const int timeoutSeconds = 30;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ DB_USER = 'root'
|
||||||
DB_PASSWORD = '' # Ganti dengan password MySQL Anda jika ada
|
DB_PASSWORD = '' # Ganti dengan password MySQL Anda jika ada
|
||||||
DB_NAME = 'prediksi_stok_db'
|
DB_NAME = 'prediksi_stok_db'
|
||||||
|
|
||||||
|
# Table names (use backticks for names with spaces)
|
||||||
|
TRANSACTIONS_TABLE = "`Stock In`"
|
||||||
|
|
||||||
def get_db_connection():
|
def get_db_connection():
|
||||||
"""Get MySQL database connection"""
|
"""Get MySQL database connection"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -686,8 +689,8 @@ def save_transaction():
|
||||||
return jsonify({'status': 'error', 'message': 'Database connection failed'}), 500
|
return jsonify({'status': 'error', 'message': 'Database connection failed'}), 500
|
||||||
|
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
cursor.execute("""
|
cursor.execute(f"""
|
||||||
INSERT INTO transactions
|
INSERT INTO {TRANSACTIONS_TABLE}
|
||||||
(product_name, category, quantity, unit_price, total_price, transaction_date)
|
(product_name, category, quantity, unit_price, total_price, transaction_date)
|
||||||
VALUES (%s, %s, %s, %s, %s, %s)
|
VALUES (%s, %s, %s, %s, %s, %s)
|
||||||
""", (
|
""", (
|
||||||
|
|
@ -762,8 +765,8 @@ def add_transaction_with_stock_update():
|
||||||
}), 404
|
}), 404
|
||||||
|
|
||||||
# 2. Save transaction
|
# 2. Save transaction
|
||||||
cursor.execute("""
|
cursor.execute(f"""
|
||||||
INSERT INTO transactions
|
INSERT INTO {TRANSACTIONS_TABLE}
|
||||||
(product_name, category, quantity, unit_price, total_price, transaction_date)
|
(product_name, category, quantity, unit_price, total_price, transaction_date)
|
||||||
VALUES (%s, %s, %s, %s, %s, %s)
|
VALUES (%s, %s, %s, %s, %s, %s)
|
||||||
""", (
|
""", (
|
||||||
|
|
@ -821,7 +824,7 @@ def get_transactions():
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
# Build query
|
# Build query
|
||||||
query = "SELECT * FROM transactions WHERE 1=1"
|
query = f"SELECT * FROM {TRANSACTIONS_TABLE} WHERE 1=1"
|
||||||
params = []
|
params = []
|
||||||
|
|
||||||
if product_name:
|
if product_name:
|
||||||
|
|
@ -835,7 +838,7 @@ def get_transactions():
|
||||||
transactions = cursor.fetchall()
|
transactions = cursor.fetchall()
|
||||||
|
|
||||||
# Get total count
|
# Get total count
|
||||||
cursor.execute("SELECT COUNT(*) as total FROM transactions" +
|
cursor.execute(f"SELECT COUNT(*) as total FROM {TRANSACTIONS_TABLE}" +
|
||||||
(" WHERE product_name LIKE %s" if product_name else ""),
|
(" WHERE product_name LIKE %s" if product_name else ""),
|
||||||
([f"%{product_name}%"] if product_name else []))
|
([f"%{product_name}%"] if product_name else []))
|
||||||
total = cursor.fetchone()['total']
|
total = cursor.fetchone()['total']
|
||||||
|
|
|
||||||
16
pubspec.lock
16
pubspec.lock
|
|
@ -49,6 +49,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
version: "1.0.8"
|
||||||
|
equatable:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: equatable
|
||||||
|
sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.8"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -57,6 +65,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.2"
|
||||||
|
fl_chart:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: fl_chart
|
||||||
|
sha256: "00b74ae680df6b1135bdbea00a7d1fc072a9180b7c3f3702e4b19a9943f5ed7d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.66.2"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ dependencies:
|
||||||
# Intl untuk date formatting
|
# Intl untuk date formatting
|
||||||
intl: ^0.19.0
|
intl: ^0.19.0
|
||||||
|
|
||||||
|
# Charts
|
||||||
|
fl_chart: ^0.66.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue