adding whatapp

This commit is contained in:
Flatlogic Bot 2026-03-03 06:59:12 +00:00
parent d2a2461bda
commit 2a16f1f83e
8 changed files with 268 additions and 7 deletions

View File

@ -2,6 +2,17 @@
$title = 'dashboard';
require_once __DIR__ . '/includes/header.php';
// Handle WhatsApp Settings Save
if ($is_super && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_whatsapp_settings'])) {
set_setting('whatsapp_enabled', $_POST['whatsapp_enabled'] ?? '0');
set_setting('wablas_token', $_POST['wablas_token'] ?? '');
set_setting('wablas_server', $_POST['wablas_server'] ?? '');
set_setting('msg_order_created_ar', $_POST['msg_order_created_ar'] ?? '');
set_setting('msg_order_ready_ar', $_POST['msg_order_ready_ar'] ?? '');
set_setting('msg_payment_ar', $_POST['msg_payment_ar'] ?? '');
$success_msg = is_arabic() ? 'تم حفظ الإعدادات بنجاح' : 'Settings saved successfully';
}
// Helper functions for status colors
if (!function_exists('getStatusColor')) {
function getStatusColor($status) {
@ -281,8 +292,59 @@ if (!$is_limited) {
});
}
</script>
<?php if ($is_super): ?>
<div class="mt-4">
<div class="card p-4 shadow-sm" style="border-radius: 20px;">
<div class="d-flex justify-content-between align-items-center mb-4">
<h5 class="fw-bold mb-0"><i class="bi bi-whatsapp text-success me-2"></i> <?= __('whatsapp_settings') ?></h5>
<?php if (isset($success_msg)): ?>
<div class="alert alert-success py-2 px-3 mb-0" style="border-radius: 10px;"><?= $success_msg ?></div>
<?php endif; ?>
</div>
<form method="POST">
<div class="row g-3">
<div class="col-md-12">
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="whatsapp_enabled" name="whatsapp_enabled" value="1" <?= get_setting('whatsapp_enabled') == '1' ? 'checked' : '' ?>>
<label class="form-check-label" for="whatsapp_enabled"><?= __('whatsapp_enabled') ?></label>
</div>
</div>
<div class="col-md-6">
<label class="form-label fw-semibold"><?= __('wablas_token') ?></label>
<input type="text" class="form-control" name="wablas_token" value="<?= htmlspecialchars(get_setting('wablas_token', '')) ?>" placeholder="Wablas API Token">
</div>
<div class="col-md-6">
<label class="form-label fw-semibold"><?= __('wablas_server') ?></label>
<input type="text" class="form-control" name="wablas_server" value="<?= htmlspecialchars(get_setting('wablas_server', 'https://console.wablas.com')) ?>" placeholder="https://console.wablas.com">
</div>
<div class="col-md-12">
<label class="form-label fw-semibold"><?= __('msg_order_created_ar') ?></label>
<textarea class="form-control mb-2" name="msg_order_created_ar" rows="2"><?= htmlspecialchars(get_setting('msg_order_created_ar', '')) ?></textarea>
<small class="text-muted">Tags: {customer_name}, {order_number}, {order_details}, {total_price}</small>
</div>
<div class="col-md-12">
<label class="form-label fw-semibold"><?= __('msg_order_ready_ar') ?></label>
<textarea class="form-control mb-2" name="msg_order_ready_ar" rows="2"><?= htmlspecialchars(get_setting('msg_order_ready_ar', '')) ?></textarea>
<small class="text-muted">Tags: {customer_name}, {order_number}</small>
</div>
<div class="col-md-12">
<label class="form-label fw-semibold"><?= __('msg_payment_ar') ?></label>
<textarea class="form-control mb-2" name="msg_payment_ar" rows="2"><?= htmlspecialchars(get_setting('msg_payment_ar', '')) ?></textarea>
<small class="text-muted">Tags: {customer_name}, {order_number}, {amount}, {remaining_balance}</small>
</div>
<div class="col-12 mt-4">
<button type="submit" name="save_whatsapp_settings" class="btn btn-primary px-4 py-2" style="border-radius: 12px;">
<i class="bi bi-save me-2"></i> <?= is_arabic() ? 'حفظ' : 'Save' ?>
</button>
</div>
</div>
</form>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
<?php
require_once __DIR__ . '/includes/footer.php';
?>
?>

