bharat_erp/lib/shared/models/grn_model.dart

191 lines
7.1 KiB
Dart

import 'package:freezed_annotation/freezed_annotation.dart';
part 'grn_model.freezed.dart';
part 'grn_model.g.dart';
String _idFromJson(Object? value) => value?.toString() ?? '';
int? _intFromJsonNullable(Object? value) {
if (value == null) return null;
if (value is int) return value;
if (value is num) return value.toInt();
return int.tryParse(value.toString());
}
double? _doubleFromJsonNullable(Object? value) {
if (value == null) return null;
if (value is double) return value;
if (value is num) return value.toDouble();
return double.tryParse(value.toString());
}
DateTime? _dateFromJsonNullable(Object? value) {
if (value == null) return null;
if (value is DateTime) return value;
return DateTime.tryParse(value.toString());
}
Object? _readNestedName(Map<dynamic, dynamic> json, String flatKey, String nestedKey) {
final flat = json[flatKey];
if (flat is String && flat.isNotEmpty) return flat;
final nested = json[nestedKey];
if (nested is Map) {
return nested['name'] ?? nested['vendor_name'];
}
return null;
}
Object? _readVendorName(Map<dynamic, dynamic> json, String key) =>
_readNestedName(json, 'vendor_name', 'vendor');
Object? _readWarehouseName(Map<dynamic, dynamic> json, String key) =>
_readNestedName(json, 'warehouse_name', 'warehouse');
Object? _readPoNumber(Map<dynamic, dynamic> json, String key) {
final grnNumber = json['grn_number'];
if (grnNumber != null && grnNumber.toString().trim().isNotEmpty) {
return grnNumber.toString();
}
final grnNo = json['grn_no'];
if (grnNo != null && grnNo.toString().trim().isNotEmpty) {
return grnNo.toString();
}
return null;
}
Object? _readPoRefNumber(Map<dynamic, dynamic> json, String key) {
final flat = json['po_number'];
if (flat is String && flat.isNotEmpty) return flat;
final nested = json['purchase_order'] ?? json['po'];
if (nested is Map) {
return nested['po_number'] ?? nested['po_no'];
}
return null;
}
Object? _readItemName(Map<dynamic, dynamic> json, String key) {
final flat = json['item_name'];
if (flat is String && flat.isNotEmpty) return flat;
final nested = json['item'];
if (nested is Map) return nested['name'] ?? nested['item_name'];
return null;
}
Object? _readItemCode(Map<dynamic, dynamic> json, String key) {
final flat = json['item_code'];
if (flat is String && flat.isNotEmpty) return flat;
final nested = json['item'];
if (nested is Map) return nested['code'] ?? nested['item_code'];
return null;
}
Object? _readUomName(Map<dynamic, dynamic> json, String key) {
final flat = json['uom_name'];
if (flat is String && flat.isNotEmpty) return flat;
final nested = json['uom'];
if (nested is Map) return nested['name'];
return null;
}
@freezed
class GrnModel with _$GrnModel {
const GrnModel._();
const factory GrnModel({
@JsonKey(fromJson: _idFromJson) required String id,
@JsonKey(name: 'grn_number', readValue: _readPoNumber) String? grnNumber,
@JsonKey(name: 'grn_date', fromJson: _dateFromJsonNullable) DateTime? grnDate,
@Default('POSTED') String status,
@JsonKey(name: 'po_id', fromJson: _intFromJsonNullable) int? poId,
@JsonKey(name: 'po_number', readValue: _readPoRefNumber) String? poNumber,
@JsonKey(name: 'vendor_id', fromJson: _intFromJsonNullable) int? vendorId,
@JsonKey(name: 'vendor_name', readValue: _readVendorName) String? vendorName,
@JsonKey(name: 'warehouse_id', fromJson: _intFromJsonNullable) int? warehouseId,
@JsonKey(name: 'warehouse_name', readValue: _readWarehouseName) String? warehouseName,
@JsonKey(name: 'vendor_invoice_no') String? vendorInvoiceNo,
@JsonKey(name: 'vendor_invoice_date', fromJson: _dateFromJsonNullable)
DateTime? vendorInvoiceDate,
@JsonKey(name: 'vendor_invoice_amount', fromJson: _doubleFromJsonNullable)
double? vendorInvoiceAmount,
@JsonKey(name: 'vehicle_no') String? vehicleNo,
@JsonKey(name: 'lr_no') String? lrNo,
@JsonKey(name: 'lr_date', fromJson: _dateFromJsonNullable) DateTime? lrDate,
@JsonKey(name: 'received_by', fromJson: _intFromJsonNullable) int? receivedBy,
@JsonKey(name: 'quality_checked_by', fromJson: _intFromJsonNullable)
int? qualityCheckedBy,
String? remarks,
@JsonKey(name: 'cancellation_reason') String? cancellationReason,
@JsonKey(name: 'created_at', fromJson: _dateFromJsonNullable) DateTime? createdAt,
@JsonKey(name: 'updated_at', fromJson: _dateFromJsonNullable) DateTime? updatedAt,
@Default([]) List<GrnItemModel> items,
}) = _GrnModel;
factory GrnModel.fromJson(Map<String, dynamic> json) => _$GrnModelFromJson(json);
bool get canEdit => status.toUpperCase() == 'POSTED';
bool get canCancel => status.toUpperCase() == 'POSTED';
}
@freezed
class GrnItemModel with _$GrnItemModel {
const factory GrnItemModel({
@JsonKey(fromJson: _idFromJson) required String id,
@JsonKey(name: 'grn_id', fromJson: _idFromJson) String? grnId,
@JsonKey(name: 'po_item_id', fromJson: _intFromJsonNullable) int? poItemId,
@JsonKey(name: 'item_id', fromJson: _intFromJsonNullable) int? itemId,
@JsonKey(name: 'item_code', readValue: _readItemCode) String? itemCode,
@JsonKey(name: 'item_name', readValue: _readItemName) String? itemName,
@JsonKey(name: 'line_no', fromJson: _intFromJsonNullable) int? lineNo,
@JsonKey(name: 'current_qty', fromJson: _doubleFromJsonNullable) double? currentQty,
@JsonKey(name: 'accepted_qty', fromJson: _doubleFromJsonNullable) double? acceptedQty,
@JsonKey(name: 'damaged_qty', fromJson: _doubleFromJsonNullable) double? damagedQty,
@JsonKey(name: 'short_qty', fromJson: _doubleFromJsonNullable) double? shortQty,
@JsonKey(name: 'excess_qty', fromJson: _doubleFromJsonNullable) double? excessQty,
@JsonKey(name: 'rejected_qty', fromJson: _doubleFromJsonNullable) double? rejectedQty,
@JsonKey(name: 'rejection_reason') String? rejectionReason,
@JsonKey(fromJson: _doubleFromJsonNullable) double? rate,
@JsonKey(name: 'batch_no') String? batchNo,
@JsonKey(name: 'mfg_date', fromJson: _dateFromJsonNullable) DateTime? mfgDate,
@JsonKey(name: 'expiry_date', fromJson: _dateFromJsonNullable) DateTime? expiryDate,
@JsonKey(name: 'storage_location') String? storageLocation,
@JsonKey(name: 'asset_category_id', fromJson: _intFromJsonNullable)
int? assetCategoryId,
@JsonKey(name: 'uom_id', fromJson: _intFromJsonNullable) int? uomId,
@JsonKey(name: 'uom_name', readValue: _readUomName) String? uomName,
String? remarks,
}) = _GrnItemModel;
factory GrnItemModel.fromJson(Map<String, dynamic> json) =>
_$GrnItemModelFromJson(json);
}
@freezed
class GrnListQuery with _$GrnListQuery {
const factory GrnListQuery({
@Default(1) int page,
@Default(20) int limit,
String? search,
String? status,
int? poId,
int? vendorId,
int? warehouseId,
String? dateFrom,
String? dateTo,
}) = _GrnListQuery;
}
const grnStatusOptions = [
('POSTED', 'Posted'),
('CANCELLED', 'Cancelled'),
];
String grnStatusLabel(String? value) {
if (value == null) return '';
return grnStatusOptions
.where((e) => e.$1 == value.toUpperCase())
.map((e) => e.$2)
.firstOrNull ??
value.replaceAll('_', ' ');
}