From f24ef75d8a138a7bdcbea9d66b90f4834cbc5f2e Mon Sep 17 00:00:00 2001 From: mich71095 Date: Wed, 21 Feb 2018 09:57:42 +0800 Subject: [PATCH 1/6] Change subtotal computation to function --- assets/js/formset.js | 54 ++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/assets/js/formset.js b/assets/js/formset.js index cedfc64..9cdd19e 100644 --- a/assets/js/formset.js +++ b/assets/js/formset.js @@ -6,6 +6,20 @@ let formset = function() { let totalFormCounter; let arr = [] + let subTotalComputation = function(){ + // Sub-t0tal computation + $('.field-amount').each(function(counter){ + arr[counter] = Number( $(this).text() ) + }); + let subTotal = 0 + let totalForm = Number( $('#id_form-TOTAL_FORMS').val() ); + for(let counter=0; counter Date: Wed, 21 Feb 2018 09:58:31 +0800 Subject: [PATCH 2/6] Change invoice view templating --- assets/js/invoice.js | 158 ++++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 76 deletions(-) diff --git a/assets/js/invoice.js b/assets/js/invoice.js index 90f945e..cd9ccdb 100644 --- a/assets/js/invoice.js +++ b/assets/js/invoice.js @@ -4,8 +4,8 @@ $(function() { // Display invoice form $("a.create-invoice").on('click', function(e) { e.preventDefault(); - $("div.invoice-box").empty(); - $("div.invoice-box-form").show(); + $("#invView").addClass('hidden');; + $("#invForm").removeClass('hidden'); }); // Ajax view invoice @@ -14,80 +14,86 @@ $(function() { let id = $(this).attr('id').toString(); $.ajax({ - method: 'GET', - url: "/invoice/ajax/view/"+id+"", - context: $(this), - }) - .done(function(response){ - let obj = JSON.parse(response.invoice); + method: 'GET', + url: "/invoice/ajax/view/"+id+"", + dataType: 'json', + context: $(this), + success: function (resp) { + let invData = JSON.parse(resp.invoice); + let invItems = JSON.parse(resp.items); + + if (invData.length) { + invData = invData[0]; + } + + let wrapperDiv = $('#invView'); + let invForm = $('#invForm'); + let invNum = $('#invNum'); + let invDesc = $('#invDesc'); + let invClient = $('#invClient'); + let invPayStat = $('#invPayStat'); + let invDueDate = $('#invDueDate'); + let invDate = $('#invDate'); + let invRem = $('#invRem'); + let invSubTotal = $('#invSubTotal'); + let invTotal = $('#invTotal'); + + let itemsTbody = $('#itemsTbody'); + let itemsRow = $('#itemsRow'); + + wrapperDiv.removeClass('hidden'); + invForm.addClass('hidden'); - // Create invoice details template - for (let data in obj) { - $("div.invoice-box-form").hide() - $("div.invoice-box").empty() - $("div.invoice-box").append( - '
' - +'
' - +'
' - +'
' - +'Edit' - +'Delete' - +'|Generate PDF|' - +' Send' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +' ' - +'
' - +'
' - +obj[data].fields.invoice_number - +'
' - +'
' - +'
' - +'
' - +' ' - +'
' - +'
' - +obj[data].fields.client - +'
' - +'
' - +'
' - +'
' - +' ' - +'
' - +'
' - +obj[data].fields.item - +'
' - +'
' - +'
' - +'
' - +' ' - +'
' - +'
' - +obj[data].fields.invoice_date - +'
' - +'
' - +'
' - +'
' - +' ' - +'
' - +'
' - +obj[data].fields.due_date - +'
' - +'
' - +'
' - +'
' - +' ' - +'
' - +'
' - +obj[data].fields.remarks - +'
' - +'
' - ) - } - }); + let paymentStat = ''; + if (invData.fields.payment_status == false){ + paymentStat = 'unpaid'; + } else if (invData.fields.payment_status == true){ + paymentStat = 'paid'; + } + + let invDueDateData = new Date(invData.fields.due_date); + let invDateData = new Date(invData.fields.invoice_date); + + let arrInvDate = []; + let arrDueDate = []; + let invoiceDate = ''; + let invoiceDueDate = ''; + arrInvDate = String(invDateData).split(' '); + arrDueDate = String(invDueDateData).split(' '); + invoiceDate = arrInvDate[1]+' '+arrInvDate[2]+', '+arrInvDate[3]; + invoiceDueDate = arrDueDate[1]+' '+arrDueDate[2]+', '+arrDueDate[3]; + + invNum.text(resp.prefix.toUpperCase()+': '+resp.invoice_number); + invDesc.text(invData.fields.description.charAt(0).toUpperCase() + + invData.fields.description.slice(1).toLowerCase() + ); + invClient.text(resp.client.toLowerCase() + .replace(/\b[a-z]/g, function(letter) { + return letter.toUpperCase(); + }) + ); + invPayStat.text(paymentStat.charAt(0).toUpperCase()+ paymentStat.slice(1).toLowerCase()); + invDueDate.text(invoiceDueDate); + invDate.text(invoiceDate); + invRem.text(invData.fields.remarks.charAt(0).toUpperCase() + + invData.fields.remarks.slice(1).toLowerCase() + ); + invSubTotal.text(invData.fields.subtotal); + invTotal.text(invData.fields.subtotal); + + if (invItems.length) { + itemsTbody.html(''); + for (var i = invItems.length - 1; i >= 0; i--) { + let newRow = itemsRow.clone(); + newRow.removeClass('hidden'); + newRow.children('.itemDesc').html(invItems[i].fields.description); + newRow.children('.itemQty').html(invItems[i].fields.quantity); + newRow.children('.itemRate').html(invItems[i].fields.rate); + newRow.children('.itemAmount').html(invItems[i].fields.amount); + itemsTbody.append(newRow); + } + } + }, + }) }); }); From 8e5881c364e03543db46807855185bbfe657365f Mon Sep 17 00:00:00 2001 From: mich71095 Date: Wed, 21 Feb 2018 09:59:14 +0800 Subject: [PATCH 3/6] Add subtotal --- invoices/forms.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/invoices/forms.py b/invoices/forms.py index 0979643..ad9bae1 100644 --- a/invoices/forms.py +++ b/invoices/forms.py @@ -29,6 +29,7 @@ class Meta: 'remarks', 'description', 'payment_status', + 'subtotal', ) def __init__(self,*args, **kwargs): @@ -117,11 +118,8 @@ def clean(self): for count,form in enumerate(self.forms): if not form.data['form-'+str(count)+'-description']: - print("not description") raise forms.ValidationError("Description is required!") if not form.data['form-'+str(count)+'-quantity']: - print("not qty") raise forms.ValidationError("Quantity is required!") if not form.data['form-'+str(count)+'-rate']: - print("not rate") raise forms.ValidationError("Rate is required!") From fd2099f27689363b6b49162f85f0e7248ee1d6c5 Mon Sep 17 00:00:00 2001 From: mich71095 Date: Wed, 21 Feb 2018 09:59:41 +0800 Subject: [PATCH 4/6] Add subtotal field --- invoices/models.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/invoices/models.py b/invoices/models.py index 0592182..a3260b0 100644 --- a/invoices/models.py +++ b/invoices/models.py @@ -34,15 +34,13 @@ class Invoice(models.Model): payment_status = models.BooleanField( default=False) pdf = models.FileField(upload_to=get_invoice_directory,null=True, blank=True) remarks = models.TextField(max_length=255,null=True, blank=True) + subtotal = models.PositiveIntegerField() status = models.CharField(max_length=10, choices=STATUS, default='draft') class Meta: unique_together = ('invoice_number', 'company') def __str__(self): - return f"{self.invoice_number}" - - def get_invoice_number(self): return f"{self.invoice_number}".zfill(9) From bdd5b74be3a12987693a0fa2eba34a0aa7864f7b Mon Sep 17 00:00:00 2001 From: mich71095 Date: Wed, 21 Feb 2018 10:01:07 +0800 Subject: [PATCH 5/6] Change template view for invoice --- templates/invoices/all_invoice.html | 247 +++++++++++++++++++--------- 1 file changed, 168 insertions(+), 79 deletions(-) diff --git a/templates/invoices/all_invoice.html b/templates/invoices/all_invoice.html index 09dfe9b..b969968 100644 --- a/templates/invoices/all_invoice.html +++ b/templates/invoices/all_invoice.html @@ -13,25 +13,131 @@ {% endif %} -

Invoice

+ {% if not invoices %} + No invoices yet + {% endif %} {% for invoice in invoices %}
-
+ +
-
{{ invoice.client.client_company }}
-
{{ invoice.get_invoice_number }}
-
{{ invoice.due_date }}
-
{{ invoice.status }}
+
{{ invoice.client.client_company|title }}
+
{{ invoice.client.get_prefix|upper }}: {{ invoice }}
+
{{ invoice.due_date|date:"M d, Y" }}
+
+ {% if invoice.status == 'sent' %} + |{{ invoice.status|title }} + {% elif invoice.status == 'draft' %} + |{{ invoice.status|title }} + {% endif %} +
{% endfor %}
-
+ + +
{% csrf_token %}
@@ -123,48 +229,41 @@

New Invoice


{{ formset.management_form }} - {% for form in formset %} - - -
- +
{% if formset.non_form_errors %} - - {{ form.non_form_errors }} - {% for error in formset.non_form_errors %} - {{ error|escape }} - {% endfor %} - {% endif %} - - - {% if form.description.errors %} - - [{{ forloop.counter }}]description error: {{ form.description.errors.as_text }} - -
- {% endif %} - {% if form.quantity.errors %} - - [{{ forloop.counter }}]quantity error: {{ form.quantity.errors.as_text }} - -
- {% endif %} - {% if form.rate.errors %} - - [{{ forloop.counter }}]rate error: {{ form.rate.errors.as_text }} - -
- {% endif %} - {% if form.amount.errors %} - - [{{ forloop.counter }}]amount error: {{ form.amount.errors.as_text }} - -
- {% endif %} + {{ form.non_form_errors }} + {% for error in formset.non_form_errors %} + {{ error|escape }} + {% endfor %} + {% endif %} + + {% if form.description.errors %} + + [{{ forloop.counter }}]description error: {{ form.description.errors.as_text }} + +
+ {% endif %} + {% if form.quantity.errors %} + + [{{ forloop.counter }}]quantity error: {{ form.quantity.errors.as_text }} + +
+ {% endif %} + {% if form.rate.errors %} + + [{{ forloop.counter }}]rate error: {{ form.rate.errors.as_text }} + +
+ {% endif %} + {% if form.amount.errors %} + + [{{ forloop.counter }}]amount error: {{ form.amount.errors.as_text }} + +
+ {% endif %}
-
{{ form.description|attr:"class:form-control"|attr:"required:True" }} @@ -181,46 +280,36 @@

New Invoice


- - - - - - {% endfor %}
-
-
-
-
-
-
-
- -
-
- -
-
-
-
- {{ invoice_form.remarks|attr:"placeholder:Remarks"|attr:"class:form-control"}}
-
{{ invoice_form.remarks.errors.as_text }}
-
-
-
+
+
{{ invoice_form.subtotal|attr:"val:0"|attr:"hidden" }}
+ +
+
+
+ +
+
-

-
-
- - +
+ {{ invoice_form.remarks|attr:"placeholder:Remarks"|attr:"class:form-control"}}
+
{{ invoice_form.remarks.errors.as_text }}
-
-
+
+
+

+
+
+ + +
+
+
+
@@ -338,7 +427,7 @@
- {% endblock %} +{% endblock %} {% block js %}