@@ -13488,6 +13706,7 @@ document.addEventListener('DOMContentLoaded', function() {
@@ -13726,6 +13945,7 @@ document.addEventListener('DOMContentLoaded', function() {
@@ -14622,6 +14842,29 @@ document.addEventListener('DOMContentLoaded', function() {
location.reload();
}
+
+ window.downloadPDF = function(elementId, filenamePrefix) {
+ const element = document.getElementById(elementId);
+ if (!element) return;
+
+ // Hide elements with 'd-print-none' during PDF generation
+ const hiddenElements = element.querySelectorAll('.d-print-none');
+ hiddenElements.forEach(el => el.style.display = 'none');
+
+ const opt = {
+ margin: [10, 10, 10, 10],
+ filename: filenamePrefix + '_' + new Date().getTime() + '.pdf',
+ image: { type: 'jpeg', quality: 0.98 },
+ html2canvas: { scale: 2, useCORS: true },
+ jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
+ };
+
+ html2pdf().set(opt).from(element).save().then(() => {
+ // Restore hidden elements
+ hiddenElements.forEach(el => el.style.display = '');
+ });
+ };
+
// --- Language Apply Script ---
function applyLanguage(node) {
const docLang = document.documentElement.lang || 'ar';
@@ -14682,19 +14925,31 @@ document.addEventListener('DOMContentLoaded', function() {
});
// -----------------------------
- const monthlyData = = json_encode($data['monthly_sales']) ?>;
- const yearlyData = = json_encode($data['yearly_sales']) ?>;
+ const monthlyData = = json_encode($data['monthly_sales'] ?? []) ?>;
+ const yearlyData = = json_encode($data['yearly_sales'] ?? []) ?>;
+ const cashFlowData = = json_encode($data['cash_flow'] ?? []) ?>;
const ctx = document.getElementById('salesChart').getContext('2d');
+
+ let gradient = ctx.createLinearGradient(0, 0, 0, 400);
+ gradient.addColorStop(0, 'rgba(13, 110, 253, 0.4)');
+ gradient.addColorStop(1, 'rgba(13, 110, 253, 0)');
+
let salesChart = new Chart(ctx, {
type: 'line',
data: {
labels: monthlyData.map(d => d.label),
datasets: [{
- label: 'Sales (OMR)',
+ label: '= $lang === "ar" ? "المبيعات" : "Sales" ?>',
data: monthlyData.map(d => d.total),
borderColor: '#0d6efd',
- backgroundColor: 'rgba(13, 110, 253, 0.1)',
+ backgroundColor: gradient,
+ borderWidth: 3,
+ pointBackgroundColor: '#ffffff',
+ pointBorderColor: '#0d6efd',
+ pointBorderWidth: 2,
+ pointRadius: 4,
+ pointHoverRadius: 6,
fill: true,
tension: 0.4
}]
@@ -14703,16 +14958,36 @@ document.addEventListener('DOMContentLoaded', function() {
responsive: true,
maintainAspectRatio: false,
plugins: {
- legend: { display: false }
+ legend: { display: false },
+ tooltip: {
+ backgroundColor: 'rgba(0,0,0,0.8)',
+ titleFont: { size: 14, family: "'Segoe UI', Roboto, sans-serif" },
+ bodyFont: { size: 14, family: "'Segoe UI', Roboto, sans-serif" },
+ padding: 10,
+ cornerRadius: 8,
+ displayColors: false,
+ callbacks: {
+ label: function(context) {
+ let label = context.dataset.label || '';
+ if (label) { label += ': '; }
+ if (context.parsed.y !== null) { label += new Intl.NumberFormat().format(context.parsed.y) + ' OMR'; }
+ return label;
+ }
+ }
+ }
},
scales: {
- y: {
- beginAtZero: true,
+ x: { grid: { display: false, drawBorder: false } },
+ y: {
+ beginAtZero: true,
+ grid: { color: 'rgba(0,0,0,0.05)', drawBorder: false },
+ border: { dash: [5, 5] },
ticks: {
callback: function(value) { return 'OMR ' + value.toFixed(3); }
}
}
- }
+ },
+ interaction: { mode: 'index', intersect: false }
}
});
@@ -14731,6 +15006,69 @@ document.addEventListener('DOMContentLoaded', function() {
salesChart.data.datasets[0].data = yearlyData.map(d => d.total);
salesChart.update();
});
+
+ if (cashFlowData.length > 0) {
+ const ctxCf = document.getElementById('cashFlowChart').getContext('2d');
+ new Chart(ctxCf, {
+ type: 'bar',
+ data: {
+ labels: cashFlowData.map(d => d.label),
+ datasets: [
+ {
+ label: '= $lang === "ar" ? "الدخل" : "Income" ?>',
+ data: cashFlowData.map(d => d.income),
+ backgroundColor: '#198754',
+ borderRadius: 4,
+ barPercentage: 0.6,
+ categoryPercentage: 0.8
+ },
+ {
+ label: '= $lang === "ar" ? "المصروفات" : "Expenses" ?>',
+ data: cashFlowData.map(d => d.expense),
+ backgroundColor: '#dc3545',
+ borderRadius: 4,
+ barPercentage: 0.6,
+ categoryPercentage: 0.8
+ }
+ ]
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ plugins: {
+ legend: {
+ position: 'top',
+ labels: { usePointStyle: true, boxWidth: 8, font: { family: "'Segoe UI', Roboto, sans-serif" } }
+ },
+ tooltip: {
+ backgroundColor: 'rgba(0,0,0,0.8)',
+ padding: 10,
+ cornerRadius: 8,
+ callbacks: {
+ label: function(context) {
+ let label = context.dataset.label || '';
+ if (label) { label += ': '; }
+ if (context.parsed.y !== null) { label += new Intl.NumberFormat().format(context.parsed.y) + ' OMR'; }
+ return label;
+ }
+ }
+ }
+ },
+ scales: {
+ x: { grid: { display: false, drawBorder: false } },
+ y: {
+ beginAtZero: true,
+ grid: { color: 'rgba(0,0,0,0.05)', drawBorder: false },
+ border: { dash: [5, 5] },
+ ticks: {
+ callback: function(value) { return 'OMR ' + value.toFixed(3); }
+ }
+ }
+ },
+ interaction: { mode: 'index', intersect: false }
+ }
+ });
+ }
diff --git a/patch_cashflow.php b/patch_cashflow.php
new file mode 100644
index 0000000..e9f98d4
--- /dev/null
+++ b/patch_cashflow.php
@@ -0,0 +1,60 @@
+query("
+ SELECT m.sort_col, m.label,
+ (
+ SELECT COALESCE(SUM(amount), 0) FROM payments WHERE DATE_FORMAT(payment_date, \'%Y-%m\') = m.sort_col
+ ) + (
+ SELECT COALESCE(SUM(amount), 0) FROM pos_payments WHERE DATE_FORMAT(created_at, \'%Y-%m\') = m.sort_col
+ ) as income,
+ (
+ SELECT COALESCE(SUM(amount), 0) FROM expenses WHERE DATE_FORMAT(expense_date, \'%Y-%m\') = m.sort_col
+ ) + (
+ SELECT COALESCE(SUM(amount), 0) FROM purchase_payments WHERE DATE_FORMAT(payment_date, \'%Y-%m\') = m.sort_col
+ ) + (
+ SELECT COALESCE(SUM(net_salary), 0) FROM hr_payroll WHERE DATE_FORMAT(payment_date, \'%Y-%m\') = m.sort_col
+ ) as expense
+ FROM (
+ SELECT DISTINCT DATE_FORMAT(dt, \'%Y-%m\') as sort_col, DATE_FORMAT(dt, \'%M %Y\') as label
+ FROM (
+ SELECT payment_date as dt FROM payments
+ UNION SELECT created_at as dt FROM pos_payments
+ UNION SELECT expense_date as dt FROM expenses
+ UNION SELECT payment_date as dt FROM purchase_payments
+ ) dates
+ ) m
+ ORDER BY m.sort_col DESC LIMIT 6
+ ")->fetchAll(PDO::FETCH_ASSOC);';
+
+$repl_cf = ' // Cash Flow Data (Income vs Expense - last 6 months)
+ $data[\'cash_flow\'] = db()->query("
+ SELECT m.sort_col, m.label,
+ (
+ SELECT COALESCE(SUM(amount), 0) FROM payments WHERE DATE_FORMAT(payment_date, \'%Y-%m\') = m.sort_col $out_and
+ ) + (
+ SELECT COALESCE(SUM(amount), 0) FROM pos_payments WHERE DATE_FORMAT(created_at, \'%Y-%m\') = m.sort_col $out_and
+ ) as income,
+ (
+ SELECT COALESCE(SUM(amount), 0) FROM expenses WHERE DATE_FORMAT(expense_date, \'%Y-%m\') = m.sort_col $out_and
+ ) + (
+ SELECT COALESCE(SUM(amount), 0) FROM purchase_payments WHERE DATE_FORMAT(payment_date, \'%Y-%m\') = m.sort_col $out_and
+ ) + (
+ SELECT COALESCE(SUM(net_salary), 0) FROM hr_payroll WHERE DATE_FORMAT(payment_date, \'%Y-%m\') = m.sort_col $out_and
+ ) as expense
+ FROM (
+ SELECT DISTINCT DATE_FORMAT(dt, \'%Y-%m\') as sort_col, DATE_FORMAT(dt, \'%M %Y\') as label
+ FROM (
+ SELECT payment_date as dt FROM payments $out_w
+ UNION SELECT created_at as dt FROM pos_payments $out_w
+ UNION SELECT expense_date as dt FROM expenses $out_w
+ UNION SELECT payment_date as dt FROM purchase_payments $out_w
+ ) dates
+ ) m
+ ORDER BY m.sort_col DESC LIMIT 6
+ ")->fetchAll(PDO::FETCH_ASSOC);';
+
+$c = str_replace($find_cf, $repl_cf, $c);
+file_put_contents('index.php', $c);
+echo "Cash flow patched\n";
diff --git a/patch_dashboard.php b/patch_dashboard.php
new file mode 100644
index 0000000..721f84f
--- /dev/null
+++ b/patch_dashboard.php
@@ -0,0 +1,81 @@
+query("SELECT * FROM customers ORDER BY id DESC LIMIT 5")->fetchAll();
+ $data[\'stats\'] = [
+ \'total_customers\' => db()->query("SELECT COUNT(*) FROM customers")->fetchColumn(),
+ \'total_items\' => db()->query("SELECT COUNT(*) FROM stock_items")->fetchColumn(),
+ \'total_sales\' => (db()->query("SELECT SUM(total_with_vat) FROM invoices")->fetchColumn() ?: 0) + (db()->query("SELECT SUM(net_amount) FROM pos_transactions WHERE status = \'completed\'")->fetchColumn() ?: 0),
+ \'total_received\' => (db()->query("SELECT SUM(amount) FROM payments")->fetchColumn() ?: 0) + (db()->query("SELECT SUM(amount) FROM pos_payments")->fetchColumn() ?: 0),
+ \'total_purchases\' => db()->query("SELECT SUM(total_with_vat) FROM purchases")->fetchColumn() ?: 0,
+ \'total_paid\' => db()->query("SELECT SUM(amount) FROM purchase_payments")->fetchColumn() ?: 0,
+ \'expired_items\' => db()->query("SELECT COUNT(*) FROM stock_items WHERE expiry_date IS NOT NULL AND expiry_date <= CURDATE()")->fetchColumn(),
+ \'near_expiry_items\' => db()->query("SELECT COUNT(*) FROM stock_items WHERE expiry_date IS NOT NULL AND expiry_date > CURDATE() AND expiry_date <= DATE_ADD(CURDATE(), INTERVAL 30 DAY)")->fetchColumn(),
+ \'low_stock_items_count\' => db()->query("SELECT COUNT(*) FROM stock_items WHERE stock_quantity <= min_stock_level")->fetchColumn(),
+ ];';
+
+$repl_dashboard = ' if (can(\'dashboard_view\')) {
+ $out_w = isset($_SESSION[\'outlet_id\']) ? "WHERE outlet_id = " . (int)$_SESSION[\'outlet_id\'] : "WHERE 1=1";
+ $out_and = isset($_SESSION[\'outlet_id\']) ? "AND outlet_id = " . (int)$_SESSION[\'outlet_id\'] : "";
+
+ $data[\'customers\'] = db()->query("SELECT * FROM customers $out_w ORDER BY id DESC LIMIT 5")->fetchAll();
+ $data[\'stats\'] = [
+ \'total_customers\' => db()->query("SELECT COUNT(*) FROM customers $out_w")->fetchColumn(),
+ \'total_items\' => db()->query("SELECT COUNT(*) FROM stock_items $out_w")->fetchColumn(),
+ \'total_sales\' => (db()->query("SELECT SUM(total_with_vat) FROM invoices $out_w")->fetchColumn() ?: 0) + (db()->query("SELECT SUM(net_amount) FROM pos_transactions WHERE status = \'completed\' $out_and")->fetchColumn() ?: 0),
+ \'total_received\' => (db()->query("SELECT SUM(amount) FROM payments $out_w")->fetchColumn() ?: 0) + (db()->query("SELECT SUM(amount) FROM pos_payments WHERE 1=1 $out_and")->fetchColumn() ?: 0),
+ \'total_purchases\' => db()->query("SELECT SUM(total_with_vat) FROM purchases $out_w")->fetchColumn() ?: 0,
+ \'total_paid\' => db()->query("SELECT SUM(amount) FROM purchase_payments $out_w")->fetchColumn() ?: 0,
+ \'expired_items\' => db()->query("SELECT COUNT(*) FROM stock_items WHERE expiry_date IS NOT NULL AND expiry_date <= CURDATE() $out_and")->fetchColumn(),
+ \'near_expiry_items\' => db()->query("SELECT COUNT(*) FROM stock_items WHERE expiry_date IS NOT NULL AND expiry_date > CURDATE() AND expiry_date <= DATE_ADD(CURDATE(), INTERVAL 30 DAY) $out_and")->fetchColumn(),
+ \'low_stock_items_count\' => db()->query("SELECT COUNT(*) FROM stock_items WHERE stock_quantity <= min_stock_level $out_and")->fetchColumn(),
+ ];';
+
+$c = str_replace($find_dashboard, $repl_dashboard, $c);
+
+// Also replace the queries for Cash Flow and Charts
+$find_charts = ' $data[\'monthly_sales\'] = db()->query("
+ SELECT label, SUM(tot) as total FROM (
+ SELECT DATE_FORMAT(invoice_date, \'%M %Y\') as label, total_with_vat as tot, DATE_FORMAT(invoice_date, \'%Y-%m\') as sort_col FROM invoices
+ UNION ALL
+ SELECT DATE_FORMAT(created_at, \'%M %Y\') as label, net_amount as tot, DATE_FORMAT(created_at, \'%Y-%m\') as sort_col FROM pos_transactions WHERE status = \'completed\'
+ ) t
+ GROUP BY label, sort_col
+ ORDER BY sort_col ASC LIMIT 12
+ ")->fetchAll(PDO::FETCH_ASSOC);
+
+ $data[\'yearly_sales\'] = db()->query("
+ SELECT label, SUM(tot) as total FROM (
+ SELECT YEAR(invoice_date) as label, total_with_vat as tot FROM invoices
+ UNION ALL
+ SELECT YEAR(created_at) as label, net_amount as tot FROM pos_transactions WHERE status = \'completed\'
+ ) t
+ GROUP BY label
+ ORDER BY label ASC LIMIT 5
+ ")->fetchAll(PDO::FETCH_ASSOC);';
+
+$repl_charts = ' $data[\'monthly_sales\'] = db()->query("
+ SELECT label, SUM(tot) as total FROM (
+ SELECT DATE_FORMAT(invoice_date, \'%M %Y\') as label, total_with_vat as tot, DATE_FORMAT(invoice_date, \'%Y-%m\') as sort_col FROM invoices $out_w
+ UNION ALL
+ SELECT DATE_FORMAT(created_at, \'%M %Y\') as label, net_amount as tot, DATE_FORMAT(created_at, \'%Y-%m\') as sort_col FROM pos_transactions WHERE status = \'completed\' $out_and
+ ) t
+ GROUP BY label, sort_col
+ ORDER BY sort_col ASC LIMIT 12
+ ")->fetchAll(PDO::FETCH_ASSOC);
+
+ $data[\'yearly_sales\'] = db()->query("
+ SELECT label, SUM(tot) as total FROM (
+ SELECT YEAR(invoice_date) as label, total_with_vat as tot FROM invoices $out_w
+ UNION ALL
+ SELECT YEAR(created_at) as label, net_amount as tot FROM pos_transactions WHERE status = \'completed\' $out_and
+ ) t
+ GROUP BY label
+ ORDER BY label ASC LIMIT 5
+ ")->fetchAll(PDO::FETCH_ASSOC);';
+
+$c = str_replace($find_charts, $repl_charts, $c);
+
+file_put_contents('index.php', $c);
+echo "Dashboard Patched\n";
diff --git a/patch_expenses.php b/patch_expenses.php
new file mode 100644
index 0000000..5c98db2
--- /dev/null
+++ b/patch_expenses.php
@@ -0,0 +1,9 @@
+prepare\(\"INSERT INTO users \(username, password, email, phone, group_id\) VALUES \(\?, \?, \?, \?, \?\)\"\);.*?\\\$stmt->execute\(\[\\\$username, password_hash\(\\\$password, PASSWORD_DEFAULT\), \\\$email, \\\$phone, \\\$group_id\]\);/s",
+ "\$group_id = (int)(\$_POST['group_id'] ?? 0) ?: null;\n \$outlet_id = !empty(\$_POST['outlet_id']) ? (int)\$_POST['outlet_id'] : null;\n \$stmt = \$db->prepare(\"INSERT INTO users (username, password, email, phone, group_id, outlet_id) VALUES (?, ?, ?, ?, ?, ?)\");\n \$stmt->execute([\$username, password_hash(\$password, PASSWORD_DEFAULT), \$email, \$phone, \$group_id, \$outlet_id]);",
+ $content
+);
+
+// 3. Fix Edit User POST
+$content = preg_replace(
+ "/\\\$group_id = \(int\)\(\\\$_POST\['group_id'\] \?\? 0\) \?\: null;.*?if \(\!empty\(\\\$password\)\) \{.*?\\\$stmt = \\\$db->prepare\(\"UPDATE users SET username=\?, password=\?, email=\?, phone=\?, group_id=\? WHERE id=\?\"\);.*?\\\$stmt->execute\(\[\\\$username, password_hash\(\\\$password, PASSWORD_DEFAULT\), \\\$email, \\\$phone, \\\$group_id, \\\$id\]\);.*?\} else \{.*?\\\$stmt = \\\$db->prepare\(\"UPDATE users SET username=\?, email=\?, phone=\?, group_id=\? WHERE id=\?\"\);.*?\\\$stmt->execute\(\[\\\$username, \\\$email, \\\$phone, \\\$group_id, \\\$id\]\);.*?\}/s",
+ "\$group_id = (int)(\$_POST['group_id'] ?? 0) ?: null;\n \$outlet_id = !empty(\$_POST['outlet_id']) ? (int)\$_POST['outlet_id'] : null;\n if (!empty(\$password)) {\n \$stmt = \$db->prepare(\"UPDATE users SET username=?, password=?, email=?, phone=?, group_id=?, outlet_id=? WHERE id=?\");\n \$stmt->execute([\$username, password_hash(\$password, PASSWORD_DEFAULT), \$email, \$phone, \$group_id, \$outlet_id, \$id]);\n } else {\n \$stmt = \$db->prepare(\"UPDATE users SET username=?, email=?, phone=?, group_id=?, outlet_id=? WHERE id=?\");\n \$stmt->execute([\$username, \$email, \$phone, \$group_id, \$outlet_id, \$id]);\n }",
+ $content
+);
+
+file_put_contents('index.php', $content);
+echo "Patched auth & post logic\n";
diff --git a/patch_users.php b/patch_users.php
new file mode 100644
index 0000000..4b3de37
--- /dev/null
+++ b/patch_users.php
@@ -0,0 +1,46 @@
+prepare("INSERT INTO users (username, password, email, phone, group_id) VALUES (?, ?, ?, ?, ?)");
+ try {
+ $stmt->execute([$username, $hashed_password, $email, $phone, $group_id]);';
+
+$repl_add = ' $outlet_id = !empty($_POST[\'outlet_id\']) ? (int)$_POST[\'outlet_id\'] : null;
+ $stmt = db()->prepare("INSERT INTO users (username, password, email, phone, group_id, outlet_id) VALUES (?, ?, ?, ?, ?, ?)");
+ try {
+ $stmt->execute([$username, $hashed_password, $email, $phone, $group_id, $outlet_id]);';
+
+$c = str_replace($find_add, $repl_add, $c);
+
+// Fix Edit User
+$find_edit = ' if ($password) {
+ $hashed_password = password_hash($password, PASSWORD_DEFAULT);
+ $stmt = db()->prepare("UPDATE users SET username = ?, password = ?, email = ?, phone = ?, group_id = ? WHERE id = ?");
+ $stmt->execute([$username, $hashed_password, $email, $phone, $group_id, $id]);
+ } else {
+ $stmt = db()->prepare("UPDATE users SET username = ?, email = ?, phone = ?, group_id = ? WHERE id = ?");
+ $stmt->execute([$username, $email, $phone, $group_id, $id]);
+ }';
+
+$repl_edit = ' $outlet_id = !empty($_POST[\'outlet_id\']) ? (int)$_POST[\'outlet_id\'] : null;
+ if ($password) {
+ $hashed_password = password_hash($password, PASSWORD_DEFAULT);
+ $stmt = db()->prepare("UPDATE users SET username = ?, password = ?, email = ?, phone = ?, group_id = ?, outlet_id = ? WHERE id = ?");
+ $stmt->execute([$username, $hashed_password, $email, $phone, $group_id, $outlet_id, $id]);
+ } else {
+ $stmt = db()->prepare("UPDATE users SET username = ?, email = ?, phone = ?, group_id = ?, outlet_id = ? WHERE id = ?");
+ $stmt->execute([$username, $email, $phone, $group_id, $outlet_id, $id]);
+ }';
+
+$c = str_replace($find_edit, $repl_edit, $c);
+
+// Fix login session
+$c = str_replace(
+ "\$_SESSION['user_role_name'] = \$u['role_name'];",
+ "\$_SESSION['user_role_name'] = \$u['role_name'];\n \$_SESSION['outlet_id'] = \$u['outlet_id'];",
+ $c
+);
+
+file_put_contents('index.php', $c);
+echo "Patched users.php\n";
diff --git a/patch_users_edit_post.php b/patch_users_edit_post.php
new file mode 100644
index 0000000..6b3b5d1
--- /dev/null
+++ b/patch_users_edit_post.php
@@ -0,0 +1,17 @@
+prepare("UPDATE users SET username = ?, email = ?, phone = ?, group_id = ?, status = ? WHERE id = ?");
+ $stmt->execute([$username, $email, $phone, $group_id, $status, $id]);';
+
+$repl_edit_post = '$status = $_POST[\'status\'] ?? \'active\';
+ $outlet_id = !empty($_POST[\'outlet_id\']) ? (int)$_POST[\'outlet_id\'] : null;
+ if ($id && $username) {
+ $stmt = db()->prepare("UPDATE users SET username = ?, email = ?, phone = ?, group_id = ?, status = ?, outlet_id = ? WHERE id = ?");
+ $stmt->execute([$username, $email, $phone, $group_id, $status, $outlet_id, $id]);';
+
+$c = str_replace($find_edit_post, $repl_edit_post, $c);
+file_put_contents('index.php', $c);
+echo "Edit Post Patched\n";
diff --git a/patch_users_edit_ui.php b/patch_users_edit_ui.php
new file mode 100644
index 0000000..ab9448e
--- /dev/null
+++ b/patch_users_edit_ui.php
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+ ';
+
+$repl_group_edit = $find_group_edit . '
+
+
+
+
';
+
+$c = str_replace($find_group_edit, $repl_group_edit, $c);
+
+// Also we need to make sure 'status' was updated in Edit User POST!
+// Looking at the previous edit_user patch, I didn't add status. I will add status now since the UI has it!
+// Actually, earlier the backend code didn't update `status`?
+// Let me just replace the file contents.
+
+file_put_contents('index.php', $c);
+echo "UI Edit Patched\n";
diff --git a/patch_users_ui.php b/patch_users_ui.php
new file mode 100644
index 0000000..bf504f5
--- /dev/null
+++ b/patch_users_ui.php
@@ -0,0 +1,34 @@
+query(\"SELECT id, name FROM role_groups ORDER BY name ASC\")->fetchAll();\n break;\n case 'backups':",
+ "\$data['role_groups'] = db()->query(\"SELECT id, name FROM role_groups ORDER BY name ASC\")->fetchAll();\n \$data['outlets'] = db()->query(\"SELECT id, name FROM outlets ORDER BY name ASC\")->fetchAll();\n break;\n case 'backups':",
+ $c
+);
+
+// Add Outlet field to Add User
+$find_group_add = '
+ ';
+
+$repl_group_add = $find_group_add . '
+