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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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