diff --git a/app/Controllers/MedicalProcurement.php b/app/Controllers/MedicalProcurement.php index a0e39d3..49e6052 100644 --- a/app/Controllers/MedicalProcurement.php +++ b/app/Controllers/MedicalProcurement.php @@ -25,6 +25,46 @@ class MedicalProcurement extends BaseController $this->poItemModel = new PharmacyPurchaseOrderItemModel(); $this->grnModel = new PharmacyGrnModel(); $this->grnItemModel = new PharmacyGrnItemModel(); + $this->ensureGrnSchema(); + } + + private function ensureGrnSchema(): void + { + try { + if (!$this->db->tableExists('mst_grns')) { + return; + } + + if (!$this->db->fieldExists('cgst_amount', 'mst_grns')) { + $this->db->query("ALTER TABLE `mst_grns` ADD COLUMN `cgst_amount` DECIMAL(10,2) DEFAULT 0.00 AFTER `total_tax_amount`"); + } + if (!$this->db->fieldExists('sgst_amount', 'mst_grns')) { + $this->db->query("ALTER TABLE `mst_grns` ADD COLUMN `sgst_amount` DECIMAL(10,2) DEFAULT 0.00 AFTER `cgst_amount`"); + } + if (!$this->db->fieldExists('igst_amount', 'mst_grns')) { + $this->db->query("ALTER TABLE `mst_grns` ADD COLUMN `igst_amount` DECIMAL(10,2) DEFAULT 0.00 AFTER `sgst_amount`"); + } + if (!$this->db->fieldExists('round_off', 'mst_grns')) { + $this->db->query("ALTER TABLE `mst_grns` ADD COLUMN `round_off` DECIMAL(6,2) DEFAULT 0.00 AFTER `igst_amount`"); + } + if (!$this->db->fieldExists('gst_type', 'mst_grns')) { + $this->db->query("ALTER TABLE `mst_grns` ADD COLUMN `gst_type` VARCHAR(20) DEFAULT 'intra_state' AFTER `round_off`"); + } + + if ($this->db->tableExists('mst_grn_items')) { + if (!$this->db->fieldExists('gross_amount', 'mst_grn_items')) { + $this->db->query("ALTER TABLE `mst_grn_items` ADD COLUMN `gross_amount` DECIMAL(12,2) DEFAULT 0.00 AFTER `unit_purchase_rate`"); + } + if (!$this->db->fieldExists('sch_disc_per', 'mst_grn_items')) { + $this->db->query("ALTER TABLE `mst_grn_items` ADD COLUMN `sch_disc_per` DECIMAL(5,2) DEFAULT 0.00 AFTER `discount_percent`"); + } + if (!$this->db->fieldExists('sch_disc_amt', 'mst_grn_items')) { + $this->db->query("ALTER TABLE `mst_grn_items` ADD COLUMN `sch_disc_amt` DECIMAL(10,2) DEFAULT 0.00 AFTER `sch_disc_per`"); + } + } + } catch (\Throwable $e) { + log_message('error', 'ensureGrnSchema: ' . $e->getMessage()); + } } private function ensurePharmacyAccess() diff --git a/app/Database/Migrations/2026-10-22-000001_AddGrnEnhancementsColumns.php b/app/Database/Migrations/2026-10-22-000001_AddGrnEnhancementsColumns.php new file mode 100644 index 0000000..801aa97 --- /dev/null +++ b/app/Database/Migrations/2026-10-22-000001_AddGrnEnhancementsColumns.php @@ -0,0 +1,120 @@ +tableExists('mst_grns')) { + $colsToAdd = []; + if (!$this->fieldExists('mst_grns', 'cgst_amount')) { + $colsToAdd['cgst_amount'] = [ + 'type' => 'DECIMAL', + 'constraint' => '10,2', + 'default' => 0.00, + 'after' => 'total_tax_amount', + ]; + } + if (!$this->fieldExists('mst_grns', 'sgst_amount')) { + $colsToAdd['sgst_amount'] = [ + 'type' => 'DECIMAL', + 'constraint' => '10,2', + 'default' => 0.00, + 'after' => 'cgst_amount', + ]; + } + if (!$this->fieldExists('mst_grns', 'igst_amount')) { + $colsToAdd['igst_amount'] = [ + 'type' => 'DECIMAL', + 'constraint' => '10,2', + 'default' => 0.00, + 'after' => 'sgst_amount', + ]; + } + if (!$this->fieldExists('mst_grns', 'round_off')) { + $colsToAdd['round_off'] = [ + 'type' => 'DECIMAL', + 'constraint' => '6,2', + 'default' => 0.00, + 'after' => 'igst_amount', + ]; + } + if (!$this->fieldExists('mst_grns', 'gst_type')) { + $colsToAdd['gst_type'] = [ + 'type' => 'VARCHAR', + 'constraint' => 20, + 'default' => 'intra_state', + 'after' => 'round_off', + ]; + } + if (!empty($colsToAdd)) { + $this->forge->addColumn('mst_grns', $colsToAdd); + } + } + + // 2. Enhancements to mst_grn_items + if ($this->tableExists('mst_grn_items')) { + $itemColsToAdd = []; + if (!$this->fieldExists('mst_grn_items', 'gross_amount')) { + $itemColsToAdd['gross_amount'] = [ + 'type' => 'DECIMAL', + 'constraint' => '12,2', + 'default' => 0.00, + 'after' => 'unit_purchase_rate', + ]; + } + if (!$this->fieldExists('mst_grn_items', 'sch_disc_per')) { + $itemColsToAdd['sch_disc_per'] = [ + 'type' => 'DECIMAL', + 'constraint' => '5,2', + 'default' => 0.00, + 'after' => 'discount_percent', + ]; + } + if (!$this->fieldExists('mst_grn_items', 'sch_disc_amt')) { + $itemColsToAdd['sch_disc_amt'] = [ + 'type' => 'DECIMAL', + 'constraint' => '10,2', + 'default' => 0.00, + 'after' => 'sch_disc_per', + ]; + } + if (!empty($itemColsToAdd)) { + $this->forge->addColumn('mst_grn_items', $itemColsToAdd); + } + } + } + + public function down(): void + { + if ($this->tableExists('mst_grn_items')) { + foreach (['sch_disc_amt', 'sch_disc_per', 'gross_amount'] as $col) { + if ($this->fieldExists('mst_grn_items', $col)) { + $this->forge->dropColumn('mst_grn_items', $col); + } + } + } + + if ($this->tableExists('mst_grns')) { + foreach (['gst_type', 'round_off', 'igst_amount', 'sgst_amount', 'cgst_amount'] as $col) { + if ($this->fieldExists('mst_grns', $col)) { + $this->forge->dropColumn('mst_grns', $col); + } + } + } + } + + private function tableExists(string $table): bool + { + return $this->db->tableExists($table); + } + + private function fieldExists(string $table, string $field): bool + { + return $this->db->fieldExists($field, $table); + } +} diff --git a/app/Views/medical/grn_detail.php b/app/Views/medical/grn_detail.php index cea61b5..e725c50 100644 --- a/app/Views/medical/grn_detail.php +++ b/app/Views/medical/grn_detail.php @@ -2,7 +2,7 @@

