From ac9a4fe03c40409af44f2f101d75968991a5f579 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Tue, 11 Jun 2019 14:25:44 +0530 Subject: [PATCH 01/49] feat: add tax and charges in expense claim --- .../hr/doctype/expense_claim/expense_claim.js | 62 +++++++++++ .../doctype/expense_claim/expense_claim.json | 22 +++- .../hr/doctype/expense_claim/expense_claim.py | 33 +++++- .../expense_taxes_and_charges/__init__.py | 0 .../expense_taxes_and_charges.json | 103 ++++++++++++++++++ .../expense_taxes_and_charges.py | 10 ++ 6 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 erpnext/hr/doctype/expense_taxes_and_charges/__init__.py create mode 100644 erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json create mode 100644 erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index 7c6abc7f94..0ff70cb680 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -157,6 +157,14 @@ frappe.ui.form.on("Expense Claim", { } }; }); + // frm.set_query("taxes", "account_head", function(doc) { + // return { + // filters: [ + // ['docstatus', '=', 1], + // ['company', '=', doc.company] + // ] + // }; + // }); }, onload: function(frm) { @@ -259,6 +267,18 @@ frappe.ui.form.on("Expense Claim", { frm.events.get_advances(frm); }, + get_taxes: function(frm) { + if(frm.doc.taxes) { + frappe.call({ + method: "calculate_taxes", + doc: frm.doc, + callback: (r) => { + refresh_field("taxes"); + } + }); + } + }, + get_advances: function(frm) { frappe.model.clear_table(frm.doc, "advances"); if (frm.doc.employee) { @@ -298,6 +318,7 @@ frappe.ui.form.on("Expense Claim Detail", { sanctioned_amount: function(frm, cdt, cdn) { var doc = frm.doc; cur_frm.cscript.calculate_total(doc,cdt,cdn); + frm.trigger("get_taxes"); } }); @@ -332,6 +353,47 @@ frappe.ui.form.on("Expense Claim Advance", { } }); +frappe.ui.form.on("Expense Taxes and Charges", { + account_head: function(frm, cdt, cdn) { + var child = locals[cdt][cdn]; + if(child.account_head && !child.description && !child.rate) { + // set description from account head + child.description = child.account_head.split(' - ').slice(0, -1).join(' - '); + + // set the tax rate from account head + frappe.db.get_value("Account", child.account_head, "tax_rate").then((r) => { + if(r.message) { + frappe.model.set_value(cdt, cdn, 'rate', r.message.tax_rate); + } + }); + refresh_field("taxes"); + } + }, + + calculate_total: function(frm, cdt, cdn) { + var child = locals[cdt][cdn]; + child.total = flt(frm.doc.total_sanctioned_amount) + flt(child.tax_amount); + + refresh_field("taxes"); + }, + + rate: function(frm, cdt, cdn) { + var child = locals[cdt][cdn]; + if(!child.amount) { + child.tax_amount = flt(frm.doc.total_sanctioned_amount) * (flt(child.rate)/100); + refresh_field("taxes"); + } + frm.trigger("calculate_total", cdt, cdn) + }, + + tax_amount: function(frm, cdt, cdn) { + var child = locals[cdt][cdn]; + child.rate = flt(child.tax_amount/frm.doc.total_sanctioned_amount) * 100; + frm.trigger("calculate_total", cdt, cdn) + refresh_field("taxes"); + } +}); + cur_frm.fields_dict['task'].get_query = function(doc) { return { filters:{ diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json index 6e04644036..007e646815 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.json +++ b/erpnext/hr/doctype/expense_claim/expense_claim.json @@ -4,6 +4,7 @@ "creation": "2013-01-10 16:34:14", "doctype": "DocType", "document_type": "Setup", + "engine": "InnoDB", "field_order": [ "naming_series", "employee", @@ -18,6 +19,9 @@ "expense_details", "expenses", "sb1", + "taxes", + "net_total", + "section_break_16", "posting_date", "vehicle_log", "task", @@ -315,12 +319,28 @@ { "fieldname": "dimension_col_break", "fieldtype": "Column Break" + }, + { + "fieldname": "taxes", + "fieldtype": "Table", + "label": "Expense Taxes and Charges", + "options": "Expense Taxes and Charges" + }, + { + "fieldname": "section_break_16", + "fieldtype": "Section Break" + }, + { + "fieldname": "net_total", + "fieldtype": "Currency", + "label": "Net Total", + "read_only": 1 } ], "icon": "fa fa-money", "idx": 1, "is_submittable": 1, - "modified": "2019-05-25 22:53:31.682151", + "modified": "2019-06-11 13:21:42.386420", "modified_by": "Administrator", "module": "HR", "name": "Expense Claim", diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index d6b0eca70e..c5b6ebe56b 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -12,6 +12,7 @@ from erpnext.accounts.general_ledger import make_gl_entries from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account from erpnext.controllers.accounts_controller import AccountsController from frappe.utils.csvutils import getlink +from erpnext.accounts.utils import get_account_currency class InvalidExpenseApproverError(frappe.ValidationError): pass class ExpenseApproverIdentityError(frappe.ValidationError): pass @@ -29,6 +30,7 @@ class ExpenseClaim(AccountsController): self.set_expense_account(validate=True) self.set_payable_account() self.set_cost_center() + self.calculate_taxes() self.set_status() if self.task and not self.project: self.project = frappe.db.get_value("Task", self.task, "project") @@ -93,7 +95,7 @@ class ExpenseClaim(AccountsController): elif self.project: frappe.get_doc("Project", self.project).update_project() - def make_gl_entries(self, cancel = False): + def make_gl_entries(self, cancel=False): if flt(self.total_sanctioned_amount) > 0: gl_entries = self.get_gl_entries() make_gl_entries(gl_entries, cancel) @@ -102,7 +104,7 @@ class ExpenseClaim(AccountsController): gl_entry = [] self.validate_account_details() - payable_amount = flt(self.total_sanctioned_amount) - flt(self.total_advance_amount) + payable_amount = flt(self.net_total) - flt(self.total_advance_amount) # payable entry if payable_amount: @@ -170,8 +172,26 @@ class ExpenseClaim(AccountsController): }) ) + gl_entry = self.make_tax_gl_entries(gl_entry) + return gl_entry + def make_tax_gl_entries(self, gl_entries): + # tax table gl entries + for tax in self.get("taxes"): + account_currency = get_account_currency(tax.account_head) + gl_entries.append( + self.get_gl_dict({ + "account": tax.account_head, + "debit": tax.tax_amount, + "against": self.employee, + "cost_center": self.cost_center, + "against_voucher_type": self.doctype, + "against_voucher": self.name + }, account_currency) + ) + return gl_entries + def validate_account_details(self): if not self.cost_center: frappe.throw(_("Cost center is required to book an expense claim")) @@ -193,6 +213,15 @@ class ExpenseClaim(AccountsController): self.total_claimed_amount += flt(d.claim_amount) self.total_sanctioned_amount += flt(d.sanctioned_amount) + def calculate_taxes(self): + for tax in self.taxes: + if tax.rate: + tax.tax_amount = flt(self.total_sanctioned_amount) * flt(tax.rate/100) + if tax.tax_amount: + tax.rate = flt(tax.tax_amount)/flt(self.total_sanctioned_amount) * 100 + tax.total = flt(tax.tax_amount) + flt(self.total_sanctioned_amount) + self.net_total += tax.total + def update_task(self): task = frappe.get_doc("Task", self.task) task.update_total_expense_claim() diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/__init__.py b/erpnext/hr/doctype/expense_taxes_and_charges/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json new file mode 100644 index 0000000000..8caf0a975a --- /dev/null +++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json @@ -0,0 +1,103 @@ +{ + "autoname": "hash", + "creation": "2019-06-03 11:42:33.123976", + "doctype": "DocType", + "document_type": "Setup", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "account_head", + "cost_center", + "col_break1", + "rate", + "description", + "section_break_6", + "tax_amount", + "column_break_8", + "total" + ], + "fields": [ + { + "fieldname": "col_break1", + "fieldtype": "Column Break" + }, + { + "columns": 2, + "fieldname": "account_head", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Account Head", + "oldfieldname": "account_head", + "oldfieldtype": "Link", + "options": "Account", + "reqd": 1 + }, + { + "default": ":Company", + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "oldfieldname": "cost_center", + "oldfieldtype": "Link", + "options": "Cost Center" + }, + { + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Description", + "oldfieldname": "description", + "oldfieldtype": "Small Text", + "print_width": "300px", + "reqd": 1, + "width": "300px" + }, + { + "columns": 2, + "fieldname": "rate", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Rate", + "oldfieldname": "rate", + "oldfieldtype": "Currency" + }, + { + "columns": 2, + "fieldname": "tax_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Amount", + "oldfieldname": "tax_amount", + "oldfieldtype": "Currency", + "options": "currency" + }, + { + "columns": 2, + "fieldname": "total", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Total", + "oldfieldname": "total", + "oldfieldtype": "Currency", + "options": "currency", + "read_only": 1 + }, + { + "fieldname": "section_break_6", + "fieldtype": "Section Break" + }, + { + "fieldname": "column_break_8", + "fieldtype": "Column Break" + } + ], + "istable": 1, + "modified": "2019-06-11 14:19:34.780611", + "modified_by": "Administrator", + "module": "HR", + "name": "Expense Taxes and Charges", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "ASC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py new file mode 100644 index 0000000000..4103bef1ff --- /dev/null +++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class ExpenseTaxesandCharges(Document): + pass From 444313bdfcd2b1b06e2590c8db9d9c5cf827cb0d Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 12 Jun 2019 12:52:02 +0530 Subject: [PATCH 02/49] feat: change the claim amount in expenses to amount --- erpnext/demo/user/hr.py | 4 ++-- .../hr/doctype/expense_claim/expense_claim.js | 6 +++--- .../doctype/expense_claim/expense_claim.json | 21 ++++++++++++------- .../hr/doctype/expense_claim/expense_claim.py | 9 ++++---- .../expense_claim/test_expense_claim.js | 2 +- .../expense_claim/test_expense_claim.py | 6 +++--- .../expense_claim_detail.json | 6 +++--- erpnext/hr/doctype/vehicle_log/vehicle_log.py | 8 +++---- 8 files changed, 34 insertions(+), 28 deletions(-) diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py index 79f3c19287..0211bc8a90 100644 --- a/erpnext/demo/user/hr.py +++ b/erpnext/demo/user/hr.py @@ -97,7 +97,7 @@ def get_expenses(): "expense_date": frappe.flags.current_date, "expense_type": expense_type.name, "default_account": expense_type.default_account or "Miscellaneous Expenses - WPL", - "claim_amount": claim_amount, + "amount": claim_amount, "sanctioned_amount": claim_amount }) @@ -107,7 +107,7 @@ def update_sanctioned_amount(expense_claim): for expense in expense_claim.expenses: sanctioned_amount = random.randint(1,20)*10 - if sanctioned_amount < expense.claim_amount: + if sanctioned_amount < expense.amount: expense.sanctioned_amount = sanctioned_amount def get_timesheet_based_salary_slip_employee(): diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index 0ff70cb680..6425b95d7e 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -109,7 +109,7 @@ cur_frm.cscript.calculate_total = function(doc){ doc.total_claimed_amount = 0; doc.total_sanctioned_amount = 0; $.each((doc.expenses || []), function(i, d) { - doc.total_claimed_amount += d.claim_amount; + doc.total_claimed_amount += d.amount; doc.total_sanctioned_amount += d.sanctioned_amount; }); @@ -308,10 +308,10 @@ frappe.ui.form.on("Expense Claim", { }); frappe.ui.form.on("Expense Claim Detail", { - claim_amount: function(frm, cdt, cdn) { + amount: function(frm, cdt, cdn) { var child = locals[cdt][cdn]; var doc = frm.doc; - frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.claim_amount); + frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.amount); cur_frm.cscript.calculate_total(doc,cdt,cdn); }, diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json index 007e646815..409bdc8615 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.json +++ b/erpnext/hr/doctype/expense_claim/expense_claim.json @@ -13,20 +13,21 @@ "column_break_5", "expense_approver", "approval_status", - "total_claimed_amount", - "total_sanctioned_amount", "is_paid", "expense_details", "expenses", "sb1", "taxes", - "net_total", + "transactions_section", + "total_tax_amount", + "total_amount_reimbursed", + "total_sanctioned_amount", + "total_claimed_amount", "section_break_16", "posting_date", "vehicle_log", "task", "cb1", - "total_amount_reimbursed", "remark", "title", "email_id", @@ -331,16 +332,22 @@ "fieldtype": "Section Break" }, { - "fieldname": "net_total", + "fieldname": "transactions_section", + "fieldtype": "Section Break", + "label": "Transactions" + }, + { + "fieldname": "total_tax_amount", "fieldtype": "Currency", - "label": "Net Total", + "label": "Total Tax Amount", + "options": "Company:company:default_currency", "read_only": 1 } ], "icon": "fa fa-money", "idx": 1, "is_submittable": 1, - "modified": "2019-06-11 13:21:42.386420", + "modified": "2019-06-12 12:32:13.775009", "modified_by": "Administrator", "module": "HR", "name": "Expense Claim", diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index c5b6ebe56b..07e711939c 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -172,11 +172,11 @@ class ExpenseClaim(AccountsController): }) ) - gl_entry = self.make_tax_gl_entries(gl_entry) + self.add_tax_gl_entries(gl_entry) return gl_entry - def make_tax_gl_entries(self, gl_entries): + def add_tax_gl_entries(self, gl_entries): # tax table gl entries for tax in self.get("taxes"): account_currency = get_account_currency(tax.account_head) @@ -190,7 +190,6 @@ class ExpenseClaim(AccountsController): "against_voucher": self.name }, account_currency) ) - return gl_entries def validate_account_details(self): if not self.cost_center: @@ -210,7 +209,7 @@ class ExpenseClaim(AccountsController): if self.approval_status == 'Rejected': d.sanctioned_amount = 0.0 - self.total_claimed_amount += flt(d.claim_amount) + self.total_claimed_amount += flt(d.amount) self.total_sanctioned_amount += flt(d.sanctioned_amount) def calculate_taxes(self): @@ -253,7 +252,7 @@ class ExpenseClaim(AccountsController): def validate_sanctioned_amount(self): for d in self.get('expenses'): - if flt(d.sanctioned_amount) > flt(d.claim_amount): + if flt(d.sanctioned_amount) > flt(d.amount): frappe.throw(_("Sanctioned Amount cannot be greater than Claim Amount in Row {0}.").format(d.idx)) def set_expense_account(self, validate=False): diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.js b/erpnext/hr/doctype/expense_claim/test_expense_claim.js index 070474e10f..d0c43d3be4 100644 --- a/erpnext/hr/doctype/expense_claim/test_expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.js @@ -17,7 +17,7 @@ QUnit.test("Test: Expense Claim [HR]", function (assert) { d.expense_date = '2017-08-01', d.expense_type = 'Test Expense Type 1', d.description = 'This is just to test Expense Claim', - d.claim_amount = 2000, + d.amount = 2000, d.sanctioned_amount=2000, refresh_field('expenses'); }, diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py index 075bc63345..6fc2a83ebd 100644 --- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py @@ -89,7 +89,7 @@ class TestExpenseClaim(unittest.TestCase): "payable_account": payable_account, "approval_status": "Rejected", "expenses": - [{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "claim_amount": 300, "sanctioned_amount": 200 }] + [{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "amount": 300, "sanctioned_amount": 200 }] }) expense_claim.submit() @@ -102,7 +102,7 @@ class TestExpenseClaim(unittest.TestCase): def get_payable_account(company): return frappe.get_cached_value('Company', company, 'default_payable_account') -def make_expense_claim(payable_account,claim_amount, sanctioned_amount, company, account, project=None, task_name=None): +def make_expense_claim(payable_account,amount, sanctioned_amount, company, account, project=None, task_name=None): expense_claim = frappe.get_doc({ "doctype": "Expense Claim", "employee": "_T-Employee-00001", @@ -110,7 +110,7 @@ def make_expense_claim(payable_account,claim_amount, sanctioned_amount, company, "approval_status": "Approved", "company": company, "expenses": - [{ "expense_type": "Travel", "default_account": account, "claim_amount": claim_amount, "sanctioned_amount": sanctioned_amount }] + [{ "expense_type": "Travel", "default_account": account, "amount": amount, "sanctioned_amount": sanctioned_amount }] }) if project: expense_claim.project = project diff --git a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json index d4e70575e9..b23fb6af0f 100644 --- a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json +++ b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json @@ -253,7 +253,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "claim_amount", + "fieldname": "amount", "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, @@ -262,7 +262,7 @@ "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, - "label": "Claim Amount", + "label": "Amount", "length": 0, "no_copy": 0, "oldfieldname": "claim_amount", @@ -360,7 +360,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2019-02-24 08:41:36.122565", + "modified": "2019-06-10 08:41:36.122565", "modified_by": "Administrator", "module": "HR", "name": "Expense Claim Detail", diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.py b/erpnext/hr/doctype/vehicle_log/vehicle_log.py index ceea4933f3..df633611be 100644 --- a/erpnext/hr/doctype/vehicle_log/vehicle_log.py +++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.py @@ -18,11 +18,11 @@ class VehicleLog(Document): if (service_detail.service_item or service_detail.type or service_detail.frequency or service_detail.expense_amount): if not (service_detail.service_item and service_detail.type and service_detail.frequency and service_detail.expense_amount): frappe.throw(_("Service Item,Type,frequency and expense amount are required")) - + def on_submit(self): frappe.db.sql("update `tabVehicle` set last_odometer=%s where license_plate=%s", (self.odometer, self.license_plate)) - + @frappe.whitelist() def get_make_model(license_plate): vehicle=frappe.get_doc("Vehicle",license_plate) @@ -41,7 +41,7 @@ def make_expense_claim(docname): for serdetail in vehicle_log.service_detail: total_exp_amt = total_exp_amt + serdetail.expense_amount return total_exp_amt - + vehicle_log = frappe.get_doc("Vehicle Log", docname) exp_claim = frappe.new_doc("Expense Claim") exp_claim.employee=vehicle_log.employee @@ -52,6 +52,6 @@ def make_expense_claim(docname): exp_claim.append("expenses",{ "expense_date":vehicle_log.date, "description":_("Vehicle Expenses"), - "claim_amount":total_claim_amt + "amount":total_claim_amt }) return exp_claim.as_dict() From ddea50fa223ce8caf9407ee280251bd87f914012 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Tue, 11 Jun 2019 14:44:45 +0530 Subject: [PATCH 03/49] fix(stock): Remove hardcoded validation for Item --- erpnext/stock/doctype/item/item.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 48693359fe..1a88473b1b 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -67,8 +67,6 @@ class Item(WebsiteGenerator): from frappe.model.naming import set_name_by_naming_series set_name_by_naming_series(self) self.item_code = self.name - elif not self.item_code: - msgprint(_("Item Code is mandatory because Item is not automatically numbered"), raise_exception=1) self.item_code = strip(self.item_code) self.name = self.item_code From a1d354e14752ef1ee2faee52f9239fd7b9b3ef81 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 12 Jun 2019 18:18:38 +0530 Subject: [PATCH 04/49] feat: add grand total field --- .../hr/doctype/expense_claim/expense_claim.js | 46 +++++++++++-------- .../doctype/expense_claim/expense_claim.json | 29 ++++++++---- .../hr/doctype/expense_claim/expense_claim.py | 32 ++++++------- 3 files changed, 64 insertions(+), 43 deletions(-) diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index 6425b95d7e..4a61963d49 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -112,9 +112,6 @@ cur_frm.cscript.calculate_total = function(doc){ doc.total_claimed_amount += d.amount; doc.total_sanctioned_amount += d.sanctioned_amount; }); - - refresh_field("total_claimed_amount"); - refresh_field('total_sanctioned_amount'); }; cur_frm.cscript.calculate_total_amount = function(doc,cdt,cdn){ @@ -157,14 +154,14 @@ frappe.ui.form.on("Expense Claim", { } }; }); - // frm.set_query("taxes", "account_head", function(doc) { - // return { - // filters: [ - // ['docstatus', '=', 1], - // ['company', '=', doc.company] - // ] - // }; - // }); + frm.set_query("account_head", "taxes", function(doc) { + return { + filters: [ + ['company', '=', doc.company], + ['account_type', 'in', ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation"]] + ] + }; + }); }, onload: function(frm) { @@ -205,6 +202,12 @@ frappe.ui.form.on("Expense Claim", { } }, + calculate_grand_total: function(frm) { + var grand_total = flt(frm.doc.total_sanctioned_amount) + flt(frm.doc.total_taxes_and_charges) - flt(frm.doc.total_advance_amount); + frm.set_value("grand_total", grand_total); + frm.refresh_fields(); + }, + make_payment_entry: function(frm) { var method = "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry"; if(frm.doc.__onload && frm.doc.__onload.make_payment_via_journal_entry) { @@ -319,6 +322,7 @@ frappe.ui.form.on("Expense Claim Detail", { var doc = frm.doc; cur_frm.cscript.calculate_total(doc,cdt,cdn); frm.trigger("get_taxes"); + frm.trigger("calculate_grand_total"); } }); @@ -345,6 +349,7 @@ frappe.ui.form.on("Expense Claim Advance", { child.advance_paid = r.message[0].paid_amount; child.unclaimed_amount = flt(r.message[0].paid_amount) - flt(r.message[0].claimed_amount); child.allocated_amount = flt(r.message[0].paid_amount) - flt(r.message[0].claimed_amount); + frm.trigger('calculate_grand_total'); refresh_field("advances"); } } @@ -370,27 +375,30 @@ frappe.ui.form.on("Expense Taxes and Charges", { } }, - calculate_total: function(frm, cdt, cdn) { + calculate_total_tax: function(frm, cdt, cdn) { var child = locals[cdt][cdn]; child.total = flt(frm.doc.total_sanctioned_amount) + flt(child.tax_amount); + frm.trigger("calculate_tax_amount", cdt, cdn); + }, - refresh_field("taxes"); + calculate_tax_amount: function(frm) { + frm.doc.total_taxes_and_charges = 0; + (frm.doc.taxes || []).forEach(function(d) { + frm.doc.total_taxes_and_charges += d.tax_amount; + }); + frm.trigger("calculate_grand_total") }, rate: function(frm, cdt, cdn) { var child = locals[cdt][cdn]; if(!child.amount) { child.tax_amount = flt(frm.doc.total_sanctioned_amount) * (flt(child.rate)/100); - refresh_field("taxes"); } - frm.trigger("calculate_total", cdt, cdn) + frm.trigger("calculate_total_tax", cdt, cdn) }, tax_amount: function(frm, cdt, cdn) { - var child = locals[cdt][cdn]; - child.rate = flt(child.tax_amount/frm.doc.total_sanctioned_amount) * 100; - frm.trigger("calculate_total", cdt, cdn) - refresh_field("taxes"); + frm.trigger("calculate_total_tax", cdt, cdn) } }); diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json index 409bdc8615..7b0d4943fc 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.json +++ b/erpnext/hr/doctype/expense_claim/expense_claim.json @@ -19,10 +19,13 @@ "sb1", "taxes", "transactions_section", - "total_tax_amount", - "total_amount_reimbursed", "total_sanctioned_amount", "total_claimed_amount", + "total_advance_amount", + "column_break_17", + "total_amount_reimbursed", + "total_taxes_and_charges", + "grand_total", "section_break_16", "posting_date", "vehicle_log", @@ -44,8 +47,7 @@ "status", "amended_from", "advance_payments", - "advances", - "total_advance_amount" + "advances" ], "fields": [ { @@ -122,7 +124,6 @@ { "fieldname": "total_sanctioned_amount", "fieldtype": "Currency", - "in_list_view": 1, "label": "Total Sanctioned Amount", "no_copy": 1, "oldfieldname": "total_sanctioned_amount", @@ -337,9 +338,21 @@ "label": "Transactions" }, { - "fieldname": "total_tax_amount", + "fieldname": "grand_total", "fieldtype": "Currency", - "label": "Total Tax Amount", + "in_list_view": 1, + "label": "Grand Total", + "options": "Company:company:default_currency", + "read_only": 1 + }, + { + "fieldname": "column_break_17", + "fieldtype": "Column Break" + }, + { + "fieldname": "total_taxes_and_charges", + "fieldtype": "Currency", + "label": "Total Taxes and Charges", "options": "Company:company:default_currency", "read_only": 1 } @@ -347,7 +360,7 @@ "icon": "fa fa-money", "idx": 1, "is_submittable": 1, - "modified": "2019-06-12 12:32:13.775009", + "modified": "2019-06-12 15:35:09.092603", "modified_by": "Administrator", "module": "HR", "name": "Expense Claim", diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index 07e711939c..7f660a45b5 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -104,15 +104,13 @@ class ExpenseClaim(AccountsController): gl_entry = [] self.validate_account_details() - payable_amount = flt(self.net_total) - flt(self.total_advance_amount) - # payable entry - if payable_amount: + if self.grand_total: gl_entry.append( self.get_gl_dict({ "account": self.payable_account, - "credit": payable_amount, - "credit_in_account_currency": payable_amount, + "credit": self.grand_total, + "credit_in_account_currency": self.grand_total, "against": ",".join([d.default_account for d in self.expenses]), "party_type": "Employee", "party": self.employee, @@ -146,15 +144,16 @@ class ExpenseClaim(AccountsController): "against_voucher": self.name }) ) + self.add_tax_gl_entries(gl_entry) - if self.is_paid and payable_amount: + if self.is_paid and self.grand_total: # payment entry payment_account = get_bank_cash_account(self.mode_of_payment, self.company).get("account") gl_entry.append( self.get_gl_dict({ "account": payment_account, - "credit": payable_amount, - "credit_in_account_currency": payable_amount, + "credit": self.grand_total, + "credit_in_account_currency": self.grand_total, "against": self.employee }) ) @@ -165,15 +164,13 @@ class ExpenseClaim(AccountsController): "party_type": "Employee", "party": self.employee, "against": payment_account, - "debit": payable_amount, - "debit_in_account_currency": payable_amount, + "debit": self.grand_total, + "debit_in_account_currency": self.grand_total, "against_voucher": self.name, "against_voucher_type": self.doctype, }) ) - self.add_tax_gl_entries(gl_entry) - return gl_entry def add_tax_gl_entries(self, gl_entries): @@ -184,11 +181,12 @@ class ExpenseClaim(AccountsController): self.get_gl_dict({ "account": tax.account_head, "debit": tax.tax_amount, + "debit_in_account_currency": tax.tax_amount, "against": self.employee, "cost_center": self.cost_center, "against_voucher_type": self.doctype, "against_voucher": self.name - }, account_currency) + }) ) def validate_account_details(self): @@ -213,13 +211,15 @@ class ExpenseClaim(AccountsController): self.total_sanctioned_amount += flt(d.sanctioned_amount) def calculate_taxes(self): + self.total_taxes_and_charges = 0 for tax in self.taxes: if tax.rate: tax.tax_amount = flt(self.total_sanctioned_amount) * flt(tax.rate/100) - if tax.tax_amount: - tax.rate = flt(tax.tax_amount)/flt(self.total_sanctioned_amount) * 100 + tax.total = flt(tax.tax_amount) + flt(self.total_sanctioned_amount) - self.net_total += tax.total + self.total_taxes_and_charges += flt(tax.tax_amount) + + self.grand_total = flt(self.total_sanctioned_amount) + flt(self.total_taxes_and_charges) - flt(self.total_advance_amount) def update_task(self): task = frappe.get_doc("Task", self.task) From 0a3ed374cddf38728ee5d4735d470041d707daaf Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 12 Jun 2019 20:03:22 +0530 Subject: [PATCH 05/49] test: validate tax based expense claim gl entries --- .../doctype/expense_claim/expense_claim.json | 8 ++-- .../hr/doctype/expense_claim/expense_claim.py | 1 - .../expense_claim/test_expense_claim.py | 41 +++++++++++++++---- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json index 7b0d4943fc..db85037795 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.json +++ b/erpnext/hr/doctype/expense_claim/expense_claim.json @@ -20,12 +20,12 @@ "taxes", "transactions_section", "total_sanctioned_amount", - "total_claimed_amount", + "total_taxes_and_charges", "total_advance_amount", "column_break_17", - "total_amount_reimbursed", - "total_taxes_and_charges", "grand_total", + "total_claimed_amount", + "total_amount_reimbursed", "section_break_16", "posting_date", "vehicle_log", @@ -360,7 +360,7 @@ "icon": "fa fa-money", "idx": 1, "is_submittable": 1, - "modified": "2019-06-12 15:35:09.092603", + "modified": "2019-06-12 20:00:25.734108", "modified_by": "Administrator", "module": "HR", "name": "Expense Claim", diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index 7f660a45b5..caeb2dd946 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -176,7 +176,6 @@ class ExpenseClaim(AccountsController): def add_tax_gl_entries(self, gl_entries): # tax table gl entries for tax in self.get("taxes"): - account_currency = get_account_currency(tax.account_head) gl_entries.append( self.get_gl_dict({ "account": tax.account_head, diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py index 6fc2a83ebd..a42209f6ad 100644 --- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py @@ -6,6 +6,7 @@ import frappe import unittest from frappe.utils import random_string, nowdate from erpnext.hr.doctype.expense_claim.expense_claim import make_bank_entry +from erpnext.accounts.doctype.account.test_account import create_account test_records = frappe.get_test_records('Expense Claim') test_dependencies = ['Employee'] @@ -26,7 +27,7 @@ class TestExpenseClaim(unittest.TestCase): task_name = frappe.db.get_value("Task", {"project": "_Test Project 1"}) payable_account = get_payable_account("Wind Power LLC") - make_expense_claim(payable_account, 300, 200, "Wind Power LLC","Travel Expenses - WP", "_Test Project 1", task_name) + make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP", "_Test Project 1", task_name) self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200) self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200) @@ -62,7 +63,8 @@ class TestExpenseClaim(unittest.TestCase): def test_expense_claim_gl_entry(self): payable_account = get_payable_account("Wind Power LLC") - expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP") + taxes = generate_taxes() + expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP", do_not_submit=True, taxes=taxes) expense_claim.submit() gl_entries = frappe.db.sql("""select account, debit, credit @@ -72,7 +74,8 @@ class TestExpenseClaim(unittest.TestCase): self.assertTrue(gl_entries) expected_values = dict((d[0], d) for d in [ - [payable_account, 0.0, 200.0], + ['CGST - WP',10.0, 0.0], + [payable_account, 0.0, 210.0], ["Travel Expenses - WP", 200.0, 0.0] ]) @@ -100,22 +103,44 @@ class TestExpenseClaim(unittest.TestCase): self.assertEquals(len(gl_entry), 0) def get_payable_account(company): - return frappe.get_cached_value('Company', company, 'default_payable_account') + return frappe.get_cached_value('Company', company, 'default_payable_account') -def make_expense_claim(payable_account,amount, sanctioned_amount, company, account, project=None, task_name=None): - expense_claim = frappe.get_doc({ +def generate_taxes(): + parent_account = frappe.db.get_value('Account', + {'company': "Wind Power LLC", 'is_group':1, 'account_type': 'Tax'}, + 'name') + account = create_account(company="Wind Power LLC", account_name="CGST", account_type="Tax", parent_account=parent_account) + return {'taxes':[{ + "account_head": account, + "rate": 0, + "description": "CGST", + "tax_amount": 10, + "total": 210 + }]} + +def make_expense_claim(payable_account, amount, sanctioned_amount, company, account, project=None, task_name=None, do_not_submit=False, taxes=None): + expense_claim = { "doctype": "Expense Claim", "employee": "_T-Employee-00001", "payable_account": payable_account, "approval_status": "Approved", "company": company, "expenses": - [{ "expense_type": "Travel", "default_account": account, "amount": amount, "sanctioned_amount": sanctioned_amount }] - }) + [{"expense_type": "Travel", + "default_account": account, + "amount": amount, + "sanctioned_amount": sanctioned_amount}]} + if taxes: + expense_claim.update(taxes) + + expense_claim = frappe.get_doc(expense_claim) + if project: expense_claim.project = project if task_name: expense_claim.task = task_name + if do_not_submit: + return expense_claim expense_claim.submit() return expense_claim From f8bf57c95641034f6b91c7dff56fede81acb94d0 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Thu, 13 Jun 2019 18:09:23 +0530 Subject: [PATCH 06/49] fix: remove transaction section head --- erpnext/hr/doctype/expense_claim/expense_claim.js | 6 +++--- erpnext/hr/doctype/expense_claim/expense_claim.json | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index 4a61963d49..9e78ca12c4 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -275,7 +275,7 @@ frappe.ui.form.on("Expense Claim", { frappe.call({ method: "calculate_taxes", doc: frm.doc, - callback: (r) => { + callback: () => { refresh_field("taxes"); } }); @@ -386,7 +386,7 @@ frappe.ui.form.on("Expense Taxes and Charges", { (frm.doc.taxes || []).forEach(function(d) { frm.doc.total_taxes_and_charges += d.tax_amount; }); - frm.trigger("calculate_grand_total") + frm.trigger("calculate_grand_total"); }, rate: function(frm, cdt, cdn) { @@ -398,7 +398,7 @@ frappe.ui.form.on("Expense Taxes and Charges", { }, tax_amount: function(frm, cdt, cdn) { - frm.trigger("calculate_total_tax", cdt, cdn) + frm.trigger("calculate_total_tax", cdt, cdn); } }); diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json index db85037795..f0bc268e5d 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.json +++ b/erpnext/hr/doctype/expense_claim/expense_claim.json @@ -334,8 +334,7 @@ }, { "fieldname": "transactions_section", - "fieldtype": "Section Break", - "label": "Transactions" + "fieldtype": "Section Break" }, { "fieldname": "grand_total", @@ -360,7 +359,7 @@ "icon": "fa fa-money", "idx": 1, "is_submittable": 1, - "modified": "2019-06-12 20:00:25.734108", + "modified": "2019-06-13 18:05:52.530462", "modified_by": "Administrator", "module": "HR", "name": "Expense Claim", From 6726dea88bdd59a17825d9947ec303de0a0a34a4 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Fri, 14 Jun 2019 11:17:17 +0530 Subject: [PATCH 07/49] style: change formatting --- erpnext/hr/doctype/expense_claim/expense_claim.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index 9e78ca12c4..deb6e1dc08 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -394,7 +394,7 @@ frappe.ui.form.on("Expense Taxes and Charges", { if(!child.amount) { child.tax_amount = flt(frm.doc.total_sanctioned_amount) * (flt(child.rate)/100); } - frm.trigger("calculate_total_tax", cdt, cdn) + frm.trigger("calculate_total_tax", cdt, cdn); }, tax_amount: function(frm, cdt, cdn) { From a5527225b694c6b95b5b4506df601b40388283e9 Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Fri, 14 Jun 2019 15:25:57 +0530 Subject: [PATCH 08/49] fix: requested changes --- erpnext/patches.txt | 2 +- erpnext/regional/india/setup.py | 2 +- erpnext/setup/doctype/company/company.json | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 15fd82ea72..747177a3a7 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -602,6 +602,6 @@ erpnext.patches.v11_1.set_salary_details_submittable erpnext.patches.v11_1.rename_depends_on_lwp execute:frappe.delete_doc("Report", "Inactive Items") erpnext.patches.v11_1.delete_scheduling_tool -erpnext.patches.v12_0.make_custom_fields_for_bank_remittance +erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019 execute:frappe.delete_doc_if_exists("Page", "support-analytics") erpnext.patches.v12_0.make_item_manufacturer \ No newline at end of file diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index f69c17e0c8..26fdb1a904 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -275,7 +275,7 @@ def make_custom_fields(update=True): ], 'Company': [ dict(fieldname='hra_section', label='HRA Settings', - fieldtype='Section Break', insert_after='asset_received_but_not_billed'), + fieldtype='Section Break', insert_after='asset_received_but_not_billed', collapsible=1), dict(fieldname='basic_component', label='Basic Component', fieldtype='Link', options='Salary Component', insert_after='hra_section'), dict(fieldname='hra_component', label='HRA Component', diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index fcccf5a973..d85fc45b46 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -170,9 +170,10 @@ "label": "Company Description" }, { + "collapsible": 1, "fieldname": "sales_settings", "fieldtype": "Section Break", - "label": "Sales" + "label": "Sales Settings" }, { "fieldname": "sales_monthly_history", @@ -530,6 +531,7 @@ "options": "Account" }, { + "collapsible": 1, "fieldname": "fixed_asset_depreciation_settings", "fieldtype": "Section Break", "label": "Fixed Asset Depreciation Settings" @@ -602,6 +604,7 @@ "options": "Role" }, { + "collapsible": 1, "description": "For reference only.", "fieldname": "company_info", "fieldtype": "Section Break", @@ -708,7 +711,7 @@ "icon": "fa fa-building", "idx": 1, "image_field": "company_logo", - "modified": "2019-06-13 18:03:14.764423", + "modified": "2019-06-14 14:36:11.363309", "modified_by": "Administrator", "module": "Setup", "name": "Company", From 8e99aaf6050afdf258343397c5e70109e89b56ea Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 14 Jun 2019 20:06:54 +0530 Subject: [PATCH 09/49] fix: Add erpnext website theme import --- erpnext/public/js/website_theme.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/erpnext/public/js/website_theme.js b/erpnext/public/js/website_theme.js index 6c7edfa655..84de2f5b51 100644 --- a/erpnext/public/js/website_theme.js +++ b/erpnext/public/js/website_theme.js @@ -2,16 +2,13 @@ // MIT License. See license.txt frappe.ui.form.on('Website Theme', { - apply_custom_theme(frm) { - let custom_theme = frm.doc.custom_theme; - custom_theme = custom_theme.split('\n'); - if ( - frm.doc.apply_custom_theme - && custom_theme.length === 2 - && custom_theme[1].includes('frappe/public/scss/website') + validate(frm) { + let theme_scss = frm.doc.theme_scss; + if (theme_scss.includes('frappe/public/scss/website') + && !theme_scss.includes('erpnext/public/scss/website') ) { - frm.set_value('custom_theme', - `$primary: #7575ff;\n@import "frappe/public/scss/website";\n@import "erpnext/public/scss/website";`); + frm.set_value('theme_scss', + `${frm.doc.theme_scss}\n@import "erpnext/public/scss/website";`); } } }); From 7e3a98ba334b0f5c965459848d6b79892ddec970 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Mon, 17 Jun 2019 12:44:49 +0530 Subject: [PATCH 10/49] fix: Is group filter fixes in dimensions --- erpnext/public/js/utils/dimension_tree_filter.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js index 16c1d4d248..f31b578b0b 100644 --- a/erpnext/public/js/utils/dimension_tree_filter.js +++ b/erpnext/public/js/utils/dimension_tree_filter.js @@ -14,9 +14,13 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => { onload: function(frm) { dimension_filters.then((dimensions) => { dimensions.forEach((dimension) => { - frm.set_query(dimension['fieldname'],{ - "is_group": 0 - }); + frappe.model.with_doctype(dimension['document_type'], () => { + if (frappe.meta.has_field(dimension['document_type'], 'is_group')) { + frm.set_query(dimension['fieldname'],{ + "is_group": 0 + }); + } + }) }); }); } From d1e0f42fea2937d95e595534d023b9cc4a4914cd Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Mon, 17 Jun 2019 12:47:39 +0530 Subject: [PATCH 11/49] fix: Styling fix --- erpnext/public/js/utils/dimension_tree_filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js index f31b578b0b..ccca04df26 100644 --- a/erpnext/public/js/utils/dimension_tree_filter.js +++ b/erpnext/public/js/utils/dimension_tree_filter.js @@ -16,7 +16,7 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => { dimensions.forEach((dimension) => { frappe.model.with_doctype(dimension['document_type'], () => { if (frappe.meta.has_field(dimension['document_type'], 'is_group')) { - frm.set_query(dimension['fieldname'],{ + frm.set_query(dimension['fieldname'], { "is_group": 0 }); } From 725f56faca7795fb74451cb8495a14b6cc7ec648 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 17 Jun 2019 12:50:44 +0530 Subject: [PATCH 12/49] feat: delayed order reports --- .../report/delayed_item_report/__init__.py | 0 .../delayed_item_report.js | 62 +++++++ .../delayed_item_report.json | 37 ++++ .../delayed_item_report.py | 168 ++++++++++++++++++ .../report/delayed_order_report/__init__.py | 0 .../delayed_order_report.js | 62 +++++++ .../delayed_order_report.json | 37 ++++ .../delayed_order_report.py | 83 +++++++++ 8 files changed, 449 insertions(+) create mode 100644 erpnext/stock/report/delayed_item_report/__init__.py create mode 100644 erpnext/stock/report/delayed_item_report/delayed_item_report.js create mode 100644 erpnext/stock/report/delayed_item_report/delayed_item_report.json create mode 100644 erpnext/stock/report/delayed_item_report/delayed_item_report.py create mode 100644 erpnext/stock/report/delayed_order_report/__init__.py create mode 100644 erpnext/stock/report/delayed_order_report/delayed_order_report.js create mode 100644 erpnext/stock/report/delayed_order_report/delayed_order_report.json create mode 100644 erpnext/stock/report/delayed_order_report/delayed_order_report.py diff --git a/erpnext/stock/report/delayed_item_report/__init__.py b/erpnext/stock/report/delayed_item_report/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.js b/erpnext/stock/report/delayed_item_report/delayed_item_report.js new file mode 100644 index 0000000000..5d160b1519 --- /dev/null +++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.js @@ -0,0 +1,62 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Delayed Item Report"] = { + "filters": [ + { + fieldname: "company", + label: __("Company"), + fieldtype: "Link", + options: "Company", + default: frappe.defaults.get_default("company"), + reqd: 1 + }, + { + fieldname:"from_date", + label: __("From Date"), + fieldtype: "Date", + default: frappe.datetime.month_start(), + reqd: 1 + }, + { + fieldname:"to_date", + label: __("To Date"), + fieldtype: "Date", + default: frappe.datetime.now_date(), + reqd: 1 + }, + { + fieldname:"sales_order", + label: __("Sales Order"), + fieldtype: "Link", + options: "Sales Order", + }, + { + fieldname:"customer", + label: __("Customer"), + fieldtype: "Link", + options: "Customer", + }, + { + fieldname:"customer_group", + label: __("Customer Group"), + fieldtype: "Link", + options: "Customer Group", + }, + { + fieldname:"item_group", + label: __("Item Group"), + fieldtype: "Link", + options: "Item Group", + }, + { + fieldname:"based_on", + label: __("Based On"), + fieldtype: "Select", + options: ["Delivery Note", "Sales Invoice"], + default: "Delivery Note", + reqd: 1 + }, + ] +} \ No newline at end of file diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.json b/erpnext/stock/report/delayed_item_report/delayed_item_report.json new file mode 100644 index 0000000000..f336cecf20 --- /dev/null +++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.json @@ -0,0 +1,37 @@ +{ + "add_total_row": 0, + "creation": "2019-06-17 12:45:07.324014", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "letter_head": "Gadgets International", + "modified": "2019-06-17 12:45:07.324014", + "modified_by": "Administrator", + "module": "Stock", + "name": "Delayed Item Report", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Delivery Note", + "report_name": "Delayed Item Report", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Sales User" + }, + { + "role": "Stock Manager" + }, + { + "role": "Stock User" + }, + { + "role": "Maintenance User" + } + ] +} \ No newline at end of file diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.py b/erpnext/stock/report/delayed_item_report/delayed_item_report.py new file mode 100644 index 0000000000..7b968b89a7 --- /dev/null +++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.py @@ -0,0 +1,168 @@ +# 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 date_diff + +def execute(filters=None, consolidated = False): + data, columns = DelayedItemReport(filters).run() + + return data, columns + +class DelayedItemReport(object): + def __init__(self, filters=None): + self.filters = frappe._dict(filters or {}) + + def run(self): + return self.get_columns(), self.get_data() or [] + + def get_data(self, consolidated=False): + conditions = "" + + doctype = self.filters.get("based_on") + child_doc= "%s Item" % doctype + + if doctype == "Sales Invoice": + conditions = " and `tabSales Invoice`.update_stock = 1 and `tabSales Invoice`.is_pos = 0" + + if self.filters.get("item_group"): + conditions += " and `tab%s`.item_group = %s" % (child_doc, + frappe.db.escape(self.filters.get("item_group"))) + + for field in ["customer", "customer_group", "company"]: + if self.filters.get(field): + conditions += " and `tab%s`.%s = %s" % (doctype, + field, frappe.db.escape(self.filters.get(field))) + + sales_order_field = "against_sales_order" + if doctype == "Sales Invoice": + sales_order_field = "sales_order" + + if self.filters.get("sales_order"): + conditions = " and `tab%s`.%s = '%s'" %(child_doc, sales_order_field, self.filters.get("sales_order")) + + self.transactions = frappe.db.sql(""" SELECT `tab{child_doc}`.item_code, `tab{child_doc}`.item_name, + `tab{child_doc}`.item_group, `tab{child_doc}`.qty, `tab{child_doc}`.rate, `tab{child_doc}`.amount, + `tab{child_doc}`.so_detail, `tab{child_doc}`.{so_field} as sales_order, + `tab{doctype}`.customer, `tab{doctype}`.posting_date, `tab{doctype}`.name, `tab{doctype}`.grand_total + FROM `tab{child_doc}`, `tab{doctype}` + WHERE + `tab{child_doc}`.parent = `tab{doctype}`.name and `tab{doctype}`.docstatus = 1 and + `tab{doctype}`.posting_date between %(from_date)s and %(to_date)s and + `tab{child_doc}`.{so_field} is not null and `tab{child_doc}`.{so_field} != '' {cond} + """.format(cond=conditions, doctype=doctype, child_doc=child_doc, so_field=sales_order_field), { + 'from_date': self.filters.get('from_date'), + 'to_date': self.filters.get('to_date') + }, as_dict=1) + + if self.transactions: + self.filter_transactions_data(consolidated) + + return self.transactions + + def filter_transactions_data(self, consolidated=False): + sales_orders = [d.sales_order for d in self.transactions] + doctype = "Sales Order" + filters = {'name': ('in', sales_orders)} + + if not consolidated: + sales_order_items = [d.so_detail for d in self.transactions] + doctype = "Sales Order Item" + filters = {'parent': ('in', sales_orders), 'name': ('in', sales_order_items)} + + so_data = {} + for d in frappe.get_all(doctype, filters = filters, + fields = ["delivery_date", "parent", "name"]): + key = d.name if consolidated else (d.parent, d.name) + if key not in so_data: + so_data.setdefault(key, d.delivery_date) + + for row in self.transactions: + key = row.sales_order if consolidated else (row.sales_order, row.so_detail) + row.update({ + 'delivery_date': so_data.get(key), + 'delayed_days': date_diff(row.posting_date, so_data.get(key)) + }) + + return self.transactions + + def get_columns(self): + based_on = self.filters.get("based_on") + + return [{ + "label": _(based_on), + "fieldname": "name", + "fieldtype": "Link", + "options": based_on, + "width": 100 + },{ + "label": _("Customer"), + "fieldname": "customer", + "fieldtype": "Link", + "options": "Customer", + "width": 100 + }, + { + "label": _("Expected Delivery Date"), + "fieldname": "delivery_date", + "fieldtype": "Date", + "width": 100 + }, + { + "label": _("Actual Delivery Date"), + "fieldname": "posting_date", + "fieldtype": "Date", + "width": 100 + }, + { + "label": _("Item Code"), + "fieldname": "item_code", + "fieldtype": "Link", + "options": "Item", + "width": 100 + }, + { + "label": _("Item Name"), + "fieldname": "item_name", + "fieldtype": "Data", + "width": 100 + }, + { + "label": _("Quantity"), + "fieldname": "qty", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Rate"), + "fieldname": "rate", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Amount"), + "fieldname": "amount", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Delayed Days"), + "fieldname": "delayed_days", + "fieldtype": "Int", + "width": 100 + }, + { + "label": _("Sales Order"), + "fieldname": "sales_order", + "fieldtype": "Link", + "options": "Sales Order", + "width": 100 + }, + { + "label": _("Customer PO"), + "fieldname": "po_no", + "fieldtype": "Data", + "width": 100 + }] \ No newline at end of file diff --git a/erpnext/stock/report/delayed_order_report/__init__.py b/erpnext/stock/report/delayed_order_report/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.js b/erpnext/stock/report/delayed_order_report/delayed_order_report.js new file mode 100644 index 0000000000..11752ae9fb --- /dev/null +++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.js @@ -0,0 +1,62 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Delayed Order Report"] = { + "filters": [ + { + fieldname: "company", + label: __("Company"), + fieldtype: "Link", + options: "Company", + default: frappe.defaults.get_default("company"), + reqd: 1 + }, + { + fieldname:"from_date", + label: __("From Date"), + fieldtype: "Date", + default: frappe.datetime.month_start(), + reqd: 1 + }, + { + fieldname:"to_date", + label: __("To Date"), + fieldtype: "Date", + default: frappe.datetime.now_date(), + reqd: 1 + }, + { + fieldname:"sales_order", + label: __("Sales Order"), + fieldtype: "Link", + options: "Sales Order", + }, + { + fieldname:"customer", + label: __("Customer"), + fieldtype: "Link", + options: "Customer", + }, + { + fieldname:"customer_group", + label: __("Customer Group"), + fieldtype: "Link", + options: "Customer Group", + }, + { + fieldname:"item_group", + label: __("Item Group"), + fieldtype: "Link", + options: "Item Group", + }, + { + fieldname:"based_on", + label: __("Based On"), + fieldtype: "Select", + options: ["Delivery Note", "Sales Invoice"], + default: "Delivery Note", + reqd: 1 + }, + ] +} \ No newline at end of file diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.json b/erpnext/stock/report/delayed_order_report/delayed_order_report.json new file mode 100644 index 0000000000..29c27cb1a6 --- /dev/null +++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.json @@ -0,0 +1,37 @@ +{ + "add_total_row": 0, + "creation": "2019-06-17 12:45:56.359322", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "letter_head": "Gadgets International", + "modified": "2019-06-17 12:45:56.359322", + "modified_by": "Administrator", + "module": "Stock", + "name": "Delayed Order Report", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Delivery Note", + "report_name": "Delayed Order Report", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Sales User" + }, + { + "role": "Stock Manager" + }, + { + "role": "Stock User" + }, + { + "role": "Maintenance User" + } + ] +} \ No newline at end of file diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.py b/erpnext/stock/report/delayed_order_report/delayed_order_report.py new file mode 100644 index 0000000000..d2a1a30d9e --- /dev/null +++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.py @@ -0,0 +1,83 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe import _ +from erpnext.stock.report.delayed_item_report.delayed_item_report import DelayedItemReport + +def execute(filters=None): + columns, data = [], [] + + columns, data = DelayedOrderReport(filters).run() + + return columns, data + +class DelayedOrderReport(DelayedItemReport): + def run(self): + return self.get_columns(), self.get_data(consolidated=True) or [] + + def get_data(self, consolidated=False): + data = super(DelayedOrderReport, self).get_data(consolidated) or [] + + so_list = [] + result = [] + for d in data: + if d.sales_order not in so_list: + so_list.append(d.sales_order) + result.append(d) + + return result + + def get_columns(self): + based_on = self.filters.get("based_on") + + return [{ + "label": _(based_on), + "fieldname": "name", + "fieldtype": "Link", + "options": based_on, + "width": 100 + },{ + "label": _("Customer"), + "fieldname": "customer", + "fieldtype": "Link", + "options": "Customer", + "width": 100 + }, + { + "label": _("Expected Delivery Date"), + "fieldname": "delivery_date", + "fieldtype": "Date", + "width": 100 + }, + { + "label": _("Actual Delivery Date"), + "fieldname": "posting_date", + "fieldtype": "Date", + "width": 100 + }, + { + "label": _("Amount"), + "fieldname": "grand_total", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Delayed Days"), + "fieldname": "delayed_days", + "fieldtype": "Int", + "width": 100 + }, + { + "label": _("Sales Order"), + "fieldname": "sales_order", + "fieldtype": "Link", + "options": "Sales Order", + "width": 100 + }, + { + "label": _("Customer PO"), + "fieldname": "po_no", + "fieldtype": "Data", + "width": 100 + }] \ No newline at end of file From 4babfdb987bcba43f7d0ea9bf8820497b2a7414c Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 15 Apr 2019 15:34:38 +0530 Subject: [PATCH 13/49] fix(delivery): Add more context for dispatch notification email + formatting fixes --- .../doctype/delivery_trip/delivery_trip.py | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py index 01b4734bf5..bc8c7493d5 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py @@ -20,8 +20,7 @@ class DeliveryTrip(Document): # Google Maps returns distances in meters by default self.default_distance_uom = frappe.db.get_single_value("Global Defaults", "default_distance_unit") or "Meter" self.uom_conversion_factor = frappe.db.get_value("UOM Conversion Factor", - {"from_uom": "Meter", "to_uom": self.default_distance_uom}, - "value") + {"from_uom": "Meter", "to_uom": self.default_distance_uom}, "value") def validate(self): self.validate_stop_addresses() @@ -139,7 +138,7 @@ class DeliveryTrip(Document): # Include last leg in the final distance calculation self.uom = self.default_distance_uom total_distance = sum([leg.get("distance", {}).get("value", 0.0) - for leg in directions.get("legs")]) # in meters + for leg in directions.get("legs")]) # in meters self.total_distance = total_distance * self.uom_conversion_factor else: idx += len(route) - 1 @@ -358,8 +357,12 @@ def notify_customers(delivery_trip): email_recipients = [] for stop in delivery_trip.delivery_stops: - contact_info = frappe.db.get_value("Contact", stop.contact, - ["first_name", "last_name", "email_id", "gender"], as_dict=1) + contact_info = frappe.db.get_value("Contact", stop.contact, ["first_name", "last_name", "email_id"], as_dict=1) + + context.update({"items": []}) + if stop.delivery_note: + items = frappe.get_all("Delivery Note Item", filters={"parent": stop.delivery_note, "docstatus": 1}, fields=["*"]) + context.update({"items": items}) if contact_info and contact_info.email_id: context.update(stop.as_dict()) @@ -369,9 +372,9 @@ def notify_customers(delivery_trip): dispatch_template = frappe.get_doc("Email Template", dispatch_template_name) frappe.sendmail(recipients=contact_info.email_id, - subject=dispatch_template.subject, - message=frappe.render_template(dispatch_template.response, context), - attachments=get_attachments(stop)) + subject=dispatch_template.subject, + message=frappe.render_template(dispatch_template.response, context), + attachments=get_attachments(stop)) stop.db_set("email_sent_to", contact_info.email_id) email_recipients.append(contact_info.email_id) @@ -388,9 +391,7 @@ def get_attachments(delivery_stop): return [] dispatch_attachment = frappe.db.get_single_value("Delivery Settings", "dispatch_attachment") - attachments = frappe.attach_print("Delivery Note", - delivery_stop.delivery_note, - file_name="Delivery Note", - print_format=dispatch_attachment) + attachments = frappe.attach_print("Delivery Note", delivery_stop.delivery_note, + file_name="Delivery Note", print_format=dispatch_attachment) return [attachments] From 7efeffa66a391d70f871c5267dcc4ae310c34e1e Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 17 Jun 2019 16:19:23 +0530 Subject: [PATCH 14/49] fix: allow edit is enabled in the pos profile still user not able to edit the rates --- .../page/point_of_sale/point_of_sale.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index 1218dd3bb4..d233b41787 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -779,6 +779,17 @@ class POSCart { const customer = this.frm.doc.customer; this.customer_field.set_value(customer); + + if (this.numpad) { + const disable_btns = this.disable_numpad_control() + const enable_btns = [__('Rate'), __('Disc')] + + if (disable_btns) { + enable_btns.filter(btn => !disable_btns.includes(btn)) + } + + this.numpad.enable_buttons(enable_btns); + } } get_grand_total() { @@ -1551,6 +1562,16 @@ class NumberPad { } } + enable_buttons(btns) { + btns.forEach((btn) => { + const $btn = this.get_btn(btn); + $btn.prop("disabled", false) + $btn.hover(() => { + $btn.css('cursor','pointer'); + }) + }) + } + set_class() { for (const btn in this.add_class) { const class_name = this.add_class[btn]; From 803f78435102745c71ff88a81937d06c9b66329b Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 17 Jun 2019 17:33:04 +0530 Subject: [PATCH 15/49] fix(minor): format date in user format for accounting dashboard --- .../account_balance_timeline/account_balance_timeline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py index f2abb81dbb..648cc68dac 100644 --- a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py +++ b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe, json -from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day +from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate from erpnext.accounts.report.general_ledger.general_ledger import execute from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_period_ending @@ -37,7 +37,7 @@ def get(chart_name=None, from_date = None, to_date = None): result = build_result(account, dates, gl_entries) return { - "labels": [r[0].strftime('%Y-%m-%d') for r in result], + "labels": [formatdate(r[0].strftime('%Y-%m-%d')) for r in result], "datasets": [{ "name": account, "values": [r[1] for r in result] From 4803e817e9efbcaf910e60b37ff38d43a3ad48a3 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 17 Jun 2019 14:57:05 +0530 Subject: [PATCH 16/49] fix: bank guarantee, not able to select the purchase order --- erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js index 2a44cb3b52..0acbe2009f 100644 --- a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js +++ b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js @@ -43,8 +43,13 @@ frappe.ui.form.on('Bank Guarantee', { reference_docname: function(frm) { if (frm.doc.reference_docname && frm.doc.reference_doctype) { - let fields_to_fetch = ["project", "grand_total"]; + let fields_to_fetch = ["grand_total"]; let party_field = frm.doc.reference_doctype == "Sales Order" ? "customer" : "supplier"; + + if (frm.doc.reference_doctype == "Sales Order") { + fields_to_fetch.push("project"); + } + fields_to_fetch.push(party_field); frappe.call({ method: "erpnext.accounts.doctype.bank_guarantee.bank_guarantee.get_vouchar_detials", From 3d47a6dbb5a7d36559edcff41529934f851fbe6b Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Mon, 17 Jun 2019 17:49:04 +0530 Subject: [PATCH 17/49] fix: Company filters in Total Stock Summary Report (#17965) --- .../total_stock_summary.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/report/total_stock_summary/total_stock_summary.js b/erpnext/stock/report/total_stock_summary/total_stock_summary.js index b7461c485f..90648f1b24 100644 --- a/erpnext/stock/report/total_stock_summary/total_stock_summary.js +++ b/erpnext/stock/report/total_stock_summary/total_stock_summary.js @@ -10,8 +10,23 @@ frappe.query_reports["Total Stock Summary"] = { "fieldtype": "Select", "width": "80", "reqd": 1, - "options": ["","Warehouse", "Company"], - "default": "Warehouse" + "options": ["", "Warehouse", "Company"], + "change": function() { + let group_by = frappe.query_report.get_filter_value("group_by") + let company_filter = frappe.query_report.get_filter("company") + if (group_by == "Company") { + company_filter.df.reqd = 0; + company_filter.df.hidden = 1; + frappe.query_report.set_filter_value("company", ""); + company_filter.refresh(); + } + else { + company_filter.df.reqd = 1; + company_filter.df.hidden = 0; + company_filter.refresh(); + frappe.query_report.refresh(); + } + } }, { "fieldname": "company", From 9ee5c8a4c68817622eabd7fb4b57f66a8c8070f6 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 17 Jun 2019 18:05:41 +0530 Subject: [PATCH 18/49] fix(employee-benefit-application): remove query from setup --- .../employee_benefit_application.js | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js index e71ce1276b..c55c46db99 100644 --- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js +++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js @@ -2,20 +2,8 @@ // For license information, please see license.txt frappe.ui.form.on('Employee Benefit Application', { - setup: function(frm) { - if(!frm.doc.employee || !frm.doc.date) { - frappe.throw(__("Please select Employee and Date first")); - } else { - frm.set_query("earning_component", "employee_benefits", function() { - return { - query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", - filters: {date: frm.doc.date, employee: frm.doc.employee} - }; - }); - } - }, - employee: function(frm) { + frm.trigger('set_earning_component'); var method, args; if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){ method = "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining"; @@ -35,6 +23,21 @@ frappe.ui.form.on('Employee Benefit Application', { get_max_benefits(frm, method, args); } }, + + date: function(frm) { + frm.trigger('set_earning_component'); + }, + + set_earning_component: function(frm) { + if(!frm.doc.employee && !frm.doc.date) return; + frm.set_query("earning_component", "employee_benefits", function() { + return { + query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", + filters: {date: frm.doc.date, employee: frm.doc.employee} + } + }); + }, + payroll_period: function(frm) { var method, args; if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){ From 7293a98a10b0a7fedf09f519af740fa98061b3d8 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 17 Jun 2019 19:03:46 +0530 Subject: [PATCH 19/49] fix: change formatting --- .../employee_benefit_application.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js index c55c46db99..b73dcf8ac3 100644 --- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js +++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js @@ -34,7 +34,7 @@ frappe.ui.form.on('Employee Benefit Application', { return { query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", filters: {date: frm.doc.date, employee: frm.doc.employee} - } + }; }); }, From 946eefe039c46f0add94f6d88178e6cba0c2e892 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Mon, 17 Jun 2019 23:10:36 +0530 Subject: [PATCH 20/49] fix: Codacy fixes --- erpnext/public/js/utils/dimension_tree_filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js index ccca04df26..fef450795b 100644 --- a/erpnext/public/js/utils/dimension_tree_filter.js +++ b/erpnext/public/js/utils/dimension_tree_filter.js @@ -20,7 +20,7 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => { "is_group": 0 }); } - }) + }); }); }); } From 48585c94ffc99dd5e1daceca98e78eae63a81ec8 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Tue, 18 Jun 2019 19:11:17 +0530 Subject: [PATCH 21/49] fix: Consider discount_amount only when provided to calculate rate After selecting item_code in items table and not entering rate, Clicking elsewhere will set rate to NaN. All DocTypes on buying side have this bug. --- erpnext/public/js/controllers/buying.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index 7e61f03af9..97c823d053 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -144,7 +144,9 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ item.discount_amount = flt(item_rate) * flt(item.discount_percentage) / 100; } - item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item)); + if (item.discount_amount) { + item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item)); + } this.calculate_taxes_and_totals(); }, From be8a46a92a3cb79861720e0f084f6c4a12b6e78e Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Tue, 18 Jun 2019 21:50:05 +0530 Subject: [PATCH 22/49] fix(tests): Timesheet tests --- erpnext/projects/doctype/timesheet/test_timesheet.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py index f1179033be..32f0428fcd 100644 --- a/erpnext/projects/doctype/timesheet/test_timesheet.py +++ b/erpnext/projects/doctype/timesheet/test_timesheet.py @@ -103,8 +103,8 @@ class TestTimesheet(unittest.TestCase): { "billable": 1, "activity_type": "_Test Activity Type", - "from_type": now_datetime(), - "hours": 3, + "from_time": now_datetime(), + "to_time": now_datetime() + datetime.timedelta(hours=3), "company": "_Test Company" } ) @@ -113,8 +113,8 @@ class TestTimesheet(unittest.TestCase): { "billable": 1, "activity_type": "_Test Activity Type", - "from_type": now_datetime(), - "hours": 3, + "from_time": now_datetime(), + "to_time": now_datetime() + datetime.timedelta(hours=3), "company": "_Test Company" } ) From 645afe16c3aaf7d45b1254d6d80682655bc49a52 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Tue, 18 Jun 2019 23:01:20 +0530 Subject: [PATCH 23/49] fix(tests): Do not test order of features in Location --- erpnext/assets/doctype/location/test_location.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/location/test_location.py b/erpnext/assets/doctype/location/test_location.py index 22d25b5e11..c98b0b0936 100644 --- a/erpnext/assets/doctype/location/test_location.py +++ b/erpnext/assets/doctype/location/test_location.py @@ -25,9 +25,12 @@ class TestLocation(unittest.TestCase): temp['features'][0]['properties']['feature_of'] = location formatted_locations.extend(temp['features']) - formatted_location_string = str(formatted_locations) test_location = frappe.get_doc('Location', 'Test Location Area') test_location.save() - self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features'])) + test_location_features = json.loads(test_location.get('location'))['features'] + ordered_test_location_features = sorted(test_location_features, key=lambda x: x['properties']['feature_of']) + ordered_formatted_locations = sorted(formatted_locations, key=lambda x: x['properties']['feature_of']) + + self.assertEqual(ordered_formatted_locations, ordered_test_location_features) self.assertEqual(area, test_location.get('area')) From 2632107129bc8726a7dcd6d70c1d6df7d4bd8eab Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 19 Jun 2019 12:15:37 +0530 Subject: [PATCH 24/49] fix: User MultiSelectList control for Party filter (#17943) * fix: User MultiSelectList control for Party filter The comma based filter wouldn't work for values that had comma in them * fix: Replace with MultiSelectList in reports * fix: Parse json instead of string split --- .../accounts/report/financial_statements.py | 4 +- .../report/general_ledger/general_ledger.js | 92 +++---------------- .../report/general_ledger/general_ledger.py | 9 +- .../gross_and_net_profit_report.js | 30 +----- .../profit_and_loss_statement.js | 30 +----- erpnext/public/js/financial_statements.js | 31 +------ 6 files changed, 31 insertions(+), 165 deletions(-) diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 41205ae2b0..c06856aa75 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -390,8 +390,8 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters): if filters: if filters.get("project"): if not isinstance(filters.get("project"), list): - projects = frappe.safe_encode(filters.get("project")) - filters.project = [d.strip() for d in projects.strip().split(',') if d] + filters.project = frappe.parse_json(filters.get("project")) + additional_conditions.append("project in %(project)s") if filters.get("cost_center"): diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index 4235b7f60d..5c98b249db 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -72,46 +72,25 @@ frappe.query_reports["General Ledger"] = { { "fieldname":"party", "label": __("Party"), - "fieldtype": "MultiSelect", - get_data: function() { + "fieldtype": "MultiSelectList", + get_data: function(txt) { if (!frappe.query_report.filters) return; - var party_type = frappe.query_report.get_filter_value('party_type'); - var parties = frappe.query_report.get_filter_value('party'); - if(!party_type) return; - const values = parties.split(/\s*,\s*/).filter(d => d); - const txt = parties.match(/[^,\s*]*$/)[0] || ''; - let data = []; + let party_type = frappe.query_report.get_filter_value('party_type'); + if (!party_type) return; - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: frappe.query_report.get_filter_value('party_type'), - txt: txt, - filters: { - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; + return frappe.db.get_link_options(party_type, txt); }, on_change: function() { var party_type = frappe.query_report.get_filter_value('party_type'); var parties = frappe.query_report.get_filter_value('party'); - const values = parties.split(/\s*,\s*/).filter(d => d); - if(!party_type || !parties || values.length>1) { + if(!party_type || parties.length === 0 || parties.length > 1) { frappe.query_report.set_filter_value('party_name', ""); frappe.query_report.set_filter_value('tax_id', ""); return; } else { - var party = values[0]; + var party = parties[0]; var fieldname = erpnext.utils.get_party_name(party_type) || "name"; frappe.db.get_value(party_type, party, fieldname, function(value) { frappe.query_report.set_filter_value('party_name', value[fieldname]); @@ -154,62 +133,17 @@ frappe.query_reports["General Ledger"] = { { "fieldname":"cost_center", "label": __("Cost Center"), - "fieldtype": "MultiSelect", - get_data: function() { - var cost_centers = frappe.query_report.get_filter_value("cost_center") || ""; - - const values = cost_centers.split(/\s*,\s*/).filter(d => d); - const txt = cost_centers.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Cost Center", - txt: txt, - filters: { - "company": frappe.query_report.get_filter_value("company"), - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } - }); - return data; + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Cost Center', txt); } }, { "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; + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Project', txt); } }, { diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index d9f395b895..1c5e089534 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -26,8 +26,7 @@ def execute(filters=None): account_details.setdefault(acc.name, acc) if filters.get('party'): - parties = cstr(filters.get("party")).strip() - filters.party = [d.strip() for d in parties.split(',') if d] + filters.party = frappe.parse_json(filters.get("party")) validate_filters(filters, account_details) @@ -61,12 +60,10 @@ def validate_filters(filters, account_details): frappe.throw(_("From Date must be before To Date")) if filters.get('project'): - projects = cstr(filters.get("project")).strip() - filters.project = [d.strip() for d in projects.split(',') if d] + filters.project = frappe.parse_json(filters.get('project')) if filters.get('cost_center'): - cost_centers = cstr(filters.get("cost_center")).strip() - filters.cost_center = [d.strip() for d in cost_centers.split(',') if d] + filters.cost_center = frappe.parse_json(filters.get('cost_center')) def validate_party(filters): 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 index 63ac281cdb..8dc5ab36dd 100644 --- 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 @@ -13,33 +13,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { frappe.query_reports["Gross and Net Profit Report"]["filters"].push( { - "fieldname":"project", + "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; + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Project', txt); } }, { diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js index 250e516d7d..df5c982258 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js @@ -8,33 +8,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { frappe.query_reports["Profit and Loss Statement"]["filters"].push( { - "fieldname":"project", + "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; + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Project', txt); } }, { diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js index 73e04c0ff0..d1113a4ca4 100644 --- a/erpnext/public/js/financial_statements.js +++ b/erpnext/public/js/financial_statements.js @@ -118,34 +118,13 @@ function get_filters(){ "options": erpnext.get_presentation_currency_list() }, { - "fieldname":"cost_center", + "fieldname": "cost_center", "label": __("Cost Center"), - "fieldtype": "MultiSelect", - get_data: function() { - var cost_centers = frappe.query_report.get_filter_value("cost_center") || ""; - - const values = cost_centers.split(/\s*,\s*/).filter(d => d); - const txt = cost_centers.match(/[^,\s*]*$/)[0] || ''; - let data = []; - - frappe.call({ - type: "GET", - method:'frappe.desk.search.search_link', - async: false, - no_spinner: true, - args: { - doctype: "Cost Center", - txt: txt, - filters: { - "company": frappe.query_report.get_filter_value("company"), - "name": ["not in", values] - } - }, - callback: function(r) { - data = r.results; - } + "fieldtype": "MultiSelectList", + get_data: function(txt) { + return frappe.db.get_link_options('Cost Center', txt, { + company: frappe.query_report.get_filter_value("company") }); - return data; } } ] From 0ef1df72adb463de7ca40c00612cde6ef938d446 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 19 Jun 2019 17:50:33 +0530 Subject: [PATCH 25/49] refactor: fetch rate directly from the account head --- erpnext/hr/doctype/expense_claim/expense_claim.js | 9 +-------- .../expense_taxes_and_charges.json | 3 ++- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index deb6e1dc08..40bec6d4d7 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -361,16 +361,9 @@ frappe.ui.form.on("Expense Claim Advance", { frappe.ui.form.on("Expense Taxes and Charges", { account_head: function(frm, cdt, cdn) { var child = locals[cdt][cdn]; - if(child.account_head && !child.description && !child.rate) { + if(child.account_head && !child.description) { // set description from account head child.description = child.account_head.split(' - ').slice(0, -1).join(' - '); - - // set the tax rate from account head - frappe.db.get_value("Account", child.account_head, "tax_rate").then((r) => { - if(r.message) { - frappe.model.set_value(cdt, cdn, 'rate', r.message.tax_rate); - } - }); refresh_field("taxes"); } }, diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json index 8caf0a975a..be51c43920 100644 --- a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json +++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json @@ -53,6 +53,7 @@ }, { "columns": 2, + "fetch_from": "account_head.tax_rate", "fieldname": "rate", "fieldtype": "Float", "in_list_view": 1, @@ -91,7 +92,7 @@ } ], "istable": 1, - "modified": "2019-06-11 14:19:34.780611", + "modified": "2019-06-19 17:47:40.236436", "modified_by": "Administrator", "module": "HR", "name": "Expense Taxes and Charges", From ecc670047e025becd81275c77b304faa176c967f Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Wed, 19 Jun 2019 18:25:38 +0530 Subject: [PATCH 26/49] fix: From date and to date filters in HSN wise summary of out ward supplies --- .../hsn_wise_summary_of_outward_supplies.js | 15 ++++++++++++++- .../hsn_wise_summary_of_outward_supplies.py | 4 +++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js index dcb81cb087..dfdf9dc095 100644 --- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js +++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js @@ -29,7 +29,20 @@ frappe.query_reports["HSN-wise-summary of outward supplies"] = { "placeholder":"Company GSTIN", "options": [""], "width": "80" - } + }, + { + "fieldname":"from_date", + "label": __("From Date"), + "fieldtype": "Date", + "width": "80" + }, + { + "fieldname":"to_date", + "label": __("To Date"), + "fieldtype": "Date", + "width": "80" + }, + ], onload: (report) => { fetch_gstins(report); diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py index e938e29c44..222dfa1eb7 100644 --- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py +++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py @@ -88,7 +88,9 @@ def get_conditions(filters): for opts in (("company", " and company=%(company)s"), ("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s"), - ("company_gstin", " and company_gstin=%(company_gstin)s")): + ("company_gstin", " and company_gstin=%(company_gstin)s"), + ("from_date", " and posting_date >= %(from_date)s"), + ("to_date", "and posting_date <= %(to_date)s")): if filters.get(opts[0]): conditions += opts[1] From 4a1c7ddb094549517dee41a403072b0a869525fd Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 19 Jun 2019 19:15:37 +0530 Subject: [PATCH 27/49] fix: App logo URL --- erpnext/hooks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index da0972bf5c..9502006265 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -10,6 +10,7 @@ app_color = "#e74c3c" app_email = "info@erpnext.com" app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" +app_logo_url = '/assets/erpnext/images/erp-icon.svg' develop_version = '12.x.x-develop' From 357592f55efb920b7ffbca0b8ea39a3b17e0366b Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 19 Jun 2019 19:17:50 +0530 Subject: [PATCH 28/49] fix: Remove logo replace logic --- erpnext/public/js/conf.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js index 477781bc80..047922f366 100644 --- a/erpnext/public/js/conf.js +++ b/erpnext/public/js/conf.js @@ -11,9 +11,6 @@ $(document).bind('toolbar_setup', function() { href="https://discuss.erpnext.com">Feedback

