diff --git a/app/Controllers/Api/v1/MedicalStoreApi.php b/app/Controllers/Api/v1/MedicalStoreApi.php index 088bb29..747438b 100644 --- a/app/Controllers/Api/v1/MedicalStoreApi.php +++ b/app/Controllers/Api/v1/MedicalStoreApi.php @@ -3002,9 +3002,62 @@ class MedicalStoreApi extends BaseController } } + // Determine latest batch, expiry, mrp, ptr, gst, hsn, shelf_no, rack_no, storage_type + $latestBatchRow = $this->db->table('mst_batches') + ->where('item_id', $itemId) + ->orderBy('batch_id', 'DESC') + ->limit(1) + ->get() + ->getRowArray(); + + $latestPiRow = !empty($rows) ? $rows[0] : null; + + $batchNo = $latestPiRow['batch_no'] ?? ($latestBatchRow['batch_no'] ?? ($history[0]['batch_no'] ?? '')); + $expDate = $latestPiRow['expiry_date'] ?? ($latestBatchRow['expiry_date'] ?? ($history[0]['expiry_date'] ?? '')); + $mrp = (float)($latestPiRow['mrp'] ?? ($latestBatchRow['mrp'] ?? ($history[0]['mrp'] ?? 0))); + $ptr = (float)($latestPiRow['ptr'] ?? ($latestBatchRow['ptr'] ?? ($history[0]['ptr'] ?? 0))); + $discPct = (float)($latestPiRow['discount_pct'] ?? ($history[0]['discount_pct'] ?? 0)); + $gstRate = (float)($latestPiRow['gst_rate'] ?? ($latestBatchRow['gst_rate'] ?? ($history[0]['gst_rate'] ?? ($mstItem['gst_rate'] ?? 12.00)))); + $hsnCode = $latestPiRow['hsn_code'] ?? ($latestBatchRow['hsn_code'] ?? ($history[0]['hsn_code'] ?? ($mstItem['hsn_code'] ?? '3004'))); + $shelfNo = $latestPiRow['shelf_no'] ?? ($latestBatchRow['shelf_no'] ?? ($history[0]['shelf_no'] ?? '')); + $rackNo = $latestPiRow['rack_no'] ?? ($latestBatchRow['rack_no'] ?? ($history[0]['rack_no'] ?? '')); + $storageType = $latestPiRow['storage_type'] ?? ($latestBatchRow['storage_type'] ?? ($history[0]['storage_type'] ?? 'Normal')); + $unitsPerPack = (int)($latestPiRow['units_per_pack'] ?? ($mstItem['units_per_pack'] ?? 10)); + $sellingPrice = (float)($latestPiRow['selling_price'] ?? ($mrp > 0 ? $mrp : 0)); + + $expMonth = '12'; + $expYear = '28'; + if (!empty($expDate)) { + $parts = explode('-', $expDate); + if (count($parts) >= 2) { + $expYear = substr($parts[0], -2); + $expMonth = str_pad($parts[1], 2, '0', STR_PAD_LEFT); + } + } + + $latestInfo = [ + 'batch_no' => $batchNo, + 'expiry_date' => $expDate, + 'exp_month' => $expMonth, + 'exp_year' => $expYear, + 'mrp' => $mrp > 0 ? $mrp : '', + 'ptr' => $ptr > 0 ? $ptr : '', + 'discount_pct' => $discPct, + 'gst_rate' => $gstRate, + 'cgst_pct' => round($gstRate / 2, 2), + 'sgst_pct' => round($gstRate / 2, 2), + 'hsn_code' => $hsnCode ?: '3004', + 'shelf_no' => $shelfNo, + 'rack_no' => $rackNo, + 'storage_type' => $storageType ?: 'Normal', + 'units_per_pack' => $unitsPerPack > 0 ? $unitsPerPack : 10, + 'selling_price' => $sellingPrice > 0 ? $sellingPrice : '' + ]; + return $this->response->setJSON([ - 'status' => 1, - 'history' => $history + 'status' => 1, + 'history' => $history, + 'latest_info' => $latestInfo ]); } diff --git a/public/App/MedicalStore/index.html b/public/App/MedicalStore/index.html index e7e346d..8e37938 100644 --- a/public/App/MedicalStore/index.html +++ b/public/App/MedicalStore/index.html @@ -4222,6 +4222,28 @@ function PurchaseView({ store, notify }) { } else { setProductHistory([]); } + if (data.status && data.latest_info) { + const info = data.latest_info; + setItemForm(prev => recomputeItemForm({ + ...prev, + batch_no: info.batch_no || prev.batch_no, + exp_month: info.exp_month || prev.exp_month, + exp_year: info.exp_year || prev.exp_year, + expiry_date: info.expiry_date || prev.expiry_date, + mrp: (info.mrp !== undefined && info.mrp !== '') ? Number(info.mrp) : prev.mrp, + ptr: (info.ptr !== undefined && info.ptr !== '') ? Number(info.ptr) : prev.ptr, + discount_pct: info.discount_pct !== undefined ? Number(info.discount_pct) : prev.discount_pct, + gst_rate: info.gst_rate !== undefined ? Number(info.gst_rate) : prev.gst_rate, + cgst_pct: info.cgst_pct !== undefined ? Number(info.cgst_pct) : prev.cgst_pct, + sgst_pct: info.sgst_pct !== undefined ? Number(info.sgst_pct) : prev.sgst_pct, + hsn_code: info.hsn_code || prev.hsn_code || '3004', + shelf_no: info.shelf_no || prev.shelf_no, + rack_no: info.rack_no || prev.rack_no, + storage_type: info.storage_type || prev.storage_type || 'Normal', + units_per_pack: info.units_per_pack ? Number(info.units_per_pack) : (prev.units_per_pack || 10), + selling_price: info.selling_price ? Number(info.selling_price) : (info.mrp ? Number(info.mrp) : prev.selling_price) + })); + } } catch (e) { console.error('fetchProductPurchaseHistory error:', e); setProductHistory([]); @@ -5620,271 +5642,295 @@ function PurchaseView({ store, notify }) { - {/* Row 2: Packaging, Batch No, Exp Month, Exp Year, MRP, Qty */} -
-
- - handleItemFormChange('units_per_pack', e.target.value)} - /> -
-
- - handleItemFormChange('batch_no', e.target.value)} - /> -
-
- - -
-
- - -
-
- - handleItemFormChange('mrp', e.target.value)} - /> -
-
- - handleItemFormChange('qty_packs', e.target.value)} - /> -
-
+ {/* Conditional display: Only show details below Product Search when a product is selected or editing */} + {(itemForm.item_id > 0 || editingItemIndex !== null) ? ( + <> + {/* Auto-filled Notification Banner */} +
+ + + {editingItemIndex !== null + ? `Editing: ${itemForm.item_name}` + : `Selected: ${itemForm.item_name} (Auto-filled with last batch, rate & location)` + } + + +
- {/* Row 3: Free Qty, Purchase Rate, Amount, Discount %, SCH Amount, SCH Discount % */} -
-
- - handleItemFormChange('free_qty_packs', e.target.value)} - /> -
-
- - handleItemFormChange('ptr', e.target.value)} - /> -
-
- - -
-
- - handleItemFormChange('discount_pct', e.target.value)} - /> -
-
- - handleItemFormChange('sch_disc_amount', e.target.value)} - /> -
-
- - handleItemFormChange('sch_disc_pct', e.target.value)} - /> -
-
+ {/* Row 2: Packaging, Batch No, Exp Month, Exp Year, MRP, Qty */} +
+
+ + handleItemFormChange('units_per_pack', e.target.value)} + /> +
+
+ + handleItemFormChange('batch_no', e.target.value)} + /> +
+
+ + +
+
+ + +
+
+ + handleItemFormChange('mrp', e.target.value)} + /> +
+
+ + handleItemFormChange('qty_packs', e.target.value)} + /> +
+
- {/* Row 4: Taxable Amount, CGST %, SGST / IGST %, Net Amount, Selling Price, HSNCODE */} -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - handleItemFormChange('selling_price', e.target.value)} - /> -
-
- - handleItemFormChange('hsn_code', e.target.value)} - /> -
-
+ {/* Row 3: Free Qty, Purchase Rate, Amount, Discount %, SCH Amount, SCH Discount % */} +
+
+ + handleItemFormChange('free_qty_packs', e.target.value)} + /> +
+
+ + handleItemFormChange('ptr', e.target.value)} + /> +
+
+ + +
+
+ + handleItemFormChange('discount_pct', e.target.value)} + /> +
+
+ + handleItemFormChange('sch_disc_amount', e.target.value)} + /> +
+
+ + handleItemFormChange('sch_disc_pct', e.target.value)} + /> +
+
- {/* Row 5: Storage, Shelf No., Rack No., Buttons */} -
-
- - + {/* Row 4: Taxable Amount, CGST %, SGST / IGST %, Net Amount, Selling Price, HSNCODE */} +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + handleItemFormChange('selling_price', e.target.value)} + /> +
+
+ + handleItemFormChange('hsn_code', e.target.value)} + /> +
+
+ + {/* Row 5: Storage, Shelf No., Rack No., Buttons */} +
+
+ + +
+
+ + handleItemFormChange('shelf_no', e.target.value)} + /> +
+
+ + handleItemFormChange('rack_no', e.target.value)} + /> +
+
+ + +
+
+ + ) : ( +
+ + Search and select a medicine in Product Search above to enter stock details and auto-fill last batch, expiry, MRP, rate & rack location.
-
- - handleItemFormChange('shelf_no', e.target.value)} - /> -
-
- - handleItemFormChange('rack_no', e.target.value)} - /> -
-
- - -
-
+ )}
{/* Primary Save Button Bar */}