2025-08-15 01:12:04 +07:00
|
|
|
class InventoryAnalyticResponseModel {
|
|
|
|
|
final bool success;
|
|
|
|
|
final InventoryAnalyticData? data;
|
|
|
|
|
final dynamic errors;
|
|
|
|
|
|
|
|
|
|
InventoryAnalyticResponseModel({
|
|
|
|
|
required this.success,
|
|
|
|
|
required this.data,
|
|
|
|
|
this.errors,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// From JSON
|
|
|
|
|
factory InventoryAnalyticResponseModel.fromJson(Map<String, dynamic> json) {
|
|
|
|
|
return InventoryAnalyticResponseModel(
|
|
|
|
|
success: json['success'],
|
|
|
|
|
data: json['data'] != null
|
|
|
|
|
? InventoryAnalyticData.fromMap(json['data'])
|
|
|
|
|
: null,
|
|
|
|
|
errors: json['errors'],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// To JSON
|
|
|
|
|
Map<String, dynamic> toJson() {
|
|
|
|
|
return {
|
|
|
|
|
'success': success,
|
|
|
|
|
'data': data?.toMap(),
|
|
|
|
|
'errors': errors,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// From Map
|
|
|
|
|
factory InventoryAnalyticResponseModel.fromMap(Map<String, dynamic> map) {
|
|
|
|
|
return InventoryAnalyticResponseModel(
|
|
|
|
|
success: map['success'],
|
|
|
|
|
data: map['data'] != null
|
|
|
|
|
? InventoryAnalyticData.fromMap(map['data'])
|
|
|
|
|
: null,
|
|
|
|
|
errors: map['errors'],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// To Map
|
|
|
|
|
Map<String, dynamic> toMap() {
|
|
|
|
|
return {
|
|
|
|
|
'success': success,
|
|
|
|
|
'data': data?.toMap(),
|
|
|
|
|
'errors': errors,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class InventoryAnalyticData {
|
|
|
|
|
final InventorySummary summary;
|
|
|
|
|
final List<InventoryProductItem> products;
|
|
|
|
|
final List<InventoryIngredientItem> ingredients;
|
|
|
|
|
|
|
|
|
|
InventoryAnalyticData({
|
|
|
|
|
required this.summary,
|
|
|
|
|
required this.products,
|
|
|
|
|
required this.ingredients,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
factory InventoryAnalyticData.fromMap(Map<String, dynamic> map) {
|
|
|
|
|
return InventoryAnalyticData(
|
|
|
|
|
summary: InventorySummary.fromMap(map['summary']),
|
|
|
|
|
products: map['products'] == null
|
|
|
|
|
? []
|
|
|
|
|
: List<InventoryProductItem>.from(
|
|
|
|
|
map['products']?.map((x) => InventoryProductItem.fromMap(x)) ??
|
|
|
|
|
[],
|
|
|
|
|
),
|
|
|
|
|
ingredients: map['ingredients'] == null
|
|
|
|
|
? []
|
|
|
|
|
: List<InventoryIngredientItem>.from(
|
|
|
|
|
map['ingredients']
|
|
|
|
|
?.map((x) => InventoryIngredientItem.fromMap(x)) ??
|
|
|
|
|
[],
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, dynamic> toMap() {
|
|
|
|
|
return {
|
|
|
|
|
'summary': summary.toMap(),
|
|
|
|
|
'products': products.map((x) => x.toMap()).toList(),
|
|
|
|
|
'ingredients': ingredients.map((x) => x.toMap()).toList(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class InventorySummary {
|
|
|
|
|
final int totalProducts;
|
|
|
|
|
final int totalIngredients;
|
|
|
|
|
final int totalValue;
|
|
|
|
|
final int lowStockProducts;
|
|
|
|
|
final int lowStockIngredients;
|
|
|
|
|
final int zeroStockProducts;
|
|
|
|
|
final int zeroStockIngredients;
|
|
|
|
|
final int totalSoldProducts;
|
|
|
|
|
final int totalSoldIngredients;
|
|
|
|
|
final String outletId;
|
|
|
|
|
final String outletName;
|
|
|
|
|
final DateTime generatedAt;
|
|
|
|
|
|
|
|
|
|
InventorySummary({
|
|
|
|
|
required this.totalProducts,
|
|
|
|
|
required this.totalIngredients,
|
|
|
|
|
required this.totalValue,
|
|
|
|
|
required this.lowStockProducts,
|
|
|
|
|
required this.lowStockIngredients,
|
|
|
|
|
required this.zeroStockProducts,
|
|
|
|
|
required this.zeroStockIngredients,
|
|
|
|
|
required this.totalSoldProducts,
|
|
|
|
|
required this.totalSoldIngredients,
|
|
|
|
|
required this.outletId,
|
|
|
|
|
required this.outletName,
|
|
|
|
|
required this.generatedAt,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
factory InventorySummary.fromMap(Map<String, dynamic> map) {
|
|
|
|
|
return InventorySummary(
|
|
|
|
|
totalProducts: map['total_products'] ?? 0,
|
|
|
|
|
totalIngredients: map['total_ingredients'] ?? 0,
|
|
|
|
|
totalValue: map['total_value'] ?? 0,
|
|
|
|
|
lowStockProducts: map['low_stock_products'] ?? 0,
|
|
|
|
|
lowStockIngredients: map['low_stock_ingredients'] ?? 0,
|
|
|
|
|
zeroStockProducts: map['zero_stock_products'] ?? 0,
|
|
|
|
|
zeroStockIngredients: map['zero_stock_ingredients'] ?? 0,
|
|
|
|
|
totalSoldProducts: map['total_sold_products'] ?? 0,
|
|
|
|
|
totalSoldIngredients: map['total_sold_ingredients'] ?? 0,
|
|
|
|
|
outletId: map['outlet_id'],
|
|
|
|
|
outletName: map['outlet_name'],
|
|
|
|
|
generatedAt: DateTime.parse(map['generated_at']),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, dynamic> toMap() {
|
|
|
|
|
return {
|
|
|
|
|
'total_products': totalProducts,
|
|
|
|
|
'total_ingredients': totalIngredients,
|
|
|
|
|
'total_value': totalValue,
|
|
|
|
|
'low_stock_products': lowStockProducts,
|
|
|
|
|
'low_stock_ingredients': lowStockIngredients,
|
|
|
|
|
'zero_stock_products': zeroStockProducts,
|
|
|
|
|
'zero_stock_ingredients': zeroStockIngredients,
|
|
|
|
|
'total_sold_products': totalSoldProducts,
|
|
|
|
|
'total_sold_ingredients': totalSoldIngredients,
|
|
|
|
|
'outlet_id': outletId,
|
|
|
|
|
'outlet_name': outletName,
|
|
|
|
|
'generated_at': generatedAt.toIso8601String(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class InventoryProductItem {
|
|
|
|
|
final String id;
|
|
|
|
|
final String productId;
|
|
|
|
|
final String productName;
|
|
|
|
|
final String categoryName;
|
|
|
|
|
final int quantity;
|
|
|
|
|
final int reorderLevel;
|
2025-09-19 19:12:35 +07:00
|
|
|
final num unitCost;
|
2025-08-15 01:12:04 +07:00
|
|
|
final int totalValue;
|
|
|
|
|
final int totalIn;
|
|
|
|
|
final int totalOut;
|
|
|
|
|
final bool isLowStock;
|
|
|
|
|
final bool isZeroStock;
|
|
|
|
|
final DateTime updatedAt;
|
|
|
|
|
|
|
|
|
|
InventoryProductItem({
|
|
|
|
|
required this.id,
|
|
|
|
|
required this.productId,
|
|
|
|
|
required this.productName,
|
|
|
|
|
required this.categoryName,
|
|
|
|
|
required this.quantity,
|
|
|
|
|
required this.reorderLevel,
|
|
|
|
|
required this.unitCost,
|
|
|
|
|
required this.totalValue,
|
|
|
|
|
required this.totalIn,
|
|
|
|
|
required this.totalOut,
|
|
|
|
|
required this.isLowStock,
|
|
|
|
|
required this.isZeroStock,
|
|
|
|
|
required this.updatedAt,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
factory InventoryProductItem.fromMap(Map<String, dynamic> map) {
|
|
|
|
|
return InventoryProductItem(
|
|
|
|
|
id: map['id'],
|
|
|
|
|
productId: map['product_id'],
|
|
|
|
|
productName: map['product_name'],
|
|
|
|
|
categoryName: map['category_name'],
|
|
|
|
|
quantity: map['quantity'] ?? 0,
|
|
|
|
|
reorderLevel: map['reorder_level'] ?? 0,
|
|
|
|
|
unitCost: map['unit_cost'] ?? 0,
|
|
|
|
|
totalValue: map['total_value'] ?? 0,
|
|
|
|
|
totalIn: map['total_in'] ?? 0,
|
|
|
|
|
totalOut: map['total_out'] ?? 0,
|
|
|
|
|
isLowStock: map['is_low_stock'] ?? false,
|
|
|
|
|
isZeroStock: map['is_zero_stock'] ?? false,
|
|
|
|
|
updatedAt: DateTime.parse(map['updated_at']),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, dynamic> toMap() {
|
|
|
|
|
return {
|
|
|
|
|
'id': id,
|
|
|
|
|
'product_id': productId,
|
|
|
|
|
'product_name': productName,
|
|
|
|
|
'category_name': categoryName,
|
|
|
|
|
'quantity': quantity,
|
|
|
|
|
'reorder_level': reorderLevel,
|
|
|
|
|
'unit_cost': unitCost,
|
|
|
|
|
'total_value': totalValue,
|
|
|
|
|
'total_in': totalIn,
|
|
|
|
|
'total_out': totalOut,
|
|
|
|
|
'is_low_stock': isLowStock,
|
|
|
|
|
'is_zero_stock': isZeroStock,
|
|
|
|
|
'updated_at': updatedAt.toIso8601String(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class InventoryIngredientItem {
|
|
|
|
|
final String id;
|
|
|
|
|
final String ingredientId;
|
|
|
|
|
final String ingredientName;
|
|
|
|
|
final String unitName;
|
|
|
|
|
final int quantity;
|
|
|
|
|
final int reorderLevel;
|
2025-09-19 19:12:35 +07:00
|
|
|
final num unitCost;
|
2025-08-15 01:12:04 +07:00
|
|
|
final int totalValue;
|
|
|
|
|
final int totalIn;
|
|
|
|
|
final int totalOut;
|
|
|
|
|
final bool isLowStock;
|
|
|
|
|
final bool isZeroStock;
|
|
|
|
|
final DateTime updatedAt;
|
|
|
|
|
|
|
|
|
|
InventoryIngredientItem({
|
|
|
|
|
required this.id,
|
|
|
|
|
required this.ingredientId,
|
|
|
|
|
required this.ingredientName,
|
|
|
|
|
required this.unitName,
|
|
|
|
|
required this.quantity,
|
|
|
|
|
required this.reorderLevel,
|
|
|
|
|
required this.unitCost,
|
|
|
|
|
required this.totalValue,
|
|
|
|
|
required this.totalIn,
|
|
|
|
|
required this.totalOut,
|
|
|
|
|
required this.isLowStock,
|
|
|
|
|
required this.isZeroStock,
|
|
|
|
|
required this.updatedAt,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
factory InventoryIngredientItem.fromMap(Map<String, dynamic> map) {
|
|
|
|
|
return InventoryIngredientItem(
|
|
|
|
|
id: map['id'],
|
|
|
|
|
ingredientId: map['ingredient_id'],
|
|
|
|
|
ingredientName: map['ingredient_name'],
|
|
|
|
|
unitName: map['unit_name'],
|
|
|
|
|
quantity: map['quantity'] ?? 0,
|
|
|
|
|
reorderLevel: map['reorder_level'] ?? 0,
|
|
|
|
|
unitCost: map['unit_cost'] ?? 0,
|
|
|
|
|
totalValue: map['total_value'] ?? 0,
|
|
|
|
|
totalIn: map['total_in'] ?? 0,
|
|
|
|
|
totalOut: map['total_out'] ?? 0,
|
|
|
|
|
isLowStock: map['is_low_stock'] ?? false,
|
|
|
|
|
isZeroStock: map['is_zero_stock'] ?? false,
|
|
|
|
|
updatedAt: DateTime.parse(map['updated_at']),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, dynamic> toMap() {
|
|
|
|
|
return {
|
|
|
|
|
'id': id,
|
|
|
|
|
'ingredient_id': ingredientId,
|
|
|
|
|
'ingredient_name': ingredientName,
|
|
|
|
|
'unit_name': unitName,
|
|
|
|
|
'quantity': quantity,
|
|
|
|
|
'reorder_level': reorderLevel,
|
|
|
|
|
'unit_cost': unitCost,
|
|
|
|
|
'total_value': totalValue,
|
|
|
|
|
'total_in': totalIn,
|
|
|
|
|
'total_out': totalOut,
|
|
|
|
|
'is_low_stock': isLowStock,
|
|
|
|
|
'is_zero_stock': isZeroStock,
|
|
|
|
|
'updated_at': updatedAt.toIso8601String(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|