---
# System prepended metadata

title: SHA GUIDE

---



# 🏥 SHA Integration Setup(HOSIPOA HMIS)

 

  This guide provides step-by-step instructions for integrating SHA into your health system(HOSIPOA), including required Composer packages and database schema changes.

  ---
  
  ## IMPORTANT: Steps to Take When Going Live
  
  ### Generating DHA Keys (Windows, Linux, macOS)

You will need OpenSSL installed on your system. Most Linux and macOS systems have it pre-installed. On Windows, you can use Git Bash or install OpenSSL separately.

### 1. Generate a 2048-bit RSA private key

Open your terminal (Command Prompt, PowerShell, Git Bash, or macOS Terminal) and run:
```bash
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
```
This will create a file named private_key.pem in your current directory. Keep this file secure.

### 2. Extract the corresponding public key
Run the following command in the same terminal:
```bash
openssl rsa -pubout -in private_key.pem -out public_key.pem
```
This will generate public_key.pem, which you can share with the DHA system as required.

# **Additional Notes:**

Ensure you run these commands in a directory where you have write permissions.

Do not share your private key (private_key.pem) with anyone.

These steps work the same on Windows (Git Bash), Linux, and macOS.

  ## 📦 Step 1: Install Required Composer Library

  Install `phpseclib` for RSA and AES encryption/decryption:

  ```bash
  composer require phpseclib/phpseclib:^3.0
```

  ## 📦 Step 2: Install Required Composer Library(Only if you want to update your database with the sha spreadsheet surgical services data)
  
  Install `phpoffice` for php spreadsheet
  
  ```bash
  composer require phpoffice/phpspreadsheet
  ```
## THIS IS A MUST OTHERWISE PAYROLL WILL NOT OUTPUT
  Install `mpdf` for payslip pdf 

  ```bash
  composer require mpdf/mpdf
  ```

---

## Etims First

```sql
ALTER TABLE `tbl_patient_billable_items`
ADD COLUMN `etimsSubmitted` VARCHAR(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT '0',
ADD COLUMN `isCreditNoteSubmitted` TINYINT(1) NOT NULL DEFAULT 0 AFTER `etimsSubmitted`,
ADD COLUMN `etimsSubmittedBy` INT(11) NULL DEFAULT NULL AFTER `isCreditNoteSubmitted`,
ADD COLUMN `creditNoteSubmittedBy` INT(11) NULL DEFAULT NULL AFTER `etimsSubmittedBy`,
ADD COLUMN `mediator_id` VARCHAR(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `creditNoteSubmittedBy`,
ADD COLUMN `consumableStoreID` INT(11) NULL DEFAULT NULL AFTER `mediator_id`,
ADD COLUMN `billItemDiscount` DECIMAL(10,2) NOT NULL DEFAULT 0.00 AFTER `consumableStoreID`,
ADD COLUMN `totalPayableAfterDiscount` DECIMAL(10,2) NOT NULL DEFAULT 0.00 AFTER `billItemDiscount`,
ADD COLUMN `originalQuantity` INT(11) NULL DEFAULT NULL AFTER `totalPayableAfterDiscount`,
ADD COLUMN `originalAmount` DECIMAL(10,2) NULL DEFAULT NULL AFTER `originalQuantity`,
ADD COLUMN `isOPBillItem` INT(11) NOT NULL DEFAULT 1 AFTER `originalAmount`;

ALTER TABLE `invms_stkitem`
ADD COLUMN `etimsItemCode` VARCHAR(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
ADD COLUMN `country_code` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `etimsItemCode`,
ADD COLUMN `itemtype_code` VARCHAR(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `country_code`,
ADD COLUMN `taxtype_code` VARCHAR(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `itemtype_code`,
ADD COLUMN `packaging_code` VARCHAR(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `taxtype_code`,
ADD COLUMN `unit_code` VARCHAR(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `packaging_code`,
ADD COLUMN `procedureclassification_code` VARCHAR(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `unit_code`;

ALTER TABLE `lab_specimen_tests`
ADD COLUMN `etimsItemCode` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `testCategoryTypeID`,
ADD COLUMN `itemClassification` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `etimsItemCode`,
ADD COLUMN `countryID` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `itemClassification`;


ALTER TABLE `setup_procedures`
ADD COLUMN `country_code` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL ,
ADD COLUMN `procedureclassification_code` VARCHAR(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL AFTER `country_code`,
ADD COLUMN `etimsItemCode` VARCHAR(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `procedureclassification_code`,
ADD COLUMN `age_restriction_label` VARCHAR(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `etimsItemCode`;
```

### Cont
```sql
-- ==============================================
-- Table structure for table `etims_invoices`
-- ==============================================

CREATE TABLE `etims_invoices` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `etimsInvoiceNo` VARCHAR(50) NOT NULL UNIQUE,
  `traderInvoiceNo` VARCHAR(50) NOT NULL UNIQUE,
  `totalAmount` DECIMAL(18,2) NOT NULL DEFAULT 0.00,
  `totalTaxableAmount` DECIMAL(18,2) NOT NULL DEFAULT 0.00,
  `totalTaxAmount` DECIMAL(18,2) NOT NULL DEFAULT 0.00,
  `paymentType` VARCHAR(10) NOT NULL,
  `salesTypeCode` VARCHAR(5) NOT NULL,
  `receiptTypeCode` VARCHAR(5) NOT NULL,
  `salesStatusCode` VARCHAR(5) NOT NULL,
  `salesDate` DATETIME NOT NULL,
  `currency` VARCHAR(5) NOT NULL DEFAULT 'KES',
  `invoiceVerificationUrl` TEXT NOT NULL,
  `scuReceiptNo` VARCHAR(50) NOT NULL,
  `customerPin` VARCHAR(50) DEFAULT NULL,
  `signature` VARCHAR(100) NOT NULL,
  `internalData` TEXT NOT NULL,
  `customerName` VARCHAR(255) NOT NULL,
  `scdcId` VARCHAR(50) NOT NULL,
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_general_ci;

-- ==============================================
-- Commit changes
-- ==============================================
COMMIT;

-- ==============================================
-- Table structure for table `etims_credit_notes`
-- ==============================================

CREATE TABLE `etims_credit_notes` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `creditNoteNo` VARCHAR(50) NOT NULL UNIQUE,
  `traderInvoiceNo` VARCHAR(50) NOT NULL,
  `traderOrgInvoiceNo` VARCHAR(50) NOT NULL,
  `totalAmount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  `totalTaxableAmount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  `totalTaxAmount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  `paymentType` VARCHAR(10) NOT NULL,
  `salesTypeCode` VARCHAR(5) NOT NULL,
  `receiptTypeCode` VARCHAR(5) NOT NULL,
  `salesStatusCode` VARCHAR(5) NOT NULL DEFAULT '02',
  `salesDate` DATETIME NOT NULL,
  `currency` VARCHAR(10) NOT NULL DEFAULT 'KES',
  `invoiceVerificationUrl` TEXT DEFAULT NULL,
  `scuReceiptNo` VARCHAR(50) DEFAULT NULL,
  `customerPin` VARCHAR(20) DEFAULT NULL,
  `signature` TEXT DEFAULT NULL,
  `internalData` TEXT DEFAULT NULL,
  `customerName` VARCHAR(255) NOT NULL,
  `scdcId` VARCHAR(50) DEFAULT NULL,
  `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_general_ci;

-- ==============================================
-- Indexes
-- ==============================================
CREATE INDEX `idx_traderInvoiceNo` ON `etims_credit_notes` (`traderInvoiceNo`);
CREATE INDEX `idx_salesDate` ON `etims_credit_notes` (`salesDate`);

-- ==============================================
-- Commit changes
-- ==============================================
COMMIT;
```

# **NB: FOLLOW THE SQL STEPS EXACTLY AS THEY ARE. DO NOT SKIP ANY STEP**

## 🗃 Step 3: Update Your Database Schema

### 1. Add SHA Eligibility Columns to `tbl_registered_patients`

```sql
ALTER TABLE tbl_registered_patients
ADD COLUMN raw_json_response JSON DEFAULT NULL COMMENT '🧾 Full raw JSON received from DHA';

ALTER TABLE tbl_registered_patients 
ADD COLUMN iseligible TINYINT(1) DEFAULT 0 COMMENT '✅ 1 if patient is eligible under SHA, 0 otherwise';

ALTER TABLE tbl_registered_patients 
ADD COLUMN cr_number VARCHAR(50) DEFAULT NULL COMMENT '🆔 Client Registry Number from SHA',
ADD COLUMN coverage_valid_until DATETIME DEFAULT NULL COMMENT '📅 Coverage end date for SHA eligibility';

ALTER TABLE tbl_registered_patients ADD COLUMN is_dependant TINYINT(1) DEFAULT 0;

ALTER TABLE tbl_registered_patients
ADD UNIQUE (cr_number);

```

### 2.👨‍⚕️ Create `tbl_practitioner_details` Table

```sql
CREATE TABLE tbl_practitioner_details (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  raw_json JSON NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES tbl_users(id)
);
```
### 3. 📋 Add DHA Metadata Columns to `setup_procedures`


```sql
ALTER TABLE setup_procedures
ADD COLUMN needs_pre_auth ENUM('Yes', 'No') NOT NULL DEFAULT 'No',
ADD COLUMN service_type ENUM('Outpatient', 'Inpatient', 'Both') NOT NULL DEFAULT 'Outpatient',
ADD COLUMN service_gender ENUM('Male', 'Female', 'Both') NOT NULL DEFAULT 'Both',
ADD COLUMN category_of_health_services ENUM('Inpatient', 'Outpatient','None') DEFAULT NULL COMMENT 'Define if procedure is for Inpatient, Outpatient or None',
ADD COLUMN age_restriction_code VARCHAR(50) DEFAULT 'all';

```

### 4. 🏥 Add DHA Metadata Columns to `tbl_facilites`

```sql
ALTER TABLE tbl_facilites
ADD COLUMN dha_facility_code VARCHAR(20) NULL,
ADD COLUMN dha_found TINYINT(1) NULL,
ADD COLUMN dha_approved TINYINT(1) NULL,
ADD COLUMN dha_facility_level VARCHAR(100) NULL,
ADD COLUMN dha_operational_status VARCHAR(100) NULL,
ADD COLUMN dha_license_expiry_date DATE NULL;
```

### 5. Create `tbl_patient_dependants` Table

```sql
CREATE TABLE `tbl_patient_dependants` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `principal_patient_id` INT NOT NULL,  -- FK to tbl_registered_patients.id
  `principal_cr_number` VARCHAR(50) DEFAULT NULL, -- e.g. CRxxxx from SHA
  `dependant_cr_number` VARCHAR(50) DEFAULT NULL, -- unique SHA CR ID
  `first_name` VARCHAR(100) NOT NULL,
  `middle_name` VARCHAR(100) DEFAULT NULL,
  `last_name` VARCHAR(100) NOT NULL,
  `gender` ENUM('Male', 'Female', 'Other') DEFAULT NULL,
  `dob` DATE DEFAULT NULL,
  `relationship` VARCHAR(50) DEFAULT NULL,  -- e.g. Child, Spouse
  `raw_json` TEXT DEFAULT NULL,             -- Full SHA response for reference
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  PRIMARY KEY (`id`),
  FOREIGN KEY (`principal_patient_id`) REFERENCES `tbl_registered_patients`(`id`)
    ON DELETE CASCADE ON UPDATE CASCADE,
  UNIQUE KEY `uq_dependant_cr` (`dependant_cr_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- Step 1: Add the columns
ALTER TABLE tbl_patient_dependants 
ADD COLUMN identification_type VARCHAR(100) DEFAULT NULL,
ADD COLUMN identification_number VARCHAR(100) DEFAULT NULL,
ADD COLUMN dependant_patient_id INT(11) NOT NULL UNIQUE AFTER dependant_cr_number;

-- Step 2: Add the foreign key constraint
ALTER TABLE tbl_patient_dependants 
ADD CONSTRAINT fk_dependant_patient 
FOREIGN KEY (dependant_patient_id) REFERENCES tbl_registered_patients(id);
```

### 6. Create `tbl_sha_claims_submission`
```sql
CREATE TABLE tbl_sha_claim_submissions (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    mediator_id VARCHAR(100) NOT NULL UNIQUE,
    patient_id INT NOT NULL,
    id_number VARCHAR(50) NOT NULL,
    visit_reference VARCHAR(100) NOT NULL,
    claim_id VARCHAR(100) NOT NULL,
    submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    response_json TEXT
);

ALTER TABLE tbl_sha_claim_submissions
ADD COLUMN last_retry_attempt DATETIME NULL AFTER submitted_at,
ADD COLUMN claim_status VARCHAR(50) AFTER response_json,
ADD COLUMN claim_outcome VARCHAR(100) DEFAULT NULL AFTER claim_status;

ALTER TABLE tbl_sha_claim_submissions
ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP AFTER response_json,
ADD COLUMN is_approved TINYINT(1) DEFAULT 0,
ADD UNIQUE (visit_reference);

ALTER TABLE theatre_request_list ADD COLUMN shaPreAuthSent TINYINT(1) DEFAULT 0;

