import 'package:flutter/material.dart'; enum MasterFieldType { text, number, boolean, dropdown } const brandTypes = ['OWN', 'OEM', 'THIRD_PARTY']; class MasterFieldDef { const MasterFieldDef({ required this.key, required this.label, this.type = MasterFieldType.text, this.required = false, this.showInList = false, this.optionsMasterKey, this.staticOptions, this.multiline = false, }); final String key; final String label; final MasterFieldType type; final bool required; final bool showInList; /// Master key used to populate dropdown options (e.g. `plants` for plant_id). final String? optionsMasterKey; /// Fixed dropdown choices (e.g. brand type) — no API lookup. final List? staticOptions; final bool multiline; } class MasterDefinition { const MasterDefinition({ required this.id, required this.title, required this.subtitle, required this.category, required this.routeKey, required this.apiPath, required this.module, required this.icon, required this.fields, }); final String id; final String title; final String subtitle; final String category; final String routeKey; final String apiPath; final String module; final IconData icon; final List fields; List get listFields => fields.where((field) => field.showInList).toList(); List get formFields => fields; String listRoute(String base) => '$base/$routeKey'; String addRoute(String base) => '$base/$routeKey/add'; String editRoute(String base, String id) => '$base/$routeKey/$id/edit'; } const _activeField = MasterFieldDef( key: 'is_active', label: 'Active', type: MasterFieldType.boolean, ); MasterDefinition? masterDefinitionById(String id) { for (final def in masterDefinitions) { if (def.id == id) return def; } return null; } MasterDefinition? masterDefinitionByRouteKey(String routeKey) { for (final def in masterDefinitions) { if (def.routeKey == routeKey) return def; } return null; } const masterDefinitions = [ MasterDefinition( id: 'uom', title: 'UOM', subtitle: 'Units of measure', category: 'Inventory & Items', routeKey: 'uom', apiPath: '/masters/uom', module: 'uom', icon: Icons.straighten_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), _activeField, ], ), MasterDefinition( id: 'item_categories', title: 'Item Categories', subtitle: 'Top-level item grouping', category: 'Inventory & Items', routeKey: 'item-categories', apiPath: '/masters/item-categories', module: 'item_categories', icon: Icons.category_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), _activeField, ], ), MasterDefinition( id: 'item_subcategories', title: 'Item Sub Categories', subtitle: 'Sub-grouping under item categories', category: 'Inventory & Items', routeKey: 'item-subcategories', apiPath: '/masters/item-subcategories', module: 'item_subcategories', icon: Icons.subdirectory_arrow_right, fields: [ MasterFieldDef( key: 'item_category_id', label: 'Item Category', type: MasterFieldType.dropdown, required: true, showInList: true, optionsMasterKey: 'item_categories', ), MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), _activeField, ], ), MasterDefinition( id: 'items', title: 'Items', subtitle: 'Material and product master', category: 'Inventory & Items', routeKey: 'items', apiPath: '/masters/items', module: 'items', icon: Icons.inventory_outlined, fields: [ MasterFieldDef(key: 'item_code', label: 'Item Code', required: true, showInList: true), MasterFieldDef(key: 'item_name', label: 'Item Name', required: true, showInList: true), MasterFieldDef( key: 'item_category_id', label: 'Category', type: MasterFieldType.dropdown, required: true, optionsMasterKey: 'item_categories', ), MasterFieldDef( key: 'item_subcategory_id', label: 'Sub Category', type: MasterFieldType.dropdown, optionsMasterKey: 'item_subcategories', ), MasterFieldDef( key: 'uom_id', label: 'UOM', type: MasterFieldType.dropdown, required: true, optionsMasterKey: 'uom', ), MasterFieldDef( key: 'gst_rate_id', label: 'GST Rate', type: MasterFieldType.dropdown, optionsMasterKey: 'gst_rates', ), MasterFieldDef( key: 'brand_id', label: 'Brand', type: MasterFieldType.dropdown, optionsMasterKey: 'brands', ), MasterFieldDef( key: 'is_asset_item', label: 'Asset Item', type: MasterFieldType.boolean, required: true, ), MasterFieldDef( key: 'min_order_qty', label: 'Min Order Qty', type: MasterFieldType.number, required: true, ), MasterFieldDef( key: 'reorder_level', label: 'Reorder Level', type: MasterFieldType.number, required: true, ), MasterFieldDef(key: 'description', label: 'Description', multiline: true), MasterFieldDef(key: 'specification', label: 'Specification', multiline: true), _activeField, ], ), MasterDefinition( id: 'brands', title: 'Brands', subtitle: 'Own and third-party brands', category: 'Inventory & Items', routeKey: 'brands', apiPath: '/masters/brands', module: 'brands', icon: Icons.loyalty_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), MasterFieldDef( key: 'brand_type', label: 'Brand Type', type: MasterFieldType.dropdown, required: true, showInList: true, staticOptions: brandTypes, ), MasterFieldDef(key: 'contact_person', label: 'Contact Person'), MasterFieldDef(key: 'phone', label: 'Phone'), MasterFieldDef(key: 'email', label: 'Email'), _activeField, ], ), MasterDefinition( id: 'document_series', title: 'Document Series', subtitle: 'Numbering series for documents', category: 'Finance & Terms', routeKey: 'document-series', apiPath: '/masters/document-series', module: 'document_series', icon: Icons.numbers_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'prefix', label: 'Prefix', required: true, showInList: true), MasterFieldDef( key: 'current_number', label: 'Current Number', type: MasterFieldType.number, required: true, showInList: true, ), MasterFieldDef( key: 'padding', label: 'Padding', type: MasterFieldType.number, required: true, ), MasterFieldDef(key: 'description', label: 'Description', multiline: true), _activeField, ], ), MasterDefinition( id: 'plants', title: 'Plants', subtitle: 'Manufacturing plants and units', category: 'Organization', routeKey: 'plants', apiPath: '/masters/plants', module: 'plants', icon: Icons.factory_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), MasterFieldDef(key: 'gstin', label: 'GSTIN', showInList: true), MasterFieldDef(key: 'city', label: 'City', showInList: true), MasterFieldDef(key: 'state', label: 'State'), MasterFieldDef(key: 'address', label: 'Address', multiline: true), MasterFieldDef(key: 'pincode', label: 'Pincode'), MasterFieldDef(key: 'phone', label: 'Phone'), _activeField, ], ), MasterDefinition( id: 'warehouses', title: 'Warehouse', subtitle: 'Storage locations by plant', category: 'Organization', routeKey: 'warehouses', apiPath: '/masters/warehouses', module: 'warehouses', icon: Icons.warehouse_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), MasterFieldDef( key: 'plant_id', label: 'Plant', type: MasterFieldType.dropdown, required: true, showInList: true, optionsMasterKey: 'plants', ), MasterFieldDef(key: 'location', label: 'Location'), _activeField, ], ), MasterDefinition( id: 'designations', title: 'Designations', subtitle: 'Employee designations', category: 'Organization', routeKey: 'designations', apiPath: '/masters/designations', module: 'designations', icon: Icons.badge_outlined, fields: [ MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), _activeField, ], ), MasterDefinition( id: 'departments', title: 'Departments', subtitle: 'Organisation departments', category: 'Organization', routeKey: 'departments', apiPath: '/masters/departments', module: 'departments', icon: Icons.apartment_outlined, fields: [ MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), _activeField, ], ), MasterDefinition( id: 'asset_categories', title: 'Asset Categories', subtitle: 'Fixed asset classification', category: 'Assets', routeKey: 'asset-categories', apiPath: '/masters/asset-categories', module: 'asset_categories', icon: Icons.precision_manufacturing_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), MasterFieldDef(key: 'code_prefix', label: 'Code Prefix', required: true, showInList: true), MasterFieldDef( key: 'default_useful_life_years', label: 'Useful Life (Years)', type: MasterFieldType.number, required: true, ), MasterFieldDef( key: 'default_depreciation_method', label: 'Depreciation Method', type: MasterFieldType.dropdown, required: true, showInList: true, optionsMasterKey: 'asset_depreciation_methods', ), _activeField, ], ), MasterDefinition( id: 'asset_subcategories', title: 'Asset Subcategories', subtitle: 'Sub-classification under asset categories', category: 'Assets', routeKey: 'asset-subcategories', apiPath: '/masters/asset-subcategories', module: 'asset_subcategories', icon: Icons.category_outlined, fields: [ MasterFieldDef( key: 'asset_category_id', label: 'Asset Category', type: MasterFieldType.dropdown, required: true, showInList: true, optionsMasterKey: 'asset_categories', ), MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), _activeField, ], ), MasterDefinition( id: 'delivery_terms', title: 'Delivery Terms', subtitle: 'Delivery incoterms and terms', category: 'Finance & Terms', routeKey: 'delivery-terms', apiPath: '/masters/delivery-terms', module: 'delivery_terms', icon: Icons.local_shipping_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), MasterFieldDef(key: 'description', label: 'Description', multiline: true), _activeField, ], ), MasterDefinition( id: 'payment_terms', title: 'Payment Terms', subtitle: 'Vendor payment terms', category: 'Finance & Terms', routeKey: 'payment-terms', apiPath: '/masters/payment-terms', module: 'payment_terms', icon: Icons.payments_outlined, fields: [ MasterFieldDef(key: 'code', label: 'Code', required: true, showInList: true), MasterFieldDef(key: 'name', label: 'Name', required: true, showInList: true), MasterFieldDef( key: 'credit_days', label: 'Credit Days', type: MasterFieldType.number, required: true, showInList: true, ), MasterFieldDef(key: 'description', label: 'Description', multiline: true), _activeField, ], ), MasterDefinition( id: 'gst_rates', title: 'GST Rates', subtitle: 'Tax rate master', category: 'Finance & Terms', routeKey: 'gst-rates', apiPath: '/masters/gst-rates', module: 'gst_rates', icon: Icons.percent_outlined, fields: [ MasterFieldDef( key: 'rate_pct', label: 'Rate (%)', type: MasterFieldType.number, required: true, showInList: true, ), MasterFieldDef(key: 'description', label: 'Description', showInList: true), _activeField, ], ), ]; List get masterCategories => masterDefinitions.map((def) => def.category).toSet().toList(); String masterRecordLabel(Map row) { final ratePct = row['rate_pct']; if (ratePct != null) { final rate = ratePct is num ? ratePct.toDouble() : double.tryParse(ratePct.toString()); if (rate != null) { return rate % 1 == 0 ? '${rate.toInt()}%' : '$rate%'; } } for (final key in ['name', 'item_name', 'code', 'item_code', 'description']) { final value = row[key]; if (value != null && value.toString().trim().isNotEmpty) { return value.toString(); } } return row['id']?.toString() ?? 'Record'; } String masterCellValue(Map row, MasterFieldDef field) { final value = row[field.key]; if (value == null || value == '') return '—'; if (field.type == MasterFieldType.boolean) { return value == true ? 'Yes' : 'No'; } if (field.type == MasterFieldType.dropdown) { final label = row['${field.key}_label']; if (label != null && label.toString().isNotEmpty) return label.toString(); if (field.staticOptions != null) { return value.toString().replaceAll('_', ' '); } } return value.toString(); } String masterStatusValue(Map row) { final active = row['is_active']; if (active == false) return 'inactive'; return 'active'; }