import 'package:intl/intl.dart'; import '../../inventory/domain/product.dart'; import '../../inventory/domain/inventory_item.dart'; import '../domain/label_document.dart'; class TemplateDataResolver { static final NumberFormat _currencyFormatter = NumberFormat('#,##,##0.##'); /// Resolves a single field value from a Product (and optional InventoryItem) static String? resolveFieldValue({ required String source, required String fieldKey, Product? product, InventoryItem? inventoryItem, }) { if (product == null && inventoryItem == null) return null; if (source == 'product' && product != null) { switch (fieldKey) { case 'name': return product.name; case 'sku': return product.sku ?? (inventoryItem?.tagNumber ?? 'SKU-001'); case 'barcode': return (product.barcode != null && product.barcode!.isNotEmpty) ? product.barcode : (inventoryItem?.tagNumber ?? product.sku ?? '8901234567890'); case 'sellingPrice': final price = product.sellingPrice ?? product.mrp; return price != null ? _currencyFormatter.format(price) : null; case 'mrp': final price = product.mrp ?? product.sellingPrice; return price != null ? _currencyFormatter.format(price) : null; case 'weightInG': final wt = inventoryItem?.grossWeight ?? product.weightInG; return wt?.toStringAsFixed(2); case 'hsnCode': return product.hsnCode; case 'gstRate': return product.gstRate != null ? product.gstRate!.toStringAsFixed(0) : '3'; case 'brandName': return product.brandName; case 'material': return product.material; case 'size': return product.size; case 'color': return product.color; case 'manufacturerCode': return inventoryItem?.huid ?? product.manufacturerCode; case 'purityFactor': if (inventoryItem?.purity != null) return inventoryItem!.purity; return product.purityFactor != null ? '${(product.purityFactor! * 100).toStringAsFixed(1)}%' : null; case 'currentStock': return product.currentStock?.toString(); case 'description': return product.description; default: return null; } } if (source == 'inventory' && inventoryItem != null) { switch (fieldKey) { case 'tagNumber': return inventoryItem.tagNumber; case 'huid': return inventoryItem.huid; case 'grossWeight': return inventoryItem.grossWeight?.toStringAsFixed(3); case 'netWeight': return inventoryItem.netWeight?.toStringAsFixed(3); case 'purity': return inventoryItem.purity; default: return null; } } return null; } /// Resolves an entire LabelDocument against sample data, returning a resolved copy static LabelDocument resolveDocument({ required LabelDocument document, Product? product, InventoryItem? inventoryItem, }) { if (product == null && inventoryItem == null) { return document; } final resolvedElements = []; for (final elem in document.elements) { if (elem is DynamicTextElement) { final rawVal = resolveFieldValue( source: elem.source, fieldKey: elem.fieldKey, product: product, inventoryItem: inventoryItem, ); final formattedText = elem.formatValue(rawVal); resolvedElements.add( TextElement( id: elem.id, xMm: elem.xMm, yMm: elem.yMm, widthMm: elem.widthMm, heightMm: elem.heightMm, rotation: elem.rotation, isLocked: elem.isLocked, zIndex: elem.zIndex, text: formattedText, fontFamily: elem.fontFamily, fontSizePt: elem.fontSizePt, isBold: elem.isBold, isItalic: elem.isItalic, alignment: elem.alignment, borderWidthMm: elem.borderWidthMm, paddingMm: elem.paddingMm, ), ); } else if (elem is BarcodeElement) { if (elem.valueType == 'dynamic') { final resolvedVal = resolveFieldValue( source: elem.source, fieldKey: elem.fieldKey, product: product, inventoryItem: inventoryItem, ) ?? elem.staticValue; final effectiveBarcode = (resolvedVal.isNotEmpty ? resolvedVal : (product?.sku ?? '8901234567890')) .replaceAll(RegExp(r'[^a-zA-Z0-9\-]'), ''); resolvedElements.add( elem.copyWithPosition( valueType: 'static', staticValue: effectiveBarcode.isNotEmpty ? effectiveBarcode : '8901234567890', ), ); } else { resolvedElements.add(elem); } } else if (elem is QrCodeElement) { if (elem.valueType == 'dynamic') { final resolvedVal = resolveFieldValue( source: elem.source, fieldKey: elem.fieldKey, product: product, inventoryItem: inventoryItem, ) ?? elem.staticValue; final effectiveQr = resolvedVal.isNotEmpty ? resolvedVal : (product?.sku ?? '8901234567890'); resolvedElements.add( elem.copyWithPosition( valueType: 'static', staticValue: effectiveQr, ), ); } else { resolvedElements.add(elem); } } else { resolvedElements.add(elem); } } return document.copyWith(elements: resolvedElements); } }