```


### 7. Create `tbl_sha_inpatientpreauthclaims`

```sql
CREATE TABLE tbl_sha_inpatientpreauthclaims (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    mediator_id VARCHAR(100) NOT NULL UNIQUE,
    patient_id INT NOT NULL,
    id_number VARCHAR(50) NOT NULL,
    visit_reference VARCHAR(100) NOT NULL,
    claim_id VARCHAR(100) NOT NULL,
    preauth_claim_id VARCHAR(100) DEFAULT NULL,
    submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    last_retry_attempt DATETIME NULL,
    response_json TEXT,
    claim_status VARCHAR(50),
    claim_outcome VARCHAR(100) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_approved TINYINT(1) DEFAULT 0,
    UNIQUE (visit_reference)
);
```

### 8. Create `tbl_sha_outpatientpreauthclaims`

```sql=
CREATE TABLE tbl_sha_outpatientpreauthclaims (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    mediator_id VARCHAR(100) NOT NULL UNIQUE,
    patient_id INT NOT NULL,
    id_number VARCHAR(50) NOT NULL,
    visit_reference VARCHAR(100) NOT NULL,
    claim_id VARCHAR(100) NOT NULL,
    preauth_claim_id VARCHAR(100) DEFAULT NULL,
    submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    last_retry_attempt DATETIME NULL,
    response_json TEXT,
    claim_status VARCHAR(50),
    claim_outcome VARCHAR(100) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_approved TINYINT(1) DEFAULT 0,
    UNIQUE (visit_reference)
);
```

### 9. Create `tbl_sha_outpatientpreauthclaims_submissions`
```sql
CREATE TABLE tbl_sha_outpatientpreauthclaims_submissions (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    mediator_id VARCHAR(100) NOT NULL UNIQUE,
    patient_id INT NOT NULL,
    id_number VARCHAR(50) NOT NULL,
    visit_reference VARCHAR(100) NOT NULL,
    claim_id VARCHAR(100) NOT NULL,
    shaPreAuthSent TINYINT(1) DEFAULT 0,
    submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    response_json TEXT
);

ALTER TABLE tbl_sha_outpatientpreauthclaims_submissions
ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP AFTER response_json,
ADD COLUMN is_approved TINYINT(1) DEFAULT 0,
ADD COLUMN last_retry_attempt DATETIME NULL AFTER submitted_at,
ADD COLUMN claim_status VARCHAR(50) AFTER response_json,
ADD COLUMN claim_outcome VARCHAR(100) DEFAULT NULL AFTER claim_status,
ADD UNIQUE (visit_reference);

```


### 10. Create `tbl_sha_preauthclaims_submissions`

```sql
CREATE TABLE tbl_sha_preauthclaims_submissions (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    mediator_id VARCHAR(100) NOT NULL UNIQUE,
    patient_id INT NOT NULL,
    id_number VARCHAR(50) NOT NULL,
    visit_reference VARCHAR(100) NOT NULL UNIQUE,
    claim_id VARCHAR(100) NOT NULL,
    submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    response_json TEXT
);

ALTER TABLE tbl_sha_preauthclaims_submissions
ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP AFTER response_json,
ADD COLUMN is_approved TINYINT(1) DEFAULT 0,
ADD COLUMN last_retry_attempt DATETIME NULL AFTER submitted_at,
ADD COLUMN claim_status VARCHAR(50) AFTER response_json,
ADD COLUMN claim_outcome VARCHAR(100) DEFAULT NULL AFTER claim_status,
ADD UNIQUE (visit_reference);

```

### 11. Create `tbl_sha_fhir_submissions`
```sql
CREATE TABLE tbl_sha_fhir_submissions (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    mediator_id VARCHAR(100) NOT NULL UNIQUE,
    patient_id INT NOT NULL,
    id_number VARCHAR(50) NOT NULL,
    visit_reference VARCHAR(100) NOT NULL,
    claim_id VARCHAR(100) NOT NULL,
    submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    response_json TEXT,
    sent_flag TINYINT(1) DEFAULT 0
);

```

### 12. Create `tbl_facility_levels`

```sql
CREATE TABLE tbl_facility_levels (
    id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

INSERT INTO tbl_facility_levels (id, name) VALUES
(1, 'Level 1'),
(2, 'Level 2'),
(3, 'Level 3'),
(4, 'Level 4'),
(5, 'Level 5'),
(6, 'Level 6');
```

### 13. Create setup_procedure_tariffs

```sql
CREATE TABLE setup_procedure_tariffs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    procedure_id INT NOT NULL,
    facility_level_id INT NOT NULL,
    tariff_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (procedure_id) REFERENCES setup_procedures(id),
    FOREIGN KEY (facility_level_id) REFERENCES tbl_facility_levels(id),
    UNIQUE (procedure_id, facility_level_id)
);

```

### 14. Create tbl_uploaded_documents

```sql
CREATE TABLE `tbl_uploaded_documents` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `patient_id` INT NOT NULL,
    `visit_reference` VARCHAR(50) NOT NULL,
    `document_name` VARCHAR(255) NOT NULL,
    `document_path` VARCHAR(500) NOT NULL,
    `uploaded_by` INT DEFAULT NULL,
    `upload_timestamp` DATETIME DEFAULT CURRENT_TIMESTAMP,
    `document_type` VARCHAR(50) DEFAULT 'PreAuth',  -- e.g. 'PreAuth', 'Claim', etc.
    `status` VARCHAR(50) DEFAULT 'active',          -- optional: active/archived/deleted
    FOREIGN KEY (`patient_id`) REFERENCES `tbl_registered_patients`(`id`) ON DELETE CASCADE
);
```

### 15. Create lab_test_tariffs

```sql
CREATE TABLE `lab_test_tariffs` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `test_id` INT NOT NULL,
  `facility_level_id` INT NOT NULL,
  `tariff_amount` DECIMAL(10,2) NOT NULL,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (`test_id`) REFERENCES `lab_specimen_tests`(`id`) ON DELETE CASCADE,
  FOREIGN KEY (`facility_level_id`) REFERENCES `tbl_facility_levels`(`id`) ON DELETE CASCADE,
  UNIQUE KEY `uq_labtest_facility_level` (`test_id`, `facility_level_id`)
);

```

### 16. Create invms_stkitem_tariffs

```sql
CREATE TABLE invms_stkitem_tariffs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    item_id INT NOT NULL,
    facility_level_id INT NOT NULL,
    tariff_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (item_id) REFERENCES invms_stkitem(id),
    FOREIGN KEY (facility_level_id) REFERENCES tbl_facility_levels(id),
    UNIQUE (item_id, facility_level_id)
);

```

### 17. Create Table tbl_mobile_payment_transactions

```sql
CREATE TABLE `tbl_mobile_payment_transactions` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `userID` INT(11) NOT NULL,
  `visitID` VARCHAR(50) NOT NULL DEFAULT '',
  `transactingCurrency` VARCHAR(19) DEFAULT 'KES',
  `txnReference` VARCHAR(19) NOT NULL,
  `txnAmount` DECIMAL(20,2) NOT NULL,
  `txnDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `MERCHANT_TRANSACTION_ID` VARCHAR(255) NOT NULL,
  `txnStatus` INT(11) NOT NULL DEFAULT 0,
  `txnStatusName` VARCHAR(30) NOT NULL DEFAULT 'PENDING',
  `userPhone` VARCHAR(34) DEFAULT NULL,
  `UIP` VARCHAR(224) DEFAULT NULL,
  `UPC` VARCHAR(224) DEFAULT NULL,
  `transactionTypeID` INT(11) DEFAULT 0,
  `isSynced` INT(11) NOT NULL DEFAULT 0,
  `mpesaReferenceID` VARCHAR(80) DEFAULT NULL,
  `mpesaIPNStatus` VARCHAR(50) DEFAULT NULL,
  `autoVerified` TINYINT(1) DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_txnReference` (`txnReference`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
```
#### 17.1
```sql
ALTER TABLE tbl_mobile_payment_transactions
ADD payerName VARCHAR(255) DEFAULT NULL,
ADD COLUMN isStrayTransaction TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 = Offline (STK Manual), 0 = STK Push',
ADD COLUMN billReferenceNumber VARCHAR(255) NULL;

ALTER TABLE tbl_mobile_payment_transactions DROP INDEX uniq_txnReference;
```

### 18 . Modify setup_facility_departments

```sql
ALTER TABLE setup_facility_departments
ADD COLUMN type_code VARCHAR(50) DEFAULT NULL,
ADD COLUMN type_display VARCHAR(255) DEFAULT NULL;

-- TRIAGE & DOCTORS
UPDATE setup_facility_departments SET type_code = '185389009', type_display = 'Triage'
WHERE departmentName = 'TRIAGE & DOCTORS';

-- DOCTORS
UPDATE setup_facility_departments SET type_code = '408443003', type_display = 'General medical service'
WHERE departmentName = 'DOCTORS';

-- DENTAL
UPDATE setup_facility_departments SET type_code = '408440000', type_display = 'Dental service'
WHERE departmentName = 'DENTAL';

-- MCH
UPDATE setup_facility_departments SET type_code = '408475000', type_display = 'Maternal health clinic service'
WHERE departmentName = 'MCH';

-- OPTICAL/OPTHALMOLOGIST
UPDATE setup_facility_departments SET type_code = '284548002', type_display = 'Ophthalmology service'
WHERE departmentName = 'OPTICAL/OPTHALMOLOGIST';

-- RADIOLOGY
UPDATE setup_facility_departments SET type_code = '408478003', type_display = 'Radiology service'
WHERE departmentName = 'RADIOLOGY';

-- MALE WARD
UPDATE setup_facility_departments SET type_code = '225728007', type_display = 'Male ward'
WHERE departmentName = 'MALE WARD';

-- LABORATORY
UPDATE setup_facility_departments SET type_code = '408459003', type_display = 'Laboratory service'
WHERE departmentName = 'LABORATORY';

-- PHARMACY
UPDATE setup_facility_departments SET type_code = '440655000', type_display = 'Pharmacy service'
WHERE departmentName = 'PHARMACY';

-- ULTRASOUND
UPDATE setup_facility_departments SET type_code = '408472002', type_display = 'Diagnostic ultrasound service'
WHERE departmentName = 'ULTRASOUND';

-- THEATRE/ SURGICAL
UPDATE setup_facility_departments SET type_code = '409967002', type_display = 'Surgical service'
WHERE departmentName = 'THEATRE/ SURGICAL';

-- CASUALTY
UPDATE setup_facility_departments SET type_code = '225728007', type_display = 'Emergency department (casualty)'
WHERE departmentName = 'CASUALTY';

-- PEADS WARD
UPDATE setup_facility_departments SET type_code = '225728002', type_display = 'Pediatric ward'
WHERE departmentName = 'PEADS WARD';

-- PEADS ANNEX
UPDATE setup_facility_departments SET type_code = '225728002', type_display = 'Pediatric ward'
WHERE departmentName = 'PEADS ANNEX';

-- MATERNITY WARD ONE
UPDATE setup_facility_departments SET type_code = '225728003', type_display = 'Maternity ward'
WHERE departmentName = 'MATERNITY WARD ONE';

-- MATERNITY
UPDATE setup_facility_departments SET type_code = '408476004', type_display = 'Maternity service'
WHERE departmentName = 'MATERNITY';

-- NUTRITION
UPDATE setup_facility_departments SET type_code = '408470000', type_display = 'Dietetic service'
WHERE departmentName = 'NUTRITION';

-- DIALYSIS
UPDATE setup_facility_departments SET type_code = '310131000000108', type_display = 'Renal dialysis service'
WHERE departmentName = 'DIALYSIS';

-- PHYSIOTHERAPY
UPDATE setup_facility_departments SET type_code = '408454008', type_display = 'Physiotherapy service'
WHERE departmentName = 'PHYSIOTHERAPY';

-- INPATIENT
UPDATE setup_facility_departments SET type_code = '225728001', type_display = 'Inpatient service'
WHERE departmentName = 'INPATIENT';

-- CCC
UPDATE setup_facility_departments SET type_code = '736253002', type_display = 'HIV care clinic service'
WHERE departmentName = 'CCC';
```

### 19. Alter tbl_disease_symptoms

```sql
ALTER TABLE tbl_disease_symptoms
ADD COLUMN snomedCode VARCHAR(20) NULL,
ADD COLUMN snomed_display_term VARCHAR(255) NULL;
```

### Important #1

```sql
ALTER TABLE invms_stkitem 
ADD COLUMN IF NOT EXISTS ciel_code VARCHAR(50) NULL,
ADD COLUMN IF NOT EXISTS rxnorm_code VARCHAR(50) NULL;

UPDATE setup_procedures 
SET procedureName = REPLACE(procedureName, '\\\'', '\'') 
WHERE procedureName LIKE '%\\\'%';
```


### Suggested Indexing 

```sql
CREATE INDEX idx_principal_id ON tbl_patient_dependants(principal_patient_id);
CREATE INDEX idx_dependant_cr ON tbl_patient_dependants(dependant_cr_number);

-- Critical joins and filters
CREATE INDEX idx_visit_isinpatient_closed_payerid ON visit_db(isInpatient, closed, payer_id);
CREATE INDEX idx_patient_insurance_schemeid ON tbl_patient_insurances(id, insuranceSchemeID);
CREATE INDEX idx_insurance_schemes_firmid ON tbl_insurance_schemes(id, insuranceFirmID);

-- Searchable fields
CREATE INDEX idx_registered_patients_search ON tbl_registered_patients(patientIPOPNumber, firstName, lastName, middleName);

-- Optional: for etims lookup
CREATE INDEX idx_billable_items_refcode_submitted ON tbl_patient_billable_items(billReferenceCode, etimsSubmittedBy, creditNoteSubmittedBy);

```

### **Note**: Indexes were added to optimize SHA Claims loading performance, especially after implementing logic to exclude procedures requiring pre-authorization from this interface.

```sql
CREATE INDEX idx_fib_billingStatus ON finance_insurance_bills(billingStatus);
CREATE INDEX idx_fib_insuranceID ON finance_insurance_bills(insuranceID);
CREATE INDEX idx_fib_insuranceSchemeID ON finance_insurance_bills(insuranceSchemeID);
CREATE INDEX idx_fib_patientID ON finance_insurance_bills(patientID);
CREATE INDEX idx_fib_visitIDReference ON finance_insurance_bills(visitIDReference);
CREATE INDEX idx_fib_dateCreated ON finance_insurance_bills(dateCreated);
CREATE INDEX idx_fib_dateCancelled ON finance_insurance_bills(dateCancelled);
CREATE INDEX idx_fib_dateDispatched ON finance_insurance_bills(dateDispatched);
CREATE INDEX idx_fib_dateDeclined ON finance_insurance_bills(dateDeclined);
CREATE INDEX idx_fib_datePaid ON finance_insurance_bills(datePaid);
CREATE INDEX idx_rp_id ON tbl_registered_patients(id);
CREATE INDEX idx_rp_insuranceMemberNumber ON tbl_registered_patients(insuranceMemberNumber);
CREATE INDEX idx_gif_id ON tbl_insurance_firms(id);
CREATE INDEX idx_tis_id ON tbl_insurance_schemes(id);

CREATE INDEX idx_sha_visit_reference ON tbl_sha_claim_submissions(visit_reference);
CREATE INDEX idx_pbi_reference_item ON tbl_patient_billable_items(billReferenceCode, isProcedureItem, billItemName);
CREATE INDEX idx_sp_procedure_name_pre_auth ON setup_procedures(procedureName, needs_pre_auth);
```

---

## ✅ Summary

This setup ensures:

* You can securely decrypt patient records using RSA & AES.
* Facilities and practitioners can be enriched with DHA data.
* SHA eligibility status and coverage validity are tracked directly in the patient table.

Make sure to:

* Use secure `.pem` keys for decryption.
* Validate and sanitize all incoming data.
* Test API credentials and tokens in **UAT** before moving to **Production**.

---


# SMART,SLADE,M-PESA,& EMAIL(DB Changes)

### Step 1 Alter table *tbl_sys_config*
```sql
ALTER TABLE tbl_sys_config 
ADD COLUMN mpesa_bill_no VARCHAR(50) DEFAULT NULL,
ADD COLUMN mpesa_passkey TEXT DEFAULT NULL,
ADD COLUMN mpesa_consumer_key TEXT DEFAULT NULL,
ADD COLUMN mpesa_consumer_secret TEXT DEFAULT NULL,
ADD COLUMN mail_driver VARCHAR(50) DEFAULT NULL,
ADD COLUMN mail_host VARCHAR(100) DEFAULT NULL,
ADD COLUMN mail_port VARCHAR(10) DEFAULT NULL,
ADD COLUMN mail_username VARCHAR(100) DEFAULT NULL,
ADD COLUMN mail_password VARCHAR(100) DEFAULT NULL,
ADD COLUMN mail_encryption VARCHAR(20) DEFAULT NULL,
ADD COLUMN mail_from_address VARCHAR(100) DEFAULT NULL,
ADD COLUMN mail_from_name VARCHAR(100) DEFAULT NULL,
ADD COLUMN at_username VARCHAR(255),
ADD COLUMN at_api_key TEXT,
ADD COLUMN at_api_url VARCHAR(255),
ADD COLUMN at_sender_id VARCHAR(100),
ADD COLUMN sms_cooldown_months INT DEFAULT 2,
ADD COLUMN sms_cooldown_days INT DEFAULT 30,
ADD COLUMN insurance_rate_type VARCHAR(20) NULL,
ADD COLUMN insurance_flat_rate DECIMAL(10,2) NULL,
ADD COLUMN insurance_percent_rate DECIMAL(10,2) NULL,
ADD COLUMN cash_rate_type VARCHAR(20) NULL,
ADD COLUMN cash_flat_rate DECIMAL(10,2) NULL,
ADD COLUMN cash_percent_rate DECIMAL(10,2) NULL,
ADD COLUMN etims_status TINYINT(1) NOT NULL DEFAULT 0;
```


### Step 2
```sql
ALTER TABLE invms_stkitem 
MODIFY country_code varchar(10) NULL,
MODIFY itemtype_code varchar(50) NULL,
MODIFY taxtype_code varchar(50) NULL,
MODIFY packaging_code varchar(100) NULL,
MODIFY unit_code varchar(100) NULL,
MODIFY procedureclassification_code varchar(100) NULL;
```

### Step 3

```sql
ALTER TABLE tbl_users ADD COLUMN pin VARCHAR(100) DEFAULT NULL;
```

#### Step 3.1

#### For Older Users Without PINs, Set a Default PIN (e.g., '0000')
```sql
UPDATE tbl_users
SET pin = '$2y$10$Rexqyhk0sFq6bldC7oKdLeV9uPzx7PuK6vZHU/em990o2czYRQkNS'
WHERE pin IS NULL OR pin = '';

ALTER TABLE tbl_users 
ADD COLUMN last_password_sms_sent_at DATETIME NULL AFTER phone,
ADD COLUMN last_pin_sms_sent_at DATETIME NULL AFTER last_password_sms_sent_at;

ALTER TABLE `tbl_users`
ADD COLUMN `isSpecialist` TINYINT(1) DEFAULT 0 AFTER `pin`,
ADD COLUMN `consultantCategoryID` INT DEFAULT NULL AFTER `isSpecialist`,
ADD COLUMN `userSpecialtyID` INT DEFAULT NULL AFTER `consultantCategoryID`,
ADD COLUMN `calendarColor` VARCHAR(20) DEFAULT NULL AFTER `userSpecialtyID`,
ADD COLUMN `initials` VARCHAR(10) DEFAULT NULL AFTER `calendarColor`,
ADD COLUMN `userTypeID` INT DEFAULT NULL AFTER `initials`;

ALTER TABLE hr_company_employees 
ADD COLUMN salarySuspended TINYINT(1) DEFAULT 0,
ADD COLUMN isSpecialist TINYINT(1) DEFAULT 0,
ADD COLUMN employeeType VARCHAR(50) DEFAULT NULL;
```


### Step 4
```sql
CREATE TABLE IF NOT EXISTS password_resets (
  id INT AUTO_INCREMENT PRIMARY KEY,
  userID INT NOT NULL,
  token VARCHAR(64) NOT NULL,
  expires_at DATETIME NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (userID) REFERENCES tbl_users(id) ON DELETE CASCADE
);
```

### Step 5
```sql
CREATE TABLE tbl_sent_sms (
    id INT AUTO_INCREMENT PRIMARY KEY,
    recipient_name VARCHAR(255),
    phone_number VARCHAR(20),
    message TEXT,
    sender_id VARCHAR(50),
    cost VARCHAR(20),
    sent_by INT,
    sent_on DATETIME DEFAULT CURRENT_TIMESTAMP
);
```
### Step 6(Removed)

### Step 7
```sql
CREATE TABLE tbl_sms_logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    recipient VARCHAR(20),
    message TEXT,
    status VARCHAR(20),
    receipt_no VARCHAR(50),
    sent_at DATETIME,
    log_response TEXT,
    cost VARCHAR(20) DEFAULT '0.00',
    message_id VARCHAR(100) DEFAULT NULL
);
```
### Step 8 (removed)

### Step 9

### CREATE TABLE  com_outbound_email_tracker

```sql
ALTER TABLE com_sms_recipients 
ADD COLUMN recipientsEmailAddress VARCHAR(255) AFTER recipientsPhoneNumber;

