diff --git a/lib/screens/prediction/prediction_controller.dart b/lib/screens/prediction/prediction_controller.dart index f9a539d..373b8e6 100644 --- a/lib/screens/prediction/prediction_controller.dart +++ b/lib/screens/prediction/prediction_controller.dart @@ -387,8 +387,8 @@ class PredictionController extends ChangeNotifier { } String formatQuantityWithUnit(double amount, String unit) { - final displayUnit = _displayUnitLabel(unit); - return '${formatQuantity(amount)} $displayUnit'; + final display = _displayQuantity(amount, unit); + return '${formatQuantity(display['value'] as double)} ${display['unit'] as String}'; } String formatStockQuantity(String ingredient, double value) { @@ -415,14 +415,46 @@ class PredictionController extends ChangeNotifier { String _displayUnitLabel(String unit) { final normalized = _normalizeUnit(unit); - if (normalized == 'gr') return 'kg'; - if (normalized == 'ml') return 'L'; + if (normalized == 'gr') return 'gr'; + if (normalized == 'ml') return 'ml'; if (normalized == 'l') return 'L'; if (normalized == 'kg') return 'kg'; if (normalized == 'butir') return 'butir'; return unit.trim().isEmpty ? 'unit' : unit.trim(); } + Map _displayQuantity(double amount, String unit) { + final normalized = _normalizeUnit(unit); + + if (normalized == 'gr') { + if (amount >= 1000) { + return {'value': amount / 1000, 'unit': 'kg'}; + } + return {'value': amount, 'unit': 'gr'}; + } + + if (normalized == 'ml') { + if (amount >= 1000) { + return {'value': amount / 1000, 'unit': 'L'}; + } + return {'value': amount, 'unit': 'ml'}; + } + + if (normalized == 'l') { + return {'value': amount, 'unit': 'L'}; + } + + if (normalized == 'butir') { + return {'value': amount, 'unit': 'butir'}; + } + + if (normalized == 'kg') { + return {'value': amount, 'unit': 'kg'}; + } + + return {'value': amount, 'unit': _displayUnitLabel(unit)}; + } + double _toDouble(dynamic value) { if (value is num) return value.toDouble(); return double.tryParse(value?.toString() ?? '') ?? 0; diff --git a/lib/screens/products/product_list_controller.dart b/lib/screens/products/product_list_controller.dart index b52415b..78a9789 100644 --- a/lib/screens/products/product_list_controller.dart +++ b/lib/screens/products/product_list_controller.dart @@ -156,20 +156,52 @@ class ProductListController extends ChangeNotifier { } String formatQuantityWithUnit(double amount, String rawUnit) { - final displayUnit = _displayUnitLabel(rawUnit); - return '${formatStock(amount)} $displayUnit'; + final display = _displayQuantity(amount, rawUnit); + return '${formatStock(display['value'] as double)} ${display['unit'] as String}'; } String _displayUnitLabel(String unit) { final normalized = _normalizeUnit(unit); if (normalized == 'pcs' || normalized == 'butir') return 'pcs'; - if (normalized == 'gr') return 'kg'; - if (normalized == 'ml') return 'L'; + if (normalized == 'gr') return 'gr'; + if (normalized == 'ml') return 'ml'; if (normalized == 'l') return 'L'; if (normalized == 'kg') return 'kg'; return unit.trim().isEmpty ? 'kg' : unit.trim(); } + Map _displayQuantity(double amount, String unit) { + final normalized = _normalizeUnit(unit); + + if (normalized == 'gr') { + if (amount >= 1000) { + return {'value': amount / 1000, 'unit': 'kg'}; + } + return {'value': amount, 'unit': 'gr'}; + } + + if (normalized == 'ml') { + if (amount >= 1000) { + return {'value': amount / 1000, 'unit': 'L'}; + } + return {'value': amount, 'unit': 'ml'}; + } + + if (normalized == 'l') { + return {'value': amount, 'unit': 'L'}; + } + + if (normalized == 'pcs' || normalized == 'butir') { + return {'value': amount, 'unit': 'pcs'}; + } + + if (normalized == 'kg') { + return {'value': amount, 'unit': 'kg'}; + } + + return {'value': amount, 'unit': _displayUnitLabel(unit)}; + } + String _normalizeUnit(String unit) { final normalized = unit.trim().toLowerCase(); if (['g', 'gr', 'gram', 'grams'].contains(normalized)) return 'gr'; diff --git a/test/widget_test.dart b/test/widget_test.dart index 017f684..b369580 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -1,30 +1,18 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:finalproject/main.dart'; +import 'package:finalproject/theme/app_theme.dart'; void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); + testWidgets('App theme builds', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + theme: AppTheme.lightTheme(), + home: const Scaffold(body: Center(child: Text('ok'))), + ), + ); - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); + expect(find.text('ok'), findsOneWidget); + expect(find.byType(Scaffold), findsOneWidget); }); }