feat: product image and printer type

This commit is contained in:
efrilm 2025-08-03 01:00:33 +07:00
parent 39e3fdc81c
commit e1825fe86f
7 changed files with 108 additions and 93 deletions

View File

@ -991,27 +991,27 @@ class PrintDataoutputs {
: '--------------------------------',
styles: const PosStyles(bold: false, align: PosAlign.center));
bytes += generator.feed(1);
// final kitchenProducts =
// products.where((p) => p.product.printerType == 'kitchen');
// for (final product in kitchenProducts) {
// bytes += generator.text('${product.quantity} x ${product.product.name}',
// styles: const PosStyles(
// align: PosAlign.left,
// bold: false,
// height: PosTextSize.size2,
// width: PosTextSize.size1,
// ));
// if (product.notes.isNotEmpty) {
// bytes += generator.text(' Notes: ${product.notes}',
// styles: const PosStyles(
// align: PosAlign.left,
// bold: false,
// height: PosTextSize.size1,
// width: PosTextSize.size1,
// fontType: PosFontType.fontA,
// ));
// }
// }
final kitchenProducts =
products.where((p) => p.product.printerType == 'kitchen');
for (final product in kitchenProducts) {
bytes += generator.text('${product.quantity} x ${product.product.name}',
styles: const PosStyles(
align: PosAlign.left,
bold: false,
height: PosTextSize.size2,
width: PosTextSize.size1,
));
if (product.notes.isNotEmpty) {
bytes += generator.text(' Notes: ${product.notes}',
styles: const PosStyles(
align: PosAlign.left,
bold: false,
height: PosTextSize.size1,
width: PosTextSize.size1,
fontType: PosFontType.fontA,
));
}
}
bytes += generator.feed(1);
bytes += generator.text(
@ -1105,26 +1105,26 @@ class PrintDataoutputs {
: '--------------------------------',
styles: const PosStyles(bold: false, align: PosAlign.center));
bytes += generator.feed(1);
// final barProducts = products.where((p) => p.product.printerType == 'bar');
// for (final product in barProducts) {
// bytes += generator.text('${product.quantity} x ${product.product.name}',
// styles: const PosStyles(
// align: PosAlign.left,
// bold: false,
// height: PosTextSize.size2,
// width: PosTextSize.size1,
// ));
// if (product.notes.isNotEmpty) {
// bytes += generator.text(' Notes: ${product.notes}',
// styles: const PosStyles(
// align: PosAlign.left,
// bold: false,
// height: PosTextSize.size1,
// width: PosTextSize.size1,
// fontType: PosFontType.fontA,
// ));
// }
// }
final barProducts = products.where((p) => p.product.printerType == 'bar');
for (final product in barProducts) {
bytes += generator.text('${product.quantity} x ${product.product.name}',
styles: const PosStyles(
align: PosAlign.left,
bold: false,
height: PosTextSize.size2,
width: PosTextSize.size1,
));
if (product.notes.isNotEmpty) {
bytes += generator.text(' Notes: ${product.notes}',
styles: const PosStyles(
align: PosAlign.left,
bold: false,
height: PosTextSize.size1,
width: PosTextSize.size1,
fontType: PosFontType.fontA,
));
}
}
bytes += generator.feed(1);
bytes += generator.text(

View File

@ -78,6 +78,8 @@ class Product {
final int? price;
final int? cost;
final String? businessType;
final String? imageUrl;
final String? printerType;
final Map<String, dynamic>? metadata;
final bool? isActive;
final DateTime? createdAt;
@ -94,6 +96,8 @@ class Product {
this.price,
this.cost,
this.businessType,
this.imageUrl,
this.printerType,
this.metadata,
this.isActive,
this.createdAt,
@ -115,6 +119,8 @@ class Product {
price: json["price"],
cost: json["cost"],
businessType: json["business_type"],
imageUrl: json["image_url"],
printerType: json["printer_type"],
metadata: json["metadata"] ?? {},
isActive: json["is_active"],
createdAt: json["created_at"] == null
@ -144,6 +150,8 @@ class Product {
price: json["price"],
cost: json["cost"],
businessType: json["business_type"],
imageUrl: json["image_url"],
printerType: json["printer_type"],
metadata: json["metadata"] ?? {},
isActive: json["is_active"],
createdAt: json["created_at"] == null
@ -168,6 +176,8 @@ class Product {
"price": price,
"cost": cost,
"business_type": businessType,
"image_url": imageUrl,
"printer_type": printerType,
"metadata": metadata,
"is_active": isActive,
"created_at": createdAt?.toIso8601String(),
@ -187,6 +197,8 @@ class Product {
"price": price,
"cost": cost,
"business_type": businessType,
"image_url": imageUrl,
"printer_type": printerType,
"metadata": metadata,
"is_active": isActive,
"created_at": createdAt?.toIso8601String(),
@ -209,6 +221,8 @@ class Product {
other.price == price &&
other.cost == cost &&
other.businessType == businessType &&
other.imageUrl == imageUrl &&
other.printerType == printerType &&
other.metadata == metadata &&
other.isActive == isActive &&
other.createdAt == createdAt &&
@ -237,6 +251,8 @@ class Product {
price.hashCode ^
cost.hashCode ^
businessType.hashCode ^
imageUrl.hashCode ^
printerType.hashCode ^
metadata.hashCode ^
isActive.hashCode ^
createdAt.hashCode ^
@ -254,6 +270,8 @@ class Product {
int? price,
int? cost,
String? businessType,
String? imageUrl,
String? printerType,
Map<String, dynamic>? metadata,
bool? isActive,
DateTime? createdAt,
@ -270,6 +288,8 @@ class Product {
price: price ?? this.price,
cost: cost ?? this.cost,
businessType: businessType ?? this.businessType,
imageUrl: imageUrl ?? this.imageUrl,
printerType: printerType ?? this.printerType,
metadata: metadata ?? this.metadata,
isActive: isActive ?? this.isActive,
createdAt: createdAt ?? this.createdAt,

View File

@ -59,9 +59,10 @@ class _OrderMenuState extends State<OrderMenu> {
// color: AppColors.primary,
// ),
CachedNetworkImage(
imageUrl: widget.data.product.name!.contains('http')
? widget.data.product.name!
: '${Variables.baseUrl}/${widget.data.product.name}',
imageUrl: (widget.data.product.imageUrl ?? '')
.contains('http')
? widget.data.product.imageUrl!
: '${Variables.baseUrl}/${widget.data.product.imageUrl}',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,

View File

@ -42,9 +42,9 @@ class ProductCard extends StatelessWidget {
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
child: CachedNetworkImage(
imageUrl: data.name!.contains('http')
? data.name!
: '${Variables.baseUrl}/${data.name}',
imageUrl: (data.imageUrl ?? "").contains('http')
? data.imageUrl!
: '${Variables.baseUrl}/${data.imageUrl}',
fit: BoxFit.cover,
width: double.infinity,
height: 120,

View File

@ -28,9 +28,9 @@ class DetailProductDialog extends StatelessWidget {
ClipRRect(
borderRadius: BorderRadius.circular(12),
child: CachedNetworkImage(
imageUrl: product.name!.contains('http')
? product.name!
: '${Variables.baseUrl}/${product.name}',
imageUrl: (product.imageUrl ?? "").contains('http')
? product.imageUrl!
: '${Variables.baseUrl}/${product.imageUrl}',
fit: BoxFit.cover,
width: 120,
height: 120,

View File

@ -296,23 +296,20 @@ class _FormProductDialogState extends State<FormProductDialog> {
return;
}
// log("isBestSeller: $isBestSeller");
// final String name = nameController!.text;
// final int stock =
// stockController!.text.toIntegerFromText;
log("isBestSeller: $isBestSeller");
final String name = nameController!.text;
final int stock =
stockController!.text.toIntegerFromText;
// final Product product = widget.product!.copyWith(
// name: name,
// price: priceValue.toString(),
// stock: stock,
// categoryId: selectCategory!.id!,
// isFavorite: isBestSeller ? 1 : 0,
// printerType: printType,
// );
final Product product = widget.product!.copyWith(
name: name,
price: priceValue,
printerType: printType,
);
// context.read<UpdateProductBloc>().add(
// UpdateProductEvent.updateProduct(
// product, imageFile));
context.read<UpdateProductBloc>().add(
UpdateProductEvent.updateProduct(
product, imageFile));
},
label: 'Ubah Produk',
);
@ -354,33 +351,30 @@ class _FormProductDialogState extends State<FormProductDialog> {
orElse: () {
return Button.filled(
onPressed: () {
// if (selectCategory == null) {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Please select a category'),
// backgroundColor: Colors.red,
// ),
// );
// return;
// }
if (selectCategory == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please select a category'),
backgroundColor: Colors.red,
),
);
return;
}
// log("isBestSeller: $isBestSeller");
// final String name = nameController!.text;
log("isBestSeller: $isBestSeller");
final String name = nameController!.text;
// final int stock =
// stockController!.text.toIntegerFromText;
// final Product product = Product(
// name: name,
// price: priceValue.toString(),
// stock: stock,
// categoryId: selectCategory!.id!,
// isFavorite: isBestSeller ? 1 : 0,
// image: imageFile!.path,
// printerType: printType,
// );
// context.read<AddProductBloc>().add(
// AddProductEvent.addProduct(
// product, imageFile!));
final int stock =
stockController!.text.toIntegerFromText;
final Product product = Product(
name: name,
price: priceValue,
imageUrl: imageFile!.path,
printerType: printType,
);
context.read<AddProductBloc>().add(
AddProductEvent.addProduct(
product, imageFile!));
},
label: 'Simpan Produk',
);

View File

@ -36,9 +36,9 @@ class MenuProductItem extends StatelessWidget {
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: CachedNetworkImage(
imageUrl: data.name!.contains('http')
? data.name!
: '${Variables.baseUrl}/${data.name}',
imageUrl: (data.imageUrl ?? '').contains('http')
? data.imageUrl!
: '${Variables.baseUrl}/${data.imageUrl}',
fit: BoxFit.cover,
errorWidget: (context, url, error) => Container(
width: double.infinity,