diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 0ec036670f..ea25fcf4f4 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '11.1.13' +__version__ = '11.1.14' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/account/account.json b/erpnext/accounts/doctype/account/account.json index e47f8d2245..460c025b69 100644 --- a/erpnext/accounts/doctype/account/account.json +++ b/erpnext/accounts/doctype/account/account.json @@ -632,6 +632,39 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:(doc.report_type == 'Profit and Loss' && !doc.is_group)", + "fieldname": "include_in_gross", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Include in gross", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 } ], "has_web_view": 0, @@ -645,7 +678,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-01-07 16:52:02.557837", + "modified": "2019-03-04 14:42:07.208893", "modified_by": "Administrator", "module": "Accounts", "name": "Account", diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 7898bb2370..3a17ce5b4b 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -52,6 +52,12 @@ class JournalEntry(AccountsController): self.update_loan() self.update_inter_company_jv() + def before_print(self): + self.gl_entries = frappe.get_list("GL Entry",filters={"voucher_type": "Journal Entry", + "voucher_no": self.name} , + fields=["account", "party_type", "party", "debit", "credit", "remarks"] + ) + def get_title(self): return self.pay_to_recd_from or self.accounts[0].account diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 2d57da08b2..818b950336 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -70,6 +70,12 @@ class PaymentEntry(AccountsController): self.update_advance_paid() self.update_expense_claim() + def before_print(self): + self.gl_entries = frappe.get_list("GL Entry",filters={"voucher_type": "Payment Entry", + "voucher_no": self.name} , + fields=["account", "party_type", "party", "debit", "credit", "remarks"] + ) + def on_cancel(self): self.setup_party_account_field() self.make_gl_entries(cancel=1) diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.js b/erpnext/accounts/doctype/pos_profile/pos_profile.js index 13d53d1f6a..a6386ddc4b 100755 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.js +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.js @@ -33,6 +33,14 @@ frappe.ui.form.on('POS Profile', { }; }); + frm.set_query("account_for_change_amount", function() { + return { + filters: { + account_type: ['in', ["Cash", "Bank"]] + } + }; + }); + frm.set_query("print_format", function() { return { filters: { doc_type: "Sales Invoice", print_format_type: "Js"} }; }); diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index a9e8fbc3e8..c0d0d837fe 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -54,6 +54,12 @@ class PurchaseInvoice(BuyingController): if not self.on_hold: self.release_date = '' + def before_print(self): + self.gl_entries = frappe.get_list("GL Entry",filters={"voucher_type": "Purchase Invoice", + "voucher_no": self.name} , + fields=["account", "party_type", "party", "debit", "credit"] + ) + def invoice_is_blocked(self): return self.on_hold and (not self.release_date or self.release_date > getdate(nowdate())) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 773d1cfe06..a4a5940fc7 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -556,6 +556,14 @@ frappe.ui.form.on('Sales Invoice', { frm.add_fetch('payment_term', 'invoice_portion', 'invoice_portion'); frm.add_fetch('payment_term', 'description', 'description'); + frm.set_query("account_for_change_amount", function() { + return { + filters: { + account_type: ['in', ["Cash", "Bank"]] + } + }; + }); + frm.custom_make_buttons = { 'Delivery Note': 'Delivery', 'Sales Invoice': 'Sales Return', diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 4cf3a1acf5..62d8ffd897 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -205,6 +205,12 @@ class SalesInvoice(SellingController): def before_cancel(self): self.update_time_sheet(None) + def before_print(self): + self.gl_entries = frappe.get_list("GL Entry",filters={"voucher_type": "Sales Invoice", + "voucher_no": self.name} , + fields=["account", "party_type", "party", "debit", "credit"] + ) + def on_cancel(self): self.check_close_sales_order("sales_order") @@ -523,8 +529,8 @@ class SalesInvoice(SellingController): def validate_pos(self): if self.is_return: - if flt(self.paid_amount) + flt(self.write_off_amount) - flt(self.grand_total) < \ - 1/(10**(self.precision("grand_total") + 1)): + if flt(self.paid_amount) + flt(self.write_off_amount) - flt(self.grand_total) > \ + 1.0/(10.0**(self.precision("grand_total") + 1.0)): frappe.throw(_("Paid amount + Write Off Amount can not be greater than Grand Total")) def validate_item_code(self): diff --git a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json index ccdabfe544..1c5962acf6 100644 --- a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json +++ b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json @@ -20,6 +20,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:parent.doctype == 'POS Profile'", + "fetch_if_empty": 0, "fieldname": "default", "fieldtype": "Check", "hidden": 0, @@ -52,6 +53,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "mode_of_payment", "fieldtype": "Link", "hidden": 0, @@ -85,8 +87,9 @@ "bold": 0, "collapsible": 0, "columns": 0, - "default": "", + "default": "0", "depends_on": "eval:parent.doctype == 'Sales Invoice'", + "fetch_if_empty": 0, "fieldname": "amount", "fieldtype": "Currency", "hidden": 0, @@ -120,6 +123,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_3", "fieldtype": "Column Break", "hidden": 0, @@ -151,6 +155,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "account", "fieldtype": "Link", "hidden": 0, @@ -185,6 +190,7 @@ "collapsible": 0, "columns": 0, "fetch_from": "mode_of_payment.type", + "fetch_if_empty": 0, "fieldname": "type", "fieldtype": "Read Only", "hidden": 0, @@ -218,6 +224,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_amount", "fieldtype": "Currency", "hidden": 0, @@ -251,6 +258,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "clearance_date", "fieldtype": "Date", "hidden": 0, @@ -287,7 +295,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2019-02-18 15:03:59.720469", + "modified": "2019-03-06 15:58:37.839241", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Payment", diff --git a/erpnext/accounts/print_format/bank_and_cash_payment_voucher/__init__.py b/erpnext/accounts/print_format/bank_and_cash_payment_voucher/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/print_format/bank_and_cash_payment_voucher/bank_and_cash_payment_voucher.html b/erpnext/accounts/print_format/bank_and_cash_payment_voucher/bank_and_cash_payment_voucher.html new file mode 100644 index 0000000000..2eadb2a92a --- /dev/null +++ b/erpnext/accounts/print_format/bank_and_cash_payment_voucher/bank_and_cash_payment_voucher.html @@ -0,0 +1,82 @@ +{%- from "templates/print_formats/standard_macros.html" import add_header -%} + +
+ {%- if not doc.get("print_heading") and not doc.get("select_print_heading") + and doc.set("select_print_heading", _("Payment Entry")) -%}{%- endif -%} + {{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }} +
+
+ + +
Voucher No: {{ doc.name }}
+
+
+ + +
Date: {{ frappe.utils.formatdate(doc.creation) }}
+
+
+
+ + + + + + + + + + + {% set total_credit = 0 -%} + {% for entries in doc.gl_entries %} + {% if entries.debit == 0.0 %} + + + + + + {% set total_credit = total_credit + entries.credit -%} + + + + + + + + + {% endif %} + {% endfor %} + + + + + + + {% set total_debit = 0 -%} + {% for entries in doc.gl_entries %} + {% if entries.credit == 0.0 %} + + + + + {% set total_debit = total_debit + entries.debit -%} + + + + + + + + + + {% endif %} + {% endfor %} +
AccountParty TypePartyAmount
Credit
{{ entries.account }}{{ entries.party_type }}{{ entries.party }}{{ entries.credit }}
Narration
{{ entries.remarks }}
Total (credit) {{total_credit}}
Debit
{{ entries.account }}{{ entries.party_type }}{{ entries.party }}{{ entries.debit }}
Narration
{{ entries.remarks }}
Total (debit) {{total_debit}}
+
+
\ No newline at end of file diff --git a/erpnext/accounts/print_format/bank_and_cash_payment_voucher/bank_and_cash_payment_voucher.json b/erpnext/accounts/print_format/bank_and_cash_payment_voucher/bank_and_cash_payment_voucher.json new file mode 100644 index 0000000000..e3afaec2ad --- /dev/null +++ b/erpnext/accounts/print_format/bank_and_cash_payment_voucher/bank_and_cash_payment_voucher.json @@ -0,0 +1,22 @@ +{ + "align_labels_right": 0, + "creation": "2019-02-15 11:49:08.608619", + "custom_format": 0, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Payment Entry", + "docstatus": 0, + "doctype": "Print Format", + "font": "Default", + "idx": 0, + "line_breaks": 0, + "modified": "2019-02-15 11:49:08.608619", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Bank and Cash Payment Voucher", + "owner": "Administrator", + "print_format_builder": 0, + "print_format_type": "Server", + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/erpnext/accounts/print_format/gst_purchase_invoice/gst_purchase_invoice.json b/erpnext/accounts/print_format/gst_purchase_invoice/gst_purchase_invoice.json index 2b7f9ce757..6d7c3d31ae 100644 --- a/erpnext/accounts/print_format/gst_purchase_invoice/gst_purchase_invoice.json +++ b/erpnext/accounts/print_format/gst_purchase_invoice/gst_purchase_invoice.json @@ -7,10 +7,10 @@ "docstatus": 0, "doctype": "Print Format", "font": "Default", - "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"
\\t\\t\\t\\t

Purchase Invoice
{{ doc.name }}\\t\\t\\t\\t

\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"supplier_name\", \"label\": \"Supplier Name\"}, {\"print_hide\": 0, \"fieldname\": \"due_date\", \"label\": \"Due Date\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"address_display\", \"label\": \"Address\"}, {\"print_hide\": 0, \"fieldname\": \"contact_display\", \"label\": \"Contact\"}, {\"print_hide\": 0, \"fieldname\": \"contact_mobile\", \"label\": \"Mobile No\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"item_name\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"image\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"received_qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rejected_qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"discount_percentage\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"pricing_rule\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"weight_per_unit\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"total_weight\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"weight_uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"warehouse\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rejected_warehouse\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"batch_no\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"serial_no\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"bom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"asset\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"items\", \"label\": \"Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"category\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"add_deduct_tax\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"charge_type\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"row_id\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"included_in_print_rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"account_head\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"cost_center\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"taxes\", \"label\": \"Purchase Taxes and Charges\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"grand_total\", \"label\": \"Grand Total\"}, {\"print_hide\": 0, \"fieldname\": \"in_words\", \"label\": \"In Words\"}, {\"print_hide\": 0, \"fieldname\": \"disable_rounded_total\", \"label\": \"Disable Rounded Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Payments\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"cash_bank_account\", \"label\": \"Cash/Bank Account\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"other_charges_calculation\", \"align\": \"left\", \"label\": \"Tax Breakup\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Raw\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"main_item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rm_item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"batch_no\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"serial_no\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"required_qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"consumed_qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"stock_uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"conversion_factor\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"current_stock\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"reference_name\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"bom_detail_no\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"supplied_items\", \"label\": \"Supplied Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Terms\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"terms\", \"label\": \"Terms and Conditions1\"}]", + "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"
\\t\\t\\t\\t

Purchase Invoice
{{ doc.name }}\\t\\t\\t\\t

\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"supplier_name\", \"label\": \"Supplier Name\"}, {\"print_hide\": 0, \"fieldname\": \"due_date\", \"label\": \"Due Date\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"address_display\", \"label\": \"Address\"}, {\"print_hide\": 0, \"fieldname\": \"contact_display\", \"label\": \"Contact\"}, {\"print_hide\": 0, \"fieldname\": \"contact_mobile\", \"label\": \"Mobile No\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"item_name\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"image\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"received_qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rejected_qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"discount_percentage\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"pricing_rule\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"weight_per_unit\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"total_weight\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"weight_uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"warehouse\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rejected_warehouse\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"batch_no\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"serial_no\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"bom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"asset\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"gst_hsn_code\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"items\", \"label\": \"Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"category\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"add_deduct_tax\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"charge_type\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"row_id\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"included_in_print_rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"account_head\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"cost_center\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"taxes\", \"label\": \"Purchase Taxes and Charges\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"grand_total\", \"label\": \"Grand Total\"}, {\"print_hide\": 0, \"fieldname\": \"in_words\", \"label\": \"In Words\"}, {\"print_hide\": 0, \"fieldname\": \"disable_rounded_total\", \"label\": \"Disable Rounded Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Payments\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"cash_bank_account\", \"label\": \"Cash/Bank Account\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"other_charges_calculation\", \"align\": \"left\", \"label\": \"Tax Breakup\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Raw\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"main_item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rm_item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"batch_no\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"serial_no\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"required_qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"consumed_qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"stock_uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"conversion_factor\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"current_stock\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"reference_name\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"bom_detail_no\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"supplied_items\", \"label\": \"Supplied Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Terms\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"terms\", \"label\": \"Terms and Conditions1\"}]", "idx": 0, "line_breaks": 0, - "modified": "2018-04-07 13:06:08.060353", + "modified": "2019-03-04 13:38:47.362002", "modified_by": "Administrator", "module": "Accounts", "name": "GST Purchase Invoice", diff --git a/erpnext/accounts/print_format/journal_auditing_voucher/__init__.py b/erpnext/accounts/print_format/journal_auditing_voucher/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/print_format/journal_auditing_voucher/journal_auditing_voucher.html b/erpnext/accounts/print_format/journal_auditing_voucher/journal_auditing_voucher.html new file mode 100644 index 0000000000..4565559084 --- /dev/null +++ b/erpnext/accounts/print_format/journal_auditing_voucher/journal_auditing_voucher.html @@ -0,0 +1,76 @@ +{%- from "templates/print_formats/standard_macros.html" import add_header -%} + +
+ {%- if not doc.get("print_heading") and not doc.get("select_print_heading") + and doc.set("select_print_heading", _("Journal Entry")) -%}{%- endif -%} + {{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }} +
+
+ + +
Voucher No: {{ doc.name }}
+
+
+ + +
Date: {{ frappe.utils.formatdate(doc.creation) }}
+
+
+
+ + + + + + + + + + + {% set total_credit = 0 -%} + {% for entries in doc.gl_entries %} + {% if entries.debit == 0.0 %} + + + + + + {% set total_credit = total_credit + entries.credit -%} + + + + + + {% endif %} + {% endfor %} + + + + + + + {% set total_debit = 0 -%} + {% for entries in doc.gl_entries %} + {% if entries.credit == 0.0 %} + + + + + {% set total_debit = total_debit + entries.debit -%} + + + + + + + {% endif %} + {% endfor %} +
AccountParty TypePartyAmount
Credit
{{ entries.account }}{{ entries.party_type }}{{ entries.party }}{{ entries.credit }}
Total (credit) {{total_credit}}
Debit
{{ entries.account }}{{ entries.party_type }}{{ entries.party }}{{ entries.debit }}
Total (debit) {{total_debit}}
+
+
\ No newline at end of file diff --git a/erpnext/accounts/print_format/journal_auditing_voucher/journal_auditing_voucher.json b/erpnext/accounts/print_format/journal_auditing_voucher/journal_auditing_voucher.json new file mode 100644 index 0000000000..927e818e01 --- /dev/null +++ b/erpnext/accounts/print_format/journal_auditing_voucher/journal_auditing_voucher.json @@ -0,0 +1,22 @@ +{ + "align_labels_right": 0, + "creation": "2019-02-15 14:13:05.721784", + "custom_format": 0, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Journal Entry", + "docstatus": 0, + "doctype": "Print Format", + "font": "Default", + "idx": 0, + "line_breaks": 0, + "modified": "2019-02-15 14:13:05.721784", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Journal Auditing Voucher", + "owner": "Administrator", + "print_format_builder": 0, + "print_format_type": "Server", + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/erpnext/accounts/print_format/purchase_auditing_voucher/__init__.py b/erpnext/accounts/print_format/purchase_auditing_voucher/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/print_format/purchase_auditing_voucher/purchase_auditing_voucher.html b/erpnext/accounts/print_format/purchase_auditing_voucher/purchase_auditing_voucher.html new file mode 100644 index 0000000000..35852e1e1c --- /dev/null +++ b/erpnext/accounts/print_format/purchase_auditing_voucher/purchase_auditing_voucher.html @@ -0,0 +1,99 @@ +{%- from "templates/print_formats/standard_macros.html" import add_header -%} +
+ {%- if not doc.get("print_heading") and not doc.get("select_print_heading") + and doc.set("select_print_heading", _("Purchase Invoice")) -%}{%- endif -%} + {{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }} +
+
+ + + + + + +
Supplier Name: {{ doc.supplier }}
Due Date: {{ frappe.utils.formatdate(doc.due_date) }}
Address: {{doc.address_display}}
Contact: {{doc.contact_display}}
Mobile no: {{doc.contact_mobile}}
+
+
+ + + +
Voucher No: {{ doc.name }}
Date: {{ frappe.utils.formatdate(doc.creation) }}
+
+
+
+ + + + + + + + + + + + + {% for item in doc.items %} + + + + + + + + + + + + {% endfor %} +
SLItem CodeItem NameUOMReceived Qty.Rejected QtyQtyBasic RateAmount
{{ loop.index }}{{ item.item_code }}{{ item.item_name }}{{ item.uom }}{{ item.received_qty }}{{ item.rejected_qty }}{{ item.qty}}{{ item.rate }}{{ item.amount }}
+
+
+
+ + + + +
Total Quantity: {{ doc.total_qty }}
Total: {{doc.total}}
Net Weight: {{ doc.total_net_weight }}
+
+
+ + + {% for tax in doc.taxes %} + + {% endfor %} + + + + +
Tax and Charges: {{doc.taxes_and_charges}}
{{ tax.account_head }}: {{ tax.tax_amount_after_discount_amount }}
Taxes and Charges Added: {{ doc.taxes_and_charges_added }}
Taxes and Charges Deducted: {{ doc.taxes_and_charges_deducted }}
Total Taxes and Charges: {{ doc.total_taxes_and_charges }}
Net Payable: {{ doc.grand_total }}
+
+
+
+ + + + + + + + + + {% for entries in doc.gl_entries %} + + + + + + + + + {% endfor %} + + + + + +
SLAccountParty TypePartyCredit AmountDebit Amount
{{ loop.index }}{{ entries.account }}{{ entries.party_type }}{{ entries.party }}{{ entries.credit }}{{ entries.debit }}
Total{{ doc.grand_total|flt }}{{ doc.grand_total|flt }}
+
+
\ No newline at end of file diff --git a/erpnext/accounts/print_format/purchase_auditing_voucher/purchase_auditing_voucher.json b/erpnext/accounts/print_format/purchase_auditing_voucher/purchase_auditing_voucher.json new file mode 100644 index 0000000000..73779d49aa --- /dev/null +++ b/erpnext/accounts/print_format/purchase_auditing_voucher/purchase_auditing_voucher.json @@ -0,0 +1,22 @@ +{ + "align_labels_right": 0, + "creation": "2019-02-14 14:42:35.151611", + "custom_format": 0, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Purchase Invoice", + "docstatus": 0, + "doctype": "Print Format", + "font": "Default", + "idx": 0, + "line_breaks": 0, + "modified": "2019-02-14 14:42:35.151611", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Purchase Auditing Voucher", + "owner": "Administrator", + "print_format_builder": 0, + "print_format_type": "Server", + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/erpnext/accounts/print_format/sales_auditing_voucher/__init__.py b/erpnext/accounts/print_format/sales_auditing_voucher/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/print_format/sales_auditing_voucher/sales_auditing_voucher.html b/erpnext/accounts/print_format/sales_auditing_voucher/sales_auditing_voucher.html new file mode 100644 index 0000000000..04de83de70 --- /dev/null +++ b/erpnext/accounts/print_format/sales_auditing_voucher/sales_auditing_voucher.html @@ -0,0 +1,93 @@ +{%- from "templates/print_formats/standard_macros.html" import add_header -%} +
+ {%- if not doc.get("print_heading") and not doc.get("select_print_heading") + and doc.set("select_print_heading", _("Sales Invoice")) -%}{%- endif -%} + {{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }} +
+
+ + + + + + +
Customer Name: {{ doc.customer }}
Due Date: {{ frappe.utils.formatdate(doc.due_date) }}
Address: {{doc.address_display}}
Contact: {{doc.contact_display}}
Mobile no: {{doc.contact_mobile}}
+
+
+ + + +
Voucher No: {{ doc.name }}
Date: {{ frappe.utils.formatdate(doc.creation) }}
+
+
+
+ + + + + + + + + + + {% for item in doc.items %} + + + + + + + + + + {% endfor %} +
SLItem CodeItem NameUOMQuantityBasic RateAmount
{{ loop.index }}{{ item.item_code }}{{ item.item_name }}{{ item.uom }}{{ item.qty}}{{ item.rate }}{{ item.amount }}
+
+
+
+ + + + +
Total Quantity: {{ doc.total_qty }}
Total: {{doc.total}}
Net Weight: {{ doc.total_net_weight }}
+
+
+ + + {% for tax in doc.taxes %} + + {% endfor %} + + +
Tax and Charges: {{doc.taxes_and_charges}}
{{ tax.account_head }}: {{ tax.tax_amount_after_discount_amount }}
Total Taxes and Charges: {{ doc.total_taxes_and_charges }}
Net Payable: {{ doc.grand_total }}
+
+
+
+ + + + + + + + + + {% for entries in doc.gl_entries %} + + + + + + + + + {% endfor %} + + + + + +
SLAccountParty TypePartyCredit AmountDebit Amount
{{ loop.index }}{{ entries.account }}{{ entries.party_type }}{{ entries.party }}{{ entries.credit }}{{ entries.debit }}
Total{{ doc.grand_total|flt }}{{ doc.grand_total|flt }}
+
+
\ No newline at end of file diff --git a/erpnext/accounts/print_format/sales_auditing_voucher/sales_auditing_voucher.json b/erpnext/accounts/print_format/sales_auditing_voucher/sales_auditing_voucher.json new file mode 100644 index 0000000000..0544e0bc9e --- /dev/null +++ b/erpnext/accounts/print_format/sales_auditing_voucher/sales_auditing_voucher.json @@ -0,0 +1,22 @@ +{ + "align_labels_right": 0, + "creation": "2019-02-15 15:02:51.454754", + "custom_format": 0, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype": "Print Format", + "font": "Default", + "idx": 0, + "line_breaks": 0, + "modified": "2019-02-15 15:02:51.454754", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Sales Auditing Voucher", + "owner": "Administrator", + "print_format_builder": 0, + "print_format_type": "Server", + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/erpnext/accounts/report/financial_statements.html b/erpnext/accounts/report/financial_statements.html index 4b3b5f2d53..449fb845d7 100644 --- a/erpnext/accounts/report/financial_statements.html +++ b/erpnext/accounts/report/financial_statements.html @@ -15,7 +15,7 @@ height: 37px; } -{% var letterhead= filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) || frappe.defaults.get_default("letter_head"); %} +{% var letterhead= filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) %} {% if(letterhead) { %}
{%= frappe.boot.letter_heads[letterhead].header %} diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index c251a028fd..43fb87c8a4 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -126,7 +126,7 @@ def get_label(periodicity, from_date, to_date): def get_data( company, root_type, balance_must_be, period_list, filters=None, accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False, - ignore_accumulated_values_for_fy=False): + ignore_accumulated_values_for_fy=False , total = True): accounts = get_accounts(company, root_type) if not accounts: @@ -154,7 +154,7 @@ def get_data( out = prepare_data(accounts, balance_must_be, period_list, company_currency) out = filter_out_zero_value_rows(out, parent_children_map) - if out: + if out and total: add_total_row(out, root_type, balance_must_be, period_list, company_currency) return out @@ -218,6 +218,9 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency): "year_start_date": year_start_date, "year_end_date": year_end_date, "currency": company_currency, + "include_in_gross": d.include_in_gross, + "account_type": d.account_type, + "is_group": d.is_group, "opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1), "account_name": ('%s - %s' %(_(d.account_number), _(d.account_name)) if d.account_number else _(d.account_name)) @@ -285,7 +288,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency def get_accounts(company, root_type): return frappe.db.sql(""" - select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name + select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name, include_in_gross, account_type, is_group, lft, rgt from `tabAccount` where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True) diff --git a/erpnext/accounts/report/gross_and_net_profit_report/__init__.py b/erpnext/accounts/report/gross_and_net_profit_report/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.html b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.html new file mode 100644 index 0000000000..40ba20c4ac --- /dev/null +++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.html @@ -0,0 +1 @@ +{% include "accounts/report/financial_statements.html" %} \ No newline at end of file diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js new file mode 100644 index 0000000000..63ac281cdb --- /dev/null +++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js @@ -0,0 +1,51 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Gross and Net Profit Report"] = { + "filters": [ + + ] +} +frappe.require("assets/erpnext/js/financial_statements.js", function() { + frappe.query_reports["Gross and Net Profit Report"] = $.extend({}, + erpnext.financial_statements); + + frappe.query_reports["Gross and Net Profit Report"]["filters"].push( + { + "fieldname":"project", + "label": __("Project"), + "fieldtype": "MultiSelect", + get_data: function() { + var projects = frappe.query_report.get_filter_value("project") || ""; + + const values = projects.split(/\s*,\s*/).filter(d => d); + const txt = projects.match(/[^,\s*]*$/)[0] || ''; + let data = []; + + frappe.call({ + type: "GET", + method:'frappe.desk.search.search_link', + async: false, + no_spinner: true, + args: { + doctype: "Project", + txt: txt, + filters: { + "name": ["not in", values] + } + }, + callback: function(r) { + data = r.results; + } + }); + return data; + } + }, + { + "fieldname": "accumulated_values", + "label": __("Accumulated Values"), + "fieldtype": "Check" + } + ); +}); diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.json b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.json new file mode 100644 index 0000000000..994b47faef --- /dev/null +++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.json @@ -0,0 +1,30 @@ +{ + "add_total_row": 0, + "creation": "2019-02-08 10:58:55.763090", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2019-02-08 10:58:55.763090", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Gross and Net Profit Report", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "GL Entry", + "report_name": "Gross and Net Profit Report", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Accounts Manager" + }, + { + "role": "Auditor" + } + ] +} \ No newline at end of file diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py new file mode 100644 index 0000000000..6550981a14 --- /dev/null +++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py @@ -0,0 +1,154 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import flt +from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data) +import copy + + +def execute(filters=None): + period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, + filters.periodicity, filters.accumulated_values, filters.company) + + columns, data = [], [] + + income = get_data(filters.company, "Income", "Credit", period_list, filters = filters, + accumulated_values=filters.accumulated_values, + ignore_closing_entries=True, ignore_accumulated_values_for_fy= True, total= False) + + expense = get_data(filters.company, "Expense", "Debit", period_list, filters=filters, + accumulated_values=filters.accumulated_values, + ignore_closing_entries=True, ignore_accumulated_values_for_fy= True, total= False) + + columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company) + + + gross_income = get_revenue(income, period_list) + + gross_expense = get_revenue(expense, period_list) + + if(len(gross_income)==0 and len(gross_expense)== 0): + data.append({"account_name": "'" + _("Nothing is included in gross") + "'", + "account": "'" + _("Nothing is included in gross") + "'"}) + + return columns, data + + data.append({"account_name": "'" + _("Included in Gross Profit") + "'", + "account": "'" + _("Included in Gross Profit") + "'"}) + + data.append({}) + data.extend(gross_income or []) + + data.append({}) + data.extend(gross_expense or []) + + data.append({}) + gross_profit = get_profit(gross_income, gross_expense, period_list, filters.company, 'Gross Profit',filters.presentation_currency) + data.append(gross_profit) + + non_gross_income = get_revenue(income, period_list, 0) + data.append({}) + data.extend(non_gross_income or []) + + non_gross_expense = get_revenue(expense, period_list, 0) + data.append({}) + data.extend(non_gross_expense or []) + + net_profit = get_net_profit(non_gross_income, gross_income, gross_expense, non_gross_expense, period_list, filters.company,filters.presentation_currency) + data.append({}) + data.append(net_profit) + + return columns, data + +def get_revenue(data, period_list, include_in_gross=1): + revenue = [item for item in data if item['include_in_gross']==include_in_gross or item['is_group']==1] + + data_to_be_removed =True + while data_to_be_removed: + revenue, data_to_be_removed = remove_parent_with_no_child(revenue, period_list) + revenue = adjust_account(revenue, period_list) + return copy.deepcopy(revenue) + +def remove_parent_with_no_child(data, period_list): + data_to_be_removed = False + for parent in data: + if 'is_group' in parent and parent.get("is_group") == 1: + have_child = False + for child in data: + if 'parent_account' in child and child.get("parent_account") == parent.get("account"): + have_child = True + break + + if not have_child: + data_to_be_removed = True + data.remove(parent) + + return data, data_to_be_removed + +def adjust_account(data, period_list, consolidated= False): + leaf_nodes = [item for item in data if item['is_group'] == 0] + totals = {} + for node in leaf_nodes: + set_total(node, node["total"], data, totals) + for d in data: + for period in period_list: + key = period if consolidated else period.key + d[key] = totals[d["account"]] + d['total'] = totals[d["account"]] + return data + +def set_total(node, value, complete_list, totals): + if not totals.get(node['account']): + totals[node["account"]] = 0 + totals[node["account"]] += value + + parent = node['parent_account'] + if not parent == '': + return set_total(next(item for item in complete_list if item['account'] == parent), value, complete_list, totals) + + +def get_profit(gross_income, gross_expense, period_list, company, profit_type, currency=None, consolidated=False): + + profit_loss = { + "account_name": "'" + _(profit_type) + "'", + "account": "'" + _(profit_type) + "'", + "warn_if_negative": True, + "currency": currency or frappe.get_cached_value('Company', company, "default_currency") + } + + has_value = False + + for period in period_list: + key = period if consolidated else period.key + profit_loss[key] = flt(gross_income[0].get(key, 0)) - flt(gross_expense[0].get(key, 0)) + + if profit_loss[key]: + has_value=True + + if has_value: + return profit_loss + +def get_net_profit(non_gross_income, gross_income, gross_expense, non_gross_expense, period_list, company, currency=None, consolidated=False): + profit_loss = { + "account_name": "'" + _("Net Profit") + "'", + "account": "'" + _("Net Profit") + "'", + "warn_if_negative": True, + "currency": currency or frappe.get_cached_value('Company', company, "default_currency") + } + + has_value = False + + for period in period_list: + key = period if consolidated else period.key + total_income = flt(gross_income[0].get(key, 0)) + flt(non_gross_income[0].get(key, 0)) + total_expense = flt(gross_expense[0].get(key, 0)) + flt(non_gross_expense[0].get(key, 0)) + profit_loss[key] = flt(total_income) - flt(total_expense) + + if profit_loss[key]: + has_value=True + + if has_value: + return profit_loss diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 20af2c2824..4d26aa3c8d 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -6,7 +6,7 @@ import frappe from frappe import _, scrub from erpnext.stock.utils import get_incoming_rate from erpnext.controllers.queries import get_match_cond -from frappe.utils import flt +from frappe.utils import flt, cint def execute(filters=None): @@ -106,11 +106,14 @@ class GrossProfitGenerator(object): self.grouped = {} self.grouped_data = [] + self.currency_precision = cint(frappe.db.get_default("currency_precision")) or 3 + self.float_precision = cint(frappe.db.get_default("float_precision")) or 2 + for row in self.si_list: if self.skip_row(row, self.product_bundles): continue - row.base_amount = flt(row.base_net_amount) + row.base_amount = flt(row.base_net_amount, self.currency_precision) product_bundles = [] if row.update_stock: @@ -129,15 +132,15 @@ class GrossProfitGenerator(object): # get buying rate if row.qty: - row.buying_rate = row.buying_amount / row.qty - row.base_rate = row.base_amount / row.qty + row.buying_rate = flt(row.buying_amount / row.qty, self.float_precision) + row.base_rate = flt(row.base_amount / row.qty, self.float_precision) else: row.buying_rate, row.base_rate = 0.0, 0.0 # calculate gross profit - row.gross_profit = flt(row.base_amount - row.buying_amount, 3) + row.gross_profit = flt(row.base_amount - row.buying_amount, self.currency_precision) if row.base_amount: - row.gross_profit_percent = flt((row.gross_profit / row.base_amount) * 100.0, 3) + row.gross_profit_percent = flt((row.gross_profit / row.base_amount) * 100.0, self.currency_precision) else: row.gross_profit_percent = 0.0 @@ -156,8 +159,8 @@ class GrossProfitGenerator(object): new_row = row else: new_row.qty += row.qty - new_row.buying_amount += row.buying_amount - new_row.base_amount += row.base_amount + new_row.buying_amount += flt(row.buying_amount, self.currency_precision) + new_row.base_amount += flt(row.base_amount, self.currency_precision) new_row = self.set_average_rate(new_row) self.grouped_data.append(new_row) else: @@ -167,18 +170,19 @@ class GrossProfitGenerator(object): returned_item_rows = self.returned_invoices[row.parent][row.item_code] for returned_item_row in returned_item_rows: row.qty += returned_item_row.qty - row.base_amount += returned_item_row.base_amount - row.buying_amount = row.qty * row.buying_rate + row.base_amount += flt(returned_item_row.base_amount, self.currency_precision) + row.buying_amount = flt(row.qty * row.buying_rate, self.currency_precision) if row.qty or row.base_amount: row = self.set_average_rate(row) self.grouped_data.append(row) def set_average_rate(self, new_row): - new_row.gross_profit = flt(new_row.base_amount - new_row.buying_amount,3) - new_row.gross_profit_percent = flt(((new_row.gross_profit / new_row.base_amount) * 100.0),3) \ + new_row.gross_profit = flt(new_row.base_amount - new_row.buying_amount, self.currency_precision) + new_row.gross_profit_percent = flt(((new_row.gross_profit / new_row.base_amount) * 100.0), self.currency_precision) \ if new_row.base_amount else 0 - new_row.buying_rate = (new_row.buying_amount / new_row.qty) if new_row.qty else 0 - new_row.base_rate = (new_row.base_amount / new_row.qty) if new_row.qty else 0 + new_row.buying_rate = flt(new_row.buying_amount / new_row.qty, self.float_precision) if new_row.qty else 0 + new_row.base_rate = flt(new_row.base_amount / new_row.qty, self.float_precision) if new_row.qty else 0 + return new_row def get_returned_invoice_items(self): diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 85a6310bb6..1bf03ec803 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -172,8 +172,8 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals or tabItem.item_code LIKE %(txt)s or tabItem.item_group LIKE %(txt)s or tabItem.item_name LIKE %(txt)s - or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s - {description_cond})) + or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s) + {description_cond}) {fcond} {mcond} order by if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999), diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 9873efa124..947d6931e2 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -282,6 +282,10 @@ class WorkOrder(Document): total_bundle_qty = frappe.db.sql(""" select sum(qty) from `tabProduct Bundle Item` where parent = %s""", (frappe.db.escape(self.product_bundle_item)))[0][0] + if not total_bundle_qty: + # product bundle is 0 (product bundle allows 0 qty for items) + total_bundle_qty = 1 + cond = "product_bundle_item = %s" if self.product_bundle_item else "production_item = %s" qty = frappe.db.sql(""" select sum(qty) from diff --git a/erpnext/patches/v10_0/item_barcode_childtable_migrate.py b/erpnext/patches/v10_0/item_barcode_childtable_migrate.py index bc6005677d..e30e0a74c0 100644 --- a/erpnext/patches/v10_0/item_barcode_childtable_migrate.py +++ b/erpnext/patches/v10_0/item_barcode_childtable_migrate.py @@ -27,5 +27,5 @@ def execute(): 'parent': item.name, 'parentfield': 'barcodes' }).insert() - except frappe.DuplicateEntryError: + except (frappe.DuplicateEntryError, frappe.UniqueValidationError): continue diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 5da7e73775..1430383a95 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -314,14 +314,21 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ show_description(row_to_modify.idx, row_to_modify.item_code); + this.frm.from_barcode = true; frappe.model.set_value(row_to_modify.doctype, row_to_modify.name, { item_code: data.item_code, qty: (row_to_modify.qty || 0) + 1 }); - this.frm.refresh_field('items'); + ['serial_no', 'batch_no', 'barcode'].forEach(field => { + if (data[field] && frappe.meta.has_field(row_to_modify.doctype, field)) { + frappe.model.set_value(row_to_modify.doctype, + row_to_modify.name, field, data[field]); + } + }); + + scan_barcode_field.set_value(''); }); - scan_barcode_field.set_value(''); } return false; }, @@ -384,10 +391,12 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ // barcode cleared, remove item d.item_code = ""; } - this.item_code(doc, cdt, cdn, true); + + this.frm.from_barcode = true; + this.item_code(doc, cdt, cdn); }, - item_code: function(doc, cdt, cdn, from_barcode) { + item_code: function(doc, cdt, cdn) { var me = this; var item = frappe.get_doc(cdt, cdn); var update_stock = 0, show_batch_dialog = 0; @@ -400,9 +409,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ show_batch_dialog = 1; } // clear barcode if setting item (else barcode will take priority) - if(!from_barcode) { + if(!this.frm.from_barcode) { item.barcode = null; } + + this.frm.from_barcode = false; if(item.item_code || item.barcode || item.serial_no) { if(!this.validate_company_and_party()) { this.frm.fields_dict["items"].grid.grid_rows[item.idx - 1].remove(); diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py index f55fa97cf3..52a5ddcfd9 100644 --- a/erpnext/regional/italy/utils.py +++ b/erpnext/regional/italy/utils.py @@ -353,4 +353,7 @@ def set_state_code(doc, method): return state_codes_lower = {key.lower():value for key,value in state_codes.items()} - doc.state_code = state_codes_lower.get(doc.get('state','').lower()) + + state = doc.get('state','').lower() + if state_codes_lower.get(state): + doc.state_code = state_codes_lower.get(state) diff --git a/erpnext/selling/report/address_and_contacts/address_and_contacts.py b/erpnext/selling/report/address_and_contacts/address_and_contacts.py index eb242d0a73..a9e43034b4 100644 --- a/erpnext/selling/report/address_and_contacts/address_and_contacts.py +++ b/erpnext/selling/report/address_and_contacts/address_and_contacts.py @@ -102,8 +102,7 @@ def get_party_details(party_type, party_list, doctype, party_details): records = frappe.get_list(doctype, filters=filters, fields=fields, as_list=True) for d in records: details = party_details.get(d[0]) - if details: - details.setdefault(frappe.scrub(doctype), []).append(d[1:]) + details.setdefault(frappe.scrub(doctype), []).append(d[1:]) return party_details