/**
* @class CheckoutManager
* @description ระบบจัดการกระบวนการสั่งซื้อและชำระเงิน
* รับผิดชอบการจัดการขั้นตอนการสั่งซื้อตั้งแต่ตรวจสอบตะกร้า จนถึงการชำระเงิน
*/
const CheckoutManager = {
/**
* @method init
* @description เริ่มต้นระบบ
* - ลงทะเบียนเทมเพลต
* - ตั้งค่าตัวรับฟังเหตุการณ์
*/
init() {
this.setupTemplates();
this.setupEventListeners();
},
/**
* @method setupTemplates
* @description ลงทะเบียนเทมเพลตทั้งหมดที่จำเป็นสำหรับกระบวนการสั่งซื้อ
*/
setupTemplates() {
// เทมเพลตแสดงรายละเอียดการสั่งซื้อ
TemplateManager.registerTemplate('checkout-details-template',
`
🛍️ คำสั่งซื้อใหม่ #
📋 ข้อมูลลูกค้า
ชื่อผู้รับ:
เบอร์โทร:
ที่อยู่:
หมายเหตุ:
💰 สรุปยอดเงิน
ราคารวม:
฿
ค่าจัดส่ง:
฿
ราคาสุทธิ:
฿
`
);
// เทมเพลตสำหรับแต่ละรายการสินค้า
TemplateManager.registerTemplate('checkout-item-template',
`
x
฿
`
);
// เทมเพลตสำหรับหน้ายืนยันการสั่งซื้อ
TemplateManager.registerTemplate('checkout-confirmation-template',
``
);
},
/**
* @method setupEventListeners
* @description ตั้งค่าตัวรับฟังเหตุการณ์ต่างๆ ที่เกี่ยวข้องกับการสั่งซื้อ
*/
setupEventListeners() {
document.addEventListener('click', (e) => {
if (e.target.id === 'editCustomerInfo') {
this.handleEditCustomerInfo();
} else if (e.target.id === 'confirmOrder') {
this.handleConfirmOrder();
}
});
// รับฟังผลการชำระเงิน
EventBus.on('payment:completed', this.handlePaymentCompleted.bind(this));
},
/**
* @method startCheckout
* @description เริ่มกระบวนการสั่งซื้อ
* - ตรวจสอบสินค้าในตะกร้า
* - แสดงฟอร์มข้อมูลลูกค้า
* - แสดงหน้ายืนยันการสั่งซื้อ
*/
async startCheckout() {
try {
const cartItems = CartManager.getCartItems();
if (cartItems.length === 0) {
NotificationManager.warning('ไม่มีสินค้าในตะกร้า');
return;
}
CustomerManager.showEditForm((savedInfo) => {
this.showOrderConfirmation();
});
} catch (error) {
console.error('เกิดข้อผิดพลาดในการสั่งซื้อ:', error);
NotificationManager.error('เกิดข้อผิดพลาด กรุณาลองใหม่อีกครั้ง');
}
},
/**
* @method showOrderConfirmation
* @description แสดงหน้าต่างยืนยันการสั่งซื้อพร้อมรายละเอียดการสั่งซื้อปัจจุบัน
*/
showOrderConfirmation() {
const orderDetails = this.createOrderDetails();
const orderDetailsHtml = this.createOrderDetailsHtml(orderDetails);
TemplateManager.showModal('checkout-confirmation-template', {
orderDetails: orderDetailsHtml
});
},
/**
* @method handleEditCustomerInfo
* @description จัดการเมื่อต้องการแก้ไขข้อมูลลูกค้า
*/
handleEditCustomerInfo() {
document.getElementById('orderConfirmationModal')?.remove();
CustomerManager.showEditForm(() => {
this.showOrderConfirmation();
});
},
/**
* @method handleConfirmOrder
* @description จัดการเมื่อกดยืนยันการสั่งซื้อ
*/
async handleConfirmOrder() {
try {
// สร้าง Order
const orderDetails = this.createOrderDetails();
// บันทึก Order
const savedOrder = await OrderManager.createOrder(orderDetails);
// ล้างตะกร้า
CartManager.clearCart();
// ปิดหน้ายืนยันการสั่งซื้อ
document.getElementById('orderConfirmationModal')?.remove();
// แสดงหน้าชำระเงิน
PaymentManager.showPaymentModal(savedOrder);
} catch (error) {
console.error('Order confirmation error:', error);
NotificationManager.error('เกิดข้อผิดพลาด กรุณาลองใหม่อีกครั้ง');
}
},
/**
* @method createOrderDetailsHtml
* @description สร้าง HTML สำหรับแสดงรายละเอียดการสั่งซื้อ
* @param {Object} order - ข้อมูลการสั่งซื้อ
* @returns {DocumentFragment} HTML สำหรับแสดงรายละเอียดการสั่งซื้อ
*/
createOrderDetailsHtml(order) {
const templateData = {
...order,
orderDate: new Date(order.orderDate).toLocaleString('th-TH', {
dateStyle: 'medium',
timeStyle: 'medium'
}),
name: order.customer.name,
phone: order.customer.phone,
address: this.formatAddress(order.customer),
deliveryNotes: order.customer.deliveryNotes,
subtotal: Utils.formatCurrency(order.total.subtotal),
deliveryFee: Utils.formatCurrency(order.total.deliveryFee),
total: Utils.formatCurrency(order.total.total)
};
const itemsList = order.items.map(item => ({
name: item.name,
quantity: item.quantity,
totalPrice: Utils.formatCurrency(item.price * item.quantity)
}));
const itemsHtml = itemsList.map(item =>
TemplateManager.create('checkout-item-template', item)
);
return TemplateManager.create('checkout-details-template', {
...templateData,
itemsList: itemsHtml
});
},
/**
* @method createOrderDetails
* @description สร้างออบเจ็กต์ข้อมูลการสั่งซื้อจากข้อมูลตะกร้าและข้อมูลลูกค้าปัจจุบัน
* @returns {Object} ข้อมูลการสั่งซื้อที่สมบูรณ์
*/
createOrderDetails() {
const customerInfo = CustomerManager.getCustomerInfo();
const cartItems = CartManager.getCartItems();
const cartTotal = CartManager.getCartTotal();
return {
orderId: `ORDER${Date.now()}`,
orderDate: new Date().toISOString(),
customer: customerInfo,
items: cartItems,
total: cartTotal,
status: CONFIG.ORDER_STATUS.PENDING
};
},
/**
* @method handlePaymentCompleted
* @description จัดการเมื่อชำระเงินเสร็จสิ้น
* - อัพเดทสถานะออเดอร์
* - แจ้งเตือนแอดมิน
* - ส่งอีเวนต์แจ้งการสั่งซื้อสำเร็จ
* @param {Object} paymentResult - ผลลัพธ์การชำระเงิน
*/
async handlePaymentCompleted({orderId, paymentResult}) {
try {
if (!paymentResult.success) {
NotificationManager.error('การชำระเงินไม่สำเร็จ');
return;
}
const updatedOrder = await OrderManager.updateOrder(orderId, {
status: CONFIG.ORDER_STATUS.COMPLETED,
payment: paymentResult,
completedAt: paymentResult.completedAt
});
const notificationHtml = this.createOrderDetailsHtml(updatedOrder);
await AdminNotifier.notify(notificationHtml);
EventBus.emit('order:completed', updatedOrder);
} catch (error) {
console.error('เกิดข้อผิดพลาดในการจัดการการชำระเงิน:', error);
NotificationManager.error('เกิดข้อผิดพลาดในการดำเนินการ');
}
},
/**
* @method formatAddress
* @description จัดรูปแบบที่อยู่ให้เป็นข้อความบรรทัดเดียว
* @param {Object} customer - ข้อมูลลูกค้า
* @returns {string} ที่อยู่ที่จัดรูปแบบแล้ว
*/
formatAddress(customer) {
return [
customer.addressLine1,
customer.addressLine2,
customer.district,
customer.province,
customer.postalCode
].filter(Boolean).join(' ');
}
};