Accept Quote: This will convert the quote to an invoice.
DRAFT
MGT Business Solutons Sdn Bhd
1-9, 2-9 Jalan Bukit Jalil Indah 4,
Komplex Niaga LTAT, Bukit Jalil,
Kuala Lumpur
sales@mugattionline.com.my
01154095478
http://www.mgtbusinesssolutions.com
Wendy Wu
Quote Number EIQN_000001
Quote Date 11/08/2025
Valid Until Date 12/08/2025

To

面之吻调肤养肤
sungei wang
mianzhiwen8899@gmail.com
Business Kick Start Content Ads Management
Service Qty Rate Adjust (%) Total
一次性拍摄(1天完成)
拍摄 4支广告影片(30–45秒) 内容专为 Meta 广告用途(Facebook / Instagram) 含基础脚本策划、镜头分镜与现场指导 广告管理服务(3个月) 广告策略设定与目标受众规划 广告文案及视觉素材优化 每月广告数据分析与调整建议 广告守候优化:若广告未达预期,团队将进行剪辑及投放内容调整 售后支持 项目期间提供咨询与优化建议 必要时可额外出勤一次进行补拍(不额外收费)
1 MYR5,000.00 MYR5,000.00
拍摄 4支广告影片(30–45秒)
1 MYR0.00 MYR0.00
Sub Total:MYR5,000.00
SST (8%):MYR400.00
Total:MYR5,400.00

Notes:

1. 所有配套为一次性收费,须在付款完成后方可启动服务。 2. 拍摄为一次性完成,内容专为 Meta 广告用途。Kick Start 含 4 支影片,Pro 含 8 支影片。 3. 项目期间包含广告守候与优化服务,若广告未达预期,可进行内容调整及必要时一次额外补拍。 4. 每支影片包含一次修改机会,超出范围的修改将另行收费。 5. 项目启动后不设退款,所有素材版权归制作团队所有。

Terms & Conditions:

This quote has a fixed price.
DRAFT
`; // Write the content to the new window printWindow.document.write(printHTML); printWindow.document.close(); // Wait for content to load, then print printWindow.onload = function() { setTimeout(function() { printWindow.print(); printWindow.close(); }, 500); }; } document.addEventListener('DOMContentLoaded', function() { const quoteId = '11'; const acceptActionDescription = 'This will convert the quote to an invoice.'; const declinedMessage = ''; const isDeclineReasonRequired = false; // Utility: Show loading spinner in a button function setButtonLoading(btn, loadingText) { btn.disabled = true; btn.innerHTML = ` ${loadingText}`; } // resetButtonLoading function is now defined globally above // Accept Quote Button const acceptButton = document.querySelector('.quote-actions .accept'); if (acceptButton) { acceptButton.addEventListener('click', function() { let message = 'Accept this quote?'; if (acceptActionDescription) { message += '\n\n' + acceptActionDescription; } showConfirmationModal( 'Accept Quote', message, 'Accept Quote', 'Cancel', 'primary', function(modal, confirmBtn, originalText) { handleAcceptQuote(quoteId, confirmBtn, originalText); } ); }); } // Decline Quote Button const declineButton = document.querySelector('.quote-actions .decline'); if (declineButton) { declineButton.addEventListener('click', function() { let message = 'Decline this quote?'; if (declinedMessage) { message += '\n\n' + declinedMessage; } if (isDeclineReasonRequired) { showDeclineModalWithReason(); } else { showConfirmationModal( 'Decline Quote', message, 'Decline Quote', 'Cancel', 'danger', function(modal, confirmBtn, originalText) { handleDeclineQuote(quoteId, confirmBtn, originalText); } ); } }); } // Note: Download and Send Email buttons are handled via inline onclick attributes to avoid duplicate bindings // Custom Modal System function showConfirmationModal(title, message, confirmText, cancelText, confirmType, onConfirm) { // Remove existing modal if any const existingModal = document.querySelector('.ei-modal-overlay'); if (existingModal) { existingModal.remove(); } // Create modal overlay const overlay = document.createElement('div'); overlay.className = 'ei-modal-overlay'; // Create modal content const modal = document.createElement('div'); modal.className = 'ei-modal'; const confirmBtnClass = confirmType === 'danger' ? 'ei-modal-btn-danger' : 'ei-modal-btn-primary'; const iconClass = confirmType === 'danger' ? 'danger' : 'info'; const icon = confirmType === 'danger' ? '' : ''; modal.innerHTML = `
${icon}

