update keep alive filter
This commit is contained in:
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:hive_ce/hive.dart';
|
||||
|
||||
import 'package:worker/core/constants/api_constants.dart';
|
||||
import 'package:worker/core/constants/storage_constants.dart';
|
||||
import 'package:worker/features/products/domain/entities/product.dart';
|
||||
|
||||
@@ -141,61 +142,101 @@ class ProductModel extends HiveObject {
|
||||
///
|
||||
/// Maps Frappe Item doctype fields to our ProductModel structure.
|
||||
/// Frappe fields:
|
||||
/// - name: Item code (e.g., "GIB20 G02")
|
||||
/// - name: Item code (e.g., "CHG S01P")
|
||||
/// - item_name: Display name
|
||||
/// - description: Product description
|
||||
/// - standard_rate: Price
|
||||
/// - price: Price (from product detail API)
|
||||
/// - standard_rate: Price (from product list API)
|
||||
/// - stock_uom: Unit of measurement
|
||||
/// - image: Image path
|
||||
/// - thumbnail: Thumbnail image path
|
||||
/// - thumbnail: Thumbnail image URL
|
||||
/// - image_list: Array of images with image_url
|
||||
/// - brand: Brand name
|
||||
/// - item_group: Category/group
|
||||
/// - item_group_name: Category/group name
|
||||
/// - custom_link_360: Custom 360 view link
|
||||
/// - attributes: Array of product attributes (Size, Color, Surface, etc.)
|
||||
factory ProductModel.fromFrappeJson(Map<String, dynamic> json) {
|
||||
// Handle image - prepend base URL if needed
|
||||
String? imageUrl;
|
||||
if (json['image'] != null && (json['image'] as String).isNotEmpty) {
|
||||
final imagePath = json['image'] as String;
|
||||
if (imagePath.startsWith('/')) {
|
||||
imageUrl = 'https://land.dbiz.com$imagePath';
|
||||
} else if (imagePath.startsWith('http')) {
|
||||
imageUrl = imagePath;
|
||||
} else {
|
||||
imageUrl = 'https://land.dbiz.com/$imagePath';
|
||||
}
|
||||
}
|
||||
|
||||
// Handle thumbnail - prepend base URL if needed
|
||||
String? thumbnailUrl;
|
||||
if (json['thumbnail'] != null && (json['thumbnail'] as String).isNotEmpty) {
|
||||
final thumbnailPath = json['thumbnail'] as String;
|
||||
if (thumbnailPath.startsWith('/')) {
|
||||
thumbnailUrl = 'https://land.dbiz.com$thumbnailPath';
|
||||
thumbnailUrl = '${ApiConstants.baseUrl}$thumbnailPath';
|
||||
} else if (thumbnailPath.startsWith('http')) {
|
||||
thumbnailUrl = thumbnailPath;
|
||||
} else {
|
||||
thumbnailUrl = 'https://land.dbiz.com/$thumbnailPath';
|
||||
thumbnailUrl = '${ApiConstants.baseUrl}/$thumbnailPath';
|
||||
}
|
||||
}
|
||||
|
||||
// Convert single image to list format
|
||||
final imagesList = imageUrl != null ? [imageUrl] : [];
|
||||
// Handle image_list array (from product detail API)
|
||||
final List<String> imagesList = [];
|
||||
final Map<String, String> imageCaptionsMap = {};
|
||||
|
||||
if (json['image_list'] != null && json['image_list'] is List) {
|
||||
final imageListData = json['image_list'] as List;
|
||||
for (final imgData in imageListData) {
|
||||
if (imgData is Map<String, dynamic> && imgData['image_url'] != null) {
|
||||
final imageUrl = imgData['image_url'] as String;
|
||||
imagesList.add(imageUrl);
|
||||
|
||||
// Store image caption (image_name: A, B, C, etc.)
|
||||
if (imgData['image_name'] != null) {
|
||||
imageCaptionsMap[imageUrl] = imgData['image_name'] as String;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback to single image field (from product list API)
|
||||
else if (json['image'] != null && (json['image'] as String).isNotEmpty) {
|
||||
final imagePath = json['image'] as String;
|
||||
String imageUrl;
|
||||
if (imagePath.startsWith('/')) {
|
||||
imageUrl = '${ApiConstants.baseUrl}$imagePath';
|
||||
} else if (imagePath.startsWith('http')) {
|
||||
imageUrl = imagePath;
|
||||
} else {
|
||||
imageUrl = '${ApiConstants.baseUrl}/$imagePath';
|
||||
}
|
||||
imagesList.add(imageUrl);
|
||||
}
|
||||
|
||||
// Parse attributes array into specifications map
|
||||
final Map<String, dynamic> specificationsMap = {};
|
||||
if (json['attributes'] != null && json['attributes'] is List) {
|
||||
final attributesData = json['attributes'] as List;
|
||||
for (final attr in attributesData) {
|
||||
if (attr is Map<String, dynamic> &&
|
||||
attr['attribute_name'] != null &&
|
||||
attr['attribute_value'] != null) {
|
||||
specificationsMap[attr['attribute_name'] as String] =
|
||||
attr['attribute_value'] as String;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final now = DateTime.now();
|
||||
|
||||
// Handle price from both product detail (price) and product list (standard_rate)
|
||||
final price = (json['price'] as num?)?.toDouble() ??
|
||||
(json['standard_rate'] as num?)?.toDouble() ??
|
||||
0.0;
|
||||
|
||||
return ProductModel(
|
||||
productId: json['name'] as String, // Item code
|
||||
name: json['item_name'] as String? ?? json['name'] as String,
|
||||
description: json['description'] as String?,
|
||||
basePrice: (json['standard_rate'] as num?)?.toDouble() ?? 0.0,
|
||||
basePrice: price,
|
||||
images: imagesList.isNotEmpty ? jsonEncode(imagesList) : null,
|
||||
thumbnail: thumbnailUrl,
|
||||
imageCaptions: null, // Not provided by API
|
||||
customLink360: json['custom_link_360'] as String?,
|
||||
specifications: json['specifications'] != null
|
||||
? jsonEncode(json['specifications'])
|
||||
imageCaptions: imageCaptionsMap.isNotEmpty
|
||||
? jsonEncode(imageCaptionsMap)
|
||||
: null,
|
||||
category: json['item_group'] as String?, // Frappe uses item_group
|
||||
customLink360: json['custom_link_360'] as String?,
|
||||
specifications: specificationsMap.isNotEmpty
|
||||
? jsonEncode(specificationsMap)
|
||||
: null,
|
||||
category: json['item_group_name'] as String? ??
|
||||
json['item_group'] as String?, // Try item_group_name first, fallback to item_group
|
||||
brand: json['brand'] as String?,
|
||||
unit: json['stock_uom'] as String? ?? 'm²',
|
||||
isActive: (json['disabled'] as int?) == 0, // Frappe uses 'disabled' field
|
||||
|
||||
Reference in New Issue
Block a user