GRN Inspection Details - +

Inward Goods Inspection & Live Stock Posting
@@ -10,9 +10,11 @@ Back to GRN List - - Print Slip - + + + Print Slip + + @@ -21,19 +23,19 @@
Supplier / Vendor - +
Vendor Invoice # - +
Invoice Date - +
GRN Date - +
Linked PO @@ -56,8 +58,8 @@
Verified Medicine Items - - + +
@@ -91,44 +93,56 @@ $it): ?> 0 + ? (float)$it['gross_amount'] + : round($recPacks * $rate, 2); + $schPer = (float)($it['sch_disc_per'] ?? 0); $schAmt = (float)($it['sch_disc_amt'] ?? 0); - $schTotal = ($schPer > 0 ? ($gross * $schPer / 100) : 0) + $schAmt; - $tradeDisc = (float)$it['discount_percent']; + $schTotal = ($schPer > 0 ? round($gross * $schPer / 100, 2) : 0) + $schAmt; + $tradeDisc = (float)($it['discount_percent'] ?? 0); $afterSch = max(0, $gross - $schTotal); - $tradeDiscAmt = ($tradeDisc > 0) ? ($afterSch * $tradeDisc / 100) : 0; + $tradeDiscAmt = ($tradeDisc > 0) ? round($afterSch * $tradeDisc / 100, 2) : 0; $rowDisc = $schTotal + $tradeDiscAmt; $totalGross += $gross; $totalDiscount += $rowDisc; - $isInter = (!empty($grn['gst_type']) && $grn['gst_type'] === 'inter_state') || ((float)$it['igst_percent'] > 0); + $cgstPer = (float)($it['cgst_percent'] ?? 0); + $sgstPer = (float)($it['sgst_percent'] ?? 0); + $igstPer = (float)($it['igst_percent'] ?? 0); + + $isInter = (!empty($grn['gst_type']) && $grn['gst_type'] === 'inter_state') || ($igstPer > 0); $gstLabel = $isInter - ? number_format((float)$it['igst_percent'], 1) . '% IGST' - : number_format((float)$it['cgst_percent'] + (float)$it['sgst_percent'], 0) . '% (' . number_format((float)$it['cgst_percent'], 1) . '+' . number_format((float)$it['sgst_percent'], 1) . '%)'; + ? number_format($igstPer, 1) . '% IGST' + : number_format($cgstPer + $sgstPer, 0) . '% (' . number_format($cgstPer, 1) . '+' . number_format($sgstPer, 1) . '%)'; + + $taxableAmt = isset($it['taxable_amount']) ? (float)$it['taxable_amount'] : ($gross - $rowDisc); + $totalAmt = isset($it['total_amount']) ? (float)$it['total_amount'] : ($taxableAmt + ($taxableAmt * ($cgstPer + $sgstPer + $igstPer) / 100)); ?> - + 0): ?> - Damaged: () + Damaged: () - - - s - - - ₹ - ₹ + + + s + + + ₹ + ₹ ₹ % ₹ - ₹ + ₹ - ₹ + ₹ Item # @@ -153,30 +167,30 @@ Taxable Amount: - ₹ + ₹ IGST Amount: - ₹ + ₹ CGST Amount: - ₹ + ₹ SGST Amount: - ₹ + ₹ Total GST: - ₹ + ₹ @@ -188,7 +202,7 @@ Net Inward Bill Total (Grand Total): - ₹ + ₹ @@ -200,9 +214,9 @@
- + - Posted to Live Store Inventory (Purchase Bill Ref #) + Posted to Live Store Inventory (Purchase Bill Ref #) @@ -211,11 +225,11 @@
- + - + View Purchase Invoice diff --git a/app/Views/medical/grn_print_pdf.php b/app/Views/medical/grn_print_pdf.php index a9261db..3fad94b 100644 --- a/app/Views/medical/grn_print_pdf.php +++ b/app/Views/medical/grn_print_pdf.php @@ -86,38 +86,50 @@ $it): ?> 0 + ? (float)$it['gross_amount'] + : round($recPacks * $rate, 2); + $schPer = (float)($it['sch_disc_per'] ?? 0); $schAmt = (float)($it['sch_disc_amt'] ?? 0); - $schTotal = ($schPer > 0 ? ($gross * $schPer / 100) : 0) + $schAmt; - $tradeDisc = (float)$it['discount_percent']; + $schTotal = ($schPer > 0 ? round($gross * $schPer / 100, 2) : 0) + $schAmt; + $tradeDisc = (float)($it['discount_percent'] ?? 0); $afterSch = max(0, $gross - $schTotal); - $tradeDiscAmt = ($tradeDisc > 0) ? ($afterSch * $tradeDisc / 100) : 0; + $tradeDiscAmt = ($tradeDisc > 0) ? round($afterSch * $tradeDisc / 100, 2) : 0; $rowDisc = $schTotal + $tradeDiscAmt; $pdfGross += $gross; $pdfDisc += $rowDisc; - $isInter = (!empty($grn['gst_type']) && $grn['gst_type'] === 'inter_state') || ((float)($it['igst_percent'] ?? 0) > 0); + $cgstPer = (float)($it['cgst_percent'] ?? 0); + $sgstPer = (float)($it['sgst_percent'] ?? 0); + $igstPer = (float)($it['igst_percent'] ?? 0); + + $isInter = (!empty($grn['gst_type']) && $grn['gst_type'] === 'inter_state') || ($igstPer > 0); $gstStr = $isInter - ? number_format((float)($it['igst_percent'] ?? 0), 0) . '% IGST' - : number_format((float)$it['cgst_percent'] + (float)$it['sgst_percent'], 0) . '%'; + ? number_format($igstPer, 0) . '% IGST' + : number_format($cgstPer + $sgstPer, 0) . '%'; + + $taxableAmt = isset($it['taxable_amount']) ? (float)$it['taxable_amount'] : ($gross - $rowDisc); + $totalAmt = isset($it['total_amount']) ? (float)$it['total_amount'] : ($taxableAmt + ($taxableAmt * ($cgstPer + $sgstPer + $igstPer) / 100)); ?> - - - - s - - - ₹ - ₹ + + + + s + + + ₹ + ₹ ₹ % - ₹ + ₹ - ₹ + ₹ @@ -135,7 +147,7 @@ Taxable Amount: - ₹ + ₹