From faca47831780c5cbcee303a2b2a1032c78ab653a Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 12 Apr 2021 15:40:27 +0530 Subject: [PATCH 01/27] fix: payment amount showing in foreign currency --- .../accounts/doctype/payment_schedule/payment_schedule.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json index e362566af08..39eda331db7 100644 --- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json +++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json @@ -65,7 +65,6 @@ "fieldtype": "Currency", "in_list_view": 1, "label": "Payment Amount", - "options": "currency", "reqd": 1 }, { @@ -150,7 +149,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-02-15 21:03:12.540546", + "modified": "2021-04-12 15:39:47.363609", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Schedule", From ebbcc90d89539fd9dd50478d42f25809241aabfb Mon Sep 17 00:00:00 2001 From: Meike Nedwidek Date: Mon, 19 Apr 2021 15:28:37 +0200 Subject: [PATCH 02/27] :sparkles: add check field for subscription invoices if they should be submitted automatically --- .../doctype/subscription/subscription.json | 145 +++++------------- .../doctype/subscription/subscription.py | 4 +- 2 files changed, 45 insertions(+), 104 deletions(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.json b/erpnext/accounts/doctype/subscription/subscription.json index e80df2ab886..c4e4be7f781 100644 --- a/erpnext/accounts/doctype/subscription/subscription.json +++ b/erpnext/accounts/doctype/subscription/subscription.json @@ -36,6 +36,7 @@ "additional_discount_percentage", "additional_discount_amount", "sb_3", + "submit_invoice", "invoices", "accounting_dimensions_section", "cost_center", @@ -45,9 +46,7 @@ { "allow_on_submit": 1, "fieldname": "cb_1", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "status", @@ -55,97 +54,73 @@ "label": "Status", "no_copy": 1, "options": "\nTrialling\nActive\nPast Due Date\nCancelled\nUnpaid\nCompleted", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "subscription_period", "fieldtype": "Section Break", - "label": "Subscription Period", - "show_days": 1, - "show_seconds": 1 + "label": "Subscription Period" }, { "fieldname": "cancelation_date", "fieldtype": "Date", "label": "Cancelation Date", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "allow_on_submit": 1, "fieldname": "trial_period_start", "fieldtype": "Date", "label": "Trial Period Start Date", - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "depends_on": "eval:doc.trial_period_start", "fieldname": "trial_period_end", "fieldtype": "Date", "label": "Trial Period End Date", - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "fieldname": "column_break_11", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "current_invoice_start", "fieldtype": "Date", "label": "Current Invoice Start Date", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "current_invoice_end", "fieldtype": "Date", "label": "Current Invoice End Date", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "default": "0", "description": "Number of days that the subscriber has to pay invoices generated by this subscription", "fieldname": "days_until_due", "fieldtype": "Int", - "label": "Days Until Due", - "show_days": 1, - "show_seconds": 1 + "label": "Days Until Due" }, { "default": "0", "fieldname": "cancel_at_period_end", "fieldtype": "Check", - "label": "Cancel At End Of Period", - "show_days": 1, - "show_seconds": 1 + "label": "Cancel At End Of Period" }, { "default": "0", "fieldname": "generate_invoice_at_period_start", "fieldtype": "Check", - "label": "Generate Invoice At Beginning Of Period", - "show_days": 1, - "show_seconds": 1 + "label": "Generate Invoice At Beginning Of Period" }, { "allow_on_submit": 1, "fieldname": "sb_4", "fieldtype": "Section Break", - "label": "Plans", - "show_days": 1, - "show_seconds": 1 + "label": "Plans" }, { "allow_on_submit": 1, @@ -153,84 +128,62 @@ "fieldtype": "Table", "label": "Plans", "options": "Subscription Plan Detail", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "depends_on": "eval:['Customer', 'Supplier'].includes(doc.party_type)", "fieldname": "sb_1", "fieldtype": "Section Break", - "label": "Taxes", - "show_days": 1, - "show_seconds": 1 + "label": "Taxes" }, { "fieldname": "sb_2", "fieldtype": "Section Break", - "label": "Discounts", - "show_days": 1, - "show_seconds": 1 + "label": "Discounts" }, { "fieldname": "apply_additional_discount", "fieldtype": "Select", "label": "Apply Additional Discount On", - "options": "\nGrand Total\nNet Total", - "show_days": 1, - "show_seconds": 1 + "options": "\nGrand Total\nNet Total" }, { "fieldname": "cb_2", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "additional_discount_percentage", "fieldtype": "Percent", - "label": "Additional DIscount Percentage", - "show_days": 1, - "show_seconds": 1 + "label": "Additional DIscount Percentage" }, { "collapsible": 1, "fieldname": "additional_discount_amount", "fieldtype": "Currency", - "label": "Additional DIscount Amount", - "show_days": 1, - "show_seconds": 1 + "label": "Additional DIscount Amount" }, { "depends_on": "eval:doc.invoices", "fieldname": "sb_3", "fieldtype": "Section Break", - "label": "Invoices", - "show_days": 1, - "show_seconds": 1 + "label": "Invoices" }, { "collapsible": 1, "fieldname": "invoices", "fieldtype": "Table", "label": "Invoices", - "options": "Subscription Invoice", - "show_days": 1, - "show_seconds": 1 + "options": "Subscription Invoice" }, { "collapsible": 1, "fieldname": "accounting_dimensions_section", "fieldtype": "Section Break", - "label": "Accounting Dimensions", - "show_days": 1, - "show_seconds": 1 + "label": "Accounting Dimensions" }, { "fieldname": "dimension_col_break", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "party_type", @@ -238,9 +191,7 @@ "label": "Party Type", "options": "DocType", "reqd": 1, - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "fieldname": "party", @@ -249,27 +200,21 @@ "label": "Party", "options": "party_type", "reqd": 1, - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "depends_on": "eval:doc.party_type === 'Customer'", "fieldname": "sales_tax_template", "fieldtype": "Link", "label": "Sales Taxes and Charges Template", - "options": "Sales Taxes and Charges Template", - "show_days": 1, - "show_seconds": 1 + "options": "Sales Taxes and Charges Template" }, { "depends_on": "eval:doc.party_type === 'Supplier'", "fieldname": "purchase_tax_template", "fieldtype": "Link", "label": "Purchase Taxes and Charges Template", - "options": "Purchase Taxes and Charges Template", - "show_days": 1, - "show_seconds": 1 + "options": "Purchase Taxes and Charges Template" }, { "default": "0", @@ -277,55 +222,49 @@ "fieldname": "follow_calendar_months", "fieldtype": "Check", "label": "Follow Calendar Months", - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "default": "0", "description": "New invoices will be generated as per schedule even if current invoices are unpaid or past due date", "fieldname": "generate_new_invoices_past_due_date", "fieldtype": "Check", - "label": "Generate New Invoices Past Due Date", - "show_days": 1, - "show_seconds": 1 + "label": "Generate New Invoices Past Due Date" }, { "fieldname": "end_date", "fieldtype": "Date", "label": "Subscription End Date", - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "fieldname": "start_date", "fieldtype": "Date", "label": "Subscription Start Date", - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "fieldname": "cost_center", "fieldtype": "Link", "label": "Cost Center", - "options": "Cost Center", - "show_days": 1, - "show_seconds": 1 + "options": "Cost Center" }, { "fieldname": "company", "fieldtype": "Link", "label": "Company", - "options": "Company", - "show_days": 1, - "show_seconds": 1 + "options": "Company" + }, + { + "default": "1", + "fieldname": "submit_invoice", + "fieldtype": "Check", + "label": "Submit Invoice Automatically" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-02-09 15:44:20.024789", + "modified": "2021-04-19 15:24:27.550797", "modified_by": "Administrator", "module": "Accounts", "name": "Subscription", diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index 826044a4075..f19bae7465c 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -383,7 +383,9 @@ class Subscription(Document): invoice.flags.ignore_mandatory = True invoice.save() - invoice.submit() + + if self.submit_invoice == 1: + invoice.submit() return invoice From 66250351d2e8cd6aa6d02b81bc3e1540243fdd60 Mon Sep 17 00:00:00 2001 From: Ernesto Ruiz Date: Tue, 20 Apr 2021 14:35:14 -0600 Subject: [PATCH 03/27] fix: Add transtlation function to strings Add transtlation function to strings --- erpnext/payroll/doctype/salary_structure/salary_structure.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.js b/erpnext/payroll/doctype/salary_structure/salary_structure.js index e00bd870848..44368a69fb2 100755 --- a/erpnext/payroll/doctype/salary_structure/salary_structure.js +++ b/erpnext/payroll/doctype/salary_structure/salary_structure.js @@ -16,11 +16,11 @@ frappe.ui.form.on('Salary Structure', { onload: function(frm) { let help_button = $(` - Condition and Formula Help + ${__(Condition and Formula Help)} `).click(()=>{ let d = new frappe.ui.Dialog({ - title: 'Condition and Formula Help', + title: __('Condition and Formula Help'), fields: [ { fieldname: 'msg_wrapper', From 090177494dbc4bd6477c7783ee5eaa6113726658 Mon Sep 17 00:00:00 2001 From: Ernesto Ruiz Date: Wed, 21 Apr 2021 09:04:06 -0600 Subject: [PATCH 04/27] fix: Make strings translatable Make strings translatable --- .../projects/report/project_summary/project_summary.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/projects/report/project_summary/project_summary.py b/erpnext/projects/report/project_summary/project_summary.py index ea7f1ab2e77..2c7bb49cfba 100644 --- a/erpnext/projects/report/project_summary/project_summary.py +++ b/erpnext/projects/report/project_summary/project_summary.py @@ -131,25 +131,25 @@ def get_report_summary(data): { "value": avg_completion, "indicator": "Green" if avg_completion > 50 else "Red", - "label": "Average Completion", + "label": _("Average Completion"), "datatype": "Percent", }, { "value": total, "indicator": "Blue", - "label": "Total Tasks", + "label": _("Total Tasks"), "datatype": "Int", }, { "value": completed, "indicator": "Green", - "label": "Completed Tasks", + "label": _("Completed Tasks"), "datatype": "Int", }, { "value": total_overdue, "indicator": "Green" if total_overdue == 0 else "Red", - "label": "Overdue Tasks", + "label": _("Overdue Tasks"), "datatype": "Int", } ] From b0e160ff7838442270d6918ef1aa4a6668e3b7f4 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Thu, 22 Apr 2021 13:23:50 +0530 Subject: [PATCH 05/27] fix: ignore fraction difference while making round off gl entry --- erpnext/accounts/general_ledger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index dac0c216c8a..f18de020fc4 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -170,11 +170,11 @@ def round_off_debit_credit(gl_map): else: allowance = .5 - if abs(debit_credit_diff) >= allowance: + if abs(debit_credit_diff) > allowance: frappe.throw(_("Debit and Credit not equal for {0} #{1}. Difference is {2}.") .format(gl_map[0].voucher_type, gl_map[0].voucher_no, debit_credit_diff)) - elif abs(debit_credit_diff) >= (1.0 / (10**precision)): + elif abs(debit_credit_diff) > (1.0 / (10**precision)): make_round_off_gle(gl_map, debit_credit_diff, precision) def make_round_off_gle(gl_map, debit_credit_diff, precision): From 8787ebf83d7a3ca217e130d8c8eec62d36410a3e Mon Sep 17 00:00:00 2001 From: meike289 <63092915+meike289@users.noreply.github.com> Date: Fri, 23 Apr 2021 08:06:29 +0200 Subject: [PATCH 06/27] Apply suggestions from code review Co-authored-by: Ankush Menat --- erpnext/accounts/doctype/subscription/subscription.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index f19bae7465c..175710c9f8a 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -384,7 +384,7 @@ class Subscription(Document): invoice.flags.ignore_mandatory = True invoice.save() - if self.submit_invoice == 1: + if self.submit_invoice: invoice.submit() return invoice From d552fe6778f71e940f4acdb594afcf79fe5757c2 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Fri, 23 Apr 2021 14:46:52 +0530 Subject: [PATCH 07/27] feat: base payment amount in payment schedule --- .../payment_schedule/payment_schedule.json | 36 +++++++++++-- .../purchase_invoice/test_purchase_invoice.py | 2 +- erpnext/controllers/accounts_controller.py | 53 ++++++++++++------- erpnext/public/js/controllers/transaction.js | 5 +- 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json index 39eda331db7..e9f8ba29dc6 100644 --- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json +++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json @@ -20,10 +20,13 @@ "discount", "section_break_9", "payment_amount", + "outstanding", + "paid_amount", "discounted_amount", "column_break_3", - "outstanding", - "paid_amount" + "base_payment_amount", + "base_outstanding", + "base_paid_amount" ], "fields": [ { @@ -65,6 +68,7 @@ "fieldtype": "Currency", "in_list_view": 1, "label": "Payment Amount", + "options": "currency", "reqd": 1 }, { @@ -77,7 +81,8 @@ "depends_on": "paid_amount", "fieldname": "paid_amount", "fieldtype": "Currency", - "label": "Paid Amount" + "label": "Paid Amount", + "options": "currency" }, { "fieldname": "column_break_3", @@ -96,6 +101,7 @@ "fieldname": "outstanding", "fieldtype": "Currency", "label": "Outstanding", + "options": "currency", "read_only": 1 }, { @@ -144,12 +150,34 @@ { "fieldname": "section_break_4", "fieldtype": "Section Break" + }, + { + "fieldname": "base_payment_amount", + "fieldtype": "Currency", + "label": "Payment Amount (Company Currency)", + "options": "Company:company:default_currency" + }, + { + "default": "0", + "fieldname": "base_outstanding", + "fieldtype": "Currency", + "label": "Outstanding (Company Currency)", + "options": "Company:company:default_currency", + "read_only": 1 + }, + { + "default": "0", + "fieldname": "base_paid_amount", + "fieldtype": "Currency", + "label": "Paid Amount (Company Currency)", + "options": "Company:company:default_currency", + "read_only": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-04-12 15:39:47.363609", + "modified": "2021-04-23 13:55:59.548043", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Schedule", diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 50492f50b51..66be11ff231 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -397,7 +397,7 @@ class TestPurchaseInvoice(unittest.TestCase): pi.update({ "payment_schedule": get_payment_terms("_Test Payment Term Template", - pi.posting_date, pi.grand_total) + pi.posting_date, pi.grand_total, pi.base_grand_total) }) pi.save() diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index d36e7b03f40..c51d8283e5e 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -904,20 +904,24 @@ class AccountsController(TransactionBase): date = self.get("due_date") due_date = date or posting_date - if party_account_currency == self.company_currency: - grand_total = self.get("base_rounded_total") or self.base_grand_total - else: - grand_total = self.get("rounded_total") or self.grand_total + base_grand_total = self.get("base_rounded_total") or self.base_grand_total + grand_total = self.get("rounded_total") or self.grand_total if self.doctype in ("Sales Invoice", "Purchase Invoice"): + base_grand_total = base_grand_total - flt(self.base_write_off_amount) grand_total = grand_total - flt(self.write_off_amount) if self.get("total_advance"): - grand_total -= self.get("total_advance") + if party_account_currency == self.company_currency: + base_grand_total -= self.get("total_advance") + grand_total = flt(base_grand_total / self.get("conversion_rate"), self.precision("grand_total")) + else: + grand_total -= self.get("total_advance") + base_grand_total = flt(grand_total * self.get("conversion_rate"), self.precision("base_grand_total")) if not self.get("payment_schedule"): if self.get("payment_terms_template"): - data = get_payment_terms(self.payment_terms_template, posting_date, grand_total) + data = get_payment_terms(self.payment_terms_template, posting_date, grand_total, base_grand_total) for item in data: self.append("payment_schedule", item) else: @@ -927,7 +931,9 @@ class AccountsController(TransactionBase): for d in self.get("payment_schedule"): if d.invoice_portion: d.payment_amount = flt(grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount')) + d.base_payment_amount = flt(base_grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount')) d.outstanding = d.payment_amount + d.base_outstanding = d.base_payment_amount def set_due_date(self): due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date] @@ -963,22 +969,28 @@ class AccountsController(TransactionBase): if self.get("payment_schedule"): total = 0 + base_total = 0 for d in self.get("payment_schedule"): total += flt(d.payment_amount) + base_total += flt(d.base_payment_amount) - if party_account_currency == self.company_currency: - total = flt(total, self.precision("base_grand_total")) - grand_total = flt(self.get("base_rounded_total") or self.base_grand_total, self.precision('base_grand_total')) - else: - total = flt(total, self.precision("grand_total")) - grand_total = flt(self.get("rounded_total") or self.grand_total, self.precision('grand_total')) - - if self.get("total_advance"): - grand_total -= self.get("total_advance") + base_grand_total = self.get("base_rounded_total") or self.base_grand_total + grand_total = self.get("rounded_total") or self.grand_total if self.doctype in ("Sales Invoice", "Purchase Invoice"): + base_grand_total = base_grand_total - flt(self.base_write_off_amount) grand_total = grand_total - flt(self.write_off_amount) - if total != flt(grand_total, self.precision("grand_total")): + + if self.get("total_advance"): + if party_account_currency == self.company_currency: + base_grand_total -= self.get("total_advance") + grand_total = flt(base_grand_total / self.get("conversion_rate"), self.precision("grand_total")) + else: + grand_total -= self.get("total_advance") + base_grand_total = flt(grand_total * self.get("conversion_rate"), self.precision("base_grand_total")) + + if total != flt(grand_total, self.precision("grand_total")) or \ + base_total != flt(base_grand_total, self.precision("base_grand_total")): frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total")) def is_rounded_total_disabled(self): @@ -1218,7 +1230,7 @@ def update_invoice_status(): @frappe.whitelist() -def get_payment_terms(terms_template, posting_date=None, grand_total=None, bill_date=None): +def get_payment_terms(terms_template, posting_date=None, grand_total=None, base_grand_total=None, bill_date=None): if not terms_template: return @@ -1226,14 +1238,14 @@ def get_payment_terms(terms_template, posting_date=None, grand_total=None, bill_ schedule = [] for d in terms_doc.get("terms"): - term_details = get_payment_term_details(d, posting_date, grand_total, bill_date) + term_details = get_payment_term_details(d, posting_date, grand_total, base_grand_total, bill_date) schedule.append(term_details) return schedule @frappe.whitelist() -def get_payment_term_details(term, posting_date=None, grand_total=None, bill_date=None): +def get_payment_term_details(term, posting_date=None, grand_total=None, base_grand_total=None, bill_date=None): term_details = frappe._dict() if isinstance(term, text_type): term = frappe.get_doc("Payment Term", term) @@ -1242,10 +1254,11 @@ def get_payment_term_details(term, posting_date=None, grand_total=None, bill_dat term_details.description = term.description term_details.invoice_portion = term.invoice_portion term_details.payment_amount = flt(term.invoice_portion) * flt(grand_total) / 100 + term_details.base_payment_amount = flt(term.invoice_portion) * flt(base_grand_total) / 100 term_details.discount_type = term.discount_type term_details.discount = term.discount - # term_details.discounted_amount = flt(grand_total) * (term.discount / 100) if term.discount_type == 'Percentage' else discount term_details.outstanding = term_details.payment_amount + term_details.base_outstanding = term_details.base_payment_amount term_details.mode_of_payment = term.mode_of_payment if bill_date: diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index a0398e718f0..258262aed37 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1995,6 +1995,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ terms_template: doc.payment_terms_template, posting_date: posting_date, grand_total: doc.rounded_total || doc.grand_total, + base_grand_total: doc.base_rounded_total || doc.base_grand_total, bill_date: doc.bill_date }, callback: function(r) { @@ -2009,13 +2010,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ payment_term: function(doc, cdt, cdn) { var row = locals[cdt][cdn]; if(row.payment_term) { + debugger; frappe.call({ method: "erpnext.controllers.accounts_controller.get_payment_term_details", args: { term: row.payment_term, bill_date: this.frm.doc.bill_date, posting_date: this.frm.doc.posting_date || this.frm.doc.transaction_date, - grand_total: this.frm.doc.rounded_total || this.frm.doc.grand_total + grand_total: this.frm.doc.rounded_total || this.frm.doc.grand_total, + base_grand_total: this.frm.doc.base_rounded_total || this.frm.doc.base_grand_total }, callback: function(r) { if(r.message && !r.exc) { From c5c9f9a9416250d8ed4fe72d9b738ba586aa54b4 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Fri, 23 Apr 2021 15:34:58 +0530 Subject: [PATCH 08/27] feat: set dynamic labels for payment schedule fields --- erpnext/public/js/controllers/transaction.js | 54 +++++++++++++++++--- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 258262aed37..dc731ca2133 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -640,6 +640,10 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ let key = item.name; me.apply_rule_on_other_items({key: item}); } + }, + () => { + var company_currency = me.get_company_currency(); + me.update_item_grid_labels(company_currency); } ]); } @@ -1321,11 +1325,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ change_grid_labels: function(company_currency) { var me = this; - this.frm.set_currency_labels(["base_rate", "base_net_rate", "base_price_list_rate", "base_amount", "base_net_amount", "base_rate_with_margin"], - company_currency, "items"); + this.update_item_grid_labels(company_currency); - this.frm.set_currency_labels(["rate", "net_rate", "price_list_rate", "amount", "net_amount", "stock_uom_rate", "rate_with_margin"], - this.frm.doc.currency, "items"); + this.toggle_item_grid_columns(company_currency); if(this.frm.fields_dict["operations"]) { this.frm.set_currency_labels(["operating_cost", "hour_rate"], this.frm.doc.currency, "operations"); @@ -1360,6 +1362,42 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ this.frm.doc.party_account_currency, "advances"); } + this.update_payment_schedule_grid_labels(company_currency); + + // set labels + var $wrapper = $(this.frm.wrapper); + }, + + update_item_grid_labels: function(company_currency) { + this.frm.set_currency_labels([ + "base_rate", "base_net_rate", "base_price_list_rate", + "base_amount", "base_net_amount", "base_rate_with_margin" + ], company_currency, "items"); + + this.frm.set_currency_labels([ + "rate", "net_rate", "price_list_rate", "amount", + "net_amount", "stock_uom_rate", "rate_with_margin" + ], this.frm.doc.currency, "items"); + }, + + update_payment_schedule_grid_labels: function(company_currency) { + const me = this; + if(this.frm.fields_dict["payment_schedule"]) { + this.frm.set_currency_labels(["base_payment_amount", "base_outstanding", "base_paid_amount"], + company_currency, "payment_schedule"); + this.frm.set_currency_labels(["payment_amount", "outstanding", "paid_amount"], + this.frm.doc.currency, "payment_schedule"); + + var schedule_grid = this.frm.fields_dict["payment_schedule"].grid; + $.each(["base_payment_amount", "base_outstanding", "base_paid_amount"], function(i, fname) { + if(frappe.meta.get_docfield(schedule_grid.doctype, fname)) + schedule_grid.set_column_disp(fname, me.frm.doc.currency != company_currency); + }); + } + }, + + toggle_item_grid_columns: function(company_currency) { + const me = this; // toggle columns var item_grid = this.frm.fields_dict["items"].grid; $.each(["base_rate", "base_price_list_rate", "base_amount", "base_rate_with_margin"], function(i, fname) { @@ -1379,9 +1417,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ if(frappe.meta.get_docfield(item_grid.doctype, fname)) item_grid.set_column_disp(fname, (show && (me.frm.doc.currency != company_currency))); }); - - // set labels - var $wrapper = $(this.frm.wrapper); }, recalculate: function() { @@ -2001,6 +2036,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ callback: function(r) { if(r.message && !r.exc) { me.frm.set_value("payment_schedule", r.message); + const company_currency = me.get_company_currency(); + this.update_payment_schedule_grid_labels(company_currency); } } }) @@ -2010,7 +2047,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ payment_term: function(doc, cdt, cdn) { var row = locals[cdt][cdn]; if(row.payment_term) { - debugger; frappe.call({ method: "erpnext.controllers.accounts_controller.get_payment_term_details", args: { @@ -2024,6 +2060,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ if(r.message && !r.exc) { for (var d in r.message) { frappe.model.set_value(cdt, cdn, d, r.message[d]); + const company_currency = me.get_company_currency(); + this.update_payment_schedule_grid_labels(company_currency); } } } From 8a1e5e189ca0705ed85db27f9665ac34e066cea3 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 27 Apr 2021 16:57:34 +0530 Subject: [PATCH 09/27] fix: Ageing errors in PSOA --- .../process_statement_of_accounts.html | 12 ++++++------ .../process_statement_of_accounts.py | 13 +++++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html index b6238988295..f61aacbce27 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html @@ -60,8 +60,8 @@

-{% if aging %} -

{{ _("Ageing Report Based On ") }} {{ aging.ageing_based_on }}

+{% if ageing %} +

{{ _("Ageing Report Based On ") }} {{ ageing.ageing_based_on }}

{{ _("Up to " ) }} {{ frappe.format(filters.to_date, 'Date')}}
@@ -78,10 +78,10 @@ - {{ frappe.utils.fmt_money(aging.range1, currency=filters.presentation_currency) }} - {{ frappe.utils.fmt_money(aging.range2, currency=filters.presentation_currency) }} - {{ frappe.utils.fmt_money(aging.range3, currency=filters.presentation_currency) }} - {{ frappe.utils.fmt_money(aging.range4, currency=filters.presentation_currency) }} + {{ frappe.utils.fmt_money(ageing.range1, currency=filters.presentation_currency) }} + {{ frappe.utils.fmt_money(ageing.range2, currency=filters.presentation_currency) }} + {{ frappe.utils.fmt_money(ageing.range3, currency=filters.presentation_currency) }} + {{ frappe.utils.fmt_money(ageing.range4, currency=filters.presentation_currency) }} diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py index b6149e89f5f..62090c02556 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py @@ -40,7 +40,7 @@ class ProcessStatementOfAccounts(Document): def get_report_pdf(doc, consolidated=True): statement_dict = {} - aging = '' + ageing = '' base_template_path = "frappe/www/printview.html" template_path = "erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html" @@ -56,8 +56,10 @@ def get_report_pdf(doc, consolidated=True): 'range4': 120, 'customer': entry.customer }) - col1, aging = get_ageing(ageing_filters) - aging[0]['ageing_based_on'] = doc.ageing_based_on + col1, ageing = get_ageing(ageing_filters) + + if ageing: + ageing[0]['ageing_based_on'] = doc.ageing_based_on tax_id = frappe.get_doc('Customer', entry.customer).tax_id presentation_currency = get_party_account_currency('Customer', entry.customer, doc.company) \ @@ -87,11 +89,14 @@ def get_report_pdf(doc, consolidated=True): if len(res) == 3: continue + html = frappe.render_template(template_path, \ - {"filters": filters, "data": res, "aging": aging[0] if doc.include_ageing else None}) + {"filters": filters, "data": res, "ageing": ageing[0] if (doc.include_ageing and ageing) else None}) + html = frappe.render_template(base_template_path, {"body": html, \ "css": get_print_style(), "title": "Statement For " + entry.customer}) statement_dict[entry.customer] = html + if not bool(statement_dict): return False elif consolidated: From ad4365eb0eb4583333243c5c7a18995e736ec0d0 Mon Sep 17 00:00:00 2001 From: Saqib Date: Tue, 27 Apr 2021 20:00:21 +0530 Subject: [PATCH 10/27] fix: unexpected keyword argument 'merge_logs' (#25489) * fix: unexpected keyword arguement 'merge_logs' * fix: reference error * fix: test --- .../pos_invoice_merge_log.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py index 6d2cffcf685..4d5472df4b4 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py @@ -235,11 +235,11 @@ def get_invoice_customer_map(pos_invoices): return pos_invoice_customer_map -def consolidate_pos_invoices(pos_invoices=[], closing_entry={}): - invoices = pos_invoices or closing_entry.get('pos_transactions') or get_all_unconsolidated_invoices() +def consolidate_pos_invoices(pos_invoices=None, closing_entry=None): + invoices = pos_invoices or (closing_entry and closing_entry.get('pos_transactions')) or get_all_unconsolidated_invoices() invoice_by_customer = get_invoice_customer_map(invoices) - if len(invoices) >= 5 and closing_entry: + if len(invoices) >= 1 and closing_entry: closing_entry.set_status(update=True, status='Queued') enqueue_job(create_merge_logs, invoice_by_customer=invoice_by_customer, closing_entry=closing_entry) else: @@ -252,18 +252,18 @@ def unconsolidate_pos_invoices(closing_entry): pluck='name' ) - if len(merge_logs) >= 5: + if len(merge_logs) >= 1: closing_entry.set_status(update=True, status='Queued') enqueue_job(cancel_merge_logs, merge_logs=merge_logs, closing_entry=closing_entry) else: cancel_merge_logs(merge_logs, closing_entry) -def create_merge_logs(invoice_by_customer, closing_entry={}): +def create_merge_logs(invoice_by_customer, closing_entry=None): for customer, invoices in iteritems(invoice_by_customer): merge_log = frappe.new_doc('POS Invoice Merge Log') - merge_log.posting_date = getdate(closing_entry.get('posting_date')) + merge_log.posting_date = getdate(closing_entry.get('posting_date')) if closing_entry else nowdate() merge_log.customer = customer - merge_log.pos_closing_entry = closing_entry.get('name', None) + merge_log.pos_closing_entry = closing_entry.get('name') if closing_entry else None merge_log.set('pos_invoices', invoices) merge_log.save(ignore_permissions=True) @@ -273,7 +273,7 @@ def create_merge_logs(invoice_by_customer, closing_entry={}): closing_entry.set_status(update=True, status='Submitted') closing_entry.update_opening_entry() -def cancel_merge_logs(merge_logs, closing_entry={}): +def cancel_merge_logs(merge_logs, closing_entry=None): for log in merge_logs: merge_log = frappe.get_doc('POS Invoice Merge Log', log) merge_log.flags.ignore_permissions = True @@ -283,20 +283,20 @@ def cancel_merge_logs(merge_logs, closing_entry={}): closing_entry.set_status(update=True, status='Cancelled') closing_entry.update_opening_entry(for_cancel=True) -def enqueue_job(job, merge_logs=None, invoice_by_customer=None, closing_entry=None): +def enqueue_job(job, **kwargs): check_scheduler_status() + closing_entry = kwargs.get('closing_entry') or {} + job_name = closing_entry.get("name") if not job_already_enqueued(job_name): enqueue( job, + **kwargs, queue="long", timeout=10000, event="processing_merge_logs", job_name=job_name, - closing_entry=closing_entry, - invoice_by_customer=invoice_by_customer, - merge_logs=merge_logs, now=frappe.conf.developer_mode or frappe.flags.in_test ) From 7b3dd3585b5f2371254a02fe2ae713a23bdc9871 Mon Sep 17 00:00:00 2001 From: Saqib Date: Tue, 27 Apr 2021 20:00:21 +0530 Subject: [PATCH 11/27] fix: unexpected keyword argument 'merge_logs' (#25489) * fix: unexpected keyword arguement 'merge_logs' * fix: reference error * fix: test --- .../pos_invoice_merge_log.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py index 6d2cffcf685..4d5472df4b4 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py @@ -235,11 +235,11 @@ def get_invoice_customer_map(pos_invoices): return pos_invoice_customer_map -def consolidate_pos_invoices(pos_invoices=[], closing_entry={}): - invoices = pos_invoices or closing_entry.get('pos_transactions') or get_all_unconsolidated_invoices() +def consolidate_pos_invoices(pos_invoices=None, closing_entry=None): + invoices = pos_invoices or (closing_entry and closing_entry.get('pos_transactions')) or get_all_unconsolidated_invoices() invoice_by_customer = get_invoice_customer_map(invoices) - if len(invoices) >= 5 and closing_entry: + if len(invoices) >= 1 and closing_entry: closing_entry.set_status(update=True, status='Queued') enqueue_job(create_merge_logs, invoice_by_customer=invoice_by_customer, closing_entry=closing_entry) else: @@ -252,18 +252,18 @@ def unconsolidate_pos_invoices(closing_entry): pluck='name' ) - if len(merge_logs) >= 5: + if len(merge_logs) >= 1: closing_entry.set_status(update=True, status='Queued') enqueue_job(cancel_merge_logs, merge_logs=merge_logs, closing_entry=closing_entry) else: cancel_merge_logs(merge_logs, closing_entry) -def create_merge_logs(invoice_by_customer, closing_entry={}): +def create_merge_logs(invoice_by_customer, closing_entry=None): for customer, invoices in iteritems(invoice_by_customer): merge_log = frappe.new_doc('POS Invoice Merge Log') - merge_log.posting_date = getdate(closing_entry.get('posting_date')) + merge_log.posting_date = getdate(closing_entry.get('posting_date')) if closing_entry else nowdate() merge_log.customer = customer - merge_log.pos_closing_entry = closing_entry.get('name', None) + merge_log.pos_closing_entry = closing_entry.get('name') if closing_entry else None merge_log.set('pos_invoices', invoices) merge_log.save(ignore_permissions=True) @@ -273,7 +273,7 @@ def create_merge_logs(invoice_by_customer, closing_entry={}): closing_entry.set_status(update=True, status='Submitted') closing_entry.update_opening_entry() -def cancel_merge_logs(merge_logs, closing_entry={}): +def cancel_merge_logs(merge_logs, closing_entry=None): for log in merge_logs: merge_log = frappe.get_doc('POS Invoice Merge Log', log) merge_log.flags.ignore_permissions = True @@ -283,20 +283,20 @@ def cancel_merge_logs(merge_logs, closing_entry={}): closing_entry.set_status(update=True, status='Cancelled') closing_entry.update_opening_entry(for_cancel=True) -def enqueue_job(job, merge_logs=None, invoice_by_customer=None, closing_entry=None): +def enqueue_job(job, **kwargs): check_scheduler_status() + closing_entry = kwargs.get('closing_entry') or {} + job_name = closing_entry.get("name") if not job_already_enqueued(job_name): enqueue( job, + **kwargs, queue="long", timeout=10000, event="processing_merge_logs", job_name=job_name, - closing_entry=closing_entry, - invoice_by_customer=invoice_by_customer, - merge_logs=merge_logs, now=frappe.conf.developer_mode or frappe.flags.in_test ) From a86a51f0207cdd9480d84cbebea3abd93a60f435 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 23 Apr 2021 20:03:50 +0530 Subject: [PATCH 12/27] fix(HR): Permission error while adding weekly holidays (#25450) --- erpnext/hr/doctype/holiday_list/holiday_list.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/hr/doctype/holiday_list/holiday_list.py b/erpnext/hr/doctype/holiday_list/holiday_list.py index 6df7bc88c02..67630a0abe6 100644 --- a/erpnext/hr/doctype/holiday_list/holiday_list.py +++ b/erpnext/hr/doctype/holiday_list/holiday_list.py @@ -16,6 +16,7 @@ class HolidayList(Document): self.validate_days() self.total_holidays = len(self.holidays) + @frappe.whitelist() def get_weekly_off_dates(self): self.validate_values() date_list = self.get_weekly_off_date_list(self.from_date, self.to_date) From 3e5c6424ed4f15c16be0f909f0cf110879fa50d5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 27 Apr 2021 20:28:01 +0550 Subject: [PATCH 13/27] bumped to version 13.1.1 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 4da06053707..ea83d08bf2b 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '13.1.0' +__version__ = '13.1.1' def get_default_company(user=None): '''Get default company for user''' From c9187b00af2d13ec3f5c1a696e66c74346778fa0 Mon Sep 17 00:00:00 2001 From: Mohammad Hasnain Mohsin Rajan Date: Wed, 28 Apr 2021 13:32:27 +0530 Subject: [PATCH 14/27] fix: change coveralls version (#25499) --- .github/workflows/ci-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 824b74e0135..4103bc68a91 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -85,8 +85,8 @@ jobs: run: | cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE} cd ${GITHUB_WORKSPACE} - pip install coveralls==3.0.1 - pip install coverage==5.5 + pip install coveralls==2.2.0 + pip install coverage==4.5.4 coveralls --service=github env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From aa4f750d8c9eae6cdf3d4b853ed3de3e08a5f38e Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Wed, 28 Apr 2021 14:42:49 +0530 Subject: [PATCH 15/27] fix: test --- erpnext/accounts/general_ledger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 4c285ff0884..f1717c50d8d 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -175,7 +175,7 @@ def round_off_debit_credit(gl_map): frappe.throw(_("Debit and Credit not equal for {0} #{1}. Difference is {2}.") .format(gl_map[0].voucher_type, gl_map[0].voucher_no, debit_credit_diff)) - elif abs(debit_credit_diff) > (1.0 / (10**precision)): + elif abs(debit_credit_diff) >= (1.0 / (10**precision)): make_round_off_gle(gl_map, debit_credit_diff, precision) def make_round_off_gle(gl_map, debit_credit_diff, precision): From da5b55c4f5fa89770ace9a400f7523d0e83550d0 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Wed, 28 Apr 2021 14:55:33 +0530 Subject: [PATCH 16/27] fix: test --- erpnext/controllers/accounts_controller.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index d7f89b62702..a61292491cf 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -944,7 +944,7 @@ class AccountsController(TransactionBase): for item in data: self.append("payment_schedule", item) else: - data = dict(due_date=due_date, invoice_portion=100, payment_amount=grand_total) + data = dict(due_date=due_date, invoice_portion=100, payment_amount=grand_total, base_payment_amount=base_grand_total) self.append("payment_schedule", data) else: for d in self.get("payment_schedule"): @@ -1007,7 +1007,8 @@ class AccountsController(TransactionBase): else: grand_total -= self.get("total_advance") base_grand_total = flt(grand_total * self.get("conversion_rate"), self.precision("base_grand_total")) - + print(total, base_total) + print(grand_total, base_grand_total) if total != flt(grand_total, self.precision("grand_total")) or \ base_total != flt(base_grand_total, self.precision("base_grand_total")): frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total")) From 44b07e4ef590d5f8a41b14c75291b86e251faeec Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Wed, 28 Apr 2021 15:11:57 +0530 Subject: [PATCH 17/27] refactor: remove extra fields --- .../payment_schedule/payment_schedule.json | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json index e9f8ba29dc6..6ed7a3154e5 100644 --- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json +++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json @@ -24,9 +24,7 @@ "paid_amount", "discounted_amount", "column_break_3", - "base_payment_amount", - "base_outstanding", - "base_paid_amount" + "base_payment_amount" ], "fields": [ { @@ -156,28 +154,12 @@ "fieldtype": "Currency", "label": "Payment Amount (Company Currency)", "options": "Company:company:default_currency" - }, - { - "default": "0", - "fieldname": "base_outstanding", - "fieldtype": "Currency", - "label": "Outstanding (Company Currency)", - "options": "Company:company:default_currency", - "read_only": 1 - }, - { - "default": "0", - "fieldname": "base_paid_amount", - "fieldtype": "Currency", - "label": "Paid Amount (Company Currency)", - "options": "Company:company:default_currency", - "read_only": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-04-23 13:55:59.548043", + "modified": "2021-04-28 05:41:35.084233", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Schedule", From a949480acf0e124e013dd0a936412b5593df7fe6 Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Wed, 28 Apr 2021 12:38:23 +0200 Subject: [PATCH 18/27] fix: add translation to make semgrep pass --- erpnext/accounts/doctype/subscription/subscription.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index 175710c9f8a..7c4ff73d908 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -276,7 +276,7 @@ class Subscription(Document): frappe.throw(_('Subscription End Date is mandatory to follow calendar months')) if billing_info[0]['billing_interval'] != 'Month': - frappe.throw('Billing Interval in Subscription Plan must be Month to follow calendar months') + frappe.throw(_('Billing Interval in Subscription Plan must be Month to follow calendar months')) def after_insert(self): # todo: deal with users who collect prepayments. Maybe a new Subscription Invoice doctype? From 64a38f52cf72a56568876bcc376e69aec3680007 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 28 Apr 2021 13:46:47 +0530 Subject: [PATCH 19/27] chore: remove frappe from requirements.txt Due to recent changes in pip dependency resolver, in some random cases pip thinks frappe is not installed and tries to fetch it from pypi, which results in errors like #25496 Until a better solution is available, frappe should not be part of requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 377fd7df6ca..f1ffeb8f481 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -frappe +# frappe # https://github.com/frappe/frappe is installed during bench-init gocardless-pro~=1.22.0 googlemaps # used in ERPNext, but dependency is defined in Frappe pandas~=1.1.5 From ab052599c055789a5519c10cdd1567c4a86c78c4 Mon Sep 17 00:00:00 2001 From: Afshan Date: Wed, 28 Apr 2021 20:21:04 +0530 Subject: [PATCH 20/27] fix: allow to cancel loan with cancelled replayment entry --- erpnext/loan_management/doctype/loan/loan.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/loan_management/doctype/loan/loan.py b/erpnext/loan_management/doctype/loan/loan.py index 83a813f947b..20b44a15e34 100644 --- a/erpnext/loan_management/doctype/loan/loan.py +++ b/erpnext/loan_management/doctype/loan/loan.py @@ -44,6 +44,7 @@ class Loan(AccountsController): def on_cancel(self): self.unlink_loan_security_pledge() + self.ignore_linked_doctypes = ['GL Entry'] def set_missing_fields(self): if not self.company: @@ -359,4 +360,4 @@ def get_shortfall_applicants(): return { "value": len(applicants), "fieldtype": "Int" - } \ No newline at end of file + } From dc086dd52ffa6a06afbc965587f2a9c0f34f7edf Mon Sep 17 00:00:00 2001 From: Noah Jacob Date: Thu, 29 Apr 2021 11:03:27 +0530 Subject: [PATCH 21/27] fix: item stock levels displaying inconsistently (#25506) * fix: fixed stock levels dashboard not displaying after any interactions * fix: minor translation fix --- erpnext/stock/doctype/item/item.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 2079cf88dd9..8aec89381a1 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -46,9 +46,6 @@ frappe.ui.form.on("Item", { }, __("View")); } - if (!frm.doc.is_fixed_asset) { - erpnext.item.make_dashboard(frm); - } if (frm.doc.is_fixed_asset) { frm.trigger('is_fixed_asset'); @@ -96,6 +93,10 @@ frappe.ui.form.on("Item", { erpnext.item.edit_prices_button(frm); erpnext.item.toggle_attributes(frm); + + if (!frm.doc.is_fixed_asset) { + erpnext.item.make_dashboard(frm); + } frm.add_custom_button(__('Duplicate'), function() { var new_item = frappe.model.copy_doc(frm.doc); @@ -473,11 +474,15 @@ $.extend(erpnext.item, { me.multiple_variant_dialog.get_primary_btn().html(__('Create Variants')); me.multiple_variant_dialog.disable_primary_action(); } else { + let no_of_combinations = lengths.reduce((a, b) => a * b, 1); - me.multiple_variant_dialog.get_primary_btn() - .html(__( - `Make ${no_of_combinations} Variant${no_of_combinations === 1 ? '' : 's'}` - )); + let msg; + if (no_of_combinations === 1) { + msg = __("Make {0} Variant", [no_of_combinations]); + } else { + msg = __("Make {0} Variants", [no_of_combinations]); + } + me.multiple_variant_dialog.get_primary_btn().html(msg); me.multiple_variant_dialog.enable_primary_action(); } } From 83e3820575a2706f7b6ca8b150e0455df716a9cb Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 29 Apr 2021 12:21:56 +0530 Subject: [PATCH 22/27] fix: remove print statement --- erpnext/controllers/accounts_controller.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index a61292491cf..c409850734c 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -952,7 +952,6 @@ class AccountsController(TransactionBase): d.payment_amount = flt(grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount')) d.base_payment_amount = flt(base_grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount')) d.outstanding = d.payment_amount - d.base_outstanding = d.base_payment_amount def set_due_date(self): due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date] @@ -1007,7 +1006,6 @@ class AccountsController(TransactionBase): else: grand_total -= self.get("total_advance") base_grand_total = flt(grand_total * self.get("conversion_rate"), self.precision("base_grand_total")) - print(total, base_total) print(grand_total, base_grand_total) if total != flt(grand_total, self.precision("grand_total")) or \ base_total != flt(base_grand_total, self.precision("base_grand_total")): @@ -1278,7 +1276,6 @@ def get_payment_term_details(term, posting_date=None, grand_total=None, base_gra term_details.discount_type = term.discount_type term_details.discount = term.discount term_details.outstanding = term_details.payment_amount - term_details.base_outstanding = term_details.base_payment_amount term_details.mode_of_payment = term.mode_of_payment if bill_date: From 6fb417590fd4ed431aae585b5a30612ab5e900a0 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Thu, 29 Apr 2021 14:05:20 +0530 Subject: [PATCH 23/27] fix: sider issues --- erpnext/public/js/controllers/transaction.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index dc731ca2133..a2b95cb757b 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1363,9 +1363,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } this.update_payment_schedule_grid_labels(company_currency); - - // set labels - var $wrapper = $(this.frm.wrapper); }, update_item_grid_labels: function(company_currency) { @@ -1382,7 +1379,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ update_payment_schedule_grid_labels: function(company_currency) { const me = this; - if(this.frm.fields_dict["payment_schedule"]) { + if (this.frm.fields_dict["payment_schedule"]) { this.frm.set_currency_labels(["base_payment_amount", "base_outstanding", "base_paid_amount"], company_currency, "payment_schedule"); this.frm.set_currency_labels(["payment_amount", "outstanding", "paid_amount"], @@ -1390,7 +1387,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ var schedule_grid = this.frm.fields_dict["payment_schedule"].grid; $.each(["base_payment_amount", "base_outstanding", "base_paid_amount"], function(i, fname) { - if(frappe.meta.get_docfield(schedule_grid.doctype, fname)) + if (frappe.meta.get_docfield(schedule_grid.doctype, fname)) schedule_grid.set_column_disp(fname, me.frm.doc.currency != company_currency); }); } @@ -2045,6 +2042,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ }, payment_term: function(doc, cdt, cdn) { + const me = this; var row = locals[cdt][cdn]; if(row.payment_term) { frappe.call({ @@ -2061,7 +2059,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ for (var d in r.message) { frappe.model.set_value(cdt, cdn, d, r.message[d]); const company_currency = me.get_company_currency(); - this.update_payment_schedule_grid_labels(company_currency); + me.update_payment_schedule_grid_labels(company_currency); } } } From 0dc00219e8e0dbc32f0b6b00c3b268c2f2fb908a Mon Sep 17 00:00:00 2001 From: Mohammad Hasnain Mohsin Rajan Date: Thu, 29 Apr 2021 15:21:16 +0530 Subject: [PATCH 24/27] fix: coveralls different services for different events (#25513) --- .github/workflows/ci-tests.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 4103bc68a91..84ecfb14571 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -80,8 +80,8 @@ jobs: env: TYPE: ${{ matrix.TYPE }} - - name: Coverage - if: matrix.TYPE == 'server' + - name: Coverage - Pull Request + if: matrix.TYPE == 'server' && github.event_name == 'pull_request' run: | cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE} cd ${GITHUB_WORKSPACE} @@ -91,3 +91,18 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + COVERALLS_SERVICE_NAME: github + + - name: Coverage - Push + if: matrix.TYPE == 'server' && github.event_name == 'push' + run: | + cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE} + cd ${GITHUB_WORKSPACE} + pip install coveralls==2.2.0 + pip install coverage==4.5.4 + coveralls --service=github-actions + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + COVERALLS_SERVICE_NAME: github-actions + From dd1e7624bf62aaa6b7a4fa797bdde4d61ea6f215 Mon Sep 17 00:00:00 2001 From: Anuja P Date: Thu, 29 Apr 2021 17:00:59 +0530 Subject: [PATCH 25/27] fix: changing paid amount should change allocated amount --- erpnext/accounts/doctype/payment_entry/payment_entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 830a7f25c00..b80e8ada38f 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -561,7 +561,7 @@ frappe.ui.form.on('Payment Entry', { flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate)); if(frm.doc.payment_type == "Pay") - frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount); + frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount, 1); else frm.events.set_unallocated_amount(frm); From 76e1e68cf4d3bcbc29a8061c53e31c1960230071 Mon Sep 17 00:00:00 2001 From: Ernesto Ruiz Date: Thu, 29 Apr 2021 08:24:56 -0600 Subject: [PATCH 26/27] fix: Make strings translatable Make strings translatable --- erpnext/payroll/doctype/salary_structure/salary_structure.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.js b/erpnext/payroll/doctype/salary_structure/salary_structure.js index 44368a69fb2..d5c20dce6b0 100755 --- a/erpnext/payroll/doctype/salary_structure/salary_structure.js +++ b/erpnext/payroll/doctype/salary_structure/salary_structure.js @@ -16,7 +16,7 @@ frappe.ui.form.on('Salary Structure', { onload: function(frm) { let help_button = $(` - ${__(Condition and Formula Help)} + ${__("Condition and Formula Help")} `).click(()=>{ let d = new frappe.ui.Dialog({ From 7783a56c08d343baab2e583d7f90f6e25e69a8ac Mon Sep 17 00:00:00 2001 From: Vignesh S Date: Thu, 29 Apr 2021 22:39:42 +0530 Subject: [PATCH 27/27] fix: List invoices in Payment Reconciliation Payment Invoices are not listed in the Payment Reconciliation Payment table due to a typo in the code --- .../doctype/payment_reconciliation/payment_reconciliation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js index 08103184d54..d1523cd7aca 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js @@ -234,7 +234,7 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext }); if (invoices) { - this.frm.fields_dict.payment.grid.update_docfield_property( + this.frm.fields_dict.payments.grid.update_docfield_property( 'invoice_number', 'options', "\n" + invoices.join("\n") );