dasaproject/django/Invoice/templates/Invoice/create-update.html
2023-09-27 15:49:36 +07:00

525 lines
22 KiB
HTML

{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% load humanize %}
{% block title %}Invoice{% endblock title %}
{% block body %}
{% comment %} {% if messages %}
<div class="alert alert-success" role="alert">
{{message}}
</div>
{% endif %} {% endcomment %}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="alert alert-{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<div class="container-fluid">
<form action="" method="POST" class="card border-info-subtle p-3 mt-2" autocomplete="off" id="form">
{% csrf_token %}
<div class="row">
<div class="col-6">{{form.CustomerRefFullName|as_crispy_field}}</div>
</div>
<div class="row">
<div class="col-sm">{{form.BillAddr1|as_crispy_field}}</div>
<div class="col">
<div class="row">
<div class="col-sm">{{form.TxnDate|as_crispy_field}}</div>
<div class="col">{{form.RefNumber|as_crispy_field}}</div>
</div>
<div class="row">
<div class="col">{{form.PONumber|as_crispy_field}}</div>
</div>
<div class="row">
<div class="col">{{form.SalesRepRefFullName|as_crispy_field}}</div>
</div>
</div>
<div class="col">{{form.ShipAddr1|as_crispy_field}}</div>
</div>
{{form.TotalAmount}}
{% comment %} <div >{{form.IsToBePrinted.as_hidden}}</div>
<div >{{form.IsToBeEmailed.as_hidden}}</div>
<div >{{form.IsManuallyClosed.as_hidden}}</div> {% endcomment %}
<div >{{form.KTP.as_hidden}}</div>
<div >{{form.NPWP.as_hidden}}</div>
<div >{{form.DMS_Cust_Name.as_hidden}}</div>
<div >{{form.DMS_Cust_Code.as_hidden}}</div>
<div >{{form.Special_Cust.as_hidden}}</div>
<div >{{form.EFaktur_Name.as_hidden}}</div>
<div >{{form.Efaktur_Address.as_hidden}}</div>
<div class="col">{{form.Coordinates.as_hidden}}</div>
<hr style="border: 1px solid #007bff">
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% if formset %}
{{ formset.management_form }}
<div class="row">
<div class="col-2 text-center mb-1">ItemRefFullName*</div>
<div class="col-3 text-center">Description</div>
<div class="col-1 text-center">Qty</div>
<div class="col-1 text-center">UOM</div>
<div class="col-2 text-center">Rate</div>
<div class="col">
<div class='row'>
<div class='col-10 text-end'>
Amount</div>
<div class='col text-end'>Del</div>
</div>
</div>
<div id='itemline-form-list'>
{% comment %} {% for form in formset %} {% endcomment %}
{% for qs, form in qsformset %}
<div class='itemline-form'>
{{form.id}}
{% comment %} {{form.ItemRefFullName.field}} {% endcomment %}
<div class="row parentrow">
<div class="col-2">
<div id='div_id_form-{{forloop.counter0}}-inputitem' class='mb-1'>
{% comment %} <label for="id_form-{{forloop.counter0}}-inputitem" class="form-label requiredField"> ItemRefFullName<span class="asteriskField">*</span>
</label> {% endcomment %}
<div></div>
<input type='text' list='itemname' onchange='changeitem(event)' value='{{qs.ItemRefFullName}}' class='textinput form-control inputitem'
id='id_form-{{forloop.counter0}}-inputitem'>
</div>
</div>
<div class="col hidden">{{form.ItemRefFullName|as_crispy_field}}</div>
<div class="col-3" onchange='descchanged(event)'>{{form.Desc|as_crispy_field}}</div>
<div class="col-1" onchange='qtychanged(event)'>{{form.Quantity|as_crispy_field}}</div>
<div class="col-1">{{form.UnitOfMeasure|as_crispy_field}}</div>
<div class="col-2" onchange='ratechanged(event)'>{{form.Rate|as_crispy_field}}</div>
<div class="col">
<div class="row">
<div class='col text-end' onchange='amountchanged(event)'>{{form.Amount|as_crispy_field}}</div>
<div class="col-1 mt-1" onchange='deletechanged(event)' onclick='return confirm("Are you sure DELETE this Item Line?")'>{{form.DELETE|as_crispy_field}}</div>
</div>
</div>
{{form.Invoiced.as_hidden}}
{{form.LineIsManuallyClosed.as_hidden}}
</div>
</div>
{% endfor %}
</div>
<br>
{% endif %}
<div class="row justify-content-between ">
<div class="col-5 mt-3">
<button type="button" class="btn btn-primary me-2" id='add-more'>+ More ItemLine</button>
<button type="submit" class="btn btn-primary me-2 ms-2" id="id_btnsave" onclick="checksubmit(event)">Save</button>
<button type="button" class="btn btn-primary me-2 ms-2" onclick="revert()" id="id_btnrevert">Revert</button>
{% comment %} <div class="col-4"> {% endcomment %}
</div>
<div class='col text-end mt-3 fs-5 fw-bold'>
Total Amount Rp.
</div>
<div id='div_id_TotalAmount' class='col col-md-4 mb-1 mt-2 text-end mt-3 me-4 fs-5 fw-bold'>{{form.TotalAmount.value|intcomma}}
{% comment %} <input type='text' name='TotalAmount' value="{{form.Amount.value|intcomma}}" class='hidden text-end fs-5 form-control' id='id_TotalAmount' readonly> {% endcomment %}
</div>
{% comment %} <div class='col-1'></div> {% endcomment %}
</div>
</div>
</form>
<div id='empty-form' class='hidden'>
<div class="row parentrow">
<div class="col-2">
<div id='div_id_form-__prefix__-inputitem' class='mb-1'>
{% comment %} <label for="id_form-__prefix__-inputitem" class="form-label requiredField"> ItemRefFullName<span class="asteriskField">*</span>
</label> {% endcomment %}
<input type='text' list='itemname' onchange='changeitem(event)' value='{{qs.ItemRefFullName}}' class='textinput form-control'
id='id_form-__prefix__-inputitem'>
</div>
</div>
<div class="col hidden">{{formset.empty_form.ItemRefFullName|as_crispy_field}}</div>
<div class="col-3">{{formset.empty_form.Desc|as_crispy_field}}</div>
<div class="col-1" onchange='qtychanged(event)'>{{formset.empty_form.Quantity|as_crispy_field}}</div>
<div class="col-1">{{formset.empty_form.UnitOfMeasure|as_crispy_field}}</div>
<div class="col-2" onchange='ratechanged(event)'>{{formset.empty_form.Rate|as_crispy_field}}</div>
{% comment %} <div class="col" onchange='amountchanged(event)'>{{formset.empty_form.Amount|as_crispy_field}}</div> {% endcomment %}
{% comment %} <div class="col">{{formset.empty_form.DELETE|as_crispy_field}}</div> {% endcomment %}
<div class="col">
<div class="row">
<div class='col text-end' onchange='amountchanged(event)'>{{formset.empty_form.Amount|as_crispy_field}}</div>
<div class="col-1 mt-1" onchange='deletechanged(event)'>{{formset.empty_form.DELETE|as_crispy_field}}</div>
</div>
</div>
{{formset.empty_form.Invoiced.as_hidden}}
{{formset.empty_form.LineIsManuallyClosed.as_hidden}}
</div>
</div>
</div>
<datalist id='itemname'>
{% for item in itemdatalist %}
<option value="{{item.FullName}}" data-pk="{{item.id}}" data-desc="{{item.SalesDesc}}" data-rate="{{item.SalesPrice}}">
{% endfor %}
</datalist>
<script>
document.getElementById('id_CustomerRefFullName').addEventListener('focusout', function() {
console.log(this.value);
if (this.value == '') {
return};
let str='';
let url="{% url 'Invoice:getpricelist' %}"+this.value
console.log(url)
fetch(url)
.then((response) => {
return response.json();
})
.then((data) => {
//console.log(data);
data=JSON.parse(data);
let dt=JSON.parse(data['itemdatalist']);
console.log(dt)
console.log(dt.length)
for (let k=0;k<dt.length;k++){
//console.log(dt[k]);
//console.log("dt[k]")
if (dt[k].itempricelevel__Price) {
str+='<option value="' + dt[k].FullName + '" data-pk="' + dt[k].id + '" data-desc="' + dt[k].SalesDesc + '" data-rate="' + dt[k].itempricelevel__Price + '">';
} else {
str+='<option value="' + dt[k].FullName + '" data-pk="' + dt[k].id + '" data-desc="' + dt[k].SalesDesc + '" data-rate="' + dt[k].SalesPrice + '">';
}
}
//console.log(str);
dt=JSON.parse(data['obj']);
console.log(dt)
console.log(dt.length)
document.getElementById('itemname').innerHTML = str;
str='';
for (let k=0;k<dt.length;k++){
console.log(dt[0].pk);
console.log(dt[0].fields.BillAddr1);
str= dt[0].fields.BillAddr1;
if (dt[0].fields.BillAddr2) {str+="\n"+dt[0].fields.BillAddr2}
if (dt[0].fields.BillAddr3) {str+="\n"+dt[0].fields.BillAddr3}
if (dt[0].fields.BillAddr4) {str+="\n"+dt[0].fields.BillAddr4}
if (dt[0].fields.BillAddr5) {str+="\n"+dt[0].fields.BillAddr5}
document.getElementById('id_BillAddr1').value = str
str=dt[0].fields.ShipAddr1;
if (dt[0].fields.ShipAddr2) {str+="\n"+dt[0].fields.ShipAddr2}
if (dt[0].fields.ShipAddr3) {str+="\n"+dt[0].fields.ShipAddr3}
if (dt[0].fields.ShipAddr4) {str+="\n"+dt[0].fields.ShipAddr4}
if (dt[0].fields.ShipAddr5) {str+="\n"+dt[0].fields.ShipAddr5}
document.getElementById('id_ShipAddr1').value = str;
//document.getElementById('id_ShipAddr1').value = dt[0].fields.ShipAddr1;
}
});
console.log(str)
//for (let i=0;i<12;i++){
// str+= '<option value="' + i + '">';
//}
//document.getElementById('itemname').innerHTML = str;
});
function customerChanged(e){
console.log(e)
}
</script>
<script>
function number_format( number, decimals, dec_point, thousands_sep ) {
// http://kevin.vanzonneveld.net
// + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfix by: Michael White (http://crestidg.com)
// + bugfix by: Benjamin Lupton
// + bugfix by: Allan Jensen (http://www.winternet.no)
// + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// * example 1: number_format(1234.5678, 2, '.', '');
// * returns 1: 1234.57
var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals;
var d = dec_point == undefined ? "," : dec_point;
var t = thousands_sep == undefined ? "." : thousands_sep, s = n < 0 ? "-" : "";
var i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
}
</script>
<script>
var totalAmount = 0;
var boloktosave = 0;
function revert(){
document.getElementById("form").reset();
findTotalAmount()
}
function numberOnly(event){
//console.log(event.cancelable);
if ((event.charCode >= 48 && event.charCode <= 57) || event.charCode==46) {
//console.log("true");
return true;
} else {
//console.log("false");
event.preventDefault();
return false;
}
}
function checksubmit(e){
console.log('boloktosave:' + boloktosave);
if (boloktosave==0) {
console.log("prevented")
e.preventDefault();
return false;
}
const customerreffullname = document.getElementById('id_CustomerRefFullName');
if (!customerreffullname.value){
console.log('customer is empty');
e.preventDefault();
return false
}
const inputitem = document.getElementsByClassName('inputitem');
for (let i=0; i<inputitem.length;i++) {
if (!inputitem[i].value){
console.log(getElementByElEventClass(inputitem[i], "checkboxinput").checked)
if (getElementByElEventClass(inputitem[i], "checkboxinput").checked==true) {
continue;
};
//console.log()
console.log("ItemRefFullName cannot be empty");
alert('ItemRefFullName cannot be empty');
console.log(i);
console.log(inputitem[i]);
inputitem[i].focus();
e.preventDefault();
return false
}
}
console.log("submitted")
}
function changeitem(e) {
console.log(e.cancelable);
const inputValue=e.target.value;
console.log("inputval="+inputValue);
const dtlist = document.getElementById('itemname');
const selectedOption = dtlist.querySelector('option[value="' + inputValue + '"]');
console.log(selectedOption)
if (!selectedOption && e.target.value!="") {
console.log("cannot find item")
//e.preventDefault;
boloktosave=0;
e.target.focus();
e.target.onblur= function() {
setTimeout(function() {
e.target.focus();
}, 0);
};
return false;
}
if (e.target.value=="" || !e.target.value){
boloktosave=0;
return false;
}
e.target.onblur="";
boloktosave=1;
const datasetPK = selectedOption.dataset.pk;
const datasetDesc = selectedOption.dataset.desc;
const datasetRate = selectedOption.dataset.rate;
console.log(datasetPK, datasetDesc, datasetRate);
const targetELParent = e.target.parentElement.parentElement.parentElement;
console.log(targetELParent);
//const targetELParent = e.target.parentElement.parentElement;
//const targetELItemRef = targetELParent.nextElementSibling.children[0].children[1];
const targetELItemRef = targetELParent.getElementsByClassName('itemreffullname')[0];
console.log(targetELItemRef);
targetELItemRef.value = datasetPK;
//const targetELDesc = targetELParent.nextElementSibling.nextElementSibling.children[0].children[1];
const targetELDesc = getElementByElEventClass(e, "desc");
//const targetELDesc = targetELParent.getElementsByClassName('desc')[0];
console.log(targetELDesc);
targetELDesc.value = datasetDesc;
//const targetELRate = targetELParent.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.children[0].children[1];
const targetELRate = getElementByElEventClass(e, "rate");
//const targetELRate = targetELParent.getElementsByClassName('rate')[0];
console.log(targetELRate);
targetELRate.value = parseFloat(datasetRate).toFixed(2);
//const targetELAmount = targetELParent.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.children[0].children[1];
const targetELAmount = getElementByElEventClass(e, "amount");
//const targetELAmount = targetELParent.getElementsByClassName('amount')[0];
//const qty = targetELParent.nextElementSibling.nextElementSibling.nextElementSibling.children[0].children[1].value;
const qtyEL = getElementByElEventClass(e, "quantity");
//const qtyEL = targetELParent.getElementsByClassName('quantity')[0];
console.log(qtyEL.value);
if (!qtyEL.value){
qtyEL.value=1;
}
targetELAmount.value=(qtyEL.value*parseFloat(datasetRate)).toFixed(2)
findTotalAmount();
}
function findTotalAmount() {
let arr=document.getElementsByClassName('amount');
let tot=0;
for(let i=0;i<arr.length;i++){
if(parseFloat(arr[i].value)) {
tot += parseFloat(arr[i].value);
}
}
console.log(tot);
const totalamountEL=document.getElementById('id_TotalAmount');
const dividtotalamountEL = document.getElementById('div_id_TotalAmount');
const totFormated = number_format(tot,"2",".",",");
console.log(totFormated);
console.log(dividtotalamountEL)
dividtotalamountEL.innerHTML = totFormated;
console.log(dividtotalamountEL.innerHTML)
totalamountEL.value=tot;
}
function descchanged(e) {
boloktosave=1;
}
function qtychanged(e) {
console.log(e);
let qty=e.target.value;
console.log(qty);
if (!qty) {
qty=1;
e.target.value=qty;
} else if (qty<0) {
qty=0;
e.target.value=qty;
}
const rate=getElementByElEventClass(e, "rate").value;
//const rate=e.target.parentElement.parentElement.nextElementSibling.nextElementSibling.children[0].children[1].value;
console.log(rate * qty);
let amountValue=rate*qty;
const amount=getElementByElEventClass(e, "amount")
//let amount=e.target.parentElement.parentElement.nextElementSibling.nextElementSibling.nextElementSibling.children[0].children[1];
console.log(amount);
amount.value=amountValue.toFixed(2);
findTotalAmount();
boloktosave=1;
}
function ratechanged(e) {
console.log(e);
let rate=e.target.value;
console.log(rate);
if (!rate){
rate=0;
e.target.value=0;
} else if(rate<0){
rate=0;
e.target.value=0;
}
const qty=getElementByElEventClass(e, "quantity").value;
//const qty=e.target.parentElement.parentElement.previousElementSibling.previousElementSibling.children[0].children[1].value;
console.log("qty"+qty);
let amountValue=rate*qty;
console.log(amountValue);
const amount=getElementByElEventClass(e,"amount");
//const amount=e.target.parentElement.parentElement.nextElementSibling.children[0].children[1];
console.log(amount);
amount.value=amountValue.toFixed(2);
console.log(amount.value);
findTotalAmount();
boloktosave=1;
}
function amountchanged(e) {
console.log(e);
let amount=e.target.value;
if (!amount){
amount=0;
e.target.value=0;
} else if(amount<0){
amount=0;
e.target.value=0;
alert("Amount cannot be a negative value.")
}
const qty=getElementByElEventClass(e, "quantity");
console.log(qty.value);
if (qty.value){
const rateEL=getElementByElEventClass(e, "rate")
if (qty.value>0){
rateEL.value=(amount/qty.value).toFixed(2)
} else {
qty.value=(amount/rateEL.value).toFixed(2)
}
findTotalAmount();
boloktosave=1;
}
}
function getElementByElEventClass(e, classname){
let parent;
console.log("eventclaaaaaaasss");
console.log("eventclass",e,classname)
if (e.target){
parent = e.target.parentElement;
}
else {
parent = e.parentElement;
}
console.log(parent);
console.log(e, classname);
while (!parent.classList.contains('parentrow')){
parent = parent.parentElement;
}
console.log(parent);
//const parent=e.target.parentElement.parentElement.parentElement;
console.log(parent);
const el=parent.getElementsByClassName(classname)[0];
console.log(el);
return el;
}
function deletechanged(e){
console.log("DELETEEEEE")
boloktosave=1;
findTotalAmount();
}
</script>
<script>
document.addEventListener('click', (event)=>{
if (event.target.id == 'add-more') {
console.log("addmore clicked")
add_new_form(event);
}
})
function add_new_form(e) {
if (e) {
e.preventDefault();
}
const totalNewForms = document.getElementById('id_invoiceitemline_set-TOTAL_FORMS'); //'id_invoiceitemline_set-TOTAL_FORMS' 'id_form-TOTAL_FORMS'
const curItemLineForms = document.getElementsByClassName('itemline-form');
const curFormCount = curItemLineForms.length;
console.log('curformcount=' + curFormCount);
const formCopyTarget = document.getElementById('itemline-form-list');
const copyEmptyFormEl = document.getElementById('empty-form').cloneNode(true);
copyEmptyFormEl.setAttribute('class', 'itemline-form');
copyEmptyFormEl.setAttribute('id', `form-${curFormCount}`);
const regex = new RegExp('__prefix__', 'g');
copyEmptyFormEl.innerHTML = copyEmptyFormEl.innerHTML.replace(regex, curFormCount);
totalNewForms.setAttribute('value', curFormCount + 1);
formCopyTarget.append(copyEmptyFormEl);
}
</script>
{% endblock body %}