CREATE TABLE `com_outbound_email_tracker` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `emailReference` varchar(120) DEFAULT NULL,
  `emailSubject` varchar(255) DEFAULT NULL,
  `emailText` mediumtext,
  `recipientGroupID` int(11) DEFAULT NULL,
  `createdBYUID` int(11) NOT NULL,
  `UIP` varchar(225) DEFAULT NULL,
  `UPC` varchar(225) DEFAULT NULL,
  `isActive` int(2) NOT NULL DEFAULT '1',
  `datePosted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `startDate` date DEFAULT NULL,
  `templateID` int(11) DEFAULT '0',
  `smsStatus` varchar(45) DEFAULT 'PENDING',
  `totalRecipients` int(11) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
```

### Step 10
```sql
CREATE TABLE `com_processed_outbound_email` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `emailRecipientName` varchar(255) DEFAULT NULL,
  `emailRecipientPhone` varchar(20) DEFAULT NULL,
  `emailMainReference` varchar(120) DEFAULT NULL,
  `emailSubject` varchar(500) DEFAULT NULL,
  `emailMainText` mediumtext,
  `emailTrackerID` int(11) DEFAULT NULL,
  `processedBYUID` int(11) NOT NULL,
  `processedbyUIP` varchar(225) DEFAULT NULL,
  `processedbyUPC` varchar(225) DEFAULT NULL,
  `isActive` int(2) NOT NULL DEFAULT '1',
  `dateProcessed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `isSent` int(2) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
```
### Step 11
```sql
CREATE TABLE smart_api_logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    visit_id INT,
    session_id VARCHAR(100),
    global_id VARCHAR(100),
    raw_response JSON,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE tbl_insurance_schemes
ADD COLUMN isOnSladeSystem INT(1) NOT NULL DEFAULT 0 AFTER isOnSmartSystem,
ADD COLUMN schemeProceduresCopayAmount DECIMAL(18,2) AFTER schemeProceduresCoverAmount;
```

### Step 12(Removed)

### Step 13
```sql
ALTER TABLE tbl_insurance_schemes
ADD COLUMN schemeProceduresCopayType ENUM('fixed','percent') DEFAULT 'fixed' AFTER schemeProceduresCoverAmount;

CREATE TABLE visit_payers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    visitID INT NOT NULL,
    visitReference CHAR(122) NOT NULL,
    payerID INT NOT NULL,
    splitAmount DECIMAL(12,2) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
### Step 14(Removed)

### Step 15
```sql
CREATE TABLE `smart_api_connections` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `smartItemID` INT(11) DEFAULT NULL,
  `Smart_File` BLOB DEFAULT NULL,
  `Exchange_File` BLOB DEFAULT NULL,
  `Global_ID` VARCHAR(50) DEFAULT NULL,
  `UIP` TEXT DEFAULT NULL,
  `UID` INT(11) DEFAULT NULL,
  `UPC` TEXT DEFAULT NULL,
  `dateCreated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `isActive` INT(11) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
```

#### Step 15.1

```sql
ALTER TABLE smart_api_connections
ADD COLUMN patientIPOPNumber VARCHAR(50) NOT NULL AFTER Global_ID,
ADD COLUMN visitIDReference VARCHAR(50) DEFAULT NULL AFTER patientIPOPNumber,
ADD COLUMN isCardRerun TINYINT(1) DEFAULT 0 AFTER visitIDReference,
ADD COLUMN isClaimSubmitted TINYINT(1) DEFAULT 0 AFTER isCardRerun,
ADD COLUMN dateUpdated TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

