--Skooly V2 to be selected by default in sms settings
/views/smssettings/index.php
on line 39
--Disable payment amount field for other users except accounts and admin
/views/invoice/payment.php
on line 185
--Cash and bank is hidden when paying so user can only use wallet
/views/invoice/payment.php
on line 45
-- Send SMS
----Students to be default on dropdown
--views/mailandsms/add.php
--Line 47
----Students form group to be default
--/views/mailandsms/add.php
----var usertypeID = "= $setSMSUserTypeID = 3 ?>";
--Line 484
--To change FONTS
-- /views/_layout_main.php
I copied this code at the top for the font google sans
-- then add the font
-- /assets/inilabs/themes/default/style.css
font-family: 'Google Sans', 'OpenSans Regular';
BULK IMPORT
---Allow some fields not to be required
DATE NOT REQUIRED BUT TODAY'S DATE IF EMPTY
/mvc/controllers/Bulkimport.php
--line 1151
EMAIL NOT REQUIRED AND PASSES WHEN
/mvc/controllers/Bulkimport.php
--line 1090
// USERNAME, ROLL, PASSWORD TO BE SAME AS REGISTRATION (ADM NO) IF EMPTY
/mvc/controllers/Bulkimport.php
--line 1090
LOGIN PAGE
--GLASS EFFECT
---/home/skooly/demo.skooly.co.ke/assets/inilabs/themes/default/login_glass.css
----ADDEDED CSS STYLE
--I CREATED NEW _layout_signin.php AND RENAMED existing to _layout_signin_OLD.php
----demo.skooly.co.ke/mvc/views/
SELFHOST GOOGLE FONT FOR LOGIN
--DOWNLOAD FONT
--CONVERTED FONT USING google webfonts helper https://transfonter.org/ TO WOFF AND WOFF2
----UPLOAD TO FONTS FOLDER
--------demo.skooly.co.ke/assets/fonts
--CREATE FONT CSS STYLE
--- Created fontstyle.css in FONT FOLDER
--LINK the FONTS IN THE fontstyle.css to where the fonts are located
--------src: url('../../../fonts/Manrope-Bold.woff2') format('woff2')
--INCLUDE the new font in the Page CSS font-family
-----In the HTML link the fontstyle.css and make sure its linked correctly
.HTACCESS
ADDED Options -Indexes (TO PREVENT VIEWING DIRECTORIES IF NO INDEX FILE)
IDREPORT
----Changed css and html IdcardReport.php View file
------So as to achieve same onscreen and onprint design
----Created a back card design
Included extra setting table column for motto, if found message, and softwareicon
SETTING
ADDED FIELDS
INSERT INTO setting (fieldoption, value) VALUES
('app_bg', ''),
('app_logo', ''),
('slogan', ''),
('favicon', ''),
('softwareicon', ''),
('motto', ''),
('iffound', ''),
('school_code', '')
Also included School Name Abbreviation
PRODUCT PURCHASE
Changed language of product to item
Changed sale to issue
---
Added button to hide/reveal search by date filter and a fieldset to group in purchases and issue
LANGUAGE
Changed from Add to New e.g Add Student to New Students
UPDATED SMS LOGIC FOR LOGS, TAGS, TEMPLATE
-UPDATED LOGS to include, usertype,action (e.g. edit, add or delete),module (e.g invoice, payments,attendance) and tags e.g([balance] [adm]
--UPDATED SMS LOGS TABLE
---ALTER TABLE mailandsms
ADD COLUMN module VARCHAR(50) DEFAULT NULL,
ADD COLUMN action VARCHAR(50) DEFAULT NULL,
ADD COLUMN template_id INT DEFAULT NULL,
ADD COLUMN tags TEXT DEFAULT NULL;
ALL SMS LOGGING CENTRALISED IN library/sms/smsservice
----CRONJOB ADDED (All automations (SMS, email, data, etc.) are defined in crons)
ALTER TABLE `crons`
ADD COLUMN `last_status` VARCHAR(20) DEFAULT NULL AFTER `last_run`,
ADD COLUMN `failure_reason` TEXT DEFAULT NULL AFTER `last_status`,
ADD COLUMN `enabled` TINYINT(1) DEFAULT 1 AFTER `next_run`,
ADD COLUMN `notify_admin` TINYINT(1) DEFAULT 0 AFTER `enabled`,
ADD COLUMN `admin_contact` VARCHAR(50) DEFAULT NULL AFTER `notify_admin`,
ADD COLUMN `template_id` INT DEFAULT NULL AFTER `admin_contact`;
CREATE TABLE cron_notifications (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
cron_id BIGINT UNSIGNED NOT NULL,
contact_type ENUM('user_id','usertype','phone','email') NOT NULL,
contact_value VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (cron_id) REFERENCES crons(id) ON DELETE CASCADE
);
Invoice
1. ✔Autopay in Order of the feetype/ autopay preceding invoices first (DEEPSEEK) MODIFIED INVOICE MODEL public function get_order_by_invoice
AND Replace the processStudentPayment Function CONTROLLER(demo FOLDER updated)
Key Changes Summary:
1. Modified the model to accept an order parameter for flexible sorting
2. Removed fee type prioritization - No more LUNCH first logic
3. Added invoice ID ordering - Invoices processed from oldest to newest
4. Maintained all existing functionality - Payments, SMS, balance updates remain intact
2. ✔SMS FOREVER IN ADD INVOICE (DEEPSEEK)(REPLACEd entire sms() method IN Invoice controller)
Explanation of "if you don't need status tracking":
The original code was trying to track whether SMS were sent successfully ($status) and then potentially do something with that information. But in reality:
1. processAndSendMessage() inside newInvoice() already:
◦ Sends the SMS immediately ✅
◦ Logs it to the database ✅
◦ Handles errors internally ✅
2. You don't actually use the status for anything critical in your workflow
3. The bulk SMS sending was redundant since each student already got their individual SMS
What this solution does:
1. ✅ No duplicate SMS - Only the template message is sent
2. ✅ Maintains database logging - Each SMS is still logged individually
3. ✅ No errors - Doesn't try to access undefined array keys
4. ✅ Consistency - Keeps newInvoice() identical to other SmsService functions
5. ✅ Works for single/multiple/all students - The loop handles all cases
3. ✔100 invoices error (DEEPSEEK) MODIFIED MAININVOICE MODEL AND SAVEINVOICE CONTROLLER(demo FOLDER updated)
4. WAIVER. INCLUDE WAIVER IN INVOICE PAYMENT SMS
Step 1: Added the New Tags to mailandsmstemplatetag Database
INSERT INTO `mailandsmstemplatetag` (`usertypeID`, `tagname`, `create_date`) VALUES
(3, '[waived]', NOW()),
(3, '[waiver_reason]', NOW()),
(3, '[total_credit]', NOW());
(3, '[feetype]', NOW());
Step 2: Add Tag Replacement Logic in SmsUtils
In application/helpers/SmsUtils.php, added these conditions to the tagConvertor method:
} elseif ($userTag->tagname == '[waived]') {
if (isset($data['waived_amount'])) {
$message = str_replace("[waived]", $data['waived_amount'], $message);
} else {
$message = str_replace("[waived]", '0', $message);
}
} elseif ($userTag->tagname == '[waived_amount]') {
if (isset($data['waived_amount'])) {
$message = str_replace("[waived_amount]", $data['waived_amount'], $message);
} else {
$message = str_replace("[waived_amount]", '0', $message);
}
} elseif ($userTag->tagname == '[waiver_reason]') {
if (isset($data['waiver_reason'])) {
$message = str_replace("[waiver_reason]", $data['waiver_reason'], $message);
} else {
$message = str_replace("[waiver_reason]", 'Not specified', $message);
}
} elseif ($userTag->tagname == '[total_credit]') {
$paid = isset($data['paid_amount']) ? $data['paid_amount'] : 0;
$waived = isset($data['waived_amount']) ? $data['waived_amount'] : 0;
$message = str_replace("[total_credit]", $paid + $waived, $message);
}
Step 3: Updated SmsService Invoice Payment Method
In SmsService.php, modify the invoicePayment method:
php
public static function invoicePayment($user, $usertypeID, $data, $paid, $waived = 0)
{
// Ensure data array exists and add our values
if (!is_array($data)) {
$data = [];
}
$data['paid_amount'] = $paid;
$data['waived_amount'] = $waived;
return self::processAndSendMessage(
'Invoice Payment',
$user,
$usertypeID,
$data,
[
'[paid]' => $paid,
'[waived]' => $waived,
'[total_credit]' => $paid + $waived
],
null,
'invoice',
'payment'
);
}
Step 4: Updated Payment Controller
where the SMS is sent in payment controller and update it:
php
// Calculate waived amount
$waivedAmount = 0;
foreach ($this->data['invoices'] as $inID) {
$waivedAmount += intval($this->input->post()['weaver_' . $inID->invoiceID]);
}
// Send SMS with waived amount
SmsService::invoicePayment($student, 3, $this->data, $pA, $waivedAmount);
Step 5: Updated Your SMS Template
Go to your admin panel and edit the "Invoice Payment" template:
-------------------------WAIVER SEPARATION---------------------------------
ALTER TABLE `weaverandfine`
ADD COLUMN `waiver_reason` VARCHAR(255) NULL AFTER `fine`;
---ADDED NEW CONTROLLER IN INVOICE payment_process()
-----REPLACED PAYMENT VIEW------------
-------------------------WAIVER WALLET TRANSACTION-----------------------------
----ADDED schoolyearID, action and actiontype in transactions table
ALTER TABLE `wallet_transactions`
ADD COLUMN `schoolyearID` INT NULL AFTER `payment_type`,
ADD COLUMN `trx_action` VARCHAR(50) NULL AFTER `trx_type`,
ADD COLUMN `trx_action_type` VARCHAR(20) NULL AFTER `trx_action`;
--------------ADDITIONAL SETTING RESET BUTTONS---------------------
ADDED RESET WALLET, STUDENT TABLE AND ALL TRANSACTION
1. MODIFIED FORM IN INDEX ADDITIONAL SETTINGS SECTION
2. ADDED new reset functions (resetwallets, resetstudentbalances, resetalltransactions) IN SETTINGS CONTROLLER
3. ADDED SWEET ALERT LIBRARY IN page_footer.php view
4. Added script in index.php view
-----------------------------ADDED ALERT BOX-------------------------------
1.CREATED SWEETALERTS HELPER sweetalert_helper.js TO CHECK SMS THRESHOLD, PREVENT DOUBLE ACTIONS AND CONFIRMATION ALERTS
/assets/alerts/sweetalert_helper.js
2.CREATED GETSMSDATA HELPER getSmsData();
3.UPDATED CONTROLLER TO
--LOAD action_helper.php to get getSmsData();
----$this->load->helper('action_helper'); // Load the helper
--UPDATED FUNCTION INDEX TO USE THE HELPER TO GET SMS DATA AND PASS IT TO VIEW
$smsData = getSmsData();
$this->data['smsBalance'] = $smsData['smsBalance'];
$this->data['smsThreshold'] = $smsData['smsThreshold'];
4. UPDATED VIEW
----ADDED SCRIPT AT THE TOP
----ADDED add both the confirm-action and sms-check-button classes to the button.
------UPDATED BUTTONS TO USE LINK
--------------WAIVER BY WALLET---------------------
-----REPLACED processStudentPayment and updateMainInvoiceStatus and get_invoice_balance
----Refactored the relevant logic into the new helper function get_invoice_balance, then updated both processStudentPayment and updateMainInvoiceStatus to use this new helper.
-----ADDED SWEETALERT CONFIRM FLASHDATA-----------------------
---CREATED sweetalert_helper.php in mvc/helpers
_--UPDATED autoload.php in config folder to autoload sweetalert_helper
$autoload['helper'] = array('url', 'file');
*/
$autoload['helper'] = array("url", "html", "action", "security", "file", 'sweetalert');
/*
---ADDED helper call data['smsBalance'] = $smsData['smsBalance'];
$this->data['smsThreshold'] = $smsData['smsThreshold'];
----USING standardized SweetAlert data attribute helpers. UsING helpers for all confirmation dialogs AND FLASHDATA
-----ModifING existing button helpers to use the standardized approach MAINTINING a consistent patterns
----EnsurING main template page_footer.php includes the necessary JavaScript and SMS variables MaintainING separation of concerns - JavaScript handles UI, PHP handles data