fix(medical-store): add complete base schema migration and devices table for remote server
This commit is contained in:
parent
d2f069e3c8
commit
c82892f3d2
|
|
@ -0,0 +1,816 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class CreateMedicalStoreBaseSchema extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
// 1. mst_stores
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_stores` (
|
||||||
|
`store_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_code` VARCHAR(50) NOT NULL UNIQUE,
|
||||||
|
`store_slug` VARCHAR(80) DEFAULT NULL,
|
||||||
|
`store_name` VARCHAR(150) NOT NULL,
|
||||||
|
`building_name` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`floor_no` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`room_no` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`is_main_store` TINYINT(1) DEFAULT 0,
|
||||||
|
`drug_license_no_20b` VARCHAR(100) DEFAULT NULL COMMENT 'Form 20-B (Retail Allopathic)',
|
||||||
|
`drug_license_no_21b` VARCHAR(100) DEFAULT NULL COMMENT 'Form 21-B (Schedule C & C1)',
|
||||||
|
`drug_license_no_20f_x` VARCHAR(100) DEFAULT NULL COMMENT 'Form 20-F / Schedule X Narcotics',
|
||||||
|
`gstin` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`pan_no` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`fssai_no` VARCHAR(30) DEFAULT NULL,
|
||||||
|
`state_code` VARCHAR(5) DEFAULT '07' COMMENT '2-digit Indian State Code for GST',
|
||||||
|
`state_name` VARCHAR(100) DEFAULT 'Delhi',
|
||||||
|
`registered_pharmacist_name` VARCHAR(120) DEFAULT NULL,
|
||||||
|
`pharmacist_reg_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`contact_phone` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`contact_email` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`address` TEXT DEFAULT NULL,
|
||||||
|
`invoice_prefix` VARCHAR(20) DEFAULT 'INV/',
|
||||||
|
`credit_note_prefix` VARCHAR(20) NOT NULL DEFAULT 'CRN/',
|
||||||
|
`next_invoice_no` INT DEFAULT 1001,
|
||||||
|
`next_credit_note_no` INT NOT NULL DEFAULT 1,
|
||||||
|
`bank_name` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`bank_account_no` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`bank_ifsc` VARCHAR(25) DEFAULT NULL,
|
||||||
|
`upi_id` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`terms_conditions` TEXT DEFAULT NULL,
|
||||||
|
`security_key` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`current_otp` VARCHAR(10) DEFAULT NULL,
|
||||||
|
`otp_expiry` DATETIME DEFAULT NULL,
|
||||||
|
`is_active` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`abdm_hfr_id` VARCHAR(100) DEFAULT NULL COMMENT 'Health Facility Registry ID',
|
||||||
|
`abdm_hip_id` VARCHAR(100) DEFAULT NULL COMMENT 'Health Information Provider ID',
|
||||||
|
`pharmacist_hpr_id` VARCHAR(100) DEFAULT NULL COMMENT 'Healthcare Professional Registry ID of Pharmacist',
|
||||||
|
UNIQUE KEY `idx_store_slug` (`store_slug`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// Ensure missing columns in mst_stores if table previously existed
|
||||||
|
$storeCols = [
|
||||||
|
'store_slug' => "VARCHAR(80) DEFAULT NULL AFTER `store_code`",
|
||||||
|
'credit_note_prefix' => "VARCHAR(20) NOT NULL DEFAULT 'CRN/' AFTER `invoice_prefix`",
|
||||||
|
'next_credit_note_no' => "INT NOT NULL DEFAULT 1 AFTER `next_invoice_no`",
|
||||||
|
'security_key' => "VARCHAR(100) DEFAULT NULL AFTER `terms_conditions`",
|
||||||
|
'current_otp' => "VARCHAR(10) DEFAULT NULL AFTER `security_key`",
|
||||||
|
'otp_expiry' => "DATETIME DEFAULT NULL AFTER `current_otp`",
|
||||||
|
'abdm_hfr_id' => "VARCHAR(100) DEFAULT NULL COMMENT 'Health Facility Registry ID'",
|
||||||
|
'abdm_hip_id' => "VARCHAR(100) DEFAULT NULL COMMENT 'Health Information Provider ID'",
|
||||||
|
'pharmacist_hpr_id' => "VARCHAR(100) DEFAULT NULL COMMENT 'Healthcare Professional Registry ID of Pharmacist'"
|
||||||
|
];
|
||||||
|
foreach ($storeCols as $col => $def) {
|
||||||
|
if (!$this->hasField('mst_stores', $col)) {
|
||||||
|
$this->db->query("ALTER TABLE `mst_stores` ADD COLUMN `{$col}` {$def}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->ensureIndex('mst_stores', 'idx_store_slug', 'UNIQUE INDEX `idx_store_slug` (`store_slug`)');
|
||||||
|
|
||||||
|
// 2. mst_store_devices
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_store_devices` (
|
||||||
|
`device_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`machine_name` VARCHAR(150) DEFAULT 'Pharmacy Counter PC',
|
||||||
|
`device_token` VARCHAR(128) NOT NULL UNIQUE,
|
||||||
|
`device_fingerprint` VARCHAR(128) DEFAULT NULL,
|
||||||
|
`ip_address` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`user_agent` TEXT DEFAULT NULL,
|
||||||
|
`verified_by_method` VARCHAR(30) DEFAULT 'SECURITY_KEY' COMMENT 'SECURITY_KEY, OTP, ADMIN_MANUAL',
|
||||||
|
`status` VARCHAR(20) DEFAULT 'authorized' COMMENT 'authorized, revoked',
|
||||||
|
`authorized_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`last_active_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store` (`store_id`),
|
||||||
|
INDEX `idx_token` (`device_token`),
|
||||||
|
INDEX `idx_status` (`status`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 3. mst_store_users
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_store_users` (
|
||||||
|
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`user_id` INT NOT NULL,
|
||||||
|
`user_role` VARCHAR(50) DEFAULT 'pharmacist' COMMENT 'manager, cashier, pharmacist',
|
||||||
|
`is_active` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE KEY `uniq_store_user` (`store_id`, `user_id`),
|
||||||
|
INDEX `idx_store` (`store_id`),
|
||||||
|
INDEX `idx_user` (`user_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 4. mst_items
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_items` (
|
||||||
|
`item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`item_name` VARCHAR(200) NOT NULL,
|
||||||
|
`generic_name` VARCHAR(250) DEFAULT NULL,
|
||||||
|
`category` VARCHAR(100) DEFAULT 'Tablet' COMMENT 'Tablet, Capsule, Syrup, Injection, Ointment, Surgical, Consumable, Food',
|
||||||
|
`hsn_code` VARCHAR(20) DEFAULT '3004',
|
||||||
|
`gst_rate` DECIMAL(5,2) DEFAULT 12.00,
|
||||||
|
`unit_pack` VARCHAR(50) DEFAULT '10 Tablets' COMMENT 'e.g. 10 Tablets, 100ml, 1 Vial',
|
||||||
|
`units_per_pack` INT DEFAULT 10 COMMENT 'Basic sellable loose units in 1 pack',
|
||||||
|
`drug_schedule` VARCHAR(30) DEFAULT 'Schedule H' COMMENT 'OTC, Schedule H, Schedule H1, Schedule X, Narcotic',
|
||||||
|
`manufacturer_name` VARCHAR(150) DEFAULT NULL,
|
||||||
|
`barcode` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`min_reorder_level` INT DEFAULT 10,
|
||||||
|
`is_active` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`snomed_ct_code` VARCHAR(50) DEFAULT NULL COMMENT 'SNOMED-CT clinical drug code',
|
||||||
|
`snomed_display` VARCHAR(255) DEFAULT NULL COMMENT 'SNOMED-CT clinical term',
|
||||||
|
INDEX `idx_item_name` (`item_name`),
|
||||||
|
INDEX `idx_generic` (`generic_name`),
|
||||||
|
INDEX `idx_barcode` (`barcode`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
if (!$this->hasField('mst_items', 'snomed_ct_code')) {
|
||||||
|
$this->db->query("ALTER TABLE `mst_items` ADD COLUMN `snomed_ct_code` VARCHAR(50) DEFAULT NULL COMMENT 'SNOMED-CT clinical drug code'");
|
||||||
|
}
|
||||||
|
if (!$this->hasField('mst_items', 'snomed_display')) {
|
||||||
|
$this->db->query("ALTER TABLE `mst_items` ADD COLUMN `snomed_display` VARCHAR(255) DEFAULT NULL COMMENT 'SNOMED-CT clinical term'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. mst_batches
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_batches` (
|
||||||
|
`batch_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_no` VARCHAR(100) NOT NULL,
|
||||||
|
`mfg_date` DATE DEFAULT NULL,
|
||||||
|
`expiry_date` DATE NOT NULL COMMENT 'Used for FEFO ordering and expired stock locks',
|
||||||
|
`mrp` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`ptr` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Price to Retailer / Purchase rate before GST',
|
||||||
|
`purchase_rate_net` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Net landing cost after GST and discount',
|
||||||
|
`gst_rate` DECIMAL(5,2) DEFAULT 12.00,
|
||||||
|
`barcode` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store_item` (`store_id`, `item_id`),
|
||||||
|
INDEX `idx_batch_no` (`batch_no`),
|
||||||
|
INDEX `idx_expiry` (`expiry_date`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 6. mst_stock
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_stock` (
|
||||||
|
`stock_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_id` INT NOT NULL,
|
||||||
|
`current_qty` INT NOT NULL DEFAULT 0 COMMENT 'Stock in basic units (e.g. loose tablets or bottles)',
|
||||||
|
`reserved_qty` INT NOT NULL DEFAULT 0,
|
||||||
|
`last_updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE KEY `uniq_store_item_batch` (`store_id`, `item_id`, `batch_id`),
|
||||||
|
INDEX `idx_store` (`store_id`),
|
||||||
|
INDEX `idx_item` (`item_id`),
|
||||||
|
INDEX `idx_batch` (`batch_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 7. mst_suppliers
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_suppliers` (
|
||||||
|
`supplier_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`supplier_name` VARCHAR(150) NOT NULL,
|
||||||
|
`dl_no_20b` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`dl_no_21b` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`gstin` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`pan_no` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`contact_person` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`phone` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`email` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`address` TEXT DEFAULT NULL,
|
||||||
|
`state_code` VARCHAR(5) DEFAULT '07',
|
||||||
|
`credit_days` INT DEFAULT 30,
|
||||||
|
`bank_details` TEXT DEFAULT NULL,
|
||||||
|
`is_active` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_supplier_name` (`supplier_name`),
|
||||||
|
INDEX `idx_gstin` (`gstin`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 8. mst_purchases
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_purchases` (
|
||||||
|
`purchase_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`supplier_id` INT NOT NULL,
|
||||||
|
`supplier_invoice_no` VARCHAR(100) NOT NULL,
|
||||||
|
`invoice_date` DATE NOT NULL,
|
||||||
|
`received_date` DATE NOT NULL,
|
||||||
|
`due_date` DATE DEFAULT NULL,
|
||||||
|
`taxable_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`cgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`discount_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`round_off` DECIMAL(5,2) DEFAULT 0.00,
|
||||||
|
`net_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`paid_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`payment_status` VARCHAR(20) DEFAULT 'unpaid' COMMENT 'unpaid, partial, paid',
|
||||||
|
`remarks` TEXT DEFAULT NULL,
|
||||||
|
`created_by` INT DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store` (`store_id`),
|
||||||
|
INDEX `idx_supplier` (`supplier_id`),
|
||||||
|
INDEX `idx_invoice_date` (`invoice_date`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 9. mst_purchase_items
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_purchase_items` (
|
||||||
|
`purchase_item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`purchase_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_no` VARCHAR(100) NOT NULL,
|
||||||
|
`expiry_date` DATE NOT NULL,
|
||||||
|
`qty_packs` INT NOT NULL DEFAULT 1,
|
||||||
|
`free_qty_packs` INT DEFAULT 0 COMMENT 'e.g. 10 + 1 scheme',
|
||||||
|
`units_per_pack` INT DEFAULT 10,
|
||||||
|
`total_units` INT NOT NULL,
|
||||||
|
`mrp` DECIMAL(10,2) NOT NULL,
|
||||||
|
`ptr` DECIMAL(10,2) NOT NULL,
|
||||||
|
`discount_pct` DECIMAL(5,2) DEFAULT 0.00,
|
||||||
|
`hsn_code` VARCHAR(20) DEFAULT '3004',
|
||||||
|
`gst_rate` DECIMAL(5,2) DEFAULT 12.00,
|
||||||
|
`taxable_value` DECIMAL(10,2) NOT NULL,
|
||||||
|
`cgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`total_amount` DECIMAL(10,2) NOT NULL,
|
||||||
|
`net_unit_landing_cost` DECIMAL(10,2) NOT NULL,
|
||||||
|
INDEX `idx_purchase` (`purchase_id`),
|
||||||
|
INDEX `idx_item` (`item_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 10. mst_sales
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_sales` (
|
||||||
|
`sale_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`invoice_no` VARCHAR(100) NOT NULL UNIQUE,
|
||||||
|
`sale_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`patient_type` VARCHAR(30) DEFAULT 'Walk-in' COMMENT 'Walk-in, OPD, IPD',
|
||||||
|
`uhid` VARCHAR(50) DEFAULT NULL COMMENT 'patient_master.p_code',
|
||||||
|
`patient_id` INT DEFAULT NULL COMMENT 'patient_master.id',
|
||||||
|
`opd_id` INT DEFAULT NULL COMMENT 'opd_master.opd_id',
|
||||||
|
`ipd_id` INT DEFAULT NULL COMMENT 'ipd_master.id',
|
||||||
|
`patient_name` VARCHAR(150) NOT NULL,
|
||||||
|
`patient_mobile` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`patient_address` TEXT DEFAULT NULL,
|
||||||
|
`age` VARCHAR(30) DEFAULT NULL,
|
||||||
|
`gender` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`doctor_id` INT DEFAULT NULL,
|
||||||
|
`doctor_name` VARCHAR(150) DEFAULT NULL,
|
||||||
|
`doctor_reg_no` VARCHAR(100) DEFAULT NULL COMMENT 'Mandatory for Schedule H/H1 drugs',
|
||||||
|
`ward_name` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`bed_no` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`gross_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`return_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`is_exchange_bill` TINYINT(1) NOT NULL DEFAULT 0,
|
||||||
|
`discount_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`bill_discount_type` VARCHAR(10) DEFAULT 'pct',
|
||||||
|
`bill_discount_val` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`taxable_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`cgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`round_off` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`net_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_mode` VARCHAR(30) DEFAULT NULL,
|
||||||
|
`refund_ref_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`payment_mode` VARCHAR(30) DEFAULT 'Cash' COMMENT 'Cash, UPI, Card, Mixed, IPD_Credit',
|
||||||
|
`cash_paid` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`upi_paid` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`card_paid` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`credit_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`payment_reference` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`bank_name` VARCHAR(100) DEFAULT '',
|
||||||
|
`upi_ref_no` VARCHAR(100) DEFAULT '',
|
||||||
|
`card_ref_no` VARCHAR(100) DEFAULT '',
|
||||||
|
`is_bank_reconciled` TINYINT(1) DEFAULT 0,
|
||||||
|
`reconciled_at` DATETIME DEFAULT NULL,
|
||||||
|
`reconciled_by` VARCHAR(100) DEFAULT '',
|
||||||
|
`reconciled_notes` TEXT DEFAULT NULL,
|
||||||
|
`ipd_charge_id` INT DEFAULT NULL COMMENT 'Reference in ipd_invoice_item if billed to IPD running bill',
|
||||||
|
`schedule_h1_flag` TINYINT(1) DEFAULT 0,
|
||||||
|
`status` VARCHAR(30) DEFAULT 'completed' COMMENT 'completed, cancelled, refunded',
|
||||||
|
`created_by` INT DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`abha_id` VARCHAR(50) DEFAULT NULL COMMENT '14-Digit ABHA Number',
|
||||||
|
`abha_address` VARCHAR(120) DEFAULT NULL COMMENT 'ABHA Address (user@abdm)',
|
||||||
|
`abdm_care_context_ref` VARCHAR(100) DEFAULT NULL COMMENT 'ABDM Care Context Reference ID',
|
||||||
|
`abdm_care_context_display` VARCHAR(255) DEFAULT NULL COMMENT 'ABDM Care Context Display Description',
|
||||||
|
`abdm_fhir_bundle_json` LONGTEXT DEFAULT NULL COMMENT 'ABDM FHIR R4 MedicationDispense JSON',
|
||||||
|
`abdm_sync_status` VARCHAR(30) DEFAULT 'PENDING' COMMENT 'PENDING, SYNCED, NOT_APPLICABLE',
|
||||||
|
INDEX `idx_store_date` (`store_id`, `sale_date`),
|
||||||
|
INDEX `idx_uhid` (`uhid`),
|
||||||
|
INDEX `idx_opd` (`opd_id`),
|
||||||
|
INDEX `idx_ipd` (`ipd_id`),
|
||||||
|
INDEX `idx_invoice` (`invoice_no`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// Ensure sales extra columns
|
||||||
|
$salesCols = [
|
||||||
|
'return_amount' => "DECIMAL(12,2) NOT NULL DEFAULT 0.00 AFTER `gross_amount`",
|
||||||
|
'is_exchange_bill' => "TINYINT(1) NOT NULL DEFAULT 0 AFTER `return_amount`",
|
||||||
|
'bill_discount_type' => "VARCHAR(10) DEFAULT 'pct' AFTER `discount_amount`",
|
||||||
|
'bill_discount_val' => "DECIMAL(10,2) DEFAULT 0.00 AFTER `bill_discount_type`",
|
||||||
|
'refund_amount' => "DECIMAL(12,2) NOT NULL DEFAULT 0.00 AFTER `net_amount`",
|
||||||
|
'refund_mode' => "VARCHAR(30) DEFAULT NULL AFTER `refund_amount`",
|
||||||
|
'refund_ref_no' => "VARCHAR(100) DEFAULT NULL AFTER `refund_mode`",
|
||||||
|
'cash_paid' => "DECIMAL(10,2) DEFAULT 0.00",
|
||||||
|
'upi_paid' => "DECIMAL(10,2) DEFAULT 0.00",
|
||||||
|
'card_paid' => "DECIMAL(10,2) DEFAULT 0.00",
|
||||||
|
'credit_amount' => "DECIMAL(10,2) DEFAULT 0.00",
|
||||||
|
'payment_reference' => "VARCHAR(100) DEFAULT NULL",
|
||||||
|
'bank_name' => "VARCHAR(100) DEFAULT ''",
|
||||||
|
'upi_ref_no' => "VARCHAR(100) DEFAULT ''",
|
||||||
|
'card_ref_no' => "VARCHAR(100) DEFAULT ''",
|
||||||
|
'is_bank_reconciled' => "TINYINT(1) DEFAULT 0",
|
||||||
|
'reconciled_at' => "DATETIME DEFAULT NULL",
|
||||||
|
'reconciled_by' => "VARCHAR(100) DEFAULT ''",
|
||||||
|
'reconciled_notes' => "TEXT DEFAULT NULL",
|
||||||
|
'abha_id' => "VARCHAR(50) DEFAULT NULL",
|
||||||
|
'abha_address' => "VARCHAR(120) DEFAULT NULL",
|
||||||
|
'abdm_care_context_ref' => "VARCHAR(100) DEFAULT NULL",
|
||||||
|
'abdm_care_context_display' => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
'abdm_fhir_bundle_json' => "LONGTEXT DEFAULT NULL",
|
||||||
|
'abdm_sync_status' => "VARCHAR(30) DEFAULT 'PENDING'"
|
||||||
|
];
|
||||||
|
foreach ($salesCols as $col => $def) {
|
||||||
|
if (!$this->hasField('mst_sales', $col)) {
|
||||||
|
$this->db->query("ALTER TABLE `mst_sales` ADD COLUMN `{$col}` {$def}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. mst_sales_items
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_sales_items` (
|
||||||
|
`sale_item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`sale_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_id` INT NOT NULL,
|
||||||
|
`batch_no` VARCHAR(100) NOT NULL,
|
||||||
|
`expiry_date` DATE NOT NULL,
|
||||||
|
`qty` INT NOT NULL DEFAULT 1 COMMENT 'Quantity in basic loose units dispensed',
|
||||||
|
`item_type` VARCHAR(30) NOT NULL DEFAULT 'SALE',
|
||||||
|
`return_condition` VARCHAR(30) NOT NULL DEFAULT 'RESTOCKED',
|
||||||
|
`ref_sale_id` INT DEFAULT NULL,
|
||||||
|
`ref_invoice_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`return_reason` VARCHAR(255) DEFAULT NULL,
|
||||||
|
`is_restocked` TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
|
`sell_unit` VARCHAR(30) DEFAULT 'Strip',
|
||||||
|
`units_per_pack` INT DEFAULT 1,
|
||||||
|
`total_units` INT DEFAULT 1,
|
||||||
|
`unit_price` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`loose_qty` INT DEFAULT 0,
|
||||||
|
`pack_qty` DECIMAL(10,2) DEFAULT 1.00,
|
||||||
|
`unit_mrp` DECIMAL(10,2) NOT NULL,
|
||||||
|
`discount_type` VARCHAR(10) DEFAULT 'pct',
|
||||||
|
`discount_val` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`discount_pct` DECIMAL(5,2) DEFAULT 0.00,
|
||||||
|
`discount_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`hsn_code` VARCHAR(20) DEFAULT '3004',
|
||||||
|
`gst_rate` DECIMAL(5,2) DEFAULT 12.00,
|
||||||
|
`taxable_value` DECIMAL(10,2) NOT NULL,
|
||||||
|
`cgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`total_amount` DECIMAL(10,2) NOT NULL,
|
||||||
|
INDEX `idx_sale` (`sale_id`),
|
||||||
|
INDEX `idx_item` (`item_id`),
|
||||||
|
INDEX `idx_batch` (`batch_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
$itemCols = [
|
||||||
|
'item_type' => "VARCHAR(30) NOT NULL DEFAULT 'SALE' AFTER `qty`",
|
||||||
|
'return_condition' => "VARCHAR(30) NOT NULL DEFAULT 'RESTOCKED' AFTER `item_type`",
|
||||||
|
'ref_sale_id' => "INT DEFAULT NULL AFTER `return_condition`",
|
||||||
|
'ref_invoice_no' => "VARCHAR(100) DEFAULT NULL AFTER `ref_sale_id`",
|
||||||
|
'return_reason' => "VARCHAR(255) DEFAULT NULL AFTER `ref_invoice_no`",
|
||||||
|
'is_restocked' => "TINYINT(1) NOT NULL DEFAULT 1 AFTER `return_reason`",
|
||||||
|
'sell_unit' => "VARCHAR(30) DEFAULT 'Strip'",
|
||||||
|
'units_per_pack' => "INT DEFAULT 1",
|
||||||
|
'total_units' => "INT DEFAULT 1",
|
||||||
|
'unit_price' => "DECIMAL(10,2) DEFAULT 0.00",
|
||||||
|
'loose_qty' => "INT DEFAULT 0",
|
||||||
|
'pack_qty' => "DECIMAL(10,2) DEFAULT 1.00",
|
||||||
|
'discount_type' => "VARCHAR(10) DEFAULT 'pct'",
|
||||||
|
'discount_val' => "DECIMAL(10,2) DEFAULT 0.00"
|
||||||
|
];
|
||||||
|
foreach ($itemCols as $col => $def) {
|
||||||
|
if (!$this->hasField('mst_sales_items', $col)) {
|
||||||
|
$this->db->query("ALTER TABLE `mst_sales_items` ADD COLUMN `{$col}` {$def}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12. mst_sale_returns
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_sale_returns` (
|
||||||
|
`return_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`credit_note_no` VARCHAR(100) NOT NULL,
|
||||||
|
`return_date` DATETIME NOT NULL,
|
||||||
|
`original_sale_id` INT DEFAULT NULL,
|
||||||
|
`original_invoice_no` VARCHAR(100) NOT NULL,
|
||||||
|
`new_sale_id` INT DEFAULT NULL,
|
||||||
|
`patient_id` INT DEFAULT NULL,
|
||||||
|
`uhid` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`patient_name` VARCHAR(150) NOT NULL,
|
||||||
|
`patient_mobile` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`return_reason` VARCHAR(255) DEFAULT NULL,
|
||||||
|
`gross_refund_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`discount_reversed_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`taxable_refund_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`cgst_refund_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`sgst_refund_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`igst_refund_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`round_off` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`net_refund_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_mode` VARCHAR(30) NOT NULL DEFAULT 'Cash',
|
||||||
|
`refund_ref_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`restock_condition` VARCHAR(50) NOT NULL DEFAULT 'RESTOCKED',
|
||||||
|
`remarks` TEXT DEFAULT NULL,
|
||||||
|
`created_by` INT NOT NULL DEFAULT 1,
|
||||||
|
`created_at` DATETIME NOT NULL,
|
||||||
|
KEY `idx_store_date` (`store_id`, `return_date`),
|
||||||
|
KEY `idx_orig_invoice` (`original_invoice_no`),
|
||||||
|
KEY `idx_cn_no` (`credit_note_no`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 13. mst_sale_return_items
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_sale_return_items` (
|
||||||
|
`return_item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`return_id` INT NOT NULL,
|
||||||
|
`sale_item_id` INT DEFAULT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`item_name` VARCHAR(200) NOT NULL,
|
||||||
|
`batch_id` INT NOT NULL,
|
||||||
|
`batch_no` VARCHAR(100) NOT NULL,
|
||||||
|
`expiry_date` DATE DEFAULT NULL,
|
||||||
|
`return_sell_unit` VARCHAR(30) NOT NULL DEFAULT 'Tablet',
|
||||||
|
`return_qty` DECIMAL(10,2) NOT NULL DEFAULT 1.00,
|
||||||
|
`units_per_pack` INT NOT NULL DEFAULT 1,
|
||||||
|
`return_total_units` INT NOT NULL DEFAULT 1,
|
||||||
|
`unit_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_rate` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`discount_pct` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`discount_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`hsn_code` VARCHAR(20) NOT NULL DEFAULT '3004',
|
||||||
|
`gst_rate` DECIMAL(5,2) NOT NULL DEFAULT 12.00,
|
||||||
|
`taxable_value` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`cgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`is_restocked` TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
|
KEY `idx_return_id` (`return_id`),
|
||||||
|
KEY `idx_item_batch` (`item_id`, `batch_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 14. mst_transfers
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_transfers` (
|
||||||
|
`transfer_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`transfer_no` VARCHAR(100) NOT NULL UNIQUE,
|
||||||
|
`from_store_id` INT NOT NULL,
|
||||||
|
`to_store_id` INT NOT NULL,
|
||||||
|
`status` VARCHAR(30) DEFAULT 'requested' COMMENT 'requested, approved, dispatched, received, rejected',
|
||||||
|
`requested_by` INT DEFAULT NULL,
|
||||||
|
`dispatched_by` INT DEFAULT NULL,
|
||||||
|
`received_by` INT DEFAULT NULL,
|
||||||
|
`request_date` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`dispatch_date` DATETIME DEFAULT NULL,
|
||||||
|
`receive_date` DATETIME DEFAULT NULL,
|
||||||
|
`remarks` TEXT DEFAULT NULL,
|
||||||
|
INDEX `idx_from_to` (`from_store_id`, `to_store_id`),
|
||||||
|
INDEX `idx_status` (`status`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 15. mst_transfer_items
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_transfer_items` (
|
||||||
|
`transfer_item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`transfer_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_id` INT DEFAULT NULL,
|
||||||
|
`requested_qty` INT NOT NULL,
|
||||||
|
`dispatched_qty` INT DEFAULT 0,
|
||||||
|
`received_qty` INT DEFAULT 0,
|
||||||
|
INDEX `idx_transfer` (`transfer_id`),
|
||||||
|
INDEX `idx_item` (`item_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 16. mst_account_heads
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_account_heads` (
|
||||||
|
`head_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`head_code` VARCHAR(50) NOT NULL UNIQUE,
|
||||||
|
`head_name` VARCHAR(150) NOT NULL,
|
||||||
|
`head_type` VARCHAR(50) NOT NULL COMMENT 'Asset, Liability, Equity, Income, Expense',
|
||||||
|
`parent_id` INT DEFAULT NULL,
|
||||||
|
`is_system` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 17. mst_ledger_entries
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_ledger_entries` (
|
||||||
|
`entry_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`voucher_no` VARCHAR(100) NOT NULL,
|
||||||
|
`voucher_type` VARCHAR(50) NOT NULL COMMENT 'SALE, PURCHASE, PAYMENT, RECEIPT, CONTRA, ADJUSTMENT',
|
||||||
|
`voucher_date` DATE NOT NULL,
|
||||||
|
`account_head_id` INT NOT NULL,
|
||||||
|
`debit_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`credit_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`reference_type` VARCHAR(50) DEFAULT NULL COMMENT 'sales_invoice, purchase_invoice, supplier_payment, patient_credit',
|
||||||
|
`reference_id` INT DEFAULT NULL,
|
||||||
|
`narration` TEXT DEFAULT NULL,
|
||||||
|
`reconciled_flag` TINYINT(1) DEFAULT 0,
|
||||||
|
`reconciled_at` DATETIME DEFAULT NULL,
|
||||||
|
`reconciled_ref` VARCHAR(100) DEFAULT '',
|
||||||
|
`created_by` INT DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store_date` (`store_id`, `voucher_date`),
|
||||||
|
INDEX `idx_head` (`account_head_id`),
|
||||||
|
INDEX `idx_voucher` (`voucher_no`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// 18. mst_stock_audit
|
||||||
|
$this->db->query("CREATE TABLE IF NOT EXISTS `mst_stock_audit` (
|
||||||
|
`audit_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_id` INT NOT NULL,
|
||||||
|
`audit_type` VARCHAR(50) NOT NULL COMMENT 'OPENING_STOCK, DAMAGE, BREAKAGE, EXPIRY_DUMP, PHYSICAL_VARIATION',
|
||||||
|
`system_qty` INT NOT NULL DEFAULT 0,
|
||||||
|
`physical_qty` INT NOT NULL DEFAULT 0,
|
||||||
|
`variation_qty` INT NOT NULL DEFAULT 0,
|
||||||
|
`rate` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`total_value` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`remarks` TEXT DEFAULT NULL,
|
||||||
|
`conducted_by` INT DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store_audit` (`store_id`, `audit_type`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// SEED DATA (Idempotent: Only if tables empty)
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
// Seed 1: System Account Heads
|
||||||
|
$systemHeads = [
|
||||||
|
['1001', 'Cash in Hand', 'Asset'],
|
||||||
|
['1002', 'Bank Account / UPI Clearing', 'Asset'],
|
||||||
|
['1003', 'Stock in Hand / Inventory Valuation', 'Asset'],
|
||||||
|
['1004', 'Sundry Debtors / Patient Receivables', 'Asset'],
|
||||||
|
['1005', 'IPD Credit Hospital Running Ledger', 'Asset'],
|
||||||
|
['1006', 'Input CGST Credit', 'Asset'],
|
||||||
|
['1007', 'Input SGST Credit', 'Asset'],
|
||||||
|
['1008', 'Input IGST Credit', 'Asset'],
|
||||||
|
['2001', 'Sundry Creditors / Supplier Accounts', 'Liability'],
|
||||||
|
['2002', 'Output CGST Payable', 'Liability'],
|
||||||
|
['2003', 'Output SGST Payable', 'Liability'],
|
||||||
|
['2004', 'Output IGST Payable', 'Liability'],
|
||||||
|
['3001', 'Pharmacy Sales Account (Taxable)', 'Income'],
|
||||||
|
['3002', 'Pharmacy Sales Account (Exempt)', 'Income'],
|
||||||
|
['3003', 'Discounts Received on Purchases', 'Income'],
|
||||||
|
['3004', 'Opening Stock Capital Balance', 'Equity'],
|
||||||
|
['3005', 'Sales Returns & Customer Refunds', 'Expense'],
|
||||||
|
['4001', 'Cost of Goods Sold / Purchase Inward', 'Expense'],
|
||||||
|
['4002', 'Discounts Allowed on Sales', 'Expense'],
|
||||||
|
['4003', 'Medicine Expiry & Breakage Loss', 'Expense']
|
||||||
|
];
|
||||||
|
foreach ($systemHeads as $h) {
|
||||||
|
$exists = $this->db->table('mst_account_heads')->where('head_code', $h[0])->countAllResults();
|
||||||
|
if ($exists === 0) {
|
||||||
|
$this->db->table('mst_account_heads')->insert([
|
||||||
|
'head_code' => $h[0],
|
||||||
|
'head_name' => $h[1],
|
||||||
|
'head_type' => $h[2],
|
||||||
|
'is_system' => 1,
|
||||||
|
'created_at' => date('Y-m-d H:i:s')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seed 2: Default Stores (Central Pharmacy + OPD Counter)
|
||||||
|
$storeCount = $this->db->table('mst_stores')->countAllResults();
|
||||||
|
if ($storeCount === 0) {
|
||||||
|
$this->db->table('mst_stores')->insertBatch([
|
||||||
|
[
|
||||||
|
'store_code' => 'ST-MAIN',
|
||||||
|
'store_slug' => 'storea',
|
||||||
|
'store_name' => 'City Hospital Central Pharmacy',
|
||||||
|
'building_name' => 'Main Hospital Block A',
|
||||||
|
'floor_no' => 'Ground Floor',
|
||||||
|
'room_no' => 'Room 101',
|
||||||
|
'is_main_store' => 1,
|
||||||
|
'drug_license_no_20b' => 'DL-20B-DEL-10928',
|
||||||
|
'drug_license_no_21b' => 'DL-21B-DEL-10929',
|
||||||
|
'gstin' => '07AAAAA0000A1Z5',
|
||||||
|
'pan_no' => 'AAAAA0000A',
|
||||||
|
'fssai_no' => '10020011000123',
|
||||||
|
'state_code' => '07',
|
||||||
|
'state_name' => 'Delhi',
|
||||||
|
'registered_pharmacist_name' => 'Rajesh Kumar, B.Pharm',
|
||||||
|
'pharmacist_reg_no' => 'DPC-Reg-45892',
|
||||||
|
'contact_phone' => '+91 9876543210',
|
||||||
|
'contact_email' => 'pharmacy@cityhospital.com',
|
||||||
|
'address' => 'Plot 12, Medical Enclave, Main Hospital Block, Delhi',
|
||||||
|
'invoice_prefix' => 'MAIN/26-27/',
|
||||||
|
'credit_note_prefix' => 'CRN/',
|
||||||
|
'next_invoice_no' => 1001,
|
||||||
|
'next_credit_note_no' => 1,
|
||||||
|
'upi_id' => 'cityhospital@upi',
|
||||||
|
'security_key' => 'HMS-80F6ED-297',
|
||||||
|
'abdm_hfr_id' => 'IN0710001234',
|
||||||
|
'abdm_hip_id' => 'HIP-CITYHOSP-01',
|
||||||
|
'pharmacist_hpr_id' => '91-8822-4411-9901',
|
||||||
|
'terms_conditions' => "1. Goods once sold will be returned as per Drug Rules within 7 days with bill.\n2. Keep medicines stored below 25°C away from direct sunlight.",
|
||||||
|
'is_active' => 1,
|
||||||
|
'created_at' => date('Y-m-d H:i:s')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'store_code' => 'ST-OPD-B2',
|
||||||
|
'store_slug' => 'storeb',
|
||||||
|
'store_name' => 'City Medicos - OPD Building Counter',
|
||||||
|
'building_name' => 'OPD & Diagnostic Block B',
|
||||||
|
'floor_no' => '1st Floor',
|
||||||
|
'room_no' => 'Counter 2',
|
||||||
|
'is_main_store' => 0,
|
||||||
|
'drug_license_no_20b' => 'DL-20B-DEL-11450',
|
||||||
|
'drug_license_no_21b' => 'DL-21B-DEL-11451',
|
||||||
|
'gstin' => '07BBBBB1111B2Z8',
|
||||||
|
'pan_no' => 'BBBBB1111B',
|
||||||
|
'fssai_no' => '10020011000456',
|
||||||
|
'state_code' => '07',
|
||||||
|
'state_name' => 'Delhi',
|
||||||
|
'registered_pharmacist_name' => 'Sunil Sharma, D.Pharm',
|
||||||
|
'pharmacist_reg_no' => 'DPC-Reg-67210',
|
||||||
|
'contact_phone' => '+91 9811223344',
|
||||||
|
'contact_email' => 'opdpharmacy@cityhospital.com',
|
||||||
|
'address' => 'OPD Wing, Block B, 1st Floor, Medical Enclave, Delhi',
|
||||||
|
'invoice_prefix' => 'OPD/26-27/',
|
||||||
|
'credit_note_prefix' => 'CRN/',
|
||||||
|
'next_invoice_no' => 5001,
|
||||||
|
'next_credit_note_no' => 1,
|
||||||
|
'upi_id' => 'citymedicos@upi',
|
||||||
|
'security_key' => 'HMS-72A1CF-415',
|
||||||
|
'abdm_hfr_id' => 'IN0710001234-OPD',
|
||||||
|
'abdm_hip_id' => 'HIP-CITYHOSP-02',
|
||||||
|
'pharmacist_hpr_id' => '91-8822-4411-9902',
|
||||||
|
'terms_conditions' => "1. Check expiry and batch at counter.\n2. No exchange on Schedule H/H1 drugs without valid prescription.",
|
||||||
|
'is_active' => 1,
|
||||||
|
'created_at' => date('Y-m-d H:i:s')
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seed 3: Sample Medicines Catalog
|
||||||
|
$itemCount = $this->db->table('mst_items')->countAllResults();
|
||||||
|
if ($itemCount === 0) {
|
||||||
|
$sampleItems = [
|
||||||
|
['Augmentin 625 Duo Tablet', 'Amoxycillin (500mg) + Clavulanic Acid (125mg)', 'Tablet', '3004', 12.00, '10 Tablets', 10, 'Schedule H1', 'GSK Pharmaceuticals', '890103000001', 20, '372687004', 'Amoxicillin and clavulanic acid'],
|
||||||
|
['Pan 40 Tablet', 'Pantoprazole (40mg)', 'Tablet', '3004', 12.00, '15 Tablets', 15, 'Schedule H', 'Alkem Laboratories', '890103000002', 30, '386965005', 'Pantoprazole'],
|
||||||
|
['Dolo 650 Tablet', 'Paracetamol (650mg)', 'Tablet', '3004', 12.00, '15 Tablets', 15, 'OTC', 'Micro Labs Ltd', '890103000003', 50, '387517004', 'Paracetamol'],
|
||||||
|
['Azithral 500 Tablet', 'Azithromycin (500mg)', 'Tablet', '3004', 12.00, '5 Tablets', 5, 'Schedule H1', 'Alembic Pharmaceuticals', '890103000004', 15, '387207008', 'Azithromycin'],
|
||||||
|
['Monocef 1g Injection', 'Ceftriaxone (1000mg)', 'Injection', '3004', 12.00, '1 Vial', 1, 'Schedule H1', 'Aristo Pharmaceuticals', '890103000005', 25, '387325003', 'Ceftriaxone'],
|
||||||
|
['Betadine 10% Ointment', 'Povidone Iodine (10% w/w)', 'Ointment', '3004', 12.00, '20 gm Tube', 1, 'OTC', 'Win-Medicare', '890103000006', 15, NULL, NULL],
|
||||||
|
['Ascoril LS Syrup', 'Levosalbutamol + Ambroxol + Guaifenesin', 'Syrup', '3004', 12.00, '100 ml Bottle', 1, 'Schedule H', 'Glenmark Pharmaceuticals', '890103000007', 20, NULL, NULL],
|
||||||
|
['Telma 40 Tablet', 'Telmisartan (40mg)', 'Tablet', '3004', 12.00, '30 Tablets', 30, 'Schedule H', 'Glenmark Pharmaceuticals', '890103000008', 25, NULL, NULL],
|
||||||
|
['Normal Saline 0.9% IV', 'Sodium Chloride (0.9% w/v)', 'Consumable', '3004', 12.00, '500 ml Bottle', 1, 'Schedule H', 'Aculife Healthcare', '890103000009', 40, NULL, NULL]
|
||||||
|
];
|
||||||
|
foreach ($sampleItems as $it) {
|
||||||
|
$this->db->table('mst_items')->insert([
|
||||||
|
'item_name' => $it[0],
|
||||||
|
'generic_name' => $it[1],
|
||||||
|
'category' => $it[2],
|
||||||
|
'hsn_code' => $it[3],
|
||||||
|
'gst_rate' => $it[4],
|
||||||
|
'unit_pack' => $it[5],
|
||||||
|
'units_per_pack' => $it[6],
|
||||||
|
'drug_schedule' => $it[7],
|
||||||
|
'manufacturer_name' => $it[8],
|
||||||
|
'barcode' => $it[9],
|
||||||
|
'min_reorder_level' => $it[10],
|
||||||
|
'snomed_ct_code' => $it[11],
|
||||||
|
'snomed_display' => $it[12],
|
||||||
|
'is_active' => 1,
|
||||||
|
'created_at' => date('Y-m-d H:i:s')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seed 4: Sample Batches & Stock
|
||||||
|
$batchCount = $this->db->table('mst_batches')->countAllResults();
|
||||||
|
if ($batchCount === 0) {
|
||||||
|
$this->db->query("INSERT INTO `mst_batches` (`store_id`, `item_id`, `batch_no`, `mfg_date`, `expiry_date`, `mrp`, `ptr`, `purchase_rate_net`, `gst_rate`) VALUES
|
||||||
|
(1, 1, 'AUG-2401', '2024-01-01', '2026-10-31', 204.50, 155.00, 173.60, 12.00),
|
||||||
|
(1, 1, 'AUG-2409', '2024-09-01', '2027-04-30', 204.50, 155.00, 173.60, 12.00),
|
||||||
|
(1, 2, 'PAN-5512', '2024-03-01', '2027-02-28', 162.00, 115.00, 128.80, 12.00),
|
||||||
|
(1, 3, 'DOL-9901', '2024-06-01', '2027-06-30', 34.00, 22.50, 25.20, 12.00),
|
||||||
|
(1, 4, 'AZI-3321', '2024-02-01', '2026-12-31', 125.00, 89.00, 99.68, 12.00),
|
||||||
|
(1, 5, 'MON-8810', '2024-05-01', '2026-11-30', 68.00, 48.00, 53.76, 12.00),
|
||||||
|
(2, 1, 'AUG-2401', '2024-01-01', '2026-10-31', 204.50, 155.00, 173.60, 12.00),
|
||||||
|
(2, 2, 'PAN-5512', '2024-03-01', '2027-02-28', 162.00, 115.00, 128.80, 12.00),
|
||||||
|
(2, 3, 'DOL-9901', '2024-06-01', '2027-06-30', 34.00, 22.50, 25.20, 12.00)
|
||||||
|
");
|
||||||
|
|
||||||
|
$this->db->query("INSERT INTO `mst_stock` (`store_id`, `item_id`, `batch_id`, `current_qty`) VALUES
|
||||||
|
(1, 1, 1, 150),
|
||||||
|
(1, 1, 2, 200),
|
||||||
|
(1, 2, 3, 300),
|
||||||
|
(1, 3, 4, 450),
|
||||||
|
(1, 4, 5, 120),
|
||||||
|
(1, 5, 6, 80),
|
||||||
|
(2, 1, 7, 50),
|
||||||
|
(2, 2, 8, 90),
|
||||||
|
(2, 3, 9, 150)
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seed 5: Sample Supplier
|
||||||
|
$supCount = $this->db->table('mst_suppliers')->countAllResults();
|
||||||
|
if ($supCount === 0) {
|
||||||
|
$this->db->table('mst_suppliers')->insert([
|
||||||
|
'supplier_name' => 'Apex Healthcare Distributors',
|
||||||
|
'dl_no_20b' => 'DL-20B-DEL-98441',
|
||||||
|
'dl_no_21b' => 'DL-21B-DEL-98442',
|
||||||
|
'gstin' => '07AACCA1234F1Z9',
|
||||||
|
'pan_no' => 'AACCA1234F',
|
||||||
|
'contact_person' => 'Ramesh Gupta',
|
||||||
|
'phone' => '+91 9811002233',
|
||||||
|
'email' => 'sales@apexhealth.in',
|
||||||
|
'address' => '45, Wholesale Medicine Market, Bhagirath Palace, Chandni Chowk, Delhi',
|
||||||
|
'state_code' => '07',
|
||||||
|
'credit_days' => 30,
|
||||||
|
'is_active' => 1,
|
||||||
|
'created_at' => date('Y-m-d H:i:s')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Safe rollback: drop in reverse dependency order
|
||||||
|
$tables = [
|
||||||
|
'mst_sale_return_items',
|
||||||
|
'mst_sale_returns',
|
||||||
|
'mst_sales_items',
|
||||||
|
'mst_sales',
|
||||||
|
'mst_transfer_items',
|
||||||
|
'mst_transfers',
|
||||||
|
'mst_stock_audit',
|
||||||
|
'mst_ledger_entries',
|
||||||
|
'mst_stock',
|
||||||
|
'mst_batches',
|
||||||
|
'mst_purchase_items',
|
||||||
|
'mst_purchases',
|
||||||
|
'mst_suppliers',
|
||||||
|
'mst_items',
|
||||||
|
'mst_store_users',
|
||||||
|
'mst_store_devices',
|
||||||
|
'mst_account_heads',
|
||||||
|
'mst_stores'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($tables as $tbl) {
|
||||||
|
if ($this->hasTable($tbl)) {
|
||||||
|
$this->forge->dropTable($tbl, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function hasTable(string $table): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$rows = $this->db->query('SHOW TABLES LIKE ' . $this->db->escape($table))->getResultArray();
|
||||||
|
return !empty($rows);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function hasField(string $table, string $field): bool
|
||||||
|
{
|
||||||
|
if (!$this->hasTable($table)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$safeTable = str_replace('`', '``', $table);
|
||||||
|
$sql = 'SHOW COLUMNS FROM `' . $safeTable . '` LIKE ' . $this->db->escape($field);
|
||||||
|
$rows = $this->db->query($sql)->getResultArray();
|
||||||
|
return !empty($rows);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function ensureIndex(string $table, string $indexName, string $createIndexSql): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$safeTable = str_replace('`', '``', $table);
|
||||||
|
$check = $this->db->query("SHOW INDEX FROM `{$safeTable}` WHERE Key_name = " . $this->db->escape($indexName))->getResultArray();
|
||||||
|
if (empty($check)) {
|
||||||
|
$this->db->query("ALTER TABLE `{$safeTable}` ADD {$createIndexSql}");
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
// Index already exists or error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,137 +1,567 @@
|
||||||
-- =========================================================================
|
-- =========================================================================
|
||||||
-- Medical Store: B2C Sales Returns & Same-Invoice Exchanges (Marg ERP Standard)
|
-- Medical Store & Multi-Building Pharmacy: Complete Schema & B2C Returns
|
||||||
-- Target: Remote Server MySQL / MariaDB Database Migration
|
-- Target: Remote Server MySQL / MariaDB Database Migration
|
||||||
-- Date: 2026-09-08
|
-- Date: 2026-09-08
|
||||||
-- =========================================================================
|
-- =========================================================================
|
||||||
|
|
||||||
-- 1. Add Return and Refund tracking columns to mst_sales (if not exists)
|
SET NAMES utf8mb4;
|
||||||
SET @dbname = DATABASE();
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
-- mst_sales.return_amount
|
-- 1. mst_stores
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales' AND COLUMN_NAME = 'return_amount');
|
CREATE TABLE IF NOT EXISTS `mst_stores` (
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales` ADD COLUMN `return_amount` DECIMAL(12,2) DEFAULT 0.00 AFTER `gross_amount`', 'SELECT 1');
|
`store_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
`store_code` VARCHAR(50) NOT NULL UNIQUE,
|
||||||
|
`store_slug` VARCHAR(80) DEFAULT NULL,
|
||||||
|
`store_name` VARCHAR(150) NOT NULL,
|
||||||
|
`building_name` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`floor_no` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`room_no` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`is_main_store` TINYINT(1) DEFAULT 0,
|
||||||
|
`drug_license_no_20b` VARCHAR(100) DEFAULT NULL COMMENT 'Form 20-B (Retail Allopathic)',
|
||||||
|
`drug_license_no_21b` VARCHAR(100) DEFAULT NULL COMMENT 'Form 21-B (Schedule C & C1)',
|
||||||
|
`drug_license_no_20f_x` VARCHAR(100) DEFAULT NULL COMMENT 'Form 20-F / Schedule X Narcotics',
|
||||||
|
`gstin` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`pan_no` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`fssai_no` VARCHAR(30) DEFAULT NULL,
|
||||||
|
`state_code` VARCHAR(5) DEFAULT '07' COMMENT '2-digit Indian State Code for GST',
|
||||||
|
`state_name` VARCHAR(100) DEFAULT 'Delhi',
|
||||||
|
`registered_pharmacist_name` VARCHAR(120) DEFAULT NULL,
|
||||||
|
`pharmacist_reg_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`contact_phone` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`contact_email` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`address` TEXT DEFAULT NULL,
|
||||||
|
`invoice_prefix` VARCHAR(20) DEFAULT 'INV/',
|
||||||
|
`credit_note_prefix` VARCHAR(20) NOT NULL DEFAULT 'CRN/',
|
||||||
|
`next_invoice_no` INT DEFAULT 1001,
|
||||||
|
`next_credit_note_no` INT NOT NULL DEFAULT 1,
|
||||||
|
`bank_name` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`bank_account_no` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`bank_ifsc` VARCHAR(25) DEFAULT NULL,
|
||||||
|
`upi_id` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`terms_conditions` TEXT DEFAULT NULL,
|
||||||
|
`security_key` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`current_otp` VARCHAR(10) DEFAULT NULL,
|
||||||
|
`otp_expiry` DATETIME DEFAULT NULL,
|
||||||
|
`is_active` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`abdm_hfr_id` VARCHAR(100) DEFAULT NULL COMMENT 'Health Facility Registry ID',
|
||||||
|
`abdm_hip_id` VARCHAR(100) DEFAULT NULL COMMENT 'Health Information Provider ID',
|
||||||
|
`pharmacist_hpr_id` VARCHAR(100) DEFAULT NULL COMMENT 'Healthcare Professional Registry ID of Pharmacist',
|
||||||
|
UNIQUE KEY `idx_store_slug` (`store_slug`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- mst_sales.is_exchange_bill
|
-- 2. mst_store_devices
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales' AND COLUMN_NAME = 'is_exchange_bill');
|
CREATE TABLE IF NOT EXISTS `mst_store_devices` (
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales` ADD COLUMN `is_exchange_bill` TINYINT(1) DEFAULT 0 AFTER `return_amount`', 'SELECT 1');
|
`device_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
`store_id` INT NOT NULL,
|
||||||
|
`machine_name` VARCHAR(150) DEFAULT 'Pharmacy Counter PC',
|
||||||
|
`device_token` VARCHAR(128) NOT NULL UNIQUE,
|
||||||
|
`device_fingerprint` VARCHAR(128) DEFAULT NULL,
|
||||||
|
`ip_address` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`user_agent` TEXT DEFAULT NULL,
|
||||||
|
`verified_by_method` VARCHAR(30) DEFAULT 'SECURITY_KEY' COMMENT 'SECURITY_KEY, OTP, ADMIN_MANUAL',
|
||||||
|
`status` VARCHAR(20) DEFAULT 'authorized' COMMENT 'authorized, revoked',
|
||||||
|
`authorized_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`last_active_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store` (`store_id`),
|
||||||
|
INDEX `idx_token` (`device_token`),
|
||||||
|
INDEX `idx_status` (`status`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- mst_sales.refund_amount
|
-- 3. mst_store_users
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales' AND COLUMN_NAME = 'refund_amount');
|
CREATE TABLE IF NOT EXISTS `mst_store_users` (
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales` ADD COLUMN `refund_amount` DECIMAL(12,2) DEFAULT 0.00 AFTER `net_amount`', 'SELECT 1');
|
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
`store_id` INT NOT NULL,
|
||||||
|
`user_id` INT NOT NULL,
|
||||||
|
`user_role` VARCHAR(50) DEFAULT 'pharmacist' COMMENT 'manager, cashier, pharmacist',
|
||||||
|
`is_active` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE KEY `uniq_store_user` (`store_id`, `user_id`),
|
||||||
|
INDEX `idx_store` (`store_id`),
|
||||||
|
INDEX `idx_user` (`user_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- mst_sales.refund_mode
|
-- 4. mst_items
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales' AND COLUMN_NAME = 'refund_mode');
|
CREATE TABLE IF NOT EXISTS `mst_items` (
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales` ADD COLUMN `refund_mode` VARCHAR(50) NULL AFTER `refund_amount`', 'SELECT 1');
|
`item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
`item_name` VARCHAR(200) NOT NULL,
|
||||||
|
`generic_name` VARCHAR(250) DEFAULT NULL,
|
||||||
|
`category` VARCHAR(100) DEFAULT 'Tablet' COMMENT 'Tablet, Capsule, Syrup, Injection, Ointment, Surgical, Consumable, Food',
|
||||||
|
`hsn_code` VARCHAR(20) DEFAULT '3004',
|
||||||
|
`gst_rate` DECIMAL(5,2) DEFAULT 12.00,
|
||||||
|
`unit_pack` VARCHAR(50) DEFAULT '10 Tablets' COMMENT 'e.g. 10 Tablets, 100ml, 1 Vial',
|
||||||
|
`units_per_pack` INT DEFAULT 10 COMMENT 'Basic sellable loose units in 1 pack',
|
||||||
|
`drug_schedule` VARCHAR(30) DEFAULT 'Schedule H' COMMENT 'OTC, Schedule H, Schedule H1, Schedule X, Narcotic',
|
||||||
|
`manufacturer_name` VARCHAR(150) DEFAULT NULL,
|
||||||
|
`barcode` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`min_reorder_level` INT DEFAULT 10,
|
||||||
|
`is_active` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`snomed_ct_code` VARCHAR(50) DEFAULT NULL COMMENT 'SNOMED-CT clinical drug code',
|
||||||
|
`snomed_display` VARCHAR(255) DEFAULT NULL COMMENT 'SNOMED-CT clinical term',
|
||||||
|
INDEX `idx_item_name` (`item_name`),
|
||||||
|
INDEX `idx_generic` (`generic_name`),
|
||||||
|
INDEX `idx_barcode` (`barcode`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- mst_sales.refund_ref_no
|
-- 5. mst_batches
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales' AND COLUMN_NAME = 'refund_ref_no');
|
CREATE TABLE IF NOT EXISTS `mst_batches` (
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales` ADD COLUMN `refund_ref_no` VARCHAR(100) NULL AFTER `refund_mode`', 'SELECT 1');
|
`batch_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
`store_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_no` VARCHAR(100) NOT NULL,
|
||||||
|
`mfg_date` DATE DEFAULT NULL,
|
||||||
|
`expiry_date` DATE NOT NULL COMMENT 'Used for FEFO ordering and expired stock locks',
|
||||||
|
`mrp` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`ptr` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Price to Retailer / Purchase rate before GST',
|
||||||
|
`purchase_rate_net` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Net landing cost after GST and discount',
|
||||||
|
`gst_rate` DECIMAL(5,2) DEFAULT 12.00,
|
||||||
|
`barcode` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store_item` (`store_id`, `item_id`),
|
||||||
|
INDEX `idx_batch_no` (`batch_no`),
|
||||||
|
INDEX `idx_expiry` (`expiry_date`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- 6. mst_stock
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_stock` (
|
||||||
|
`stock_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_id` INT NOT NULL,
|
||||||
|
`current_qty` INT NOT NULL DEFAULT 0 COMMENT 'Stock in basic units (e.g. loose tablets or bottles)',
|
||||||
|
`reserved_qty` INT NOT NULL DEFAULT 0,
|
||||||
|
`last_updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE KEY `uniq_store_item_batch` (`store_id`, `item_id`, `batch_id`),
|
||||||
|
INDEX `idx_store` (`store_id`),
|
||||||
|
INDEX `idx_item` (`item_id`),
|
||||||
|
INDEX `idx_batch` (`batch_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- 2. Add Return Item tracking columns to mst_sales_items (if not exists)
|
-- 7. mst_suppliers
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_suppliers` (
|
||||||
|
`supplier_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`supplier_name` VARCHAR(150) NOT NULL,
|
||||||
|
`dl_no_20b` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`dl_no_21b` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`gstin` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`pan_no` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`contact_person` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`phone` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`email` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`address` TEXT DEFAULT NULL,
|
||||||
|
`state_code` VARCHAR(5) DEFAULT '07',
|
||||||
|
`credit_days` INT DEFAULT 30,
|
||||||
|
`bank_details` TEXT DEFAULT NULL,
|
||||||
|
`is_active` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_supplier_name` (`supplier_name`),
|
||||||
|
INDEX `idx_gstin` (`gstin`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- mst_sales_items.item_type
|
-- 8. mst_purchases
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales_items' AND COLUMN_NAME = 'item_type');
|
CREATE TABLE IF NOT EXISTS `mst_purchases` (
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales_items` ADD COLUMN `item_type` ENUM(\'SALE\', \'RETURN\') NOT NULL DEFAULT \'SALE\' AFTER `qty`', 'SELECT 1');
|
`purchase_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
`store_id` INT NOT NULL,
|
||||||
|
`supplier_id` INT NOT NULL,
|
||||||
|
`supplier_invoice_no` VARCHAR(100) NOT NULL,
|
||||||
|
`invoice_date` DATE NOT NULL,
|
||||||
|
`received_date` DATE NOT NULL,
|
||||||
|
`due_date` DATE DEFAULT NULL,
|
||||||
|
`taxable_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`cgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`discount_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`round_off` DECIMAL(5,2) DEFAULT 0.00,
|
||||||
|
`net_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`paid_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`payment_status` VARCHAR(20) DEFAULT 'unpaid' COMMENT 'unpaid, partial, paid',
|
||||||
|
`remarks` TEXT DEFAULT NULL,
|
||||||
|
`created_by` INT DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store` (`store_id`),
|
||||||
|
INDEX `idx_supplier` (`supplier_id`),
|
||||||
|
INDEX `idx_invoice_date` (`invoice_date`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- mst_sales_items.return_condition
|
-- 9. mst_purchase_items
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales_items' AND COLUMN_NAME = 'return_condition');
|
CREATE TABLE IF NOT EXISTS `mst_purchase_items` (
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales_items` ADD COLUMN `return_condition` ENUM(\'RESTOCKED\', \'DAMAGED\', \'EXPIRED\') DEFAULT \'RESTOCKED\' AFTER `item_type`', 'SELECT 1');
|
`purchase_item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
`purchase_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
-- mst_sales_items.ref_sale_id
|
`batch_no` VARCHAR(100) NOT NULL,
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales_items' AND COLUMN_NAME = 'ref_sale_id');
|
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales_items` ADD COLUMN `ref_sale_id` INT UNSIGNED NULL AFTER `return_condition`', 'SELECT 1');
|
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
||||||
|
|
||||||
-- mst_sales_items.ref_invoice_no
|
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales_items' AND COLUMN_NAME = 'ref_invoice_no');
|
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales_items` ADD COLUMN `ref_invoice_no` VARCHAR(50) NULL AFTER `ref_sale_id`', 'SELECT 1');
|
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
||||||
|
|
||||||
-- mst_sales_items.return_reason
|
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales_items' AND COLUMN_NAME = 'return_reason');
|
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales_items` ADD COLUMN `return_reason` VARCHAR(255) NULL AFTER `ref_invoice_no`', 'SELECT 1');
|
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
||||||
|
|
||||||
-- mst_sales_items.is_restocked
|
|
||||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'mst_sales_items' AND COLUMN_NAME = 'is_restocked');
|
|
||||||
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `mst_sales_items` ADD COLUMN `is_restocked` TINYINT(1) DEFAULT 1 AFTER `return_reason`', 'SELECT 1');
|
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
||||||
|
|
||||||
|
|
||||||
-- 3. Create mst_sale_returns (Sequential GST Credit Notes)
|
|
||||||
CREATE TABLE IF NOT EXISTS `mst_sale_returns` (
|
|
||||||
`return_id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
`store_id` INT UNSIGNED NOT NULL,
|
|
||||||
`credit_note_no` VARCHAR(50) NOT NULL UNIQUE,
|
|
||||||
`return_date` DATETIME NOT NULL,
|
|
||||||
`original_sale_id` INT UNSIGNED NULL,
|
|
||||||
`original_invoice_no` VARCHAR(50) NULL,
|
|
||||||
`new_sale_id` INT UNSIGNED NULL,
|
|
||||||
`patient_id` INT UNSIGNED NULL,
|
|
||||||
`uhid` VARCHAR(50) NULL,
|
|
||||||
`patient_name` VARCHAR(150) NULL,
|
|
||||||
`patient_mobile` VARCHAR(20) NULL,
|
|
||||||
`return_reason` VARCHAR(255) NULL,
|
|
||||||
`gross_refund_amount` DECIMAL(12,2) DEFAULT 0.00,
|
|
||||||
`discount_reversed_amount` DECIMAL(12,2) DEFAULT 0.00,
|
|
||||||
`taxable_refund_amount` DECIMAL(12,2) DEFAULT 0.00,
|
|
||||||
`cgst_refund_amount` DECIMAL(12,2) DEFAULT 0.00,
|
|
||||||
`sgst_refund_amount` DECIMAL(12,2) DEFAULT 0.00,
|
|
||||||
`igst_refund_amount` DECIMAL(12,2) DEFAULT 0.00,
|
|
||||||
`round_off` DECIMAL(6,2) DEFAULT 0.00,
|
|
||||||
`net_refund_amount` DECIMAL(12,2) DEFAULT 0.00,
|
|
||||||
`refund_mode` VARCHAR(50) DEFAULT 'EXCHANGE_BILL_ADJUSTMENT',
|
|
||||||
`refund_ref_no` VARCHAR(100) NULL,
|
|
||||||
`restock_condition` ENUM('RESTOCKED', 'DAMAGED', 'EXPIRED') DEFAULT 'RESTOCKED',
|
|
||||||
`remarks` TEXT NULL,
|
|
||||||
`created_by` INT UNSIGNED NOT NULL DEFAULT 1,
|
|
||||||
`created_at` DATETIME NOT NULL,
|
|
||||||
KEY `idx_store_date` (`store_id`, `return_date`),
|
|
||||||
KEY `idx_orig_sale` (`original_sale_id`),
|
|
||||||
KEY `idx_new_sale` (`new_sale_id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
|
|
||||||
-- 4. Create mst_sale_return_items
|
|
||||||
CREATE TABLE IF NOT EXISTS `mst_sale_return_items` (
|
|
||||||
`return_item_id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
`return_id` INT UNSIGNED NOT NULL,
|
|
||||||
`sale_item_id` INT UNSIGNED NULL,
|
|
||||||
`item_id` INT UNSIGNED NOT NULL,
|
|
||||||
`batch_id` INT UNSIGNED NOT NULL,
|
|
||||||
`batch_no` VARCHAR(50) NOT NULL,
|
|
||||||
`expiry_date` DATE NOT NULL,
|
`expiry_date` DATE NOT NULL,
|
||||||
`hsn_code` VARCHAR(20) NULL,
|
`qty_packs` INT NOT NULL DEFAULT 1,
|
||||||
`units_per_pack` INT NOT NULL DEFAULT 1,
|
`free_qty_packs` INT DEFAULT 0 COMMENT 'e.g. 10 + 1 scheme',
|
||||||
`return_sell_unit` VARCHAR(20) NOT NULL DEFAULT 'Tablet',
|
`units_per_pack` INT DEFAULT 10,
|
||||||
`return_qty` INT NOT NULL DEFAULT 1,
|
`total_units` INT NOT NULL,
|
||||||
`return_total_units` INT NOT NULL DEFAULT 1,
|
`mrp` DECIMAL(10,2) NOT NULL,
|
||||||
`unit_price` DECIMAL(10,2) NOT NULL,
|
`ptr` DECIMAL(10,2) NOT NULL,
|
||||||
`taxable_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
`discount_pct` DECIMAL(5,2) DEFAULT 0.00,
|
||||||
`gst_rate` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
`hsn_code` VARCHAR(20) DEFAULT '3004',
|
||||||
|
`gst_rate` DECIMAL(5,2) DEFAULT 12.00,
|
||||||
|
`taxable_value` DECIMAL(10,2) NOT NULL,
|
||||||
|
`cgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`total_amount` DECIMAL(10,2) NOT NULL,
|
||||||
|
`net_unit_landing_cost` DECIMAL(10,2) NOT NULL,
|
||||||
|
INDEX `idx_purchase` (`purchase_id`),
|
||||||
|
INDEX `idx_item` (`item_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- 10. mst_sales
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_sales` (
|
||||||
|
`sale_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`invoice_no` VARCHAR(100) NOT NULL UNIQUE,
|
||||||
|
`sale_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`patient_type` VARCHAR(30) DEFAULT 'Walk-in' COMMENT 'Walk-in, OPD, IPD',
|
||||||
|
`uhid` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`patient_id` INT DEFAULT NULL,
|
||||||
|
`opd_id` INT DEFAULT NULL,
|
||||||
|
`ipd_id` INT DEFAULT NULL,
|
||||||
|
`patient_name` VARCHAR(150) NOT NULL,
|
||||||
|
`patient_mobile` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`patient_address` TEXT DEFAULT NULL,
|
||||||
|
`age` VARCHAR(30) DEFAULT NULL,
|
||||||
|
`gender` VARCHAR(20) DEFAULT NULL,
|
||||||
|
`doctor_id` INT DEFAULT NULL,
|
||||||
|
`doctor_name` VARCHAR(150) DEFAULT NULL,
|
||||||
|
`doctor_reg_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`ward_name` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`bed_no` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`gross_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`return_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`is_exchange_bill` TINYINT(1) NOT NULL DEFAULT 0,
|
||||||
|
`discount_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`bill_discount_type` VARCHAR(10) DEFAULT 'pct',
|
||||||
|
`bill_discount_val` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`taxable_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
`cgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
`cgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
`sgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
`sgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
`total_refund_amount` DECIMAL(12,2) NOT NULL,
|
`igst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
`return_condition` ENUM('RESTOCKED', 'DAMAGED', 'EXPIRED') DEFAULT 'RESTOCKED',
|
`round_off` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
||||||
`is_restocked` TINYINT(1) DEFAULT 1,
|
`net_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_mode` VARCHAR(30) DEFAULT NULL,
|
||||||
|
`refund_ref_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`payment_mode` VARCHAR(30) DEFAULT 'Cash' COMMENT 'Cash, UPI, Card, Mixed, IPD_Credit',
|
||||||
|
`cash_paid` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`upi_paid` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`card_paid` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`credit_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`payment_reference` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`bank_name` VARCHAR(100) DEFAULT '',
|
||||||
|
`upi_ref_no` VARCHAR(100) DEFAULT '',
|
||||||
|
`card_ref_no` VARCHAR(100) DEFAULT '',
|
||||||
|
`is_bank_reconciled` TINYINT(1) DEFAULT 0,
|
||||||
|
`reconciled_at` DATETIME DEFAULT NULL,
|
||||||
|
`reconciled_by` VARCHAR(100) DEFAULT '',
|
||||||
|
`reconciled_notes` TEXT DEFAULT NULL,
|
||||||
|
`ipd_charge_id` INT DEFAULT NULL,
|
||||||
|
`schedule_h1_flag` TINYINT(1) DEFAULT 0,
|
||||||
|
`status` VARCHAR(30) DEFAULT 'completed' COMMENT 'completed, cancelled, refunded',
|
||||||
|
`created_by` INT DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`abha_id` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`abha_address` VARCHAR(120) DEFAULT NULL,
|
||||||
|
`abdm_care_context_ref` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`abdm_care_context_display` VARCHAR(255) DEFAULT NULL,
|
||||||
|
`abdm_fhir_bundle_json` LONGTEXT DEFAULT NULL,
|
||||||
|
`abdm_sync_status` VARCHAR(30) DEFAULT 'PENDING',
|
||||||
|
INDEX `idx_store_date` (`store_id`, `sale_date`),
|
||||||
|
INDEX `idx_uhid` (`uhid`),
|
||||||
|
INDEX `idx_opd` (`opd_id`),
|
||||||
|
INDEX `idx_ipd` (`ipd_id`),
|
||||||
|
INDEX `idx_invoice` (`invoice_no`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- 11. mst_sales_items
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_sales_items` (
|
||||||
|
`sale_item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`sale_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_id` INT NOT NULL,
|
||||||
|
`batch_no` VARCHAR(100) NOT NULL,
|
||||||
|
`expiry_date` DATE NOT NULL,
|
||||||
|
`qty` INT NOT NULL DEFAULT 1,
|
||||||
|
`item_type` VARCHAR(30) NOT NULL DEFAULT 'SALE',
|
||||||
|
`return_condition` VARCHAR(30) NOT NULL DEFAULT 'RESTOCKED',
|
||||||
|
`ref_sale_id` INT DEFAULT NULL,
|
||||||
|
`ref_invoice_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`return_reason` VARCHAR(255) DEFAULT NULL,
|
||||||
|
`is_restocked` TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
|
`sell_unit` VARCHAR(30) DEFAULT 'Strip',
|
||||||
|
`units_per_pack` INT DEFAULT 1,
|
||||||
|
`total_units` INT DEFAULT 1,
|
||||||
|
`unit_price` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`loose_qty` INT DEFAULT 0,
|
||||||
|
`pack_qty` DECIMAL(10,2) DEFAULT 1.00,
|
||||||
|
`unit_mrp` DECIMAL(10,2) NOT NULL,
|
||||||
|
`discount_type` VARCHAR(10) DEFAULT 'pct',
|
||||||
|
`discount_val` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`discount_pct` DECIMAL(5,2) DEFAULT 0.00,
|
||||||
|
`discount_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`hsn_code` VARCHAR(20) DEFAULT '3004',
|
||||||
|
`gst_rate` DECIMAL(5,2) DEFAULT 12.00,
|
||||||
|
`taxable_value` DECIMAL(10,2) NOT NULL,
|
||||||
|
`cgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`total_amount` DECIMAL(10,2) NOT NULL,
|
||||||
|
INDEX `idx_sale` (`sale_id`),
|
||||||
|
INDEX `idx_item` (`item_id`),
|
||||||
|
INDEX `idx_batch` (`batch_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- 12. mst_sale_returns (Sequential GST Credit Notes)
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_sale_returns` (
|
||||||
|
`return_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`credit_note_no` VARCHAR(100) NOT NULL,
|
||||||
|
`return_date` DATETIME NOT NULL,
|
||||||
|
`original_sale_id` INT DEFAULT NULL,
|
||||||
|
`original_invoice_no` VARCHAR(100) NOT NULL,
|
||||||
|
`new_sale_id` INT DEFAULT NULL,
|
||||||
|
`patient_id` INT DEFAULT NULL,
|
||||||
|
`uhid` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`patient_name` VARCHAR(150) NOT NULL,
|
||||||
|
`patient_mobile` VARCHAR(50) DEFAULT NULL,
|
||||||
|
`return_reason` VARCHAR(255) DEFAULT NULL,
|
||||||
|
`gross_refund_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`discount_reversed_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`taxable_refund_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`cgst_refund_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`sgst_refund_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`igst_refund_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`round_off` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`net_refund_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_mode` VARCHAR(30) NOT NULL DEFAULT 'Cash',
|
||||||
|
`refund_ref_no` VARCHAR(100) DEFAULT NULL,
|
||||||
|
`restock_condition` VARCHAR(50) NOT NULL DEFAULT 'RESTOCKED',
|
||||||
|
`remarks` TEXT DEFAULT NULL,
|
||||||
|
`created_by` INT NOT NULL DEFAULT 1,
|
||||||
`created_at` DATETIME NOT NULL,
|
`created_at` DATETIME NOT NULL,
|
||||||
|
KEY `idx_store_date` (`store_id`, `return_date`),
|
||||||
|
KEY `idx_orig_invoice` (`original_invoice_no`),
|
||||||
|
KEY `idx_cn_no` (`credit_note_no`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- 13. mst_sale_return_items
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_sale_return_items` (
|
||||||
|
`return_item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`return_id` INT NOT NULL,
|
||||||
|
`sale_item_id` INT DEFAULT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`item_name` VARCHAR(200) NOT NULL,
|
||||||
|
`batch_id` INT NOT NULL,
|
||||||
|
`batch_no` VARCHAR(100) NOT NULL,
|
||||||
|
`expiry_date` DATE DEFAULT NULL,
|
||||||
|
`return_sell_unit` VARCHAR(30) NOT NULL DEFAULT 'Tablet',
|
||||||
|
`return_qty` DECIMAL(10,2) NOT NULL DEFAULT 1.00,
|
||||||
|
`units_per_pack` INT NOT NULL DEFAULT 1,
|
||||||
|
`return_total_units` INT NOT NULL DEFAULT 1,
|
||||||
|
`unit_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_rate` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`discount_pct` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`discount_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`hsn_code` VARCHAR(20) NOT NULL DEFAULT '3004',
|
||||||
|
`gst_rate` DECIMAL(5,2) NOT NULL DEFAULT 12.00,
|
||||||
|
`taxable_value` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`cgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`sgst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`igst_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`refund_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`is_restocked` TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
KEY `idx_return_id` (`return_id`),
|
KEY `idx_return_id` (`return_id`),
|
||||||
KEY `idx_item_id` (`item_id`),
|
KEY `idx_item_batch` (`item_id`, `batch_id`)
|
||||||
KEY `idx_batch_id` (`batch_id`)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
|
-- 14. mst_transfers
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_transfers` (
|
||||||
|
`transfer_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`transfer_no` VARCHAR(100) NOT NULL UNIQUE,
|
||||||
|
`from_store_id` INT NOT NULL,
|
||||||
|
`to_store_id` INT NOT NULL,
|
||||||
|
`status` VARCHAR(30) DEFAULT 'requested' COMMENT 'requested, approved, dispatched, received, rejected',
|
||||||
|
`requested_by` INT DEFAULT NULL,
|
||||||
|
`dispatched_by` INT DEFAULT NULL,
|
||||||
|
`received_by` INT DEFAULT NULL,
|
||||||
|
`request_date` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`dispatch_date` DATETIME DEFAULT NULL,
|
||||||
|
`receive_date` DATETIME DEFAULT NULL,
|
||||||
|
`remarks` TEXT DEFAULT NULL,
|
||||||
|
INDEX `idx_from_to` (`from_store_id`, `to_store_id`),
|
||||||
|
INDEX `idx_status` (`status`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- 5. Seed Account Head 3005: Sales Returns & Customer Refunds
|
-- 15. mst_transfer_items
|
||||||
INSERT INTO `mst_account_heads` (`head_code`, `head_name`, `head_type`, `is_system`, `status`, `created_at`)
|
CREATE TABLE IF NOT EXISTS `mst_transfer_items` (
|
||||||
SELECT '3005', 'Sales Returns & Customer Refunds', 'Expense', 1, 'active', NOW()
|
`transfer_item_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
WHERE NOT EXISTS (
|
`transfer_id` INT NOT NULL,
|
||||||
SELECT 1 FROM `mst_account_heads` WHERE `head_code` = '3005'
|
`item_id` INT NOT NULL,
|
||||||
);
|
`batch_id` INT DEFAULT NULL,
|
||||||
|
`requested_qty` INT NOT NULL,
|
||||||
|
`dispatched_qty` INT DEFAULT 0,
|
||||||
|
`received_qty` INT DEFAULT 0,
|
||||||
|
INDEX `idx_transfer` (`transfer_id`),
|
||||||
|
INDEX `idx_item` (`item_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- 16. mst_account_heads
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_account_heads` (
|
||||||
|
`head_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`head_code` VARCHAR(50) NOT NULL UNIQUE,
|
||||||
|
`head_name` VARCHAR(150) NOT NULL,
|
||||||
|
`head_type` VARCHAR(50) NOT NULL COMMENT 'Asset, Liability, Equity, Income, Expense',
|
||||||
|
`parent_id` INT DEFAULT NULL,
|
||||||
|
`is_system` TINYINT(1) DEFAULT 1,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- 17. mst_ledger_entries
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_ledger_entries` (
|
||||||
|
`entry_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`voucher_no` VARCHAR(100) NOT NULL,
|
||||||
|
`voucher_type` VARCHAR(50) NOT NULL COMMENT 'SALE, PURCHASE, PAYMENT, RECEIPT, CONTRA, ADJUSTMENT',
|
||||||
|
`voucher_date` DATE NOT NULL,
|
||||||
|
`account_head_id` INT NOT NULL,
|
||||||
|
`debit_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`credit_amount` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`reference_type` VARCHAR(50) DEFAULT NULL COMMENT 'sales_invoice, purchase_invoice, supplier_payment, patient_credit',
|
||||||
|
`reference_id` INT DEFAULT NULL,
|
||||||
|
`narration` TEXT DEFAULT NULL,
|
||||||
|
`reconciled_flag` TINYINT(1) DEFAULT 0,
|
||||||
|
`reconciled_at` DATETIME DEFAULT NULL,
|
||||||
|
`reconciled_ref` VARCHAR(100) DEFAULT '',
|
||||||
|
`created_by` INT DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store_date` (`store_id`, `voucher_date`),
|
||||||
|
INDEX `idx_head` (`account_head_id`),
|
||||||
|
INDEX `idx_voucher` (`voucher_no`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- 18. mst_stock_audit
|
||||||
|
CREATE TABLE IF NOT EXISTS `mst_stock_audit` (
|
||||||
|
`audit_id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`store_id` INT NOT NULL,
|
||||||
|
`item_id` INT NOT NULL,
|
||||||
|
`batch_id` INT NOT NULL,
|
||||||
|
`audit_type` VARCHAR(50) NOT NULL COMMENT 'OPENING_STOCK, DAMAGE, BREAKAGE, EXPIRY_DUMP, PHYSICAL_VARIATION',
|
||||||
|
`system_qty` INT NOT NULL DEFAULT 0,
|
||||||
|
`physical_qty` INT NOT NULL DEFAULT 0,
|
||||||
|
`variation_qty` INT NOT NULL DEFAULT 0,
|
||||||
|
`rate` DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
`total_value` DECIMAL(12,2) DEFAULT 0.00,
|
||||||
|
`remarks` TEXT DEFAULT NULL,
|
||||||
|
`conducted_by` INT DEFAULT NULL,
|
||||||
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX `idx_store_audit` (`store_id`, `audit_type`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- SEED DATA (System Accounts, Stores, Catalog, Batches, Stock)
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
|
||||||
|
INSERT IGNORE INTO `mst_account_heads` (`head_code`, `head_name`, `head_type`, `is_system`, `created_at`) VALUES
|
||||||
|
('1001', 'Cash in Hand', 'Asset', 1, NOW()),
|
||||||
|
('1002', 'Bank Account / UPI Clearing', 'Asset', 1, NOW()),
|
||||||
|
('1003', 'Stock in Hand / Inventory Valuation', 'Asset', 1, NOW()),
|
||||||
|
('1004', 'Sundry Debtors / Patient Receivables', 'Asset', 1, NOW()),
|
||||||
|
('1005', 'IPD Credit Hospital Running Ledger', 'Asset', 1, NOW()),
|
||||||
|
('1006', 'Input CGST Credit', 'Asset', 1, NOW()),
|
||||||
|
('1007', 'Input SGST Credit', 'Asset', 1, NOW()),
|
||||||
|
('1008', 'Input IGST Credit', 'Asset', 1, NOW()),
|
||||||
|
('2001', 'Sundry Creditors / Supplier Accounts', 'Liability', 1, NOW()),
|
||||||
|
('2002', 'Output CGST Payable', 'Liability', 1, NOW()),
|
||||||
|
('2003', 'Output SGST Payable', 'Liability', 1, NOW()),
|
||||||
|
('2004', 'Output IGST Payable', 'Liability', 1, NOW()),
|
||||||
|
('3001', 'Pharmacy Sales Account (Taxable)', 'Income', 1, NOW()),
|
||||||
|
('3002', 'Pharmacy Sales Account (Exempt)', 'Income', 1, NOW()),
|
||||||
|
('3003', 'Discounts Received on Purchases', 'Income', 1, NOW()),
|
||||||
|
('3004', 'Opening Stock Capital Balance', 'Equity', 1, NOW()),
|
||||||
|
('3005', 'Sales Returns & Customer Refunds', 'Expense', 1, NOW()),
|
||||||
|
('4001', 'Cost of Goods Sold / Purchase Inward', 'Expense', 1, NOW()),
|
||||||
|
('4002', 'Discounts Allowed on Sales', 'Expense', 1, NOW()),
|
||||||
|
('4003', 'Medicine Expiry & Breakage Loss', 'Expense', 1, NOW());
|
||||||
|
|
||||||
|
-- Seed Default Stores if none exist
|
||||||
|
INSERT INTO `mst_stores` (
|
||||||
|
`store_id`, `store_code`, `store_slug`, `store_name`, `building_name`, `floor_no`, `room_no`, `is_main_store`,
|
||||||
|
`drug_license_no_20b`, `drug_license_no_21b`, `gstin`, `pan_no`, `fssai_no`, `state_code`, `state_name`,
|
||||||
|
`registered_pharmacist_name`, `pharmacist_reg_no`, `contact_phone`, `contact_email`, `address`,
|
||||||
|
`invoice_prefix`, `credit_note_prefix`, `next_invoice_no`, `next_credit_note_no`, `upi_id`, `security_key`,
|
||||||
|
`abdm_hfr_id`, `abdm_hip_id`, `pharmacist_hpr_id`, `terms_conditions`, `is_active`, `created_at`
|
||||||
|
)
|
||||||
|
SELECT 1, 'ST-MAIN', 'storea', 'City Hospital Central Pharmacy', 'Main Hospital Block A', 'Ground Floor', 'Room 101', 1,
|
||||||
|
'DL-20B-DEL-10928', 'DL-21B-DEL-10929', '07AAAAA0000A1Z5', 'AAAAA0000A', '10020011000123', '07', 'Delhi',
|
||||||
|
'Rajesh Kumar, B.Pharm', 'DPC-Reg-45892', '+91 9876543210', 'pharmacy@cityhospital.com', 'Plot 12, Medical Enclave, Main Hospital Block, Delhi',
|
||||||
|
'MAIN/26-27/', 'CRN/', 1001, 1, 'cityhospital@upi', 'HMS-80F6ED-297',
|
||||||
|
'IN0710001234', 'HIP-CITYHOSP-01', '91-8822-4411-9901', '1. Goods once sold will be returned as per Drug Rules within 7 days with bill.\n2. Keep medicines stored below 25°C away from direct sunlight.', 1, NOW()
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `mst_stores` WHERE `store_id` = 1);
|
||||||
|
|
||||||
|
INSERT INTO `mst_stores` (
|
||||||
|
`store_id`, `store_code`, `store_slug`, `store_name`, `building_name`, `floor_no`, `room_no`, `is_main_store`,
|
||||||
|
`drug_license_no_20b`, `drug_license_no_21b`, `gstin`, `pan_no`, `fssai_no`, `state_code`, `state_name`,
|
||||||
|
`registered_pharmacist_name`, `pharmacist_reg_no`, `contact_phone`, `contact_email`, `address`,
|
||||||
|
`invoice_prefix`, `credit_note_prefix`, `next_invoice_no`, `next_credit_note_no`, `upi_id`, `security_key`,
|
||||||
|
`abdm_hfr_id`, `abdm_hip_id`, `pharmacist_hpr_id`, `terms_conditions`, `is_active`, `created_at`
|
||||||
|
)
|
||||||
|
SELECT 2, 'ST-OPD-B2', 'storeb', 'City Medicos - OPD Building Counter', 'OPD & Diagnostic Block B', '1st Floor', 'Counter 2', 0,
|
||||||
|
'DL-20B-DEL-11450', 'DL-21B-DEL-11451', '07BBBBB1111B2Z8', 'BBBBB1111B', '10020011000456', '07', 'Delhi',
|
||||||
|
'Sunil Sharma, D.Pharm', 'DPC-Reg-67210', '+91 9811223344', 'opdpharmacy@cityhospital.com', 'OPD Wing, Block B, 1st Floor, Medical Enclave, Delhi',
|
||||||
|
'OPD/26-27/', 'CRN/', 5001, 1, 'citymedicos@upi', 'HMS-72A1CF-415',
|
||||||
|
'IN0710001234-OPD', 'HIP-CITYHOSP-02', '91-8822-4411-9902', '1. Check expiry and batch at counter.\n2. No exchange on Schedule H/H1 drugs without valid prescription.', 1, NOW()
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `mst_stores` WHERE `store_id` = 2);
|
||||||
|
|
||||||
|
-- Seed Sample Supplier
|
||||||
|
INSERT INTO `mst_suppliers` (
|
||||||
|
`supplier_id`, `supplier_name`, `dl_no_20b`, `dl_no_21b`, `gstin`, `pan_no`, `contact_person`,
|
||||||
|
`phone`, `email`, `address`, `state_code`, `credit_days`, `is_active`, `created_at`
|
||||||
|
)
|
||||||
|
SELECT 1, 'Apex Healthcare Distributors', 'DL-20B-DEL-98441', 'DL-21B-DEL-98442', '07AACCA1234F1Z9',
|
||||||
|
'AACCA1234F', 'Ramesh Gupta', '+91 9811002233', 'sales@apexhealth.in',
|
||||||
|
'45, Wholesale Medicine Market, Bhagirath Palace, Chandni Chowk, Delhi', '07', 30, 1, NOW()
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `mst_suppliers` WHERE `supplier_id` = 1);
|
||||||
|
|
||||||
|
-- Seed Sample Medicines Catalog
|
||||||
|
INSERT IGNORE INTO `mst_items` (`item_id`, `item_name`, `generic_name`, `category`, `hsn_code`, `gst_rate`, `unit_pack`, `units_per_pack`, `drug_schedule`, `manufacturer_name`, `barcode`, `min_reorder_level`, `snomed_ct_code`, `snomed_display`, `is_active`, `created_at`) VALUES
|
||||||
|
(1, 'Augmentin 625 Duo Tablet', 'Amoxycillin (500mg) + Clavulanic Acid (125mg)', 'Tablet', '3004', 12.00, '10 Tablets', 10, 'Schedule H1', 'GSK Pharmaceuticals', '890103000001', 20, '372687004', 'Amoxicillin and clavulanic acid', 1, NOW()),
|
||||||
|
(2, 'Pan 40 Tablet', 'Pantoprazole (40mg)', 'Tablet', '3004', 12.00, '15 Tablets', 15, 'Schedule H', 'Alkem Laboratories', '890103000002', 30, '386965005', 'Pantoprazole', 1, NOW()),
|
||||||
|
(3, 'Dolo 650 Tablet', 'Paracetamol (650mg)', 'Tablet', '3004', 12.00, '15 Tablets', 15, 'OTC', 'Micro Labs Ltd', '890103000003', 50, '387517004', 'Paracetamol', 1, NOW()),
|
||||||
|
(4, 'Azithral 500 Tablet', 'Azithromycin (500mg)', 'Tablet', '3004', 12.00, '5 Tablets', 5, 'Schedule H1', 'Alembic Pharmaceuticals', '890103000004', 15, '387207008', 'Azithromycin', 1, NOW()),
|
||||||
|
(5, 'Monocef 1g Injection', 'Ceftriaxone (1000mg)', 'Injection', '3004', 12.00, '1 Vial', 1, 'Schedule H1', 'Aristo Pharmaceuticals', '890103000005', 25, '387325003', 'Ceftriaxone', 1, NOW()),
|
||||||
|
(6, 'Betadine 10% Ointment', 'Povidone Iodine (10% w/w)', 'Ointment', '3004', 12.00, '20 gm Tube', 1, 'OTC', 'Win-Medicare', '890103000006', 15, NULL, NULL, 1, NOW()),
|
||||||
|
(7, 'Ascoril LS Syrup', 'Levosalbutamol + Ambroxol + Guaifenesin', 'Syrup', '3004', 12.00, '100 ml Bottle', 1, 'Schedule H', 'Glenmark Pharmaceuticals', '890103000007', 20, NULL, NULL, 1, NOW()),
|
||||||
|
(8, 'Telma 40 Tablet', 'Telmisartan (40mg)', 'Tablet', '3004', 12.00, '30 Tablets', 30, 'Schedule H', 'Glenmark Pharmaceuticals', '890103000008', 25, NULL, NULL, 1, NOW()),
|
||||||
|
(9, 'Normal Saline 0.9% IV', 'Sodium Chloride (0.9% w/v)', 'Consumable', '3004', 12.00, '500 ml Bottle', 1, 'Schedule H', 'Aculife Healthcare', '890103000009', 40, NULL, NULL, 1, NOW());
|
||||||
|
|
||||||
|
-- Seed Sample Batches & Stock if empty
|
||||||
|
INSERT IGNORE INTO `mst_batches` (`batch_id`, `store_id`, `item_id`, `batch_no`, `mfg_date`, `expiry_date`, `mrp`, `ptr`, `purchase_rate_net`, `gst_rate`) VALUES
|
||||||
|
(1, 1, 1, 'AUG-2401', '2024-01-01', '2026-10-31', 204.50, 155.00, 173.60, 12.00),
|
||||||
|
(2, 1, 1, 'AUG-2409', '2024-09-01', '2027-04-30', 204.50, 155.00, 173.60, 12.00),
|
||||||
|
(3, 1, 2, 'PAN-5512', '2024-03-01', '2027-02-28', 162.00, 115.00, 128.80, 12.00),
|
||||||
|
(4, 1, 3, 'DOL-9901', '2024-06-01', '2027-06-30', 34.00, 22.50, 25.20, 12.00),
|
||||||
|
(5, 1, 4, 'AZI-3321', '2024-02-01', '2026-12-31', 125.00, 89.00, 99.68, 12.00),
|
||||||
|
(6, 1, 5, 'MON-8810', '2024-05-01', '2026-11-30', 68.00, 48.00, 53.76, 12.00),
|
||||||
|
(7, 2, 1, 'AUG-2401', '2024-01-01', '2026-10-31', 204.50, 155.00, 173.60, 12.00),
|
||||||
|
(8, 2, 2, 'PAN-5512', '2024-03-01', '2027-02-28', 162.00, 115.00, 128.80, 12.00),
|
||||||
|
(9, 2, 3, 'DOL-9901', '2024-06-01', '2027-06-30', 34.00, 22.50, 25.20, 12.00);
|
||||||
|
|
||||||
|
INSERT IGNORE INTO `mst_stock` (`stock_id`, `store_id`, `item_id`, `batch_id`, `current_qty`) VALUES
|
||||||
|
(1, 1, 1, 1, 150),
|
||||||
|
(2, 1, 1, 2, 200),
|
||||||
|
(3, 1, 2, 3, 300),
|
||||||
|
(4, 1, 3, 4, 450),
|
||||||
|
(5, 1, 4, 5, 120),
|
||||||
|
(6, 1, 5, 6, 80),
|
||||||
|
(7, 2, 1, 7, 50),
|
||||||
|
(8, 2, 2, 8, 90),
|
||||||
|
(9, 2, 3, 9, 150);
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user