View File

@ -1,6 +1,7 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../includes/whatsapp.php';
session_start();
if (!isset($_SESSION['user_id'])) {
@ -95,9 +96,65 @@ try {
$stmt_payment->execute([$order_id, $total_price, $payment_method]);
}
// Fetch customer details for notifications
$customer = null;
if ($customer_id) {
$stmt_cust = $pdo->prepare('SELECT name_ar, phone FROM customers WHERE id = ?');
$stmt_cust->execute([$customer_id]);
$customer = $stmt_cust->fetch();
}
$pdo->commit();
// WhatsApp Notifications
try {
if (get_setting('whatsapp_enabled') === '1' && $customer && !empty($customer['phone'])) {
// 1. Order Created Notification
$template = get_setting('msg_order_created_ar');
if (!empty($template)) {
$details_parts = [];
foreach ($items as $item) {
$stmt_names = $pdo->prepare('SELECT i.name_ar as item_name, s.name_ar as service_name FROM items i, services s WHERE i.id = ? AND s.id = ?');
$stmt_names->execute([$item['itemId'], $item['serviceId']]);
$names = $stmt_names->fetch();
$details_parts[] = ($names['item_name'] ?? 'صنف') . ' (' . ($names['service_name'] ?? 'خدمة') . ') x' . $item['quantity'];
}
$order_details = implode(', ', $details_parts);
// Get order number if not already available
if (!isset($order_number)) {
$stmt_onum = $pdo->prepare('SELECT order_number FROM orders WHERE id = ?');
$stmt_onum->execute([$order_id]);
$order_number = $stmt_onum->fetchColumn();
}
$message = str_replace(
['{customer_name}', '{order_number}', '{order_details}', '{total_price}'],
[$customer['name_ar'], $order_number, $order_details, $total_price],
$template
);
send_whatsapp_message($customer['phone'], $message);
}
// 2. Payment Received Notification (if paid during checkout)
if ($payment_method && $payment_method !== 'pay_later') {
$template_pay = get_setting('msg_payment_ar');
if (!empty($template_pay)) {
$message_pay = str_replace(
['{customer_name}', '{order_number}', '{amount}', '{remaining_balance}'],
[$customer['name_ar'], $order_number, $total_price, 0],
$template_pay
);
send_whatsapp_message($customer['phone'], $message_pay);
}
}
}
} catch (Exception $e) {
// Silently fail for notifications
}
echo json_encode(['success' => true, 'order_id' => $order_id]);
} catch (Exception $e) {
if (isset($pdo)) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
}

View File

@ -1,6 +1,7 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../includes/whatsapp.php';
session_start();
if (!isset($_SESSION['user_id'])) {
@ -29,10 +30,35 @@ try {
$stmt->execute([$status, $id]);
if ($stmt->rowCount() > 0) {
// WhatsApp Notification for Order Ready
try {
if ($status === 'ready') {
if (get_setting('whatsapp_enabled') === '1') {
$stmt_details = $pdo->prepare('SELECT o.order_number, c.name_ar, c.phone FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.id = ?');
$stmt_details->execute([$id]);
$order = $stmt_details->fetch();
if ($order && !empty($order['phone'])) {
$template = get_setting('msg_order_ready_ar');
if (!empty($template)) {
$message = str_replace(
['{customer_name}', '{order_number}'],
[$order['name_ar'], $order['order_number']],
$template
);
send_whatsapp_message($order['phone'], $message);
}
}
}
}
} catch (Exception $e) {
// Silently fail for notification
}
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => 'Order not found or status already same']);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
}

