add box selected product

This commit is contained in:
2026-02-07 23:09:06 +07:00
parent 9fbd9e846a
commit 28a376fc4d
5 changed files with 395 additions and 164 deletions

View File

@@ -493,9 +493,12 @@ class AddProductState extends ConsumerState<AddProduct> {
// --- END INITIALIZE DROPDOWN SELECTIONS ---
return SingleChildScrollView(
return Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
padding: const EdgeInsets.all(16.0),
child: Form(
key: key,
child: Column(
@@ -961,127 +964,145 @@ class AddProductState extends ConsumerState<AddProduct> {
),
],
ElevatedButton(
onPressed: () async {
print('${selectedVariation.map((e) => e.toString()).toList()}');
if ((key.currentState?.validate() ?? false)) {
ProductRepo productRepo = ProductRepo();
bool success;
// 1. Prepare Stocks List based on Type
List<StockDataModel> finalStocks = [];
if (_selectedType == ProductType.single) {
// Create a single stock entry from the Single Product Form controllers
finalStocks.add(StockDataModel(
stockId: widget.productModel?.stocks?.firstOrNull?.id
.toString(), // Preserve ID if updating
warehouseId: selectedWarehouse?.id.toString(),
// Using stockAlertController as per your UI logic for stock quantity
productStock: productStockController.text,
exclusivePrice: purchaseExclusivePriceController.text,
inclusivePrice: purchaseInclusivePriceController.text,
profitPercent: profitMarginController.text,
productSalePrice: salePriceController.text,
productWholeSalePrice: wholeSalePriceController.text,
productDealerPrice: dealerPriceController.text,
mfgDate: selectedManufactureDate,
expireDate: selectedExpireDate,
));
} else if (_selectedType == ProductType.variant) {
if (variantStocks.isEmpty) {
EasyLoading.showError("Please generate variations");
return;
}
finalStocks = variantStocks;
}
print('Variation ids $variationIds');
// 2. Construct the NEW Model
CreateProductModel submitData = CreateProductModel(
productId: widget.productModel?.id.toString(),
name: nameController.text,
categoryId: selectedCategory?.id.toString(),
brandId: selectedBrand?.id.toString(),
unitId: selectedUnit?.id.toString(),
modelId: selectedModel?.id.toString(),
productCode: productCodeController.text,
alertQty: stockAlertController.text,
rackId: selectedRack?.id.toString(),
shelfId: selectedShelf?.id.toString(),
productType: _selectedType.name,
vatType: selectedTaxType,
vatId: selectedTax?.id.toString(),
vatAmount: ((num.tryParse(purchaseInclusivePriceController.text) ?? 0) -
(num.tryParse(purchaseExclusivePriceController.text) ?? 0))
.toString(),
// New structure: Pass the list of StockDataModel
stocks: finalStocks,
// Variant IDs (only needed for variant type)
variationIds: _selectedType == ProductType.variant ? variationIds : null,
// Extra Fields
productManufacturer: manufacturerController.text,
productDiscount: discountPriceController.text,
image: pickedImage != null ? File(pickedImage!.path) : null,
// Warranty
warrantyDuration: warrantyController.text,
warrantyPeriod: selectedTimeWarranty,
guaranteeDuration: guaranteeController.text,
guaranteePeriod: selectedTimeGuarantee,
);
// --- TYPE: COMBO ---
if (_selectedType == ProductType.combo) {
if (comboList.isEmpty) {
EasyLoading.showError("Please add products to combo");
return;
}
submitData.comboProducts = comboList;
submitData.comboProfitPercent = comboProfitMarginController.text;
submitData.comboProductSalePrice = comboSalePriceController.text;
}
// 3. Call API
if (widget.productModel != null) {
if (!permissionService.hasPermission(Permit.productsUpdate.value)) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.red,
content: Text(lang.S.of(context).updateProductWarn)));
return;
}
success =
await productRepo.updateProduct(data: submitData, ref: ref, context: context);
} else {
if (!permissionService.hasPermission(Permit.productsCreate.value)) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.red, content: Text(lang.S.of(context).addProductWarn)));
return;
}
success =
await productRepo.createProduct(data: submitData, ref: ref, context: context);
}
if (success) {
if (widget.productModel != null) {
ref.refresh(fetchProductDetails(widget.productModel?.id.toString() ?? ''));
}
ref.refresh(productProvider);
Navigator.pop(context);
}
}
},
child: Text(widget.productModel != null
? lang.S.of(context).update
: lang.S.of(context).saveNPublish),
),
],
),
),
),
);
),
),
Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black.withOpacity(0.05),
offset: const Offset(0, -3),
),
],
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: kMainColor,
minimumSize: const Size(double.infinity, 50),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
),
onPressed: () async {
print('${selectedVariation.map((e) => e.toString()).toList()}');
if ((key.currentState?.validate() ?? false)) {
ProductRepo productRepo = ProductRepo();
bool success;
// 1. Prepare Stocks List based on Type
List<StockDataModel> finalStocks = [];
if (_selectedType == ProductType.single) {
// Create a single stock entry from the Single Product Form controllers
finalStocks.add(StockDataModel(
stockId: widget.productModel?.stocks?.firstOrNull?.id.toString(), // Preserve ID if updating
warehouseId: selectedWarehouse?.id.toString(),
// Using stockAlertController as per your UI logic for stock quantity
productStock: productStockController.text,
exclusivePrice: purchaseExclusivePriceController.text,
inclusivePrice: purchaseInclusivePriceController.text,
profitPercent: profitMarginController.text,
productSalePrice: salePriceController.text,
productWholeSalePrice: wholeSalePriceController.text,
productDealerPrice: dealerPriceController.text,
mfgDate: selectedManufactureDate,
expireDate: selectedExpireDate,
));
} else if (_selectedType == ProductType.variant) {
if (variantStocks.isEmpty) {
EasyLoading.showError("Please generate variations");
return;
}
finalStocks = variantStocks;
}
print('Variation ids $variationIds');
// 2. Construct the NEW Model
CreateProductModel submitData = CreateProductModel(
productId: widget.productModel?.id.toString(),
name: nameController.text,
categoryId: selectedCategory?.id.toString(),
brandId: selectedBrand?.id.toString(),
unitId: selectedUnit?.id.toString(),
modelId: selectedModel?.id.toString(),
productCode: productCodeController.text,
alertQty: stockAlertController.text,
rackId: selectedRack?.id.toString(),
shelfId: selectedShelf?.id.toString(),
productType: _selectedType.name,
vatType: selectedTaxType,
vatId: selectedTax?.id.toString(),
vatAmount: ((num.tryParse(purchaseInclusivePriceController.text) ?? 0) -
(num.tryParse(purchaseExclusivePriceController.text) ?? 0))
.toString(),
// New structure: Pass the list of StockDataModel
stocks: finalStocks,
// Variant IDs (only needed for variant type)
variationIds: _selectedType == ProductType.variant ? variationIds : null,
// Extra Fields
productManufacturer: manufacturerController.text,
productDiscount: discountPriceController.text,
image: pickedImage != null ? File(pickedImage!.path) : null,
// Warranty
warrantyDuration: warrantyController.text,
warrantyPeriod: selectedTimeWarranty,
guaranteeDuration: guaranteeController.text,
guaranteePeriod: selectedTimeGuarantee,
);
// --- TYPE: COMBO ---
if (_selectedType == ProductType.combo) {
if (comboList.isEmpty) {
EasyLoading.showError("Please add products to combo");
return;
}
submitData.comboProducts = comboList;
submitData.comboProfitPercent = comboProfitMarginController.text;
submitData.comboProductSalePrice = comboSalePriceController.text;
}
// 3. Call API
if (widget.productModel != null) {
if (!permissionService.hasPermission(Permit.productsUpdate.value)) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.red, content: Text(lang.S.of(context).updateProductWarn)));
return;
}
success = await productRepo.updateProduct(data: submitData, ref: ref, context: context);
} else {
if (!permissionService.hasPermission(Permit.productsCreate.value)) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.red, content: Text(lang.S.of(context).addProductWarn)));
return;
}
success = await productRepo.createProduct(data: submitData, ref: ref, context: context);
}
if (success) {
if (widget.productModel != null) {
ref.refresh(fetchProductDetails(widget.productModel?.id.toString() ?? ''));
}
ref.refresh(productProvider);
Navigator.pop(context);
}
}
},
child: Text(
widget.productModel != null ? lang.S.of(context).update : lang.S.of(context).saveNPublish,
style: const TextStyle(fontSize: 16, color: Colors.white)),
),
),
],
);
},
),
);