${title}

${message}
`; overlay.appendChild(modal); document.body.appendChild(overlay); // Show modal with animation setTimeout(() => { overlay.classList.add('show'); modal.classList.add('show'); }, 10); // Handle button clicks const confirmBtn = modal.querySelector('#modal-confirm'); const cancelBtn = modal.querySelector('#modal-cancel'); confirmBtn.addEventListener('click', function() { const originalText = confirmBtn.innerHTML; setButtonLoading(confirmBtn, confirmBtn.textContent.trim()); onConfirm(modal, confirmBtn, originalText); }); cancelBtn.addEventListener('click', function() { hideModal(overlay); }); // Handle overlay click to close overlay.addEventListener('click', function(e) { if (e.target === overlay) { hideModal(overlay); } }); // Handle escape key const handleEscape = function(e) { if (e.key === 'Escape') { hideModal(overlay); document.removeEventListener('keydown', handleEscape); } }; document.addEventListener('keydown', handleEscape); // Focus on confirm button setTimeout(() => { confirmBtn.focus(); }, 100); } // Decline Modal with Reason Field function showDeclineModalWithReason() { // Remove existing modal if any const existingModal = document.querySelector('.ei-modal-overlay'); if (existingModal) { existingModal.remove(); } // Create modal overlay const overlay = document.createElement('div'); overlay.className = 'ei-modal-overlay'; // Create modal content const modal = document.createElement('div'); modal.className = 'ei-modal'; let message = 'Decline this quote?'; if (declinedMessage) { message += '\n\n' + declinedMessage; } modal.innerHTML = `

Decline Quote

${message}
`; overlay.appendChild(modal); document.body.appendChild(overlay); setTimeout(() => { overlay.classList.add('show'); modal.classList.add('show'); }, 10); // Handle button clicks const confirmBtn = modal.querySelector('#modal-confirm'); const cancelBtn = modal.querySelector('#modal-cancel'); const reasonField = modal.querySelector('#decline-reason'); confirmBtn.addEventListener('click', function() { const reason = reasonField.value.trim(); if (!reason) { reasonField.focus(); reasonField.classList.add('error'); return; } const originalText = confirmBtn.innerHTML; setButtonLoading(confirmBtn, confirmBtn.textContent.trim()); handleDeclineQuote(quoteId, confirmBtn, reason, originalText); }); cancelBtn.addEventListener('click', function() { hideModal(overlay); }); overlay.addEventListener('click', function(e) { if (e.target === overlay) { hideModal(overlay); } }); const handleEscape = function(e) { if (e.key === 'Escape') { hideModal(overlay); document.removeEventListener('keydown', handleEscape); } }; document.addEventListener('keydown', handleEscape); setTimeout(() => { reasonField.focus(); }, 100); reasonField.addEventListener('input', function() { this.classList.remove('error'); }); } function hideModal(overlay) { const modal = overlay.querySelector('.ei-modal'); modal.classList.remove('show'); overlay.classList.remove('show'); setTimeout(() => { if (overlay.parentNode) { overlay.remove(); } }, 300); } // Show message in modal (used for AJAX responses) function showModalMessage(type, message, onClose) { // Remove existing modal if any const existingModal = document.querySelector('.ei-modal-overlay'); if (existingModal) { existingModal.remove(); } // Create modal overlay const overlay = document.createElement('div'); overlay.className = 'ei-modal-overlay'; // Create modal content const modal = document.createElement('div'); modal.className = 'ei-modal'; const iconClass = type === 'success' ? 'info' : 'danger'; const icon = type === 'success' ? '' : ''; modal.innerHTML = `
${icon}

