From 5187fcf3ed34c1e9eb8195df979ce957938e8a72 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Thu, 10 Sep 2026 07:13:04 +0530 Subject: [PATCH] feat(tax): standardize current GST slabs (0%, 5%, 18%, 40%, legacy 12%, 28%) across HMS and Medical Store --- app/Controllers/Api/v1/MedicalStoreApi.php | 21 +++++--- app/Controllers/Medical.php | 9 +++- ...-10-000004_UpdateGstSlabsAcrossMasters.php | 39 +++++++++++++++ app/Views/medical/product_edit.php | 45 ++++++++--------- app/Views/medical/purchase_invoice_edit.php | 49 +++++++++---------- .../medical/report_gst_invoice_hsn_data.php | 6 +++ .../medical/report_gst_invoice_list_data.php | 6 +++ public/App/MedicalStore/index.html | 42 +++++++++------- 8 files changed, 142 insertions(+), 75 deletions(-) create mode 100644 app/Database/Migrations/2026-09-10-000004_UpdateGstSlabsAcrossMasters.php diff --git a/app/Controllers/Api/v1/MedicalStoreApi.php b/app/Controllers/Api/v1/MedicalStoreApi.php index 747438b..4f558de 100644 --- a/app/Controllers/Api/v1/MedicalStoreApi.php +++ b/app/Controllers/Api/v1/MedicalStoreApi.php @@ -531,20 +531,27 @@ class MedicalStoreApi extends BaseController } } - $gstRates = [0, 5, 12, 18, 28]; + // Current GST Slabs: 0% (Nil/Exempt), 5% (Common/Basic), 18% (Standard), 40% (Demerit/Sin), plus legacy 12% and 28% + $gstRates = [0, 5, 18, 40, 12, 28]; if ($this->db->tableExists('med_gst_per')) { $gRows = $this->db->table('med_gst_per')->select('gst_per')->orderBy('gst_per', 'ASC')->get()->getResultArray(); if (!empty($gRows)) { - $customRates = []; + $mappedRates = []; foreach ($gRows as $gr) { - $r = (float)$gr['gst_per']; - if (!in_array($r, $customRates, true)) { - $customRates[] = $r; + $half = (float)$gr['gst_per']; + $tot = round($half * 2, 2); // med_gst_per stores CGST half-rate + if ($tot > 0 && !in_array($tot, $mappedRates)) { + $mappedRates[] = $tot; } } - if (!empty($customRates)) { - $gstRates = $customRates; + foreach ([0, 5, 18, 40, 12, 28] as $reqRate) { + if (!in_array($reqRate, $mappedRates)) { + $mappedRates[] = $reqRate; + } } + $mappedRates = array_values(array_unique($mappedRates)); + sort($mappedRates); + $gstRates = $mappedRates; } } diff --git a/app/Controllers/Medical.php b/app/Controllers/Medical.php index d21c581..3f494a0 100644 --- a/app/Controllers/Medical.php +++ b/app/Controllers/Medical.php @@ -11053,11 +11053,13 @@ class Medical extends BaseController $camt = (float) ($row['cgst_2_5'] ?? 0) + (float) ($row['cgst_6'] ?? 0) + (float) ($row['cgst_9'] ?? 0) - + (float) ($row['cgst_14'] ?? 0); + + (float) ($row['cgst_14'] ?? 0) + + (float) ($row['cgst_20'] ?? 0); $samt = (float) ($row['sgst_2_5'] ?? 0) + (float) ($row['sgst_6'] ?? 0) + (float) ($row['sgst_9'] ?? 0) - + (float) ($row['sgst_14'] ?? 0); + + (float) ($row['sgst_14'] ?? 0) + + (float) ($row['sgst_20'] ?? 0); $hsnData[] = [ 'num' => $num++, @@ -11240,6 +11242,9 @@ class Medical extends BaseController . 'ROUND(SUM(CASE WHEN ' . $cgstPerExpr . '=14 THEN ' . $taxableExpr . ' ELSE 0 END),0) AS sale_28_amount,' . 'SUM(CASE WHEN ' . $cgstPerExpr . '=14 THEN ' . $cgstExpr . ' ELSE 0 END) AS cgst_14,' . 'SUM(CASE WHEN ' . $cgstPerExpr . '=14 THEN ' . $sgstExpr . ' ELSE 0 END) AS sgst_14,' + . 'ROUND(SUM(CASE WHEN ' . $cgstPerExpr . '=20 THEN ' . $taxableExpr . ' ELSE 0 END),0) AS sale_40_amount,' + . 'SUM(CASE WHEN ' . $cgstPerExpr . '=20 THEN ' . $cgstExpr . ' ELSE 0 END) AS cgst_20,' + . 'SUM(CASE WHEN ' . $cgstPerExpr . '=20 THEN ' . $sgstExpr . ' ELSE 0 END) AS sgst_20,' . 'ROUND(SUM(CASE WHEN ' . $cgstPerExpr . '=0 THEN ' . $taxableExpr . ' ELSE 0 END),0) AS sale_0_amount ' . 'FROM invoice_med_master m ' . 'JOIN inv_med_item i ON m.' . $mid . '=i.' . $invMedId . ' ' diff --git a/app/Database/Migrations/2026-09-10-000004_UpdateGstSlabsAcrossMasters.php b/app/Database/Migrations/2026-09-10-000004_UpdateGstSlabsAcrossMasters.php new file mode 100644 index 0000000..5d52de1 --- /dev/null +++ b/app/Database/Migrations/2026-09-10-000004_UpdateGstSlabsAcrossMasters.php @@ -0,0 +1,39 @@ + 0.00, 5% -> 2.50, 18% -> 9.00, 40% -> 20.00, 12% (legacy) -> 6.00, 28% (legacy) -> 14.00 + if ($this->db->tableExists('med_gst_per')) { + $requiredRates = [ + 0.00, + 2.50, + 6.00, + 9.00, + 14.00, + 20.00 + ]; + + foreach ($requiredRates as $rate) { + $row = $this->db->query("SELECT id FROM `med_gst_per` WHERE ROUND(`gst_per`, 2) = ROUND(?, 2) LIMIT 1", [$rate])->getRowArray(); + + if (!$row) { + $this->db->table('med_gst_per')->insert([ + 'gst_per' => $rate + ]); + } + } + } + } + + public function down() + { + // Keep rates for safety of historical data + } +} diff --git a/app/Views/medical/product_edit.php b/app/Views/medical/product_edit.php index fa80da1..f552512 100644 --- a/app/Views/medical/product_edit.php +++ b/app/Views/medical/product_edit.php @@ -121,33 +121,34 @@ $flag = static function ($v): string {
diff --git a/app/Views/medical/purchase_invoice_edit.php b/app/Views/medical/purchase_invoice_edit.php index 2ff987b..ddd2fb4 100644 --- a/app/Views/medical/purchase_invoice_edit.php +++ b/app/Views/medical/purchase_invoice_edit.php @@ -103,37 +103,34 @@
diff --git a/app/Views/medical/report_gst_invoice_hsn_data.php b/app/Views/medical/report_gst_invoice_hsn_data.php index 45ba1cb..853bd0c 100644 --- a/app/Views/medical/report_gst_invoice_hsn_data.php +++ b/app/Views/medical/report_gst_invoice_hsn_data.php @@ -30,6 +30,9 @@ $showHeader = !empty($showHeader); Tax.Amt.28% CGST 14% SGST 14% + Tax.Amt.40% + CGST 20% + SGST 20% Tax.Amt.0% @@ -54,6 +57,9 @@ $showHeader = !empty($showHeader); + + + diff --git a/app/Views/medical/report_gst_invoice_list_data.php b/app/Views/medical/report_gst_invoice_list_data.php index 2450ca7..3292829 100644 --- a/app/Views/medical/report_gst_invoice_list_data.php +++ b/app/Views/medical/report_gst_invoice_list_data.php @@ -32,6 +32,9 @@ $showHeader = !empty($showHeader); Tax.Amt.28% CGST 14% SGST 14% + Tax.Amt.40% + CGST 20% + SGST 20% Tax.Amt.0% @@ -58,6 +61,9 @@ $showHeader = !empty($showHeader); + + + diff --git a/public/App/MedicalStore/index.html b/public/App/MedicalStore/index.html index 8e37938..b5f1c67 100644 --- a/public/App/MedicalStore/index.html +++ b/public/App/MedicalStore/index.html @@ -4047,7 +4047,7 @@ function PurchaseView({ store, notify }) { const [isSearchingMeds, setIsSearchingMeds] = useState(false); const [showMasterModal, setShowMasterModal] = useState(false); const [masterTargetRow, setMasterTargetRow] = useState(null); - const [supportData, setSupportData] = useState({ formulations: [], companies: [], gst_rates: [0, 5, 12, 18, 28], schedules: [] }); + const [supportData, setSupportData] = useState({ formulations: [], companies: [], gst_rates: [0, 5, 18, 40, 12, 28], schedules: [] }); const [isSavingMaster, setIsSavingMaster] = useState(false); const [masterForm, setMasterForm] = useState({ item_name: '', @@ -4056,7 +4056,7 @@ function PurchaseView({ store, notify }) { units_per_pack: 10, packing: '10', hsn_code: '3004', - gst_rate: 12, + gst_rate: 5, drug_schedule: 'Schedule H', company_name: '', min_reorder_level: 10 @@ -5819,11 +5819,12 @@ function PurchaseView({ store, notify }) { handleItemFormChange('sgst_pct', val); }} > - - - - - + + + + + +
@@ -5833,11 +5834,12 @@ function PurchaseView({ store, notify }) { value={itemForm.sgst_pct} onChange={(e) => handleItemFormChange('sgst_pct', parseFloat(e.target.value) || 0)} > - - - - - + + + + + +
@@ -7270,9 +7272,12 @@ function PurchaseView({ store, notify }) { value={masterForm.gst_rate} onChange={(e) => setMasterForm({ ...masterForm, gst_rate: Number(e.target.value) })} > - {(supportData.gst_rates || [0, 5, 12, 18, 28]).map((g, idx) => ( - - ))} + + + + + +
@@ -7684,11 +7689,12 @@ function PurchaseView({ store, notify }) { setPoCreateForm({ ...poCreateForm, items }); }} > - + - - + + +