View File

@ -43,7 +43,23 @@ function check_permission($page = null, $user_id = null) {
return $result;
}
function get_setting($key, $default = null) {
try {
$stmt = db()->prepare('SELECT setting_value FROM settings WHERE setting_key = ?');
$stmt->execute([$key]);
$val = $stmt->fetchColumn();
return ($val !== false) ? $val : $default;
} catch (Exception $e) {
return $default;
}
}
function set_setting($key, $value) {
$stmt = db()->prepare('INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = ?, updated_at = CURRENT_TIMESTAMP');
$stmt->execute([$key, $value, $value]);
}
function has_permission($action, $page = null, $user_id = null) {
$perms = check_permission($page, $user_id);
return !empty($perms[$action]);
}
}

View File

@ -0,0 +1,14 @@
CREATE TABLE IF NOT EXISTS settings (
setting_key VARCHAR(100) PRIMARY KEY,
setting_value TEXT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Initial WhatsApp settings
INSERT INTO settings (setting_key, setting_value) VALUES
('whatsapp_enabled', '0'),
('wablas_token', ''),
('wablas_server', 'https://console.wablas.com'),
('msg_order_created_ar', 'عزيزي {customer_name}، تم استلام طلبك رقم {order_number}. التفاصيل: {order_details}. الإجمالي: {total_price}. شكراً لتعاملك معنا.'),
('msg_order_ready_ar', 'عزيزي {customer_name}، طلبك رقم {order_number} جاهز للاستلام. شكراً لتعاملك معنا.'),
('msg_payment_ar', 'عزيزي {customer_name}، تم استلام دفعة بمبلغ {amount} لطلبك رقم {order_number}. الرصيد المتبقي: {remaining_balance}. شكراً لتعاملك معنا.');

View File

@ -18,6 +18,7 @@ $translations = [
'branches' => 'Branches',
'users' => 'Users',
'settings' => 'Settings',
'whatsapp_settings' => 'WhatsApp Settings', 'whatsapp_enabled' => 'WhatsApp Enabled', 'wablas_token' => 'Wablas API Token', 'wablas_server' => 'Wablas Server URL', 'msg_order_created_ar' => 'Order Created Message (Arabic)', 'msg_order_ready_ar' => 'Order Ready Message (Arabic)', 'msg_payment_ar' => 'Payment Received Message (Arabic)',
'logout' => 'Logout',
'login' => 'Login',
'username' => 'Username',
@ -206,6 +207,7 @@ $translations = [
'branches' => 'الفروع',
'users' => 'المستخدمين',
'settings' => 'الإعدادات',
'whatsapp_settings' => 'إعدادات الواتساب', 'whatsapp_enabled' => 'تفعيل الواتساب', 'wablas_token' => 'رمز API Wablas', 'wablas_server' => 'رابط خادم Wablas', 'msg_order_created_ar' => 'رسالة إنشاء الطلب (بالعربية)', 'msg_order_ready_ar' => 'رسالة الطلب جاهز (بالعربية)', 'msg_payment_ar' => 'رسالة استلام الدفعة (بالعربية)',
'logout' => 'تسجيل الخروج',
'login' => 'تسجيل الدخول',
'username' => 'اسم المستخدم',

51
includes/whatsapp.php Normal file
View File

@ -0,0 +1,51 @@
<?php
require_once __DIR__ . '/../db/config.php';
function send_whatsapp_message($phone, $message) {
if (get_setting('whatsapp_enabled') !== '1') {
return ['success' => false, 'error' => 'WhatsApp is disabled'];
}
$token = get_setting('wablas_token');
$server = get_setting('wablas_server', 'https://console.wablas.com');
if (empty($token) || empty($server)) {
return ['success' => false, 'error' => 'Wablas configuration is incomplete'];
}
// Clean phone number (ensure it has country code, e.g., 966 for Saudi Arabia if not provided)
// For now, assume user provides it or we just use it as is if it looks correct.
$phone = preg_replace('/[^0-9]/', '', $phone);
// Wablas API expects phone number.
$curl = curl_init();
$data = [
'phone' => $phone,
'message' => $message,
];
curl_setopt($curl, CURLOPT_HTTPHEADER, [
"Authorization: $token",
]);
curl_setopt($curl, CURLOPT_URL, rtrim($server, '/') . "/api/send-message");
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$result = curl_exec($curl);
$error = curl_error($curl);
curl_close($curl);
if ($error) {
return ['success' => false, 'error' => $error];
}
$response = json_decode($result, true);
if (isset($response['status']) && $response['status'] == true) {
return ['success' => true, 'response' => $response];
}
return ['success' => false, 'error' => $response['message'] ?? 'Unknown error from Wablas'];
}

View File

@ -2,6 +2,7 @@
// ACTION HANDLING FIRST
require_once __DIR__ . '/db/config.php';
require_once __DIR__ . '/includes/lang.php';
require_once __DIR__ . '/includes/whatsapp.php';
$order_id = $_GET['id'] ?? null;
if (!$order_id) {
@ -27,10 +28,26 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$new_status = $_POST['status'];
$stmt = db()->prepare("UPDATE orders SET status = ? WHERE id = ?");
$stmt->execute([$new_status, $order_id]);
// WhatsApp Notification for Order Ready
try {
if ($new_status === 'ready' && get_setting('whatsapp_enabled') === '1' && !empty($order['customer_phone'])) {
$template = get_setting('msg_order_ready_ar');
if (!empty($template)) {
$message = str_replace(
['{customer_name}', '{order_number}'],
[$order['customer_name_ar'], $order['order_number']],
$template
);
send_whatsapp_message($order['customer_phone'], $message);
}
}
} catch (Exception $e) {}
header("Location: order_details.php?id=$order_id");
exit;
} elseif ($_POST['action'] === 'add_payment') {
$amount = $_POST['amount'];
$amount = (float)$_POST['amount'];
$method = $_POST['payment_method'];
$stmt = db()->prepare("INSERT INTO payments (order_id, amount, payment_method) VALUES (?, ?, ?)");
$stmt->execute([$order_id, $amount, $method]);
@ -43,6 +60,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$stmt = db()->prepare("UPDATE orders SET payment_status = ? WHERE id = ?");
$stmt->execute([$payment_status, $order_id]);
// WhatsApp Notification for Payment Received
try {
if (get_setting('whatsapp_enabled') === '1' && !empty($order['customer_phone'])) {
$remaining_now = (float)$order['total_price'] - (float)$total_paid;
$template = get_setting('msg_payment_ar');
if (!empty($template)) {
$message = str_replace(
['{customer_name}', '{order_number}', '{amount}', '{remaining_balance}'],
[$order['customer_name_ar'], $order['order_number'], $amount, max(0, $remaining_now)],
$template
);
send_whatsapp_message($order['customer_phone'], $message);
}
}
} catch (Exception $e) {}
header("Location: order_details.php?id=$order_id");
exit;
}
@ -193,7 +226,7 @@ $payments = $stmt->fetchAll();
$stmt = db()->prepare("SELECT SUM(amount) as total_paid FROM payments WHERE order_id = ?");
$stmt->execute([$order_id]);
$total_paid = $stmt->fetch()['total_paid'] ?? 0;
$remaining = $order['total_price'] - $total_paid;
$remaining = (float)$order['total_price'] - (float)$total_paid;
?>
<div class="d-flex justify-content-between align-items-center mb-3">
<span class="text-muted fw-bold small"><?= __('remaining_amount') ?></span>
@ -255,4 +288,4 @@ function getPaymentStatusColor($status) {
][$status] ?? 'info';
}
require_once __DIR__ . '/includes/footer.php';
?>
?>