From 1740c568f9e82c600e3a60e5ddea8edc3d373fbc Mon Sep 17 00:00:00 2001
From: Focuslinkstech <45756999+Focuslinkstech@users.noreply.github.com>
Date: Wed, 9 Apr 2025 11:39:00 +0100
Subject: [PATCH] feat: add subject field for bulk messaging and update
 validation logic

---
 system/controllers/message.php | 21 +++++++++---
 ui/ui/admin/message/bulk.tpl   | 61 +++++++++++++++++++++++++++++-----
 2 files changed, 69 insertions(+), 13 deletions(-)

diff --git a/system/controllers/message.php b/system/controllers/message.php
index f7ec29b0..01ce48a0 100644
--- a/system/controllers/message.php
+++ b/system/controllers/message.php
@@ -135,9 +135,14 @@ EOT;
         $router = $_REQUEST['router'] ?? null;
         $test = isset($_REQUEST['test']) && $_REQUEST['test'] === 'on' ? true : false;
         $service = $_REQUEST['service'] ?? '';
+        $subject = $_REQUEST['subject'] ?? '';
 
         if (empty($group) || empty($message) || empty($via) || empty($service)) {
-            die(json_encode(['status' => 'error', 'message' => 'All fields are required']));
+            die(json_encode(['status' => 'error', 'message' =>  LANG::T('All fields are required')]));
+        }
+
+        if ($via === 'all' || $via === 'email' || $via === 'inbox' && empty($subject)) {
+            die(json_encode(['status' => 'error', 'message' => LANG::T('Subject is required to send message using') . ' ' . $via . '.']));
         }
 
         // Get batch of customers based on group
@@ -153,7 +158,7 @@ EOT;
                 default:
                     $router = ORM::for_table('tbl_routers')->find_one($router);
                     if (!$router) {
-                        die(json_encode(['status' => 'error', 'message' => 'Invalid router']));
+                        die(json_encode(['status' => 'error', 'message' =>  LANG::T('Invalid router')]));
                     }
                     $routerName = $router->name;
                     break;
@@ -295,7 +300,7 @@ EOT;
         $totalInboxSent = 0;
         $totalInboxFailed = 0;
         $batchStatus = [];
-        $subject = $config['CompanyName'] . ' ' . Lang::T('Notification Message');
+        //$subject = $config['CompanyName'] . ' ' . Lang::T('Notification Message');
         $form = 'Admin';
 
         foreach ($customers as $customer) {
@@ -305,6 +310,12 @@ EOT;
                 $message
             );
 
