feat: product variant

This commit is contained in:
efrilm
2025-08-04 17:42:39 +07:00
parent 04e1edbe79
commit 835c834ce1
18 changed files with 718 additions and 1024 deletions
+21 -11
View File
@@ -95,7 +95,11 @@ class _OrderMenuState extends State<OrderMenu> {
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(widget.data.product.price!.currencyFormatRp),
Text((widget.data.product.price! +
(widget.data.variant?.priceModifier ?? 0))
.currencyFormatRp),
if (widget.data.variant != null)
Text(widget.data.variant?.name ?? ""),
],
),
),
@@ -104,9 +108,8 @@ class _OrderMenuState extends State<OrderMenu> {
children: [
GestureDetector(
onTap: () {
context
.read<CheckoutBloc>()
.add(CheckoutEvent.removeItem(widget.data.product));
context.read<CheckoutBloc>().add(CheckoutEvent.removeItem(
widget.data.product, widget.data.variant));
},
child: Container(
width: 30,
@@ -127,9 +130,12 @@ class _OrderMenuState extends State<OrderMenu> {
),
GestureDetector(
onTap: () {
context
.read<CheckoutBloc>()
.add(CheckoutEvent.addItem(widget.data.product));
context.read<CheckoutBloc>().add(
CheckoutEvent.addItem(
widget.data.product,
widget.data.variant,
),
);
},
child: Container(
width: 30,
@@ -147,7 +153,8 @@ class _OrderMenuState extends State<OrderMenu> {
SizedBox(
width: 80.0,
child: Text(
(widget.data.product.price! * widget.data.quantity)
(widget.data.product.price! * widget.data.quantity +
(widget.data.variant?.priceModifier ?? 0))
.currencyFormatRp,
textAlign: TextAlign.right,
style: const TextStyle(
@@ -179,9 +186,12 @@ class _OrderMenuState extends State<OrderMenu> {
const SpaceWidth(16.0),
GestureDetector(
onTap: () {
context
.read<CheckoutBloc>()
.add(CheckoutEvent.deleteItem(widget.data.product));
context.read<CheckoutBloc>().add(
CheckoutEvent.deleteItem(
widget.data.product,
widget.data.variant,
),
);
},
child: Container(
height: 40,
+41 -35
View File
@@ -1,5 +1,6 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/presentation/home/dialog/variant_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/constants/variables.dart';
@@ -22,7 +23,16 @@ class ProductCard extends StatelessWidget {
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
context.read<CheckoutBloc>().add(CheckoutEvent.addItem(data));
if (data.variants!.isEmpty) {
context.read<CheckoutBloc>().add(
CheckoutEvent.addItem(data, null),
);
} else {
showDialog(
context: context,
builder: (context) => VariantDialog(product: data),
);
}
},
child: Container(
decoration: BoxDecoration(
@@ -114,40 +124,36 @@ class ProductCard extends StatelessWidget {
totalPrice,
draftName,
orderType) {
return products.any((element) => element.product == data)
? products
.firstWhere(
(element) => element.product == data)
.quantity >
0
? Align(
alignment: Alignment.topRight,
child: Container(
width: 40,
height: 40,
padding: const EdgeInsets.all(6),
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(9.0)),
color: AppColors.primary,
),
child: Center(
child: Text(
products
.firstWhere((element) =>
element.product == data)
.quantity
.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
),
)
: SizedBox.shrink()
: SizedBox.shrink();
final totalQuantity = products
.where((item) => item.product.id == data.id)
.map((item) => item.quantity)
.fold(0, (sum, qty) => sum + qty);
if (totalQuantity == 0) {
return const SizedBox.shrink();
}
return Align(
alignment: Alignment.topRight,
child: Container(
width: 40,
height: 40,
padding: const EdgeInsets.all(6),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(9.0)),
color: AppColors.primary,
),
child: Center(
child: Text(
totalQuantity.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
),
);
},
);
},