' - $('.navbar-home').html(''); - $('[data-link="docs"]').attr("href", "https://erpnext.com/docs") $('[data-link="issues"]').attr("href", "https://github.com/frappe/erpnext/issues") From 23f9b6156fd16996768f531490c25824ec262514 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Thu, 20 Jun 2019 11:34:14 +0530 Subject: [PATCH 29/49] fix(Opportunity): Don't assign to Guest (#17996) If Opportunity is created from Website, it breaks because the assign_to user is Guest --- erpnext/crm/doctype/opportunity/opportunity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index 4d4593641a..adac8f5922 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -342,7 +342,7 @@ def assign_to_user(doc, subject_field): elif doc.lead: assign_user = frappe.db.get_value('Lead', doc.lead, 'lead_owner') - if assign_user and assign_user != 'Administrator': + if assign_user and assign_user not in ['Administrator', 'Guest']: if not assign_to.get(dict(doctype = doc.doctype, name = doc.name)): assign_to.add({ "assign_to": assign_user, From 8619fc7413e2cc98d7e9b768f671e54f7fcc9625 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Thu, 20 Jun 2019 12:02:47 +0530 Subject: [PATCH 30/49] fix: fetch rate only if field is empty --- .../expense_taxes_and_charges/expense_taxes_and_charges.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json index be51c43920..9bf69daf65 100644 --- a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json +++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json @@ -54,6 +54,7 @@ { "columns": 2, "fetch_from": "account_head.tax_rate", + "fetch_if_empty": 1, "fieldname": "rate", "fieldtype": "Float", "in_list_view": 1, @@ -92,7 +93,7 @@ } ], "istable": 1, - "modified": "2019-06-19 17:47:40.236436", + "modified": "2019-06-20 12:01:33.919555", "modified_by": "Administrator", "module": "HR", "name": "Expense Taxes and Charges", From 7483cb49fe939636882e608ec53db9b2a341ef7b Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 20 Jun 2019 15:25:06 +0530 Subject: [PATCH 31/49] Revert "fix: GSTR-1 Report fixes" This reverts commit 7592e0b588ad72d3e79cd101e94102ab1c1829f0. --- erpnext/regional/report/gstr_1/gstr_1.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index 9d8fa2ae53..7f323a2ab0 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -60,11 +60,8 @@ class Gstr1Report(object): else: for inv, items_based_on_rate in self.items_based_on_tax_rate.items(): invoice_details = self.invoices.get(inv) - for key, items in items_based_on_rate.items(): - rate = key[0] - account = key[1] - - row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, account, items) + for rate, items in items_based_on_rate.items(): + row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items) if self.filters.get("type_of_business") == "CDNR": row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N") @@ -103,7 +100,7 @@ class Gstr1Report(object): for key, value in iteritems(b2cs_output): self.data.append(value) - def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, account, items): + def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items): row = [] for fieldname in self.invoice_fields: if self.filters.get("type_of_business") == "CDNR" and fieldname == "invoice_value": @@ -120,10 +117,8 @@ class Gstr1Report(object): taxable_value = 0 for item_code, net_amount in self.invoice_items.get(invoice).items(): if item_code in items: - if self.item_tax_rate.get(invoice) and self.item_tax_rate.get(invoice, {}).get(item_code): - item_tax_rate = self.item_tax_rate.get(invoice, {}).get(item_code) - if account in item_tax_rate and tax_rate == item_tax_rate.get(account): - taxable_value += abs(net_amount) + if self.item_tax_rate.get(invoice) and tax_rate == self.item_tax_rate.get(invoice, {}).get(item_code): + taxable_value += abs(net_amount) elif not self.item_tax_rate.get(invoice): taxable_value += abs(net_amount) @@ -215,7 +210,8 @@ class Gstr1Report(object): item_tax_rate = json.loads(d.item_tax_rate) if item_tax_rate: - self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, item_tax_rate) + for account, rate in item_tax_rate.items(): + self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, rate) def get_items_based_on_tax_rate(self): self.tax_details = frappe.db.sql(""" @@ -255,7 +251,7 @@ class Gstr1Report(object): tax_rate *= 2 rate_based_dict = self.items_based_on_tax_rate\ - .setdefault(parent, {}).setdefault((tax_rate, account), []) + .setdefault(parent, {}).setdefault(tax_rate, []) if item_code not in rate_based_dict: rate_based_dict.append(item_code) except ValueError: From a8e49b8afdb1bce536e926165b4b3dc1ec345ae5 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 20 Jun 2019 15:26:04 +0530 Subject: [PATCH 32/49] Revert "fix: GSTR-2 Report fixes" This reverts commit a55413cb0d3828c20ad53e54ad7abe3ca2492668. --- erpnext/regional/report/gstr_1/gstr_1.py | 5 +---- erpnext/regional/report/gstr_2/gstr_2.py | 7 ++----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index 7f323a2ab0..5aa2441ee6 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -204,10 +204,7 @@ class Gstr1Report(object): sum(i.get('base_net_amount', 0) for i in items if i.item_code == d.item_code and i.parent == d.parent)) - item_tax_rate = {} - - if d.item_tax_rate: - item_tax_rate = json.loads(d.item_tax_rate) + item_tax_rate = json.loads(d.item_tax_rate) if item_tax_rate: for account, rate in item_tax_rate.items(): diff --git a/erpnext/regional/report/gstr_2/gstr_2.py b/erpnext/regional/report/gstr_2/gstr_2.py index d9cab63fef..a362269007 100644 --- a/erpnext/regional/report/gstr_2/gstr_2.py +++ b/erpnext/regional/report/gstr_2/gstr_2.py @@ -43,11 +43,8 @@ class Gstr2Report(Gstr1Report): self.get_igst_invoices() for inv, items_based_on_rate in self.items_based_on_tax_rate.items(): invoice_details = self.invoices.get(inv) - for key, items in items_based_on_rate.items(): - rate = key[0] - account = key[1] - - row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, account, items) + for rate, items in items_based_on_rate.items(): + row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items) tax_amount = taxable_value * rate / 100 if inv in self.igst_invoices: row += [tax_amount, 0, 0] From 5ff830b6f43b238453bc91f5a29216c277fc007e Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 20 Jun 2019 15:50:02 +0530 Subject: [PATCH 33/49] fix: GSTR report fixes --- erpnext/regional/report/gstr_1/gstr_1.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index 5aa2441ee6..accbff760a 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -117,7 +117,7 @@ class Gstr1Report(object): taxable_value = 0 for item_code, net_amount in self.invoice_items.get(invoice).items(): if item_code in items: - if self.item_tax_rate.get(invoice) and tax_rate == self.item_tax_rate.get(invoice, {}).get(item_code): + if self.item_tax_rate.get(invoice) and tax_rate in self.item_tax_rate.get(invoice, {}).get(item_code): taxable_value += abs(net_amount) elif not self.item_tax_rate.get(invoice): taxable_value += abs(net_amount) @@ -208,7 +208,8 @@ class Gstr1Report(object): if item_tax_rate: for account, rate in item_tax_rate.items(): - self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, rate) + tax_rate_dict = self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, []) + tax_rate_dict.append(rate) def get_items_based_on_tax_rate(self): self.tax_details = frappe.db.sql(""" From 50f4fc48a583851bd1e8314246258f8ba5173098 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 20 Jun 2019 15:53:14 +0530 Subject: [PATCH 34/49] fix: GSTR report fixes --- erpnext/regional/report/gstr_1/gstr_1.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index accbff760a..815a4e4b82 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -204,7 +204,10 @@ class Gstr1Report(object): sum(i.get('base_net_amount', 0) for i in items if i.item_code == d.item_code and i.parent == d.parent)) - item_tax_rate = json.loads(d.item_tax_rate) + item_tax_rate = {} + + if d.item_tax_rate: + item_tax_rate = json.loads(d.item_tax_rate) if item_tax_rate: for account, rate in item_tax_rate.items(): From 6ef38ebf34434c1748b0d6182ed9fe88f8b436bb Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 20 Jun 2019 15:55:09 +0530 Subject: [PATCH 35/49] fix: GSTR report fixes --- erpnext/regional/report/gstr_1/gstr_1.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index 815a4e4b82..3a8149d1cf 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -209,7 +209,6 @@ class Gstr1Report(object): if d.item_tax_rate: item_tax_rate = json.loads(d.item_tax_rate) - if item_tax_rate: for account, rate in item_tax_rate.items(): tax_rate_dict = self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, []) tax_rate_dict.append(rate) From da629810ad129fbde879de8190b6bdb3511ec20e Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 20 Jun 2019 17:20:19 +0530 Subject: [PATCH 36/49] fix: Get accounting dimensions only if user has access --- erpnext/public/js/utils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index f44fb0c1a6..86fa70d8ad 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -65,6 +65,9 @@ $.extend(erpnext, { }, get_dimension_filters: async function() { + if (!frappe.boot.user.can_read.includes('Accounting Dimension')) { + return + } let dimensions = await frappe.db.get_list('Accounting Dimension', { fields: ['label', 'fieldname', 'document_type'], filters: { From b663966c6821beafa2c77db24c245538f814aed7 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 20 Jun 2019 18:00:19 +0530 Subject: [PATCH 37/49] fix: Use can_read API --- erpnext/public/js/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 86fa70d8ad..dcc15fb5b3 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -65,7 +65,7 @@ $.extend(erpnext, { }, get_dimension_filters: async function() { - if (!frappe.boot.user.can_read.includes('Accounting Dimension')) { + if (!frappe.model.can_read('Accounting Dimension')) { return } let dimensions = await frappe.db.get_list('Accounting Dimension', { From 01f56b867e13c837347fe26b3d2056a235e34d23 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 20 Jun 2019 18:07:58 +0530 Subject: [PATCH 38/49] fix: Return empty array to avoid failure --- erpnext/public/js/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index dcc15fb5b3..f4bb64a64d 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -66,7 +66,7 @@ $.extend(erpnext, { get_dimension_filters: async function() { if (!frappe.model.can_read('Accounting Dimension')) { - return + return []; } let dimensions = await frappe.db.get_list('Accounting Dimension', { fields: ['label', 'fieldname', 'document_type'], From 23deb6f79be27430a964a52eb203bb8892129225 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Thu, 20 Jun 2019 19:11:58 +0530 Subject: [PATCH 39/49] fix: Default cost center fix for delivery note item (#17990) --- erpnext/selling/doctype/sales_order/sales_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index fb7a335302..b87ad031f5 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -581,8 +581,8 @@ def make_delivery_note(source_name, target_doc=None): if item: target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \ - or item.get("selling_cost_center") \ - or item_group.get("selling_cost_center") + or item.get("buying_cost_center") \ + or item_group.get("buying_cost_center") target_doc = get_mapped_doc("Sales Order", source_name, { "Sales Order": { From d2061b44dde0b451700892cf3b9efa89537bcfc5 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Thu, 20 Jun 2019 19:13:54 +0530 Subject: [PATCH 40/49] fix: could not find company all (#17978) --- .../employee_attendance_tool.js | 5 ++--- .../employee_attendance_tool.py | 11 +++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js index 376d0c0a5a..22ba5ad473 100644 --- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js +++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js @@ -2,9 +2,8 @@ frappe.ui.form.on("Employee Attendance Tool", { refresh: function(frm) { frm.disable_save(); }, - + onload: function(frm) { - frm.doc.department = frm.doc.branch = frm.doc.company = "All"; frm.set_value("date", frappe.datetime.get_today()); erpnext.employee_attendance_tool.load_employees(frm); }, @@ -24,7 +23,7 @@ frappe.ui.form.on("Employee Attendance Tool", { company: function(frm) { erpnext.employee_attendance_tool.load_employees(frm); } - + }); diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py index ea5f4bdeca..32fcee1abe 100644 --- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py +++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py @@ -17,12 +17,11 @@ def get_employees(date, department = None, branch = None, company = None): attendance_not_marked = [] attendance_marked = [] filters = {"status": "Active", "date_of_joining": ["<=", date]} - if department != "All": - filters["department"] = department - if branch != "All": - filters["branch"] = branch - if company != "All": - filters["company"] = company + + for field, value in {'department': department, + 'branch': branch, 'company': company}.items(): + if value: + filters[field] = value employee_list = frappe.get_list("Employee", fields=["employee", "employee_name"], filters=filters, order_by="employee_name") marked_employee = {} From 3fa112d8a7338d30112be476ea18b6734bc4c0eb Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 1 May 2019 11:16:25 +0530 Subject: [PATCH 41/49] feat(travis): Python 3.6 tests --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 869fe959c0..f2ba2c4326 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ dist: trusty python: - "2.7" + - "3.6" services: - mysql From f397acc9362d7820798dae4286c8e839fa16f0f8 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 1 May 2019 11:31:08 +0530 Subject: [PATCH 42/49] fix(travis): Refactor .travis.yml --- .travis.yml | 24 +++++++++--------------- travis/run-tests.sh | 12 ++++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 travis/run-tests.sh diff --git a/.travis.yml b/.travis.yml index f2ba2c4326..26a4caa0fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,10 @@ python: - "2.7" - "3.6" +env: + - TEST_TYPE=Server Side Test + - TEST_TYPE=Patch Test + services: - mysql @@ -40,18 +44,8 @@ before_script: - bench start & - sleep 10 -jobs: - include: - - stage: test - script: - - set -e - - bench run-tests --app erpnext --coverage - after_script: - - coveralls -b apps/erpnext -d ../../sites/.coverage - env: Server Side Test - - # stage - script: - - wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz - - bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis - - bench migrate - env: Patch Testing +script: + - $TRAVIS_BUILD_DIR/travis/run-tests.sh + +after_script: + - coveralls -b apps/erpnext -d ../../sites/.coverage diff --git a/travis/run-tests.sh b/travis/run-tests.sh new file mode 100644 index 0000000000..7cfd64833b --- /dev/null +++ b/travis/run-tests.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +if [[ $TEST_TYPE == 'Server Side Test' ]]; then + bench run-tests --app erpnext --coverage + +elif [[ $TEST_TYPE == 'Patch Test' ]]; then + wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz + bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis + bench migrate +fi From 63ddff867a0ad62648488ea99f7f1027abb965ec Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 1 May 2019 12:06:24 +0530 Subject: [PATCH 43/49] chore: Temporarily disable flake rule F821 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 26a4caa0fb..2e3a1e7782 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ install: # fix mongodb travis error - sudo rm /etc/apt/sources.list.d/mongodb*.list - pip install flake8==3.3.0 - - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics + - flake8 . --count --select=E901,E999,F822,F823 --show-source --statistics - sudo rm /etc/apt/sources.list.d/docker.list - sudo apt-get install hhvm && rm -rf /home/travis/.kiex/ - sudo apt-get purge -y mysql-common mysql-server mysql-client From bb5ca5a01fe89fcb36a73306c2dedabcee2bf334 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 1 May 2019 17:35:37 +0530 Subject: [PATCH 44/49] fix(py3): Convert filter to list --- erpnext/accounts/doctype/pricing_rule/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index 8a8e3291aa..5795b8f808 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -232,7 +232,7 @@ def filter_pricing_rules(args, pricing_rules, doc=None): if len(pricing_rules) > 1: rate_or_discount = list(set([d.rate_or_discount for d in pricing_rules])) if len(rate_or_discount) == 1 and rate_or_discount[0] == "Discount Percentage": - pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \ + pricing_rules = list(filter(lambda x: x.for_price_list==args.price_list, pricing_rules)) \ or pricing_rules if len(pricing_rules) > 1 and not args.for_shopping_cart: From c052ce61f77a1660bc9322877f05ecdfd3632841 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 1 May 2019 17:41:36 +0530 Subject: [PATCH 45/49] fix: Set file permissions 755 on travis/run-tests.sh --- travis/run-tests.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 travis/run-tests.sh diff --git a/travis/run-tests.sh b/travis/run-tests.sh old mode 100644 new mode 100755 From 44da737c1bdc50ecf623957bae2c2dda7185052a Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 1 May 2019 18:08:44 +0530 Subject: [PATCH 46/49] fix: Minor --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e3a1e7782..612a9e416c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ python: - "3.6" env: - - TEST_TYPE=Server Side Test - - TEST_TYPE=Patch Test + - TEST_TYPE="Server Side Test" + - TEST_TYPE="Patch Test" services: - mysql From 700711c28d2206efc939d6172c939b864cd81841 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 1 May 2019 18:25:53 +0530 Subject: [PATCH 47/49] fix: Run script with bash --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 612a9e416c..3ce1439d95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ before_script: - sleep 10 script: - - $TRAVIS_BUILD_DIR/travis/run-tests.sh + - bash $TRAVIS_BUILD_DIR/travis/run-tests.sh after_script: - coveralls -b apps/erpnext -d ../../sites/.coverage From 51eecd0c4276631ca267223c3fb84ef4b5a253b1 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Thu, 20 Jun 2019 14:07:32 +0530 Subject: [PATCH 48/49] chore: Enable Flake 821 rule --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3ce1439d95..a8a0d82614 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ install: # fix mongodb travis error - sudo rm /etc/apt/sources.list.d/mongodb*.list - pip install flake8==3.3.0 - - flake8 . --count --select=E901,E999,F822,F823 --show-source --statistics + - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics - sudo rm /etc/apt/sources.list.d/docker.list - sudo apt-get install hhvm && rm -rf /home/travis/.kiex/ - sudo apt-get purge -y mysql-common mysql-server mysql-client From c980143764cac7bf1ffb809c6491a396d1e91615 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Thu, 2 May 2019 21:10:13 +0530 Subject: [PATCH 49/49] fix(test): Explicitly search for Material Request Item with Item Code --- .../doctype/production_plan/test_production_plan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py index 42fce5ad49..e9ef70c49b 100644 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py @@ -152,7 +152,7 @@ class TestProductionPlan(unittest.TestCase): make_bom(item = item, raw_materials = raw_materials) production_plan = create_production_plan(item_code = 'Production Item CUST') production_plan.make_material_request() - material_request = frappe.get_value('Material Request Item', {'production_plan': production_plan.name}, 'parent') + material_request = frappe.db.get_value('Material Request Item', {'production_plan': production_plan.name, 'item_code': 'CUST-0987'}, 'parent') mr = frappe.get_doc('Material Request', material_request) self.assertTrue(mr.material_request_type, 'Customer Provided') self.assertTrue(mr.customer, '_Test Customer')