+            $currentSubject = str_replace(
+                ['[[name]]', '[[user_name]]', '[[phone]]', '[[company_name]]'],
+                [$customer['fullname'], $customer['username'], $customer['phonenumber'], $config['CompanyName']],
+                $subject
+            );
+
             $phoneNumber = preg_replace('/\D/', '', $customer['phonenumber']);
 
             if (empty($phoneNumber)) {
@@ -347,7 +358,7 @@ EOT;
                 }
 
                 if ($via === 'email' || $via === 'all') {
-                    if (Message::sendEmail($customer['email'], $subject, $currentMessage)) {
+                    if (Message::sendEmail($customer['email'], $currentSubject, $currentMessage)) {
                         $totalEmailSent++;
                         $batchStatus[] = ['name' => $customer['fullname'], 'channel' => $customer['email'], 'status' => 'Email Sent', 'message' => $currentMessage];
                     } else {
@@ -357,7 +368,7 @@ EOT;
                 }
 
                 if ($via === 'inbox' || $via === 'all') {
-                    if (Message::addToInbox($customer['customer_id'], $subject, $currentMessage, $form)) {
+                    if (Message::addToInbox($customer['customer_id'], $currentSubject, $currentMessage, $form)) {
                         $totalInboxSent++;
                         $batchStatus[] = ['name' => $customer['fullname'], 'channel' => 'Inbox', 'status' => 'Inbox Message Sent', 'message' => $currentMessage];
                     } else {
diff --git a/ui/ui/admin/message/bulk.tpl b/ui/ui/admin/message/bulk.tpl
index a0e6a903..9610309d 100644
--- a/ui/ui/admin/message/bulk.tpl
+++ b/ui/ui/admin/message/bulk.tpl
@@ -30,7 +30,8 @@
                             <select class="form-control" name="service" id="service">
                                 <option value="all" {if $group=='all' }selected{/if}>{Lang::T('All')}</option>
                                 <option value="PPPoE" {if $service=='PPPoE' }selected{/if}>{Lang::T('PPPoE')}</option>
-                                <option value="Hotspot" {if $service=='Hotspot' }selected{/if}>{Lang::T('Hotspot')}</option>
+                                <option value="Hotspot" {if $service=='Hotspot' }selected{/if}>{Lang::T('Hotspot')}
+                                </option>
                                 <option value="VPN" {if $service=='VPN' }selected{/if}>{Lang::T('VPN')}</option>
                             </select>
                         </div>
@@ -41,8 +42,10 @@
                             <select class="form-control" name="group" id="group">
                                 <option value="all" {if $group=='all' }selected{/if}>{Lang::T('All Customers')}</option>
                                 <option value="new" {if $group=='new' }selected{/if}>{Lang::T('New Customers')}</option>
-                                <option value="expired" {if $group=='expired' }selected{/if}>{Lang::T('Expired Customers')}</option>
-                                <option value="active" {if $group=='active' }selected{/if}>{Lang::T('Active Customers')}</option>
+                                <option value="expired" {if $group=='expired' }selected{/if}>{Lang::T('Expired
+                                    Customers')}</option>
+                                <option value="active" {if $group=='active' }selected{/if}>{Lang::T('Active Customers')}
+                                </option>
                             </select>
                         </div>
                     </div>
@@ -55,7 +58,8 @@
                                 <option value="email" {if $via=='email' }selected{/if}>{Lang::T('Email')}</option>
                                 <option value="sms" {if $via=='sms' }selected{/if}>{Lang::T('SMS')}</option>
                                 <option value="wa" {if $via=='wa' }selected{/if}>{Lang::T('WhatsApp')}</option>
-                                <option value="both" {if $via=='both' }selected{/if}>{Lang::T('SMS and WhatsApp')}</option>
+                                <option value="both" {if $via=='both' }selected{/if}>{Lang::T('SMS and WhatsApp')}
+                                </option>
                             </select>
                         </div>
                     </div>
@@ -75,10 +79,21 @@
                             {Lang::T('Use 20 and above if you are sending to all customers to avoid server time out')}
                         </div>
                     </div>
+                    <div class="form-group" id="subject">
+                        <label class="col-md-2 control-label">{Lang::T('Subject')}</label>
+                        <div class="col-md-6">
+                            <input type="text" class="form-control" name="subject" id="subject-content" value=""
+                                placeholder="{Lang::T('Enter message subject here')}">
+                        </div>
+                        <p class="help-block col-md-4">
+                            {Lang::T('You can also use the below placeholders here too')}.
+                        </p>
+                    </div>
                     <div class="form-group">
                         <label class="col-md-2 control-label">{Lang::T('Message')}</label>
                         <div class="col-md-6">
-                            <textarea class="form-control" id="message" name="message" required placeholder="{Lang::T('Compose your message...')}" rows="5">{$message}</textarea>
+                            <textarea class="form-control" id="message" name="message" required
+                                placeholder="{Lang::T('Compose your message...')}" rows="5">{$message}</textarea>
                             <input name="test" id="test" type="checkbox">
                             {Lang::T('Testing [if checked no real message is sent]')}
                         </div>
@@ -96,7 +111,8 @@
                     </div>
                     <div class="form-group">
                         <div class="col-lg-offset-2 col-lg-10">
-                            <button type="button" id="startBulk" class="btn btn-primary">{Lang::T('Start Bulk Messaging')}</button>
+                            <button type="button" id="startBulk" class="btn btn-primary">{Lang::T('Start Bulk
+                                Messaging')}</button>
                             <a href="{Text::url('dashboard')}" class="btn btn-default">{Lang::T('Cancel')}</a>
                         </div>
                     </div>
@@ -129,6 +145,34 @@
 
 <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
 <script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
+<script>
+    document.getElementById('via').addEventListener('change', function () {
+        const via = this.value;
+        const subject = document.getElementById('subject');
+        const subjectField = document.getElementById('subject-content');
+
+        subject.style.display = (via === 'all' || via === 'email' || via === 'inbox') ? 'block' : 'none';
+
+        switch (via) {
+            case 'all':
+                subjectField.placeholder = 'Enter a subject for all channels';
+                subjectField.required = true; 
+                break;
+            case 'email':
+                subjectField.placeholder = 'Enter a subject for email';
+                subjectField.required = true; 
+                break;
+            case 'inbox':
+                subjectField.placeholder = 'Enter a subject for inbox';
+                subjectField.required = true; 
+                break;
+            default:
+                subjectField.placeholder = 'Enter message subject here';
+                subjectField.required = false;
+                break;
+        }
+    });
+</script>
 {literal}
 <script>
     let page = 0;
@@ -154,6 +198,7 @@
             method: 'POST',
             data: {
                 group: $('#group').val(),
+                subject: $('#subject').val() || '',
                 message: $('#message').val(),
                 via: $('#via').val(),
                 batch: $('#batch').val(),
@@ -192,7 +237,7 @@
                             msg.channel,
                             `<span class="text-${statusClass}">${msg.status}</span>`,
                             msg.message || 'No message',
-                            msg.router ? msg.router : 'All Router', 
+                            msg.router ? msg.router : 'All Router',
                             msg.service == 'all' ? 'All Service' : (msg.service || 'No Service')
                         ]).draw(false); // Add row without redrawing the table
                     });
@@ -210,7 +255,7 @@
                     console.error("Unexpected response format:", response);
                     $('#status').html(`
                         <div class="alert alert-danger">
-                            <i class="fas fa-exclamation-circle"></i> Error: Unexpected response format.
+                            <i class="fas fa-exclamation-circle"></i> Error: ${response.message}
                         </div>
                     `);
                 }