${type === 'success' ? 'Success' : 'Error'}

${message}
`; overlay.appendChild(modal); document.body.appendChild(overlay); setTimeout(() => { overlay.classList.add('show'); modal.classList.add('show'); }, 10); const closeBtn = modal.querySelector('#modal-close'); closeBtn.addEventListener('click', function() { hideModal(overlay); if (onClose) onClose(); }); overlay.addEventListener('click', function(e) { if (e.target === overlay) { hideModal(overlay); if (onClose) onClose(); } }); const handleEscape = function(e) { if (e.key === 'Escape') { hideModal(overlay); document.removeEventListener('keydown', handleEscape); if (onClose) onClose(); } }; document.addEventListener('keydown', handleEscape); setTimeout(() => { closeBtn.focus(); }, 100); } // Show loading state in modal function showModalLoading(message) { // Remove existing modal if any const existingModal = document.querySelector('.ei-modal-overlay'); if (existingModal) { existingModal.remove(); } // Create modal overlay const overlay = document.createElement('div'); overlay.className = 'ei-modal-overlay'; // Create modal content const modal = document.createElement('div'); modal.className = 'ei-modal'; modal.innerHTML = `

Please wait...

${message}
`; overlay.appendChild(modal); document.body.appendChild(overlay); setTimeout(() => { overlay.classList.add('show'); modal.classList.add('show'); }, 10); } // Handle Accept Quote function handleAcceptQuote(quoteId, confirmBtn, originalText) { showModalLoading('Accepting quote...'); jQuery.ajax({ url: 'https://mugattionline.com.my/wp-admin/admin-ajax.php', type: 'POST', data: { action: 'easy_invoice_accept_quote', quote_id: quoteId, nonce: '175f77efae' }, success: function(response) { if (response.success) { // Check if an invoice was created and redirect to it if (response.data && response.data.invoice_id) { // Use the PHP-generated URL (secure URL first, then regular URL) let invoiceUrl = response.data.secure_url || response.data.invoice_url; if (invoiceUrl) { showModalMessage('success', response.data.message || 'Quote accepted successfully! Redirecting to invoice...', function() { window.location.href = invoiceUrl; }); } else { // Fallback to reload if no URL available showModalMessage('success', response.data.message || 'Quote accepted successfully', function() { location.reload(); }); } } else { // No invoice created, just show success message showModalMessage('success', response.data && response.data.message ? response.data.message : 'Quote accepted successfully', function() { location.reload(); }); } } else { resetButtonLoading(confirmBtn, originalText); showModalMessage('error', response.data || 'Error accepting quote'); } }, error: function() { resetButtonLoading(confirmBtn, originalText); showModalMessage('error', 'Error connecting to server'); } }); } // Handle Decline Quote function handleDeclineQuote(quoteId, confirmBtn, reason = '', originalText) { showModalLoading('Declining quote...'); const ajaxData = { action: 'easy_invoice_decline_quote', quote_id: quoteId, nonce: '175f77efae' }; if (reason) { ajaxData.decline_reason = reason; } jQuery.ajax({ url: 'https://mugattionline.com.my/wp-admin/admin-ajax.php', type: 'POST', data: ajaxData, success: function(response) { if (response.success) { showModalMessage('success', response.data && response.data.message ? response.data.message : 'Quote declined successfully', function() { location.reload(); }); } else { resetButtonLoading(confirmBtn, originalText); showModalMessage('error', response.data || 'Error declining quote'); } }, error: function() { resetButtonLoading(confirmBtn, originalText); showModalMessage('error', 'Error connecting to server'); } }); } // Functions moved to global scope above });