Files
kulakpos_app/lib/Screens/Sales/sales_cart_widget.dart

214 lines
11 KiB
Dart
Raw Permalink Normal View History

2026-02-07 15:57:09 +07:00
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hugeicons/hugeicons.dart';
import 'package:mobile_pos/Screens/Sales/provider/sales_cart_provider.dart';
import 'package:mobile_pos/Screens/Sales/sales_add_to_cart_sales_widget.dart';
import 'package:mobile_pos/constant.dart';
2026-02-08 14:58:52 +07:00
import 'package:mobile_pos/currency.dart';
2026-02-07 15:57:09 +07:00
import 'package:mobile_pos/generated/l10n.dart' as lang;
class SalesCartListWidget extends ConsumerWidget {
const SalesCartListWidget({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final providerData = ref.watch(cartNotifier);
final s = lang.S.of(context);
final _theme = Theme.of(context);
return providerData.cartItemList.isNotEmpty
? Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Theme(
data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
child: ExpansionTile(
initiallyExpanded: true,
collapsedBackgroundColor: kMainColor2,
backgroundColor: kMainColor2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: kLineColor,
width: 1,
),
),
title: Text(
lang.S.of(context).itemAdded,
style: _theme.textTheme.titleMedium,
),
children: [
Container(
color: Colors.white,
child: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: providerData.cartItemList.length,
itemBuilder: (context, index) {
final item = providerData.cartItemList[index];
// Calculate values for display
final double quantity = item.quantity.toDouble();
final double unitPrice = (item.unitPrice ?? 0).toDouble();
final double discountPerUnit = (item.discountAmount ?? 0).toDouble();
final double totalDiscount = quantity * discountPerUnit;
final double subTotal = quantity * unitPrice;
2026-02-08 14:58:52 +07:00
final double originalTotal = unitPrice * quantity;
final double itemVAT = (unitPrice * quantity * (item.perItemTaxPercentage ?? 0)) / 100;
final double finalTotal = originalTotal + itemVAT;
2026-02-07 15:57:09 +07:00
2026-02-08 14:58:52 +07:00
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 10.0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
// 1. Product Name (Clickable to Edit)
GestureDetector(
onTap: () => showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context2) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
s.updateProduct,
style: const TextStyle(fontWeight: FontWeight.bold),
),
CloseButton(
onPressed: () => Navigator.pop(context2),
)
],
),
),
const Divider(thickness: 1, color: kBorderColorTextField),
Padding(
padding: const EdgeInsets.all(16.0),
child: SalesAddToCartForm(
batchWiseStockModel: item,
previousContext: context2,
),
),
],
);
},
),
child: SizedBox(
width: 140,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
2026-02-07 15:57:09 +07:00
children: [
Text(
2026-02-08 14:58:52 +07:00
item.productName.toString(),
style: _theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w500,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
2026-02-07 15:57:09 +07:00
),
2026-02-08 14:58:52 +07:00
if (item.productType == 'variant')
Text(
'[${item.batchName}]',
style: const TextStyle(fontSize: 10, fontStyle: FontStyle.italic, color: Colors.grey),
),
2026-02-07 15:57:09 +07:00
],
),
),
2026-02-08 14:58:52 +07:00
),
const SizedBox(width: 8),
// 2. Decrease Icon
GestureDetector(
onTap: () => providerData.quantityDecrease(index),
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: kMainColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(4),
2026-02-07 15:57:09 +07:00
),
2026-02-08 14:58:52 +07:00
child: const Icon(Icons.remove, size: 16, color: kMainColor),
2026-02-07 15:57:09 +07:00
),
2026-02-08 14:58:52 +07:00
),
const SizedBox(width: 8),
// 3. Qty Order
Text(
formatPointNumber(quantity),
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(width: 8),
// 4. Increase Icon
GestureDetector(
onTap: () => providerData.quantityIncrease(index),
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: kMainColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(4),
),
child: const Icon(Icons.add, size: 16, color: kMainColor),
),
),
const SizedBox(width: 12),
// 5. Value Original
Text(
'$currency${formatPointNumber(originalTotal)}',
style: TextStyle(
2026-02-07 15:57:09 +07:00
color: kPeraColor,
2026-02-08 14:58:52 +07:00
fontSize: 12,
2026-02-07 15:57:09 +07:00
),
),
2026-02-08 14:58:52 +07:00
const SizedBox(width: 8),
// 6. Value VAT/Tax
if (itemVAT > 0) ...[
Text(
'VAT: $currency${formatPointNumber(itemVAT)}',
style: TextStyle(
2026-02-07 15:57:09 +07:00
color: kPeraColor,
2026-02-08 14:58:52 +07:00
fontSize: 10,
2026-02-07 15:57:09 +07:00
),
),
2026-02-08 14:58:52 +07:00
const SizedBox(width: 8),
],
// 7. Sum (Value Original + VAT/Tax)
Text(
'$currency${formatPointNumber(finalTotal)}',
2026-02-07 15:57:09 +07:00
style: _theme.textTheme.titleSmall?.copyWith(
2026-02-08 14:58:52 +07:00
color: kMainColor,
fontWeight: FontWeight.bold,
2026-02-07 15:57:09 +07:00
),
),
2026-02-08 14:58:52 +07:00
const SizedBox(width: 12),
// 8. Delete Icon
GestureDetector(
onTap: () => providerData.deleteToCart(index),
child: HugeIcon(
icon: HugeIcons.strokeRoundedDelete03,
size: 20,
color: Colors.red,
2026-02-07 15:57:09 +07:00
),
2026-02-08 14:58:52 +07:00
),
2026-02-07 15:57:09 +07:00
],
),
),
);
},
),
)
],
),
),
)
: SizedBox.shrink();
}
}