cmc-sales/app/views/elements/document_invoice_view.ctp

288 lines
11 KiB
PHP
Executable file

<h2>Invoice: <?=$document['Invoice']['title']?> for <?=$html->link($enquiry['Customer']['name'], '/customers/view/'.$enquiry['Customer']['id']);?></h2>
<h2>Job: <?=$html->link($invoice['Job']['title'], array('controller'=>'jobs', 'action'=>'view', $invoice['Job']['id']));?></h2>
<div id="flashMessage" class="message">
</div>
<div class="docButtons">
<button id="paymentReceived">Enter Payment Received</button>
<button id="pdfDocButton" data-url="/documents/pdf/<?= $document['Document']['id']; ?>">Generate PDF</button>
<button id="emailInvoiceButton" data-url="/documents/email_pdf_with_custom_recipients/<?= $document['Document']['id']; ?>">Email Invoice</button>
</div>
<!-- Email Modal -->
<div id="emailModal" class="modal-pop" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%, -50%); background:#fff; border:2px solid #1976d2; padding:14px 28px 18px 28px; z-index:1000; min-width:370px; font-size:14px; box-shadow: 0 8px 32px rgba(0,0,0,0.25), 0 1.5px 8px rgba(0,0,0,0.10); border-radius:12px;">
<h3 style="font-size:1.5em; margin-top:0; padding-bottom:10px;">Email Invoice</h3>
<form id="emailInvoiceForm">
<div class="input">
<label for="emailTo">To:
<span class="info-icon" title="Use comma separated values for multiple addresses">&#9432;</span>
</label>
<input type="text" id="emailTo" name="to" class="emailInputSmall" required value="<?= isset($accountsEmail) ? h($accountsEmail) : '' ?>" />
</div>
<div class="input">
<label for="emailCc">Cc:
<span class="info-icon" title="Use comma separated values for multiple addresses">&#9432;</span>
</label>
<input type="text" id="emailCc" name="cc" class="emailInputSmall" value="<?= isset($enquiry['Contact']['email']) ? h($enquiry['Contact']['email']) : '' ?>" />
</div>
<div class="input">
<label for="emailBcc">Bcc:
<span class="info-icon" title="Use comma separated values for multiple addresses">&#9432;</span>
</label>
<input type="text" id="emailBcc" name="bcc" class="emailInputSmall" value="sales@cmctechnologies.com.au" />
</div>
<div id="emailError" style="color:red; display:none; margin-top:8px;"></div>
<div class="modal-btn-row">
<button type="button" id="cancelEmailInvoice" class="modal-btn">Cancel</button>
<button type="submit" id="sendEmailInvoice" class="modal-btn" style="min-width:80px;">Send</button>
</div>
</form>
</div>
<div id="modalOverlay" style="display:none; position:fixed; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.3); z-index:999;"></div>
<script>
document.getElementById('emailInvoiceButton').addEventListener('click', function() {
document.getElementById('emailModal').style.display = 'block';
document.getElementById('modalOverlay').style.display = 'block';
document.getElementById('emailError').style.display = 'none';
document.getElementById('emailError').textContent = '';
// Reset to default values each time modal opens
document.getElementById('emailTo').value = "<?= isset($accountsEmail) ? h($accountsEmail) : '' ?>";
document.getElementById('emailCc').value = "<?= isset($enquiry['Contact']['email']) ? h($enquiry['Contact']['email']) : '' ?>";
document.getElementById('emailBcc').value = 'sales@cmctechnologies.com.au';
// Disable send button if 'to' field is empty
var sendBtn = document.getElementById('sendEmailInvoice');
sendBtn.disabled = !document.getElementById('emailTo').value.trim();
if (sendBtn.disabled) {
sendBtn.setAttribute('aria-disabled-msg', 'An invoice recipient must be specified');
} else {
sendBtn.removeAttribute('aria-disabled-msg');
}
});
document.getElementById('emailTo').addEventListener('input', function() {
var sendBtn = document.getElementById('sendEmailInvoice');
sendBtn.disabled = !this.value.trim();
if (sendBtn.disabled) {
sendBtn.setAttribute('aria-disabled-msg', 'An invoice recipient must be specified');
} else {
sendBtn.removeAttribute('aria-disabled-msg');
}
});
document.getElementById('cancelEmailInvoice').addEventListener('click', function() {
document.getElementById('emailModal').style.display = 'none';
document.getElementById('modalOverlay').style.display = 'none';
});
document.getElementById('modalOverlay').addEventListener('click', function() {
document.getElementById('emailModal').style.display = 'none';
document.getElementById('modalOverlay').style.display = 'none';
});
document.getElementById('emailInvoiceForm').addEventListener('submit', function(e) {
if (!confirm('Are you sure you want to send this invoice?')) {
e.preventDefault();
return;
}
e.preventDefault();
var to = document.getElementById('emailTo').value;
var cc = document.getElementById('emailCc').value;
var bcc = document.getElementById('emailBcc').value;
var url = document.getElementById('emailInvoiceButton').getAttribute('data-url');
var formData = new FormData();
formData.append('to', to);
formData.append('cc', cc);
formData.append('bcc', bcc);
var errorDiv = document.getElementById('emailError');
errorDiv.style.display = 'none';
errorDiv.textContent = '';
fetch(url, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(async response => {
// Always read the response as text first, then try to parse as JSON
let text = await response.text();
let data;
try {
data = JSON.parse(text);
} catch (err) {
data = { error: 'Unexpected server response.', raw: text };
}
return data;
})
.then(data => {
// Show SMTP errors if present, otherwise show any error or failure message
if (data && (data.error || data.smtp_errors || data.success === false)) {
var msgArr = [];
if (data.smtp_errors) {
msgArr.push('SMTP Error: ' + data.smtp_errors);
}
if (data.error) {
msgArr.push(data.error);
}
if (data.success === false && data.message) {
msgArr.push(data.message);
}
if (data.raw) {
msgArr.push(data.raw);
} else if (data.error) {
msgArr.push('<em>No response receieved.</em>');
}
if (msgArr.length === 0) {
msgArr.push('Failed to send email. No error details provided.');
}
errorDiv.innerHTML = msgArr.join('<br>');
errorDiv.style.display = 'block';
} else {
alert(data.message || 'Email sent!');
document.getElementById('emailModal').style.display = 'none';
document.getElementById('modalOverlay').style.display = 'none';
}
})
.catch((err) => {
errorDiv.innerHTML = 'Failed to send email: ' + (err && err.message ? err.message : err);
errorDiv.style.display = 'block';
});
});
</script>
<div class="docOperations">
<h3>Create new Documents based on this</h3>
<ul class="document-buttons">
<li>
<button id="createPackingList" class="button-link" data-href="/documents/newDocument/packingList/<?=$enquiry['Enquiry']['id']?>/<?=$invoice['Job']['id']?>/<?=$document['Document']['id']?>">Create Packing List</button>
</li>
</ul>
</div>
<div id="invoiceDetails" class="documentDetails">
<fieldset>
<? echo $form->create('Document',array('type'=>'post','action'=>'edit', 'default'=>false));
echo $form->input('Document.id');
echo $form->input('Invoice.id');
echo $form->input('Invoice.job_id');
echo $form->input('Invoice.currency_id');
echo $form->input('Invoice.issue_date');
echo $form->input('Invoice.due_date');
echo $form->input('billing_address_id', array('div' => 'addressradio', 'legend' => 'Select Billing Address', 'options' => $billing_addresses_list, 'type' => 'radio', 'class'=>'billing_address'));
echo $form->input('Document.bill_to');
echo $form->input('shipping_address_id', array('div' => 'addressradio','legend' => 'Select Shipping Address', 'options' => $shipping_addresses_list, 'type' => 'radio', 'class' => 'shipping_address'));
echo $form->input('Document.ship_to');
echo $form->input('Invoice.ship_via');
echo $form->input('Invoice.fob');
?>
<div class="input">Payment terms: <?=$enquiry['Customer']['payment_terms'];?></div>
<div class="input">
<a href="/customers/edit/<?=$enquiry['Customer']['id'];?>">Set the payment terms for this customer</a>
</div>
<?php
echo $form->input('Document.shipping_details', array('id'=>'shippingDetails'));
echo $form->end(array('label'=>'Save Invoice Details', 'id'=>'saveInvoiceButton'));
?>
</fieldset>
</div>
<span id="invoiceID" style="display: none;"><?=$document['Invoice']['id']?></span>
<? //debug($this->data);?>
<? //debug($enquiry);?>
<?php //debug($document);?>
<?php //debug($docType);?>
<? //debug($invoice); ?>
<style>
.emailInputSmall {
width: 100%;
font-size: 13px;
padding: 4px 6px;
}
.modal-pop {
box-shadow: 0 8px 32px rgba(0,0,0,0.25), 0 1.5px 8px rgba(0,0,0,0.10);
border-radius: 12px;
border: 2px solid #1976d2;
background: linear-gradient(135deg, #f8fafc 80%, #e3f2fd 100%);
padding: 28px 28px 18px 28px !important;
min-width: 370px;
font-size: 14px;
transition: box-shadow 0.2s;
}
.modal-btn-row {
width: 100%;
margin-top: 16px;
display: flex;
justify-content: flex-end;
gap: 10px;
/* align-items: center; */
}
.modal-btn {
font-size: 13px !important;
padding: 4px 16px !important;
border-radius: 6px;
border: 1px solid #1976d2;
background: #1976d2;
color: #fff;
transition: background 0.2s, color 0.2s;
box-shadow: 0 1px 4px rgba(25, 118, 210, 0.08);
}
.modal-btn:disabled, #sendEmailInvoice:disabled {
background: #eee !important;
color: #aaa !important;
border: 1px solid #ccc !important;
cursor: not-allowed !important;
}
.info-icon {
display: inline-block;
margin-left: 3px !important;
margin-bottom: 2px !important;
color: #888;
cursor: pointer;
font-size: 1em;
vertical-align: middle;
position: relative;
}
.info-icon:hover::after {
content: attr(title);
position: absolute;
left: 20px;
top: -18px;
background: #333;
color: #fff;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
z-index: 1001;
}
#sendEmailInvoice[aria-disabled-msg]:hover::after {
content: attr(aria-disabled-msg);
position: absolute;
left: 50%;
top: 110%;
transform: translateX(-50%);
background: #333;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
font-size: 13px;
white-space: nowrap;
z-index: 1002;
pointer-events: none;
}
#sendEmailInvoice {
position: relative;
}
</style>