ALTER TABLE smart_api_connections 
ADD COLUMN RawXML_File LONGTEXT NULL AFTER Exchange_File;
```


### Step 16
```sql
ALTER TABLE visit_db
ADD COLUMN isCancelled INT(11) NOT NULL DEFAULT 0,
ADD COLUMN isCardRerun TINYINT(1) NOT NULL DEFAULT 0 AFTER smartEntryID,
ADD COLUMN isClaimSubmitted TINYINT(1) NOT NULL DEFAULT 0 AFTER isCardRerun;
```

### Step 17

```sql
CREATE TABLE tbl_patient_benefit_pools (
    id INT AUTO_INCREMENT PRIMARY KEY,
    patient_ipop_number VARCHAR(50) NOT NULL UNIQUE, -- enforce uniqueness
    pool_id INT NOT NULL,          -- benefit.id
    pool_nr VARCHAR(10) NOT NULL,  -- benefit.pool_nr
    pool_desc VARCHAR(255),        -- benefit.pool_desc
    amount DECIMAL(12,2),
    copay_type ENUM('FIXED', 'PERCENTAGE') NOT NULL DEFAULT 'FIXED',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP
);
```
### Step 18
```sql
CREATE TABLE slade_visits_log (
    id INT AUTO_INCREMENT PRIMARY KEY,
    member_id VARCHAR(50) NOT NULL,
    otp_code VARCHAR(20) NOT NULL,
    cover_id VARCHAR(50) DEFAULT NULL,
    response_json JSON NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

### Step 19
```sql
CREATE TABLE slade_validaton_log (
    id INT AUTO_INCREMENT PRIMARY KEY,
    beneficiary_id VARCHAR(50) NOT NULL,   -- replaces member_id
    otp VARCHAR(20) NOT NULL,              -- replaces otp_code
    beneficiary_contact VARCHAR(50) DEFAULT NULL,
    cover_id VARCHAR(50) DEFAULT NULL,
    payload_json JSON DEFAULT NULL,
    response_json JSON NOT NULL,
    step VARCHAR(50) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

### Step 20
```sql
CREATE TABLE `tbl_insurance_partners` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `insurancePartnerName` varchar(225) DEFAULT NULL,
  `insurancePartnerTelephone` varchar(34) DEFAULT NULL,
  `insurancePartnerEmailID` varchar(120) DEFAULT NULL,
  `insurancePartnerTown` varchar(120) DEFAULT NULL,
  `insurancePartnerLocation` varchar(120) DEFAULT NULL,
  `insurancePartnerStreet` varchar(120) DEFAULT NULL,
  `insurancePartnerBuilding` varchar(120) DEFAULT NULL,
  `insurancePartnerAddress` varchar(255) DEFAULT NULL,
  `insurancePartnerOfficeNumber` varchar(120) DEFAULT NULL,
  `insurancePartnerLogo` varchar(255) DEFAULT NULL,
  `UIP` varchar(120) DEFAULT NULL,
  `UPC` varchar(255) DEFAULT NULL,
  `UID` int(11) DEFAULT NULL,
  `isActive` int(4) NOT NULL DEFAULT 1,
  `datePosted` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci AUTO_INCREMENT=1;
```

### Step 21
```sql
ALTER TABLE visit_db 
ADD billingSystem INT NULL,
ADD CONSTRAINT fk_visit_insurance_partner
    FOREIGN KEY (billingSystem) REFERENCES tbl_insurance_partners(id)
    ON DELETE SET NULL 
    ON UPDATE CASCADE;
    
ALTER TABLE invms_stkitem 
ADD COLUMN BuyingPrice DECIMAL(15,2) NOT NULL DEFAULT 0;
```

### Step 22(Removed)

### Step 23
```sql
CREATE TABLE tbl_slade_claims (
    id INT AUTO_INCREMENT PRIMARY KEY,
    patient_id INT NOT NULL,                  -- Patient identifier from POST
    visit_id CHAR(122) NOT NULL UNIQUE,       -- Visit ID or reference from POST
    payer_id INT DEFAULT NULL,                -- Payer/insurer from POST
    claim_payload JSON,                       -- Original JSON payload sent
    claim_response JSON,                      -- Raw API response
    claim_invoice_payload LONGTEXT NULL,      -- Invoice payload JSON
    claim_invoice_response LONGTEXT NULL,     -- Invoice response JSON
    isClaimSubmitted TINYINT(1) DEFAULT 0,
    isClaimAttachmentSubmitted TINYINT(1) DEFAULT 0,
    isClaimInvoiceSubmitted TINYINT(1) DEFAULT 0,
    isInvoiceAttachmentSubmitted TINYINT(1) DEFAULT 0,
    claim_reference VARCHAR(100) DEFAULT NULL, -- Slade API claim UUID
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP 
               ON UPDATE CURRENT_TIMESTAMP
);
```
### Step 24
```sql
CREATE TABLE tbl_smart_claims (
    id INT AUTO_INCREMENT PRIMARY KEY,
    session_id BIGINT NOT NULL,                   -- Smart's session_id
    claim_status VARCHAR(50) NOT NULL,            -- e.g. Pending, Billed, Cancelled
    claim_status_flag TINYINT(1) NOT NULL,        -- 1 = Billed, 2 = Pending, 3 = Cancelled
    payer_name VARCHAR(255) NOT NULL,             -- e.g. Jubilee Health Insurance Limited
    patient_number VARCHAR(255) NOT NULL,         -- e.g. SAMWEL NYANDORO
    visit_number VARCHAR(100) NOT NULL,           -- e.g. CH026PID28059D04Sep2025
    scheme_name VARCHAR(255) NOT NULL,            -- e.g. AGANO
    amount DECIMAL(12,2) NOT NULL,                -- e.g. 7400
    invoice_number VARCHAR(100) NOT NULL,         -- e.g. 050153/2025
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uniq_smart_claim (session_id, invoice_number)
);

ALTER TABLE tbl_slade_claims
ADD COLUMN invoice_id VARCHAR(100) DEFAULT NULL AFTER claim_invoice_response;
```
### Step 25(Removed)

### Step 26

```sql
CREATE TABLE tbl_partograph_entries (
    id INT AUTO_INCREMENT PRIMARY KEY,
    patient_id INT NOT NULL,
    cervical_dilation DECIMAL(3,1) NOT NULL,
    fetal_head_descent TINYINT NOT NULL,
    contraction_frequency TINYINT NOT NULL,
    contraction_duration INT NOT NULL,
    maternal_pulse TINYINT NOT NULL,
    bp_systolic TINYINT NOT NULL,
    bp_diastolic TINYINT NOT NULL,
    maternal_temp DECIMAL(3,1) NOT NULL,
    urine_output VARCHAR(50) NOT NULL,
    urine_protein VARCHAR(50) NOT NULL,
    fetal_heart_rate TINYINT NOT NULL,
    amniotic_fluid_status VARCHAR(50) NOT NULL,
    fetal_movements VARCHAR(50) NOT NULL,
    drugs_administered TEXT,
    entered_by INT DEFAULT NULL,
    date_recorded TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX (patient_id)
);

ALTER TABLE `tbl_partograph_entries`
  ADD COLUMN `record_time` DATETIME NULL,
  ADD COLUMN `contraction_strength` VARCHAR(20) NULL,
  ADD COLUMN `moulding` VARCHAR(10) NULL,
  ADD COLUMN `respiratory_rate` INT NULL,
  ADD COLUMN `urine_acetone` VARCHAR(20) NULL,
  ADD COLUMN `fhr_decelerations` VARCHAR(20) NULL,
  ADD COLUMN `oxytocin_dose` VARCHAR(100) NULL,
  ADD COLUMN `iv_fluids` VARCHAR(100) NULL;
```

### Step 27
```sql
ALTER TABLE visit_db
ADD COLUMN sladeAuthorizationToken VARCHAR(225) NULL AFTER smartEntryID;

ALTER TABLE theatre_laboratory_preops 
ADD COLUMN theatreNotes TEXT NULL AFTER otherNotes;

```



### Generate and store latest WHO ICD10 CODES

## Step 1
Download the claML using the below link 

[WHO ICD-10 Download Page](https://icdcdn.who.int/icd10/index.html)

Select only the one labelled `ICD-10 2019 version (including COVID-19 updates)	ClaML more info`

## Step 2

After downloading the zip file, extract and you'll find a file named `icd102019en.xml`

Copy the file to your root project folder in our case we copy it to `hos5 folder`

## Step 3 Create this table if missing
```sql
CREATE TABLE tbl_icd10_diseases (
    id INT AUTO_INCREMENT PRIMARY KEY,
    diagnosisDesc VARCHAR(500) NOT NULL,
    code VARCHAR(20) NOT NULL,
    isActive INT(11) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

```
## Step 5 Now we create a php engine to get the codes and their names

In your project root folder in our case `hos5` create a php file and name it `icd10.php`

In the php file paste this code there

```
<?php
libxml_use_internal_errors(true);

// DB Connection
include_once(__DIR__ . '/sys/config/db-cred.inc.php');
global $C;
$conn = new mysqli($C['DB_HOST'], $C['DB_USER'], $C['DB_PASS'], $C['DB_NAME']);
if ($conn->connect_error) {
    echo json_encode(['status' => 'error', 'message' => 'Database connection failed']);
    exit;
}

$xml = simplexml_load_file('icd102019en.xml');
if (!$xml) {
    echo "Failed to load XML\n";
    exit;
}

$namespaces = $xml->getNamespaces(true);
$nsPrefix = '';
if (isset($namespaces[''])) {
    $nsPrefix = 'claml';
    $xml->registerXPathNamespace($nsPrefix, $namespaces['']);
}

// Prepare queries
$checkStmt = $conn->prepare("SELECT id FROM tbl_icd10_diseases WHERE code = ? LIMIT 1");
$insertStmt = $conn->prepare("INSERT INTO tbl_icd10_diseases (diagnosisDesc, code, isActive) VALUES (?, ?, 1)");

// Look for Class elements where kind="category"
$path = $nsPrefix ? "//{$nsPrefix}:Class[@kind='category']" : "//Class[@kind='category']";
$countInserted = 0;
$countSkipped  = 0;

foreach ($xml->xpath($path) as $class) {
    $code = (string)$class['code'];

    // Get preferred label
    $rubrics = $nsPrefix
        ? $class->xpath("{$nsPrefix}:Rubric[@kind='preferred']/" . "{$nsPrefix}:Label")
        : $class->xpath("Rubric[@kind='preferred']/Label");

    $label = !empty($rubrics) ? trim((string)$rubrics[0]) : '';

    if ($code !== '' && $label !== '') {
        // Check if code already exists
        $checkStmt->bind_param("s", $code);
        $checkStmt->execute();
        $checkStmt->store_result();

        if ($checkStmt->num_rows > 0) {
            $countSkipped++;
            continue;
        }

        // Insert new record
        $insertStmt->bind_param("ss", $label, $code);
        if ($insertStmt->execute()) {
            $countInserted++;
        }
    }
}

$checkStmt->close();
$insertStmt->close();
$conn->close();

echo "Inserted {$countInserted} new ICD10 records.  
Skipped {$countSkipped} duplicate records.";
?>
```

Save the file and head over to your browser and hit this url , in our case `hos5.manager.co.ke/icd10`

**Note**: You must get this message in order to conclude that the operation was successful `Inserted 11243 new ICD10 records. Skipped 0 duplicate records.`

### Theatre sqls
### Step 1
```sql
DROP TABLE theatre_checklist_items;

-- Table structure for table `theatre_checklist_items`
CREATE TABLE `theatre_checklist_items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `subjectName` varchar(255) DEFAULT NULL,
  `checklistItemName` varchar(555) DEFAULT NULL,
  `checkListTypeID` int(11) DEFAULT NULL,
  `isActive` tinyint(1) NOT NULL DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- Dumping initial data for table `theatre_checklist_items`
INSERT INTO `theatre_checklist_items` (`id`, `subjectName`, `checklistItemName`, `checkListTypeID`, `isActive`) VALUES
(1, NULL, 'ID Bands In Place * 2 and Correct', 1, 1),
(2, NULL, 'Consent Form Labelled, Signed & Understood', 1, 1),
(3, NULL, 'Thromboprophylaxis', 1, 1),
(4, NULL, 'Last Food & Drink', 1, 1),
(5, NULL, 'Allergies (Include Food/ Latex/ Medicine etc) Correct Arm Band & Labels', 1, 1),
(6, NULL, 'MRSA Status', 1, 1),
(7, NULL, 'Correct Notes with Drug Chart, Fluid Chart & Labels', 1, 1),
(8, NULL, 'Most Recent Investigations - X-Rays, Scans, Blood etc', 1, 1),
(9, NULL, 'Any Previous Surgery - Metalwork/ Pacemaker', 1, 1),
(10, NULL, 'Any Property to Accompany Patient', 1, 1),
(11, NULL, 'Any Medication to Accompany Patient', 1, 1),
(12, NULL, 'Glasses or Contact Lenses', 1, 1),
(13, NULL, 'Dentures Removed', 1, 1),
(14, NULL, 'Loose Teeth, Caps, Crowns', 1, 1),
(15, NULL, 'Jewellery Removed or Taped', 1, 1),
(16, NULL, 'Comments', 1, 1),
(17, 'Before induction of anaesthesia', 'Patient has confirmed - Identity, Site, Procedure & Consent', 2, 1),
(18, 'Before induction of anaesthesia', 'Site Marked', 2, 1),
(19, 'Before induction of anaesthesia', 'Anaesthesia Safety Check Completed', 2, 1),
(20, 'Before induction of anaesthesia', 'Pulse Oximeter on Patient & Functioning', 2, 1),
(21, 'Before induction of anaesthesia', 'Difficult Airway/ Aspiration Risk', 2, 1),
(22, 'Before Skin Incision', 'Confirm Team Members have introduced themselves by Name and Role', 2, 1),
(23, 'Before Skin Incision', 'Surgical, Anaesthesia Professional and Nurses Confirm - Patient, Site and Procedure', 2, 1),
(24, 'Anticipated Critical Events', 'Surgical Reviews - Critical or Expected Steps, Operative Duration, Anticipated Blood Loss', 2, 1),
(25, 'Anticipated Critical Events', 'Nursing Team Reviews - Has Sterility', 2, 1),
(26, 'Anticipated Critical Events', 'Has Antibiotic Prophylaxis been administered within last 60 Minutes', 2, 1),
(27, 'Anticipated Critical Events', 'Is Essential Imaging Displayed', 2, 1),
(28, 'Sign Out - Before Leaving Operating Room', 'Nurse verbally confirms with the team', 3, 1),
(29, 'Sign Out - Before Leaving Operating Room', 'Name of the Procedure Recorded', 3, 1),
(30, 'Sign Out - Before Leaving Operating Room', 'Instruments, Sponge & Needles Counts are correct', 3, 1),
(31, 'Sign Out - Before Leaving Operating Room', 'How the Specimen is Labelled (Including Patient Name)', 3, 1),
(32, 'Sign Out - Before Leaving Operating Room', 'Equipment malfunction to be addressed', 3, 1),
(33, 'Sign Out - Before Leaving Operating Room', 'Surgeon, Anaesthesia Professional & Nurses review the Key concerns for recovery and management of patient', 3, 1),
(34, 'Anaesthesia Professional Log', 'ECG', 4, 1),
(35, 'Anaesthesia Professional Log', 'Pulse Oximeter', 4, 1),
(36, 'Anaesthesia Professional Log', 'Blood Pressure', 4, 1),
(37, 'Anaesthesia Professional Log', 'Oxygen Saturation', 4, 1);
```

### Step 2(Removed)

### Step 3
```sql
-- Table structure for table `theatre_pre_op_checklist_log`
CREATE TABLE `theatre_pre_op_checklist_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `patientUID` int(11) DEFAULT NULL,
  `visitIDRef` varchar(120) DEFAULT NULL,
  `A1` varchar(550) DEFAULT NULL,
  `A2` varchar(550) DEFAULT NULL,
  `A3` varchar(550) DEFAULT NULL,
  `A4` varchar(550) DEFAULT NULL,
  `A5` varchar(550) DEFAULT NULL,
  `A6` varchar(550) DEFAULT NULL,
  `A7` varchar(550) DEFAULT NULL,
  `A8` varchar(550) DEFAULT NULL,
  `A9` varchar(550) DEFAULT NULL,
  `A10` varchar(550) DEFAULT NULL,
  `A11` varchar(550) DEFAULT NULL,
  `A12` varchar(550) DEFAULT NULL,
  `A13` varchar(550) DEFAULT NULL,
  `A14` varchar(550) DEFAULT NULL,
  `A15` varchar(550) DEFAULT NULL,
  `A16` varchar(120) DEFAULT NULL,
  `lastFoodDate` date DEFAULT NULL,
  `lastFoodTime` varchar(20) DEFAULT NULL,
  `lastWaterDate` date DEFAULT NULL,
  `lastWaterTime` varchar(20) DEFAULT NULL,
  `isActive` tinyint(1) NOT NULL DEFAULT 1,
  `UID` int(11) DEFAULT NULL,
  `UIP` varchar(120) DEFAULT NULL,
  `UPC` varchar(220) DEFAULT NULL,
  `dateAdded` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- Dumping initial data for table `theatre_pre_op_checklist_log`
INSERT INTO `theatre_pre_op_checklist_log` 
(`id`, `patientUID`, `visitIDRef`, `A1`, `A2`, `A3`, `A4`, `A5`, `A6`, `A7`, `A8`, `A9`, `A10`, `A11`, `A12`, `A13`, `A14`, `A15`, `A16`, 
 `lastFoodDate`, `lastFoodTime`, `lastWaterDate`, `lastWaterTime`, 
 `isActive`, `UID`, `UIP`, `UPC`, `dateAdded`) 
VALUES
(1, 59, 'VMH64-06032025', 
 'NO', 'NO', 'HIGH', '', 'NO', 'LOW', 'NO', 'YES', 'NO', 'YES', 'YES', 'NO', 'NO', 'YES', 'YES', 
 'Dolore temporibus vo', 
 '0000-00-00', '00:00', 
 '0000-00-00', '00:00', 
 1, 1, '::1', 
 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36', 
 '2025-03-06 09:51:27');
```


### Step 4
```sql
-- Table structure for table `theatre_post_op_checklist_log`
CREATE TABLE `theatre_post_op_checklist_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `patientUID` int(11) DEFAULT NULL,
  `visitIDRef` varchar(120) DEFAULT NULL,
  `A1` text DEFAULT NULL,
  `A2` text DEFAULT NULL,
  `A3` text DEFAULT NULL,
  `A4` text DEFAULT NULL,
  `A5` text DEFAULT NULL,
  `isActive` tinyint(1) NOT NULL DEFAULT 1,
  `UID` int(11) DEFAULT NULL,
  `UIP` varchar(120) DEFAULT NULL,
  `UPC` varchar(220) DEFAULT NULL,
  `dateAdded` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
```

### Step 5
```sql
-- Table structure for table `theatre_intra_op_checklist_log`
CREATE TABLE `theatre_intra_op_checklist_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `patientUID` int(11) DEFAULT NULL,
  `visitIDRef` varchar(120) DEFAULT NULL,
  `A1` varchar(550) DEFAULT NULL,
  `A3` varchar(550) DEFAULT NULL,
  `A4` varchar(550) DEFAULT NULL,
  `A5` varchar(550) DEFAULT NULL,
  `A6` varchar(550) DEFAULT NULL,
  `A7` varchar(550) DEFAULT NULL,
  `A8` varchar(550) DEFAULT NULL,
  `A9` varchar(550) DEFAULT NULL,
  `A10` varchar(550) DEFAULT NULL,
  `A11` varchar(550) DEFAULT NULL,
  `A12` varchar(550) DEFAULT NULL,
  `A13` varchar(550) DEFAULT NULL,
  `isActive` tinyint(1) NOT NULL DEFAULT 1,
  `UID` int(11) DEFAULT NULL,
  `UIP` varchar(120) DEFAULT NULL,
  `UPC` varchar(220) DEFAULT NULL,
  `dateAdded` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
```

### Step 6
```sql
CREATE TABLE `theatre_anaesthetist_vitals_log` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `patientUID` INT(11) DEFAULT NULL,
  `visitIDRef` VARCHAR(120) DEFAULT NULL,
  `ECG` TEXT DEFAULT NULL,
  `bloodPressure` TEXT DEFAULT NULL,
  `pulseOximeter` TEXT DEFAULT NULL,
  `oxygenSaturation` TEXT DEFAULT NULL,
  `loggedDate` DATE DEFAULT NULL,
  `loggedTime` VARCHAR(220) DEFAULT NULL,
  `isActive` TINYINT(1) NOT NULL DEFAULT 1,
  `UID` INT(11) DEFAULT NULL,
  `UIP` VARCHAR(120) DEFAULT NULL,
  `UPC` VARCHAR(220) DEFAULT NULL,
  `dateAdded` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=latin1 
  COLLATE=latin1_swedish_ci;
```

### Step 7
```sql
ALTER TABLE `eval_nurses_queue` 
  ADD COLUMN `opticalVisionPHRight` VARCHAR(10) NULL AFTER `opticalAutoRefrLeft`,
  ADD COLUMN `opticalVisionPHLeft`  VARCHAR(10) NULL AFTER `opticalVisionPHRight`;
  
  ALTER TABLE `eval_nurses_queue` 
  ADD COLUMN `opticalFinalPrescription` TEXT NULL AFTER `opticalGeneralComments`;
  
  ALTER TABLE `eval_nurses_queue`
  ADD COLUMN `opticalEyeLidsRight` TEXT NULL AFTER `opticalFinalPrescription`,
  ADD COLUMN `opticalEyeLidsLeft` TEXT NULL AFTER `opticalEyeLidsRight`,
  ADD COLUMN `opticalConjunctivaRight` TEXT NULL AFTER `opticalEyeLidsLeft`,
  ADD COLUMN `opticalConjunctivaLeft` TEXT NULL AFTER `opticalConjunctivaRight`,
  ADD COLUMN `opticalCorneaRight` TEXT NULL AFTER `opticalConjunctivaLeft`,
  ADD COLUMN `opticalCorneaLeft` TEXT NULL AFTER `opticalCorneaRight`,
  ADD COLUMN `opticalAChamberRight` TEXT NULL AFTER `opticalCorneaLeft`,
  ADD COLUMN `opticalAChamberLeft` TEXT NULL AFTER `opticalAChamberRight`,
  ADD COLUMN `opticalPupilRight` TEXT NULL AFTER `opticalAChamberLeft`,
  ADD COLUMN `opticalPupilLeft` TEXT NULL AFTER `opticalPupilRight`,
  ADD COLUMN `opticalLensRight` TEXT NULL AFTER `opticalPupilLeft`,
  ADD COLUMN `opticalLensLeft` TEXT NULL AFTER `opticalLensRight`,
  ADD COLUMN `opticalFundusRight` TEXT NULL AFTER `opticalLensLeft`,
  ADD COLUMN `opticalFundusLeft` TEXT NULL AFTER `opticalFundusRight`;
  
  ALTER TABLE `eval_nurses_queue`
  DROP COLUMN `opticalEyeLidsRight`,
  DROP COLUMN `opticalEyeLidsLeft`,
  DROP COLUMN `opticalConjunctivaRight`,
  DROP COLUMN `opticalConjunctivaLeft`,
  DROP COLUMN `opticalCorneaRight`,
  DROP COLUMN `opticalCorneaLeft`,
  DROP COLUMN `opticalAChamberRight`,
  DROP COLUMN `opticalAChamberLeft`,
  DROP COLUMN `opticalPupilRight`,
  DROP COLUMN `opticalPupilLeft`,
  DROP COLUMN `opticalLensRight`,
  DROP COLUMN `opticalLensLeft`,
  DROP COLUMN `opticalFundusRight`,
  DROP COLUMN `opticalFundusLeft`;
```

### Step 8
```sql!
ALTER TABLE `eval_patient_history`
  ADD COLUMN `opticalEyeLidsRight` TEXT NULL AFTER `docPatientAdvice`,
  ADD COLUMN `opticalEyeLidsLeft` TEXT NULL AFTER `opticalEyeLidsRight`,
  ADD COLUMN `opticalConjunctivaRight` TEXT NULL AFTER `opticalEyeLidsLeft`,
  ADD COLUMN `opticalConjunctivaLeft` TEXT NULL AFTER `opticalConjunctivaRight`,
  ADD COLUMN `opticalCorneaRight` TEXT NULL AFTER `opticalConjunctivaLeft`,
  ADD COLUMN `opticalCorneaLeft` TEXT NULL AFTER `opticalCorneaRight`,
  ADD COLUMN `opticalAChamberRight` TEXT NULL AFTER `opticalCorneaLeft`,
  ADD COLUMN `opticalAChamberLeft` TEXT NULL AFTER `opticalAChamberRight`,
  ADD COLUMN `opticalPupilRight` TEXT NULL AFTER `opticalAChamberLeft`,
  ADD COLUMN `opticalPupilLeft` TEXT NULL AFTER `opticalPupilRight`,
  ADD COLUMN `opticalLensRight` TEXT NULL AFTER `opticalPupilLeft`,
  ADD COLUMN `opticalLensLeft` TEXT NULL AFTER `opticalLensRight`,
  ADD COLUMN `opticalFundusRight` TEXT NULL AFTER `opticalLensLeft`,
  ADD COLUMN `opticalFundusLeft` TEXT NULL AFTER `opticalFundusRight`;

```
### Step 9
```sql!
ALTER TABLE `tbl_sys_config`
ADD COLUMN `stampStatus` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 = Disabled, 1 = Enabled' ;

CREATE TABLE tbl_monthly_tickets (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    ticketMonth CHAR(7) NOT NULL, -- e.g. '2025-09'
    ticketNumber INT NOT NULL,
    UNIQUE KEY unique_ticket (ticketMonth, ticketNumber)
);
```

### Step 10(Removed)
### Step 11

```sql
DROP TABLE IF EXISTS `prmgt_payroll_nssf_deductions`;

-- Create table
CREATE TABLE `prmgt_payroll_nssf_deductions` (
  `id` INT(10) UNSIGNED NOT NULL,
  `employee_id` INT(11) NOT NULL,
  `employee_name` VARCHAR(255) NOT NULL,
  `payroll_number` VARCHAR(120) NOT NULL,
  `department_id` INT(11) NOT NULL,
  `month_id` INT(11) NOT NULL,
  `year_id` INT(11) NOT NULL,
  `deduction_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  `addedby` TINYINT(3) UNSIGNED NOT NULL,
  `employeeDepartmentName` VARCHAR(120) DEFAULT '',
  `basicSalary` DECIMAL(18,2) NOT NULL DEFAULT 0.00,
  `grossSalary` DECIMAL(18,2) NOT NULL DEFAULT 0.00,
  `totalAllowances` DECIMAL(18,2) NOT NULL DEFAULT 0.00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- Triggers
DELIMITER $$

CREATE TRIGGER `prmgt_payroll_nssf_deductions_AFTER_INSERT`
AFTER INSERT ON `prmgt_payroll_nssf_deductions`
FOR EACH ROW
BEGIN
    INSERT INTO `prmgt_employee_salgenerated`
        (`department_id`, `employee_id`, `month_id`, `year_id`, `cat_id`, `cat_name`, `cat_amount`, `item_id`, `addedby`, `cat_show_on_slip`, `paySlipItemTitle`)
    VALUES
        (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 7, 'NSSF', NEW.deduction_amount, NEW.id, NEW.addedby, 'YES', 'NSSF DEDUCTION');
END
$$

CREATE TRIGGER `prmgt_payroll_nssf_deductions_AFTER_UPDATE`
AFTER UPDATE ON `prmgt_payroll_nssf_deductions`
FOR EACH ROW
BEGIN
    DECLARE nssfExist INT DEFAULT 0;

    SELECT 1 INTO nssfExist
    FROM `prmgt_employee_salgenerated`
    WHERE month_id = NEW.month_id
      AND employee_id = NEW.employee_id
      AND year_id = NEW.year_id
      AND item_id = NEW.id
      AND cat_id = 7
    LIMIT 1;

    IF nssfExist != 1 THEN
        INSERT INTO `prmgt_employee_salgenerated`
            (`department_id`, `employee_id`, `month_id`, `year_id`, `cat_id`, `cat_name`, `cat_amount`, `item_id`, `addedby`)
        VALUES
            (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 7, 'NSSF', NEW.deduction_amount, NEW.id, NEW.addedby);
    ELSE
        UPDATE `prmgt_employee_salgenerated`
        SET `cat_amount` = NEW.deduction_amount
        WHERE `cat_id` = 7
          AND `item_id` = NEW.id
          AND `employee_id` = NEW.employee_id
          AND `month_id` = NEW.month_id
          AND `year_id` = NEW.year_id;
    END IF;
END
$$

DELIMITER ;

-- Indexes
ALTER TABLE `prmgt_payroll_nssf_deductions`
  ADD PRIMARY KEY (`id`);

-- Auto-increment
ALTER TABLE `prmgt_payroll_nssf_deductions`
  MODIFY `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT;

COMMIT;
```

### Step 12
```sql
DROP TABLE IF EXISTS `prmgt_payroll_paye_deductions`;

-- Create table
CREATE TABLE `prmgt_payroll_paye_deductions` (
  `id` BIGINT(20) UNSIGNED NOT NULL,
  `employee_id` INT(11) DEFAULT NULL,
  `employee_name` VARCHAR(255) DEFAULT '',
  `payroll_number` VARCHAR(120) DEFAULT '',
  `department_id` INT(11) DEFAULT NULL,
  `month_id` INT(11) DEFAULT NULL,
  `year_id` INT(11) DEFAULT NULL,
  `basicPay` DECIMAL(14,2) DEFAULT NULL,
  `deduction_amount` DECIMAL(18,2) DEFAULT 0.00,
  `payeAfterRelief` DECIMAL(18,2) DEFAULT 0.00,
  `addedby` INT(10) UNSIGNED NOT NULL,
  `employeeDepartmentName` VARCHAR(80) DEFAULT '',
  `absenteeism` DECIMAL(18,2) DEFAULT 0.00,
  `NHIFAmount` DECIMAL(18,2) DEFAULT 0.00,
  `NSSFAmount` DECIMAL(18,2) DEFAULT 0.00,
  `taxableIncome` DECIMAL(18,2) DEFAULT 0.00,
  `taxableAllowances` DECIMAL(18,2) DEFAULT 0.00,
  `payeRefund` DECIMAL(18,2) NOT NULL DEFAULT 0.00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- Triggers
DELIMITER $$

CREATE TRIGGER `prmgt_payroll_paye_deductions_AFTER_INSERT`
AFTER INSERT ON `prmgt_payroll_paye_deductions`
FOR EACH ROW
BEGIN
    INSERT INTO `prmgt_employee_salgenerated`
        (`department_id`, `employee_id`, `month_id`, `year_id`, `cat_id`, `cat_name`, `cat_amount`, `item_id`, `addedby`, `cat_show_on_slip`, `paySlipItemTitle`)
    VALUES
        (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 9, 'PAYE', NEW.deduction_amount, NEW.id, NEW.addedby, 'YES', 'PAYE DEDUCTIONS');
END
$$

CREATE TRIGGER `prmgt_payroll_paye_deductions_AFTER_UPDATE`
AFTER UPDATE ON `prmgt_payroll_paye_deductions`
FOR EACH ROW
BEGIN
    DECLARE payeExist INT DEFAULT 0;

    SELECT 1 INTO payeExist
    FROM `prmgt_employee_salgenerated`
    WHERE month_id = NEW.month_id
      AND employee_id = NEW.employee_id
      AND year_id = NEW.year_id
      AND item_id = NEW.id
      AND cat_id = 9
    LIMIT 1;

    IF payeExist != 1 THEN
        INSERT INTO `prmgt_employee_salgenerated`
            (`department_id`, `employee_id`, `month_id`, `year_id`, `cat_id`, `cat_name`, `cat_amount`, `item_id`, `addedby`)
        VALUES
            (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 9, 'PAYE', NEW.deduction_amount, NEW.id, NEW.addedby);
    ELSE
        UPDATE `prmgt_employee_salgenerated`
        SET `cat_amount` = NEW.deduction_amount
        WHERE `cat_id` = 9
          AND `item_id` = NEW.id
          AND `employee_id` = NEW.employee_id
          AND `month_id` = NEW.month_id
          AND `year_id` = NEW.year_id;
    END IF;
END
$$

DELIMITER ;

-- Indexes
ALTER TABLE `prmgt_payroll_paye_deductions`
  ADD PRIMARY KEY (`id`);

-- Auto-increment
ALTER TABLE `prmgt_payroll_paye_deductions`
  MODIFY `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;

COMMIT;
```

### Step 13
```sql
DROP TABLE IF EXISTS `prmgt_payroll_housinglevy_deductions`;

-- Create table
CREATE TABLE `prmgt_payroll_housinglevy_deductions` (
  `id` BIGINT(20) UNSIGNED NOT NULL,
  `employee_id` INT(11) DEFAULT NULL,
  `employee_name` VARCHAR(255) DEFAULT '',
  `payroll_number` VARCHAR(120) DEFAULT '',
  `department_id` INT(11) DEFAULT NULL,
  `month_id` INT(11) DEFAULT NULL,
  `year_id` INT(11) DEFAULT NULL,
  `basicPay` DECIMAL(14,2) DEFAULT NULL,
  `deduction_amount` DECIMAL(18,2) DEFAULT 0.00,
  `addedby` INT(10) UNSIGNED NOT NULL,
  `employeeDepartmentName` VARCHAR(80) DEFAULT '',
  `absenteeism` DECIMAL(18,2) DEFAULT 0.00,
  `NHIFAmount` DECIMAL(18,2) DEFAULT 0.00,
  `NSSFAmount` DECIMAL(18,2) DEFAULT 0.00,
  `taxableIncome` DECIMAL(18,2) DEFAULT 0.00,
  `taxableAllowances` DECIMAL(18,2) DEFAULT 0.00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- Triggers
DELIMITER $$

CREATE TRIGGER `prmgt_payroll_housinglevy_deductions_AFTER_INSERT`
AFTER INSERT ON `prmgt_payroll_housinglevy_deductions`
FOR EACH ROW
BEGIN
    INSERT INTO `prmgt_employee_salgenerated`
        (`department_id`, `employee_id`, `month_id`, `year_id`, `cat_id`, `cat_name`, `cat_amount`, `item_id`, `addedby`, `cat_show_on_slip`, `paySlipItemTitle`)
    VALUES
        (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 14, 'HOUSING LEVY', NEW.deduction_amount, NEW.id, NEW.addedby, 'YES', 'HOUSING LEVY DEDUCTION');
END
$$

CREATE TRIGGER `prmgt_payroll_housinglevy_deductions_AFTER_UPDATE`
AFTER UPDATE ON `prmgt_payroll_housinglevy_deductions`
FOR EACH ROW
BEGIN
    DECLARE hlExist INT DEFAULT 0;

    SELECT 1 INTO hlExist
    FROM `prmgt_employee_salgenerated`
    WHERE month_id = NEW.month_id
      AND employee_id = NEW.employee_id
      AND year_id = NEW.year_id
      AND item_id = NEW.id
      AND cat_id = 14
    LIMIT 1;

    IF hlExist != 1 THEN
        INSERT INTO `prmgt_employee_salgenerated`
            (`department_id`, `employee_id`, `month_id`, `year_id`, `cat_id`, `cat_name`, `cat_amount`, `item_id`, `addedby`)
        VALUES
            (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 14, 'HOUSING LEVY', NEW.deduction_amount, NEW.id, NEW.addedby);
    ELSE
        UPDATE `prmgt_employee_salgenerated`
        SET `cat_amount` = NEW.deduction_amount
        WHERE `cat_id` = 14
          AND `item_id` = NEW.id
          AND `employee_id` = NEW.employee_id
          AND `month_id` = NEW.month_id
          AND `year_id` = NEW.year_id;
    END IF;
END
$$

DELIMITER ;

-- Indexes
ALTER TABLE `prmgt_payroll_housinglevy_deductions`
  ADD PRIMARY KEY (`id`);

-- Auto-increment
ALTER TABLE `prmgt_payroll_housinglevy_deductions`
  MODIFY `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;

COMMIT;

```

### Step 14
```sql
DROP TABLE IF EXISTS `prmgt_payroll_nhif_deductions`;

-- --------------------------------------------------------
-- Table structure for table `prmgt_payroll_nhif_deductions`
-- --------------------------------------------------------
CREATE TABLE `prmgt_payroll_nhif_deductions` (
  `id` bigint(20) UNSIGNED NOT NULL,
  `employee_id` int(11) NOT NULL,
  `employee_name` varchar(255) NOT NULL,
  `payroll_number` varchar(120) NOT NULL,
  `department_id` int(11) NOT NULL,
  `month_id` int(11) NOT NULL,
  `year_id` int(11) NOT NULL,
  `basicPay` decimal(12,2) NOT NULL DEFAULT 0.00,
  `deduction_amount` decimal(10,2) NOT NULL DEFAULT 0.00,
  `addedby` tinyint(3) UNSIGNED NOT NULL,
  `employeeDepartmentName` varchar(120) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- --------------------------------------------------------
-- Triggers for table `prmgt_payroll_nhif_deductions`
-- --------------------------------------------------------
DELIMITER $$

CREATE TRIGGER `prmgt_payroll_nhif_deductions_AFTER_INSERT`
AFTER INSERT ON `prmgt_payroll_nhif_deductions`
FOR EACH ROW
BEGIN
    INSERT INTO `prmgt_employee_salgenerated` (
        `department_id`,
        `employee_id`,
        `month_id`,
        `year_id`,
        `cat_id`,
        `cat_name`,
        `cat_amount`,
        `item_id`,
        `addedby`,
        `paySlipItemTitle`
    ) VALUES (
        NEW.department_id,
        NEW.employee_id,
        NEW.month_id,
        NEW.year_id,
        6,
        'SHA',
        NEW.deduction_amount,
        NEW.id,
        NEW.addedby,
        'SHA DEDUCTION'
    );
END$$

CREATE TRIGGER `prmgt_payroll_nhif_deductions_AFTER_UPDATE`
AFTER UPDATE ON `prmgt_payroll_nhif_deductions`
FOR EACH ROW
BEGIN
    DECLARE nhifExist INT DEFAULT 0;

    SELECT 1 INTO nhifExist
    FROM prmgt_employee_salgenerated
    WHERE month_id = NEW.month_id
      AND employee_id = NEW.employee_id
      AND year_id = NEW.year_id
      AND item_id = NEW.id
      AND cat_id = 6
    LIMIT 1;

    IF nhifExist != 1 THEN
        INSERT INTO `prmgt_employee_salgenerated` (
            `department_id`,
            `employee_id`,
            `month_id`,
            `year_id`,
            `cat_id`,
            `cat_name`,
            `cat_amount`,
            `item_id`,
            `addedby`
        ) VALUES (
            NEW.department_id,
            NEW.employee_id,
            NEW.month_id,
            NEW.year_id,
            6,
            'SHA',
            NEW.deduction_amount,
            NEW.id,
            NEW.addedby
        );
    ELSE
        UPDATE `prmgt_employee_salgenerated`
        SET `cat_amount` = NEW.deduction_amount
        WHERE `cat_id` = 6
          AND `item_id` = NEW.id
          AND `employee_id` = NEW.employee_id
          AND `month_id` = NEW.month_id
          AND `year_id` = NEW.year_id;
    END IF;
END$$

DELIMITER ;

-- --------------------------------------------------------
-- Indexes for table `prmgt_payroll_nhif_deductions`
-- --------------------------------------------------------
ALTER TABLE `prmgt_payroll_nhif_deductions`
  ADD PRIMARY KEY (`id`);

-- --------------------------------------------------------
-- AUTO_INCREMENT for table `prmgt_payroll_nhif_deductions`
-- --------------------------------------------------------
ALTER TABLE `prmgt_payroll_nhif_deductions`
  MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT;

COMMIT;
```
### Step 15
```sql
DROP TABLE IF EXISTS `prmgt_payroll_advances_deductions`;

--
-- Table structure for table `prmgt_payroll_advances_deductions`
--
CREATE TABLE `prmgt_payroll_advances_deductions` (
  `id` int(11) NOT NULL,
  `deduction_id` int(11) NOT NULL,
  `employee_id` int(11) NOT NULL,
  `department_id` tinyint(3) UNSIGNED NOT NULL,
  `deductionName` varchar(45) DEFAULT NULL,
  `deductiondate` datetime NOT NULL,
  `month_id` int(11) NOT NULL,
  `year_id` int(11) NOT NULL,
  `deductionamount` decimal(10,2) NOT NULL,
  `istaxable` varchar(45) NOT NULL,
  `ispayable` varchar(45) NOT NULL,
  `showonpayslip` varchar(45) NOT NULL,
  `isActive` int(11) NOT NULL DEFAULT 0,
  `isDeleted` int(11) NOT NULL DEFAULT 0,
  `addedby` varchar(45) NOT NULL,
  `dateAdded` timestamp NOT NULL DEFAULT current_timestamp(),
  `updatedBYUID` varchar(45) DEFAULT NULL,
  `dateUpdated` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

--
-- Triggers for table `prmgt_payroll_advances_deductions`
--
DELIMITER $$
CREATE TRIGGER `prmgt_payroll_advances_deductions_AFTER_UPDATE` 
AFTER UPDATE ON `prmgt_payroll_advances_deductions` 
FOR EACH ROW 
BEGIN
    DECLARE advanceExist INT DEFAULT 0;
    DECLARE advanceName VARCHAR(40);
    DECLARE perVal INT;
    DECLARE perAmt FLOAT;

    IF NEW.isActive = 1 AND NEW.isDeleted = 0 THEN
        -- Check if already exists
        SELECT 1 INTO advanceExist 
        FROM prmgt_employee_salgenerated 
        WHERE month_id = NEW.month_id 
          AND employee_id = NEW.employee_id 
          AND year_id = NEW.year_id 
          AND item_id = NEW.id 
          AND cat_id = 4
        LIMIT 1;

        -- Get reference name
        SELECT advanceTxnReference INTO advanceName 
        FROM prmgt_staff_advance_disbursments 
        WHERE id = NEW.id 
        LIMIT 1;

        -- Get advance percent setup
        SELECT perValue INTO perVal 
        FROM prmgt_advancepercent_setup 
        WHERE perType = 'ADVANCE' 
        LIMIT 1;

        -- Calculate percentage adjustment
        SET perAmt = NEW.deductionamount + ((perVal/100) * NEW.deductionamount);

        IF advanceExist != 1 THEN
            INSERT INTO `prmgt_employee_salgenerated` 
                (`department_id`, `employee_id`, `month_id`, `year_id`, 
                 `cat_id`, `cat_name`, `cat_amount`, `cat_show_on_slip`, 
                 `item_id`, `addedby`, `paySlipItemTitle`)
            VALUES 
                (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 
                 4, CONCAT('Advance REF: ', advanceName), NEW.deductionamount, NEW.showonpayslip, 
                 NEW.id, NEW.addedby, 'ADVANCE DEDUCTION');
        ELSE
            UPDATE `prmgt_employee_salgenerated` 
            SET `cat_amount` = NEW.deductionamount, 
                `cat_show_on_slip` = NEW.showonpayslip
            WHERE `cat_id` = 4 
              AND `item_id` = NEW.id 
              AND `employee_id` = NEW.employee_id 
              AND `month_id` = NEW.month_id 
              AND `year_id` = NEW.year_id;
        END IF;
    ELSE
        -- If inactive or deleted, remove from salgenerated
        DELETE FROM `prmgt_employee_salgenerated` 
        WHERE `cat_id` = 4 
          AND `item_id` = NEW.id 
          AND `employee_id` = NEW.employee_id 
          AND `month_id` = NEW.month_id 
          AND `year_id` = NEW.year_id;      
    END IF;
END
$$
DELIMITER ;

--
-- Indexes for table `prmgt_payroll_advances_deductions`
--
ALTER TABLE `prmgt_payroll_advances_deductions`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `prmgt_payroll_advances_deductions`
--
ALTER TABLE `prmgt_payroll_advances_deductions`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

COMMIT;
```

### Step 16
```sql
DROP TABLE IF EXISTS `prmgt_payroll_paye_refund`;

--
-- Table structure for table `prmgt_payroll_paye_refund`
--
CREATE TABLE `prmgt_payroll_paye_refund` (
  `id` bigint(20) UNSIGNED NOT NULL,
  `employee_id` int(11) DEFAULT NULL,
  `employee_name` varchar(255) DEFAULT '',
  `payroll_number` varchar(120) DEFAULT '',
  `department_id` int(11) DEFAULT NULL,
  `month_id` int(11) DEFAULT NULL,
  `year_id` int(11) DEFAULT NULL,
  `payeAmount` decimal(18,2) DEFAULT 0.00,
  `payeRefund` decimal(18,2) DEFAULT 0.00,
  `isActive` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

--
-- Triggers for table `prmgt_payroll_paye_refund`
--
DELIMITER $$
CREATE TRIGGER `prmgt_payroll_paye_refund_AFTER_INSERT` 
AFTER INSERT ON `prmgt_payroll_paye_refund` 
FOR EACH ROW 
BEGIN
    IF NEW.isActive = 1 THEN
        INSERT INTO `prmgt_employee_salgenerated` 
            (`department_id`, `employee_id`, `month_id`, `year_id`, 
             `cat_id`, `cat_name`, `cat_amount`, `item_id`,  
             `cat_show_on_slip`, `paySlipItemTitle`)
        VALUES 
            (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 
             13, 'PAYE REFUND', NEW.payeRefund, NEW.id, 
             'YES', 'PAYE REFUND');
    END IF;
END
$$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER `prmgt_payroll_paye_refund_AFTER_UPDATE` 
AFTER UPDATE ON `prmgt_payroll_paye_refund` 
FOR EACH ROW 
BEGIN
    DECLARE payeExist INT DEFAULT 0;

    -- Check if record already exists in salgenerated
    SELECT 1 INTO payeExist 
    FROM prmgt_employee_salgenerated 
    WHERE month_id = NEW.month_id 
      AND employee_id = NEW.employee_id 
      AND year_id = NEW.year_id 
      AND item_id = NEW.id 
      AND cat_id = 13
    LIMIT 1;

    IF NEW.isActive = 1 THEN
        IF payeExist != 1 THEN 
            INSERT INTO `prmgt_employee_salgenerated` 
                (`department_id`, `employee_id`, `month_id`, `year_id`, 
                 `cat_id`, `cat_name`, `cat_amount`, `item_id`, 
                 `cat_show_on_slip`, `paySlipItemTitle`)
            VALUES 
                (NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 
                 13, 'PAYE REFUND', NEW.payeRefund, NEW.id, 
                 'YES', 'PAYE REFUND');
        ELSE
            UPDATE `prmgt_employee_salgenerated` 
            SET `cat_amount` = NEW.payeRefund
            WHERE `cat_id` = 13 
              AND `item_id` = NEW.id 
              AND `employee_id` = NEW.employee_id 
              AND `month_id` = NEW.month_id 
              AND `year_id` = NEW.year_id;
        END IF;
    ELSE
        -- If refund is deactivated, remove it from salgenerated
        DELETE FROM `prmgt_employee_salgenerated`
        WHERE `cat_id` = 13 
          AND `item_id` = NEW.id 
          AND `employee_id` = NEW.employee_id 
          AND `month_id` = NEW.month_id 
          AND `year_id` = NEW.year_id;
    END IF;
END
$$
DELIMITER ;

--
-- Indexes for table `prmgt_payroll_paye_refund`
--
ALTER TABLE `prmgt_payroll_paye_refund`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `prmgt_payroll_paye_refund`
--
ALTER TABLE `prmgt_payroll_paye_refund`
  MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT;

COMMIT;
```

### Step 17
```sql
DROP TABLE IF EXISTS `prmgt_payroll_shares_deductions`;

--
-- Table structure for table `prmgt_payroll_shares_deductions`
--
CREATE TABLE `prmgt_payroll_shares_deductions` (
  `id` int(11) NOT NULL,
  `shareID` int(11) NOT NULL,
  `shareTypeID` int(11) NOT NULL,
  `employee_id` int(11) NOT NULL,
  `departmentID` int(11) NOT NULL,
  `shareDeductionDate` date NOT NULL,
  `month_id` int(11) NOT NULL,
  `year_id` int(11) NOT NULL,
  `deductionamount` decimal(10,2) NOT NULL,
  `showonpayslip` varchar(45) NOT NULL,
  `isActive` int(11) NOT NULL DEFAULT 0,
  `isDeleted` tinyint(1) NOT NULL DEFAULT 0,
  `addedby` varchar(45) NOT NULL,
  `dateadded` timestamp NOT NULL DEFAULT current_timestamp(),
  `updatedby` varchar(45) DEFAULT NULL,
  `dateupdated` timestamp NULL DEFAULT NULL,
  `shareTypeName` varchar(120) NOT NULL DEFAULT '',
  `saccoID` int(11) NOT NULL,
  `employeeNames` varchar(180) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

--
-- Trigger for table `prmgt_payroll_shares_deductions`
--
DELIMITER $$
CREATE TRIGGER `prmgt_payroll_shares_deductions_AFTER_UPDATE` 
AFTER UPDATE ON `prmgt_payroll_shares_deductions` 
FOR EACH ROW 
BEGIN
    DECLARE shareExist INT DEFAULT 0;
    DECLARE payShareName VARCHAR(40);
    DECLARE payShareCurrentAmount DECIMAL(13,2) DEFAULT 0;

    -- Only process active, non-deleted entries
    IF NEW.isActive = 1 AND NEW.isDeleted = 0 THEN
        SELECT shareTypeCode INTO payShareName 
        FROM prmgt_sacco_share_types 
        WHERE id = NEW.shareTypeID;

        SELECT 1 INTO shareExist 
        FROM prmgt_employee_salgenerated 
        WHERE month_id = NEW.month_id 
          AND employee_id = NEW.employee_id 
          AND department_id = NEW.departmentID 
          AND year_id = NEW.year_id 
          AND item_id = NEW.shareID 
          AND cat_id = 12
        LIMIT 1;

        SELECT cat_amount INTO payShareCurrentAmount 
        FROM prmgt_employee_salgenerated 
        WHERE month_id = NEW.month_id 
          AND employee_id = NEW.employee_id 
          AND department_id = NEW.departmentID 
          AND year_id = NEW.year_id  
          AND item_id = NEW.shareID 
          AND cat_id = 12
        LIMIT 1;

        IF shareExist != 1 THEN
            INSERT INTO `prmgt_employee_salgenerated` 
                (`subCategoryID`, `employee_id`, `department_id`, `month_id`, `year_id`, 
                 `cat_id`, `cat_name`, `cat_amount`, `addedby`, `item_id`, 
                 `cat_show_on_slip`, `paySlipItemTitle`)
            VALUES 
                (NEW.saccoID, NEW.employee_id, NEW.departmentID, NEW.month_id, NEW.year_id, 
                 12, NEW.shareTypeName, NEW.deductionamount, NEW.addedby, NEW.shareID, 
                 'YES', 'SHARE DEDUCTIONS');

            UPDATE sacco_member_shares 
            SET totalPaidAmount = totalPaidAmount + NEW.deductionamount  
            WHERE id = NEW.shareID AND employeeID = NEW.employee_id;

        ELSE
            UPDATE `prmgt_employee_salgenerated` 
            SET `subCategoryID` = NEW.saccoID, 
                `cat_amount` = NEW.deductionamount, 
                `cat_name` = NEW.shareTypeName 
            WHERE cat_id = 12 
              AND item_id = NEW.shareID 
              AND employee_id = NEW.employee_id 
              AND department_id = NEW.departmentID 
              AND month_id = NEW.month_id 
              AND year_id = NEW.year_id;

            UPDATE sacco_member_shares 
            SET totalPaidAmount = totalPaidAmount - payShareCurrentAmount 
            WHERE id = NEW.shareID AND employeeID = NEW.employee_id;

            UPDATE sacco_member_shares 
            SET totalPaidAmount = totalPaidAmount + NEW.deductionamount 
            WHERE id = NEW.shareID AND employeeID = NEW.employee_id;
        END IF;

    ELSE 
        -- Remove from salgenerated if not active or deleted
        DELETE FROM `prmgt_employee_salgenerated` 
        WHERE cat_id = 12 
          AND item_id = NEW.shareID 
          AND employee_id = NEW.employee_id 
          AND month_id = NEW.month_id 
          AND year_id = NEW.year_id;

        UPDATE sacco_member_shares 
        SET totalPaidAmount = totalPaidAmount - payShareCurrentAmount 
        WHERE id = NEW.shareID AND employeeID = NEW.employee_id;
    END IF;
END
$$
DELIMITER ;

--
-- Indexes for table `prmgt_payroll_shares_deductions`
--
ALTER TABLE `prmgt_payroll_shares_deductions`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `prmgt_payroll_shares_deductions`
--
ALTER TABLE `prmgt_payroll_shares_deductions`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

COMMIT;
```
### Step 18
```sql
DROP TABLE IF EXISTS `prmgt_employee_allowances`;

--
-- Table structure for table `prmgt_employee_allowances`
--
CREATE TABLE `prmgt_employee_allowances` (
  `id` bigint(20) NOT NULL,
  `department_id` int(11) DEFAULT NULL,
  `allowance_id` int(11) DEFAULT NULL,
  `employee_id` int(11) DEFAULT NULL,
  `empallowdate` date DEFAULT NULL,
  `month_id` int(11) DEFAULT NULL,
  `year_id` int(11) DEFAULT NULL,
  `allowanceamount` decimal(10,2) DEFAULT NULL,
  `istaxable` varchar(45) DEFAULT NULL,
  `ispayable` varchar(45) DEFAULT NULL,
  `showonpayslip` varchar(45) DEFAULT NULL,
  `isActive` int(11) DEFAULT 0,
  `isDeleted` int(11) DEFAULT 0,
  `addedby` varchar(45) DEFAULT NULL,
  `dateAdded` timestamp NULL DEFAULT current_timestamp(),
  `updatedBYUID` int(11) DEFAULT NULL,
  `dateUpdated` timestamp DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

--
-- Trigger for table `prmgt_employee_allowances`
--
DELIMITER $$
CREATE TRIGGER `prmgt_employee_allowances_AFTER_UPDATE` 
AFTER UPDATE ON `prmgt_employee_allowances` 
FOR EACH ROW 
BEGIN
    DECLARE allowanceExist INT DEFAULT 0;
    DECLARE allowanceName VARCHAR(40);
    DECLARE grossExists INT DEFAULT 0;
    DECLARE grossAmount DECIMAL(18,2) DEFAULT 0.00;

    IF NEW.isActive = 1 AND NEW.isDeleted = 0 THEN 

        -- Get allowance description
        SELECT callw_description INTO allowanceName 
        FROM prmgt_company_allowances_benefits 
        WHERE id = NEW.allowance_id 
        LIMIT 1;

        -- Check if allowance already exists in salgenerated
        SELECT 1 INTO allowanceExist 
        FROM prmgt_employee_salgenerated 
        WHERE month_id = NEW.month_id 
          AND employee_id = NEW.employee_id 
          AND year_id = NEW.year_id  
          AND item_id = NEW.id 
          AND cat_id = 2 
          AND subCategoryID = NEW.allowance_id
        LIMIT 1;

        -- Calculate total taxable allowances
        SELECT SUM(cat_amount) INTO grossAmount 
        FROM prmgt_employee_salgenerated 
        WHERE month_id = NEW.month_id 
          AND employee_id = NEW.employee_id 
          AND year_id = NEW.year_id 
          AND cat_id = 2;

        -- Check if gross salary record exists
        SELECT 1 INTO grossExists 
        FROM prmgt_payroll_gross_salary 
        WHERE monthID = NEW.month_id 
          AND employeeID = NEW.employee_id 
          AND yearID = NEW.year_id
        LIMIT 1;

        IF allowanceExist != 1 THEN
            INSERT INTO `prmgt_employee_salgenerated` 
                (subCategoryID, department_id, employee_id, month_id, year_id, 
                 cat_id, cat_name, cat_amount, cat_taxable, cat_show_on_slip, 
                 addedby, item_id, paySlipItemTitle)
            VALUES 
                (NEW.allowance_id, NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 
                 2, allowanceName, NEW.allowanceamount, NEW.istaxable, NEW.showonpayslip, 
                 NEW.addedby, NEW.id, 'SALARY ALLOWANCES');

            IF grossExists != 1 THEN
                INSERT INTO `prmgt_payroll_gross_salary` 
                    (employeeID, departmentID, monthID, yearID, totalTaxableAllowances, addedByUID)
                VALUES 
                    (NEW.employee_id, NEW.department_id, NEW.month_id, NEW.year_id, grossAmount, NEW.addedby);
            ELSE
                UPDATE `prmgt_payroll_gross_salary` 
                SET totalTaxableAllowances = grossAmount 
                WHERE monthID = NEW.month_id AND employeeID = NEW.employee_id AND yearID = NEW.year_id;
            END IF;

        ELSE
            UPDATE `prmgt_employee_salgenerated` 
            SET cat_amount = NEW.allowanceamount, 
                cat_taxable = NEW.istaxable, 
                cat_show_on_slip = NEW.showonpayslip
            WHERE cat_id = 2 AND item_id = NEW.id AND employee_id = NEW.employee_id 
              AND month_id = NEW.month_id AND year_id = NEW.year_id 
              AND subCategoryID = NEW.allowance_id;

            UPDATE `prmgt_payroll_gross_salary` 
            SET totalTaxableAllowances = grossAmount 
            WHERE monthID = NEW.month_id AND employeeID = NEW.employee_id AND yearID = NEW.year_id;
        END IF;

    ELSE
        DELETE FROM `prmgt_employee_salgenerated` 
        WHERE cat_id = 2 AND item_id = NEW.id AND employee_id = NEW.employee_id 
          AND month_id = NEW.month_id AND year_id = NEW.year_id 
          AND subCategoryID = NEW.allowance_id; 
    END IF;
END
$$
DELIMITER ;

--
-- Indexes for table `prmgt_employee_allowances`
--
ALTER TABLE `prmgt_employee_allowances`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `prmgt_employee_allowances`
--
ALTER TABLE `prmgt_employee_allowances`
  MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=80;

COMMIT;
```
### Step 19
```sql
DROP TABLE IF EXISTS `prmgt_employee_deductions`;

--
-- Table structure for table `prmgt_employee_deductions`
--
CREATE TABLE `prmgt_employee_deductions` (
  `id` int(11) NOT NULL,
  `department_id` int(11) DEFAULT NULL,
  `deduction_id` int(11) DEFAULT NULL,
  `employee_id` int(11) DEFAULT NULL,
  `empdeductiondate` date DEFAULT NULL,
  `month_id` int(11) DEFAULT NULL,
  `year_id` int(11) DEFAULT NULL,
  `deductionamount` decimal(10,2) NOT NULL DEFAULT 0.00,
  `istaxable` varchar(45) DEFAULT NULL,
  `showonpayslip` varchar(45) DEFAULT NULL,
  `isActive` int(11) DEFAULT 0,
  `isDeleted` int(11) DEFAULT 0,
  `addedby` varchar(45) DEFAULT NULL,
  `dateadded` timestamp NULL DEFAULT current_timestamp(),
  `updatedBYUID` varchar(45) DEFAULT NULL,
  `dateUpdated` timestamp NULL DEFAULT NULL,
  `employeeDepartmentName` varchar(120) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

--
-- Trigger for table `prmgt_employee_deductions`
--
DELIMITER $$
CREATE TRIGGER `prmgt_employee_deductions_AFTER_UPDATE` 
AFTER UPDATE ON `prmgt_employee_deductions` 
FOR EACH ROW 
BEGIN
    DECLARE deductionExist INT DEFAULT 0;
    DECLARE deductionName VARCHAR(40);
    DECLARE grossExists INT DEFAULT 0;
    DECLARE grossAmount DECIMAL(18,2) DEFAULT 0.00;

    IF NEW.isActive = 1 AND NEW.isDeleted = 0 THEN

        -- Get deduction description
        SELECT cded_description INTO deductionName 
        FROM prmgt_company_deductions 
        WHERE id = NEW.deduction_id 
        LIMIT 1;

        -- Check if deduction already exists in salgenerated
        SELECT 1 INTO deductionExist 
        FROM prmgt_employee_salgenerated 
        WHERE month_id = NEW.month_id 
          AND employee_id = NEW.employee_id 
          AND year_id = NEW.year_id 
          AND item_id = NEW.id 
          AND cat_id = 3 
          AND subCategoryID = NEW.deduction_id
        LIMIT 1;

        -- Calculate total deductions
        SELECT SUM(cat_amount) INTO grossAmount 
        FROM prmgt_employee_salgenerated 
        WHERE month_id = NEW.month_id 
          AND employee_id = NEW.employee_id 
          AND year_id = NEW.year_id 
          AND cat_id = 3;

        -- Check if gross salary record exists
        SELECT 1 INTO grossExists 
        FROM prmgt_payroll_gross_salary 
        WHERE monthID = NEW.month_id 
          AND employeeID = NEW.employee_id 
          AND yearID = NEW.year_id
        LIMIT 1;

        IF deductionExist != 1 THEN
            INSERT INTO prmgt_employee_salgenerated 
                (subCategoryID, department_id, employee_id, month_id, year_id, 
                 cat_id, cat_name, cat_amount, addedby, item_id, paySlipItemTitle)
            VALUES 
                (NEW.deduction_id, NEW.department_id, NEW.employee_id, NEW.month_id, NEW.year_id, 
                 3, deductionName, NEW.deductionamount, NEW.addedby, NEW.id, 'SALARY DEDUCTIONS');

            IF grossExists != 1 THEN
                INSERT INTO prmgt_payroll_gross_salary 
                    (employeeID, departmentID, monthID, yearID, totalDeductions, addedByUID)
                VALUES 
                    (NEW.employee_id, NEW.department_id, NEW.month_id, NEW.year_id, grossAmount, NEW.addedby);
            ELSE
                UPDATE prmgt_payroll_gross_salary 
                SET totalDeductions = grossAmount 
                WHERE monthID = NEW.month_id AND employeeID = NEW.employee_id AND yearID = NEW.year_id;
            END IF;

        ELSE
            UPDATE prmgt_employee_salgenerated 
            SET cat_amount = NEW.deductionamount
            WHERE cat_id = 3 AND item_id = NEW.id AND employee_id = NEW.employee_id 
              AND month_id = NEW.month_id AND year_id = NEW.year_id 
              AND subCategoryID = NEW.deduction_id;

            UPDATE prmgt_payroll_gross_salary 
            SET totalDeductions = grossAmount 
            WHERE monthID = NEW.month_id AND employeeID = NEW.employee_id AND yearID = NEW.year_id;
        END IF;

    ELSE
        DELETE FROM prmgt_employee_salgenerated 
        WHERE cat_id = 3 AND item_id = NEW.id AND employee_id = NEW.employee_id 
          AND month_id = NEW.month_id AND year_id = NEW.year_id 
          AND subCategoryID = NEW.deduction_id;
    END IF;
END
$$
DELIMITER ;

--
-- Indexes for table `prmgt_employee_deductions`
--
ALTER TABLE `prmgt_employee_deductions`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `prmgt_employee_deductions`
--
ALTER TABLE `prmgt_employee_deductions`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

COMMIT;
```
### Step 20
```sql
DROP TABLE IF EXISTS `prmgt_staff_master_roll`;

-- Table structure for table `prmgt_staff_master_roll`
CREATE TABLE `prmgt_staff_master_roll` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `payrollNo` varchar(65) DEFAULT NULL,
  `employeeID` int(11) DEFAULT NULL,
  `employeeName` varchar(255) DEFAULT NULL,
  `basicSalary` decimal(12,0) DEFAULT 0,
  `casualSalary` decimal(12,0) DEFAULT 0,
  `overtimeAmount` decimal(12,0) DEFAULT 0,
  `grossSalary` decimal(12,0) DEFAULT 0,
  `nssf` decimal(12,0) DEFAULT 0,
  `nhif` decimal(12,0) DEFAULT 0,
  `housinglevy` decimal(12,0) DEFAULT 0,
  `paye` decimal(12,0) DEFAULT 0,
  `payeRefund` decimal(12,0) DEFAULT 0,
  `advanceAmount` decimal(12,0) DEFAULT 0,
  `bbfAmount` decimal(12,0) DEFAULT 0,
  `kenindiaSacco` decimal(12,0) DEFAULT 0,
  `saccoOne` decimal(12,0) DEFAULT 0,
  `totalDeduction` decimal(12,0) DEFAULT 0,
  `netPay` decimal(12,0) DEFAULT 0,
  `monthID` varchar(8) DEFAULT NULL,
  `yearID` varchar(8) DEFAULT NULL,
  `medicalAllowance` decimal(12,0) DEFAULT 0,
  `houseAllowance` decimal(12,0) DEFAULT 0,
  `actingAllowance` decimal(12,0) DEFAULT 0,
  `travelAllowance` decimal(12,0) DEFAULT 0,
  `saccoTwo` decimal(12,0) DEFAULT 0,
  `jobTitle` varchar(100) DEFAULT NULL,
  `abenteeismAmount` decimal(12,0) DEFAULT 0,
  `totalRelief` decimal(18,2) NOT NULL DEFAULT 0.00,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
```

### Step 21
```sql
ALTER TABLE `visit_db`
ADD COLUMN `isAllowedPharmacy` TINYINT(1) NOT NULL DEFAULT 0
AFTER `ticketNumber`,
 ADD COLUMN pharmacyApprovedBy INT NULL AFTER `isAllowedPharmacy`,
 ADD COLUMN pharmacyActionTime DATETIME NULL AFTER `pharmacyApprovedBy`;
 
 ALTER TABLE `invms_stores`
ADD COLUMN `isReceivingStore` ENUM('Yes','No') NOT NULL DEFAULT 'No' AFTER `isActive`;
```
### Step 22(Removed)
### Step 23(Removed)
### Step 24
```sql
ALTER TABLE `eval_nurses_queue`
ADD COLUMN `opticalFinalRE_SPHERE` VARCHAR(20) NULL AFTER `opticalFinalPrescription`,
ADD COLUMN `opticalFinalRE_CYL` VARCHAR(20) NULL AFTER `opticalFinalRE_SPHERE`,
ADD COLUMN `opticalFinalRE_AXIS` VARCHAR(20) NULL AFTER `opticalFinalRE_CYL`,
ADD COLUMN `opticalFinalRE_ADD` VARCHAR(20) NULL AFTER `opticalFinalRE_AXIS`,
ADD COLUMN `opticalFinalRE_VA` VARCHAR(20) NULL AFTER `opticalFinalRE_ADD`,

ADD COLUMN `opticalFinalLE_SPHERE` VARCHAR(20) NULL AFTER `opticalFinalRE_VA`,
ADD COLUMN `opticalFinalLE_CYL` VARCHAR(20) NULL AFTER `opticalFinalLE_SPHERE`,
ADD COLUMN `opticalFinalLE_AXIS` VARCHAR(20) NULL AFTER `opticalFinalLE_CYL`,
ADD COLUMN `opticalFinalLE_ADD` VARCHAR(20) NULL AFTER `opticalFinalLE_AXIS`,
ADD COLUMN `opticalFinalLE_VA` VARCHAR(20) NULL AFTER `opticalFinalLE_ADD`;
```
### Step 25
```sql
DROP TABLE IF EXISTS `hr_leave_applications`;

CREATE TABLE `hr_leave_applications` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `employeeid` INT(11) NOT NULL,
  `leave_type` INT(11) NOT NULL,
  `start_date` DATE NOT NULL,
  `end_date` DATE DEFAULT NULL,
  `start_time` TIME NOT NULL DEFAULT '08:00:00',
  `end_time` TIME NOT NULL DEFAULT '17:00:00',
  `workingdays` DECIMAL(4,1) UNSIGNED NOT NULL DEFAULT 0.0,
  `handover_employee` INT(11) NOT NULL,
  `notes` TEXT NOT NULL,
  `application_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `supervisor_approval` TINYINT(1) DEFAULT 0,
  `supervisor_notes` TEXT DEFAULT NULL,
  `supervisor_approval_date` DATETIME DEFAULT NULL,
  `hr_approval` TINYINT(1) DEFAULT 0,
  `hr_approval_date` DATETIME DEFAULT NULL,
  `updatedby` INT(11) DEFAULT NULL,
  `dateedited` DATETIME DEFAULT NULL,
  `isActive` TINYINT(3) UNSIGNED NOT NULL DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=latin1 
  COLLATE=latin1_swedish_ci;
```
### Step 26
```sql
ALTER TABLE tbl_sys_config
ADD COLUMN sha_agent_id VARCHAR(255) DEFAULT NULL,
ADD COLUMN sha_consumer_key VARCHAR(255) DEFAULT NULL,
ADD COLUMN sha_consumer_secret VARCHAR(255) DEFAULT NULL,
ADD COLUMN sha_username VARCHAR(255) DEFAULT NULL,
ADD COLUMN sha_password VARCHAR(255) DEFAULT NULL,
ADD COLUMN sha_pem_key LONGTEXT DEFAULT NULL,
ADD COLUMN sha_pem_key_expiry DATETIME  NULL,
ADD COLUMN sha_privatepem_key LONGTEXT DEFAULT NULL,
ADD COLUMN sha_privatepem_key_expiry DATETIME  NULL,
ADD COLUMN sha_app_url VARCHAR(255) DEFAULT NULL;

ALTER TABLE finance_bill_split_requests
ADD COLUMN shaRebateAmount DECIMAL(12,2) NOT NULL DEFAULT 0,
ADD COLUMN shaRebateApplied TINYINT(1) NOT NULL DEFAULT 0;

ALTER TABLE visit_payers ADD COLUMN payerType VARCHAR(50) DEFAULT NULL AFTER splitAmount;
```
### Step 27(Removed)
### Step 28(Removed)
### Step 29(REMOVED) go to step 30

### Step 30
```sql
-- Drop table if it exists (optional)
DROP TABLE IF EXISTS `setup_asset_rooms`;
-- Create table
CREATE TABLE `setup_asset_rooms` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `roomFacilityID` INT(11) DEFAULT NULL,
  `floorID` INT(11) DEFAULT NULL,
  `roomName` VARCHAR(225) DEFAULT NULL,
  `roomCode` VARCHAR(225) DEFAULT NULL,
  `UIP` VARCHAR(120) DEFAULT NULL,
  `UPC` VARCHAR(120) DEFAULT NULL,
  `UID` INT(11) NOT NULL DEFAULT 1,
  `isActive` INT(11) NOT NULL DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=latin1 
  COLLATE=latin1_swedish_ci 
  AUTO_INCREMENT=1;
COMMIT;
```
### Step 31
```sql
-- Drop table if it exists (optional)
DROP TABLE IF EXISTS `tbl_company_brands`;

-- Create table
CREATE TABLE `tbl_company_brands` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `brandCode` VARCHAR(120) DEFAULT '',
  `brandName` VARCHAR(250) DEFAULT '',
  `brandDescription` VARCHAR(250) DEFAULT '',
  `isActive` INT(11) DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_general_ci 
  AUTO_INCREMENT=1;

COMMIT;
```
### Step 32
```sql
-- Drop table if it exists (optional)
DROP TABLE IF EXISTS `tbl_models`;

-- Create table
CREATE TABLE `tbl_models` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `companyBrandID` INT(11) DEFAULT NULL,
  `modelCode` VARCHAR(120) DEFAULT '',
  `modelName` VARCHAR(250) DEFAULT '',
  `modelDescription` VARCHAR(250) DEFAULT '',
  `isActive` INT(11) DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_general_ci 
  AUTO_INCREMENT=1;

COMMIT;
```
### Step 33
```sql
-- -----------------------------------------------------
-- Table structure for `fass_sub_categories`
-- -----------------------------------------------------

-- Drop table if it exists (optional)
DROP TABLE IF EXISTS `fass_sub_categories`;

CREATE TABLE `fass_sub_categories` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `categoryID` INT(11) DEFAULT NULL,
  `faCode` VARCHAR(120) DEFAULT '',
  `subCategoryName` VARCHAR(250) DEFAULT '',
  `subCategoryDescription` VARCHAR(250) DEFAULT '',
  `isActive` TINYINT(1) DEFAULT 1,
  `faValuationTypeID` INT(11) DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_general_ci 
  AUTO_INCREMENT=1;

COMMIT;
```


[HEAD OVER TO PAGE 2](https://hackmd.io/@--LognktRUmsG6YHux0Jjw/B1-IqySCge)

[Download SQL Folder(For Other Modules) And Import](https://drive.google.com/uc?export=download&id=1_Ib8bGhT9sPMdPRiDWvNm7UXVsrORxFn)
**Author:** Samwel