From dea6a90a1f08198ae03e8f4ec80327630f0eb975 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Tue, 17 Nov 2020 22:16:13 +0000 Subject: [PATCH 01/17] feat(Accounting Dimension): other apps may have accounting dimension doctypes Prior to this change, there was simply a single hardcoded list of doctypes with accounting dimensions in ERPNext. However, when extending the capabilities of ERPNext using an add-on app rather than by modifying ERPNext itself, it may well be necessary to create new doctypes in other apps that will have accounting dimensions as well. So, this PR moves the list of doctypes with accounting dimensions into hooks.py so it can be accumulated from multiple apps. It also allows the list of doctypes in make_dimension_in_accounting_doctypes be specifiable, for more convenient use in the after_install hooks of other apps. --- .../accounting_dimension.py | 28 +++++++------------ erpnext/hooks.py | 9 ++++++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index f888d9e038a..ed1a0b68c7b 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -48,8 +48,9 @@ class AccountingDimension(Document): if not self.fieldname: self.fieldname = scrub(self.label) -def make_dimension_in_accounting_doctypes(doc): - doclist = get_doctypes_with_dimensions() +def make_dimension_in_accounting_doctypes(doc, doclist=None): + if not doclist: + doclist = get_doctypes_with_dimensions() doc_count = len(get_accounting_dimensions()) count = 0 @@ -69,13 +70,12 @@ def make_dimension_in_accounting_doctypes(doc): "owner": "Administrator" } - if doctype == "Budget": - add_dimension_to_budget_doctype(df, doc) - else: - meta = frappe.get_meta(doctype, cached=False) - fieldnames = [d.fieldname for d in meta.get("fields")] - - if df['fieldname'] not in fieldnames: + meta = frappe.get_meta(doctype, cached=False) + fieldnames = [d.fieldname for d in meta.get("fields")] + if df['fieldname'] not in fieldnames: + if doctype == "Budget": + add_dimension_to_budget_doctype(df.copy(), doc) + else: create_custom_field(doctype, df) count += 1 @@ -165,15 +165,7 @@ def toggle_disabling(doc): frappe.clear_cache(doctype=doctype) def get_doctypes_with_dimensions(): - doclist = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset", - "Expense Claim", "Expense Claim Detail", "Expense Taxes and Charges", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note", - "Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", - "Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule", - "Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation", - "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription", - "Subscription Plan"] - - return doclist + return frappe.get_hooks("accounting_dimension_doctypes") def get_accounting_dimensions(as_list=True): accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled", "document_type"]) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 987345697a2..3ef93fc0610 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -386,6 +386,15 @@ payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_account communication_doctypes = ["Customer", "Supplier"] +accounting_dimension_doctypes = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset", + "Expense Claim", "Expense Claim Detail", "Expense Taxes and Charges", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note", + "Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", + "Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule", + "Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation", + "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription", + "Subscription Plan" +] + regional_overrides = { 'France': { 'erpnext.tests.test_regional.test_method': 'erpnext.regional.france.utils.test_method' From e56daeb347e2bc1a4f4b8cbf963c5bea978a469c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 9 Feb 2021 16:13:45 +0530 Subject: [PATCH 02/17] fix: Multiple fixes in subscription --- .../doctype/subscription/subscription.js | 8 + .../doctype/subscription/subscription.json | 149 +++++++++++++----- .../doctype/subscription/subscription.py | 28 +++- .../subscription_invoice.json | 13 +- 4 files changed, 153 insertions(+), 45 deletions(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.js b/erpnext/accounts/doctype/subscription/subscription.js index ba98eb9b2a2..1b2cbc2273e 100644 --- a/erpnext/accounts/doctype/subscription/subscription.js +++ b/erpnext/accounts/doctype/subscription/subscription.js @@ -10,6 +10,14 @@ frappe.ui.form.on('Subscription', { } } }); + + frm.set_query('cost_center', function() { + return { + filters : { + company: frm.doc.company + } + } + }); }, refresh: function(frm) { diff --git a/erpnext/accounts/doctype/subscription/subscription.json b/erpnext/accounts/doctype/subscription/subscription.json index afb94fe9c95..e80df2ab886 100644 --- a/erpnext/accounts/doctype/subscription/subscription.json +++ b/erpnext/accounts/doctype/subscription/subscription.json @@ -7,9 +7,10 @@ "engine": "InnoDB", "field_order": [ "party_type", - "status", - "cb_1", "party", + "cb_1", + "company", + "status", "subscription_period", "start_date", "end_date", @@ -44,80 +45,107 @@ { "allow_on_submit": 1, "fieldname": "cb_1", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "status", "fieldtype": "Select", "label": "Status", + "no_copy": 1, "options": "\nTrialling\nActive\nPast Due Date\nCancelled\nUnpaid\nCompleted", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "subscription_period", "fieldtype": "Section Break", - "label": "Subscription Period" + "label": "Subscription Period", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "cancelation_date", "fieldtype": "Date", "label": "Cancelation Date", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "allow_on_submit": 1, "fieldname": "trial_period_start", "fieldtype": "Date", "label": "Trial Period Start Date", - "set_only_once": 1 + "set_only_once": 1, + "show_days": 1, + "show_seconds": 1 }, { "depends_on": "eval:doc.trial_period_start", "fieldname": "trial_period_end", "fieldtype": "Date", "label": "Trial Period End Date", - "set_only_once": 1 + "set_only_once": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_11", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "current_invoice_start", "fieldtype": "Date", "label": "Current Invoice Start Date", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "current_invoice_end", "fieldtype": "Date", "label": "Current Invoice End Date", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 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" + "label": "Days Until Due", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "cancel_at_period_end", "fieldtype": "Check", - "label": "Cancel At End Of Period" + "label": "Cancel At End Of Period", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "generate_invoice_at_period_start", "fieldtype": "Check", - "label": "Generate Invoice At Beginning Of Period" + "label": "Generate Invoice At Beginning Of Period", + "show_days": 1, + "show_seconds": 1 }, { "allow_on_submit": 1, "fieldname": "sb_4", "fieldtype": "Section Break", - "label": "Plans" + "label": "Plans", + "show_days": 1, + "show_seconds": 1 }, { "allow_on_submit": 1, @@ -125,62 +153,84 @@ "fieldtype": "Table", "label": "Plans", "options": "Subscription Plan Detail", - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "depends_on": "eval:['Customer', 'Supplier'].includes(doc.party_type)", "fieldname": "sb_1", "fieldtype": "Section Break", - "label": "Taxes" + "label": "Taxes", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "sb_2", "fieldtype": "Section Break", - "label": "Discounts" + "label": "Discounts", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "apply_additional_discount", "fieldtype": "Select", "label": "Apply Additional Discount On", - "options": "\nGrand Total\nNet Total" + "options": "\nGrand Total\nNet Total", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "cb_2", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "additional_discount_percentage", "fieldtype": "Percent", - "label": "Additional DIscount Percentage" + "label": "Additional DIscount Percentage", + "show_days": 1, + "show_seconds": 1 }, { "collapsible": 1, "fieldname": "additional_discount_amount", "fieldtype": "Currency", - "label": "Additional DIscount Amount" + "label": "Additional DIscount Amount", + "show_days": 1, + "show_seconds": 1 }, { "depends_on": "eval:doc.invoices", "fieldname": "sb_3", "fieldtype": "Section Break", - "label": "Invoices" + "label": "Invoices", + "show_days": 1, + "show_seconds": 1 }, { "collapsible": 1, "fieldname": "invoices", "fieldtype": "Table", "label": "Invoices", - "options": "Subscription Invoice" + "options": "Subscription Invoice", + "show_days": 1, + "show_seconds": 1 }, { "collapsible": 1, "fieldname": "accounting_dimensions_section", "fieldtype": "Section Break", - "label": "Accounting Dimensions" + "label": "Accounting Dimensions", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "dimension_col_break", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "party_type", @@ -188,7 +238,9 @@ "label": "Party Type", "options": "DocType", "reqd": 1, - "set_only_once": 1 + "set_only_once": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "party", @@ -197,21 +249,27 @@ "label": "Party", "options": "party_type", "reqd": 1, - "set_only_once": 1 + "set_only_once": 1, + "show_days": 1, + "show_seconds": 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" + "options": "Sales Taxes and Charges Template", + "show_days": 1, + "show_seconds": 1 }, { "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" + "options": "Purchase Taxes and Charges Template", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", @@ -219,36 +277,55 @@ "fieldname": "follow_calendar_months", "fieldtype": "Check", "label": "Follow Calendar Months", - "set_only_once": 1 + "set_only_once": 1, + "show_days": 1, + "show_seconds": 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" + "label": "Generate New Invoices Past Due Date", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "end_date", "fieldtype": "Date", "label": "Subscription End Date", - "set_only_once": 1 + "set_only_once": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "start_date", "fieldtype": "Date", "label": "Subscription Start Date", - "set_only_once": 1 + "set_only_once": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "cost_center", "fieldtype": "Link", "label": "Cost Center", - "options": "Cost Center" + "options": "Cost Center", + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company", + "show_days": 1, + "show_seconds": 1 } ], + "index_web_pages_for_search": 1, "links": [], - "modified": "2020-06-25 10:52:52.265105", + "modified": "2021-02-09 15:44:20.024789", "modified_by": "Administrator", "module": "Accounts", "name": "Subscription", diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index e023b47caca..74baa5ed626 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -1,3 +1,4 @@ + # -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt @@ -5,12 +6,13 @@ from __future__ import unicode_literals import frappe +import erpnext from frappe import _ from frappe.model.document import Document from frappe.utils.data import nowdate, getdate, cstr, cint, add_days, date_diff, get_last_day, add_to_date, flt from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions - +from erpnext import get_default_company class Subscription(Document): def before_insert(self): @@ -243,6 +245,7 @@ class Subscription(Document): self.validate_plans_billing_cycle(self.get_billing_cycle_and_interval()) self.validate_end_date() self.validate_to_follow_calendar_months() + self.cost_center = erpnext.get_default_cost_center(self.company) def validate_trial_period(self): """ @@ -304,6 +307,14 @@ class Subscription(Document): doctype = 'Sales Invoice' if self.party_type == 'Customer' else 'Purchase Invoice' invoice = frappe.new_doc(doctype) + + # For backward compatibility + # Earlier subscription didn't had any subscription field + company = self.company or get_default_company() + if not company: + frappe.throw(_("Company is mandatory was generating invoice. Please set default company in Global Defaults")) + + invoice.company = company invoice.set_posting_time = 1 invoice.posting_date = self.current_invoice_start if self.generate_invoice_at_period_start \ else self.current_invoice_end @@ -330,6 +341,7 @@ class Subscription(Document): # for that reason items_list = self.get_items_from_plans(self.plans, prorate) for item in items_list: + item['cost_center'] = self.cost_center invoice.append('items', item) # Taxes @@ -380,7 +392,8 @@ class Subscription(Document): Returns the `Item`s linked to `Subscription Plan` """ if prorate: - prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start) + prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start, + self.generate_invoice_at_period_start) items = [] party = self.party @@ -583,10 +596,13 @@ def get_calendar_months(billing_interval): return calendar_months -def get_prorata_factor(period_end, period_start): - diff = flt(date_diff(nowdate(), period_start) + 1) - plan_days = flt(date_diff(period_end, period_start) + 1) - prorate_factor = diff / plan_days +def get_prorata_factor(period_end, period_start, is_prepaid): + if is_prepaid: + prorate_factor = 1 + else: + diff = flt(date_diff(nowdate(), period_start) + 1) + plan_days = flt(date_diff(period_end, period_start) + 1) + prorate_factor = diff / plan_days return prorate_factor diff --git a/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.json b/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.json index f54e887f263..8a0d1de94c1 100644 --- a/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.json +++ b/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.json @@ -13,21 +13,28 @@ "fieldname": "document_type", "fieldtype": "Link", "label": "Document Type ", + "no_copy": 1, "options": "DocType", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "invoice", "fieldtype": "Dynamic Link", "in_list_view": 1, "label": "Invoice", + "no_copy": 1, "options": "document_type", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 } ], + "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-06-01 22:23:54.462718", + "modified": "2021-02-09 15:43:32.026233", "modified_by": "Administrator", "module": "Accounts", "name": "Subscription Invoice", From 5006a2065e029e81f5f1b8e4dbe82fe80eb78af9 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 9 Feb 2021 16:38:11 +0530 Subject: [PATCH 03/17] fix: Comment --- 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 74baa5ed626..3daea442071 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -309,7 +309,7 @@ class Subscription(Document): invoice = frappe.new_doc(doctype) # For backward compatibility - # Earlier subscription didn't had any subscription field + # Earlier subscription didn't had any company field company = self.company or get_default_company() if not company: frappe.throw(_("Company is mandatory was generating invoice. Please set default company in Global Defaults")) From 45cec6928bdebaa3d40dd433133eaf12ce290857 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 9 Feb 2021 16:44:12 +0530 Subject: [PATCH 04/17] fix: get company attribute --- 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 3daea442071..0f1502b8cec 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -310,7 +310,7 @@ class Subscription(Document): # For backward compatibility # Earlier subscription didn't had any company field - company = self.company or get_default_company() + company = self.get('company') or get_default_company() if not company: frappe.throw(_("Company is mandatory was generating invoice. Please set default company in Global Defaults")) From 516b3ae1bcd9a1e1b18d4f2004a8580de3fe9e27 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 9 Feb 2021 16:47:55 +0530 Subject: [PATCH 05/17] fix: get company attribute --- 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 0f1502b8cec..826044a4075 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -245,7 +245,7 @@ class Subscription(Document): self.validate_plans_billing_cycle(self.get_billing_cycle_and_interval()) self.validate_end_date() self.validate_to_follow_calendar_months() - self.cost_center = erpnext.get_default_cost_center(self.company) + self.cost_center = erpnext.get_default_cost_center(self.get('company')) def validate_trial_period(self): """ From 9d3f242f396554d87c972e977509b7aba9a23c06 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 11 Feb 2021 11:17:33 +0530 Subject: [PATCH 06/17] Update subscription.js --- erpnext/accounts/doctype/subscription/subscription.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.js b/erpnext/accounts/doctype/subscription/subscription.js index 1b2cbc2273e..1a9066470a5 100644 --- a/erpnext/accounts/doctype/subscription/subscription.js +++ b/erpnext/accounts/doctype/subscription/subscription.js @@ -13,10 +13,10 @@ frappe.ui.form.on('Subscription', { frm.set_query('cost_center', function() { return { - filters : { + filters: { company: frm.doc.company } - } + }; }); }, From e2324c77fea9c07dc1403b4701e988195ed9e71d Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 15 Feb 2021 20:01:32 +0530 Subject: [PATCH 07/17] fix: Test Cases --- erpnext/accounts/doctype/subscription/test_subscription.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py index c17fccdce04..7c58e9865fd 100644 --- a/erpnext/accounts/doctype/subscription/test_subscription.py +++ b/erpnext/accounts/doctype/subscription/test_subscription.py @@ -321,7 +321,8 @@ class TestSubscription(unittest.TestCase): self.assertEqual( flt( - get_prorata_factor(subscription.current_invoice_end, subscription.current_invoice_start), + get_prorata_factor(subscription.current_invoice_end, subscription.current_invoice_start, + subscription.generate_invoice_at_period_start), 2), flt(prorate_factor, 2) ) @@ -561,9 +562,7 @@ class TestSubscription(unittest.TestCase): current_inv = subscription.get_current_invoice() self.assertEqual(current_inv.status, "Unpaid") - diff = flt(date_diff(nowdate(), subscription.current_invoice_start) + 1) - plan_days = flt(date_diff(subscription.current_invoice_end, subscription.current_invoice_start) + 1) - prorate_factor = flt(diff / plan_days) + prorate_factor = 1 self.assertEqual(flt(current_inv.grand_total, 2), flt(prorate_factor * 900, 2)) From c04ed62863a8a926dae39213d5c25947b99bc234 Mon Sep 17 00:00:00 2001 From: Daniel Chalmers Date: Tue, 23 Feb 2021 22:02:09 -0600 Subject: [PATCH 08/17] Allow renaming skills --- erpnext/hr/doctype/skill/skill.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/hr/doctype/skill/skill.json b/erpnext/hr/doctype/skill/skill.json index 518297395bd..6f51d9455f2 100644 --- a/erpnext/hr/doctype/skill/skill.json +++ b/erpnext/hr/doctype/skill/skill.json @@ -3,7 +3,7 @@ "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, - "allow_rename": 0, + "allow_rename": 1, "autoname": "field:skill_name", "beta": 0, "creation": "2019-04-16 09:54:39.486915", @@ -56,7 +56,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-04-16 09:55:00.536328", + "modified": "2020-02-24 09:55:00.536328", "modified_by": "Administrator", "module": "HR", "name": "Skill", @@ -110,4 +110,4 @@ "track_changes": 1, "track_seen": 0, "track_views": 0 -} \ No newline at end of file +} From 23c30e43f008264fb3843252395c6bef460a4e8f Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 24 Feb 2021 11:03:24 +0530 Subject: [PATCH 09/17] fix: make round off GLE always non-opening Opening GL entries can not be for profit and loss accounts. Round off accounts are by default P&L account. Hence when making opening entry, make round off entries as non-opening. Related issue: ISS-20-21-09677 --- erpnext/accounts/general_ledger.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 287c79f13fe..158b2d9ffc1 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -194,7 +194,7 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision): if not round_off_gle: for k in ["voucher_type", "voucher_no", "company", - "posting_date", "remarks", "is_opening"]: + "posting_date", "remarks"]: round_off_gle[k] = gl_map[0][k] round_off_gle.update({ @@ -206,6 +206,7 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision): "cost_center": round_off_cost_center, "party_type": None, "party": None, + "is_opening": "No", "against_voucher_type": None, "against_voucher": None }) From d3e122259d7608482621660a1dd67cb6ebeacc33 Mon Sep 17 00:00:00 2001 From: Daniel Chalmers Date: Wed, 24 Feb 2021 17:13:48 -0600 Subject: [PATCH 10/17] Update skill.json --- erpnext/hr/doctype/skill/skill.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/skill/skill.json b/erpnext/hr/doctype/skill/skill.json index 6f51d9455f2..a10381fac19 100644 --- a/erpnext/hr/doctype/skill/skill.json +++ b/erpnext/hr/doctype/skill/skill.json @@ -56,7 +56,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2020-02-24 09:55:00.536328", + "modified": "2021-02-24 09:55:00.536328", "modified_by": "Administrator", "module": "HR", "name": "Skill", From 8cdba8ab6493cfcc8e84b384d695de09139760e9 Mon Sep 17 00:00:00 2001 From: Mohammad Hasnain Mohsin Rajan Date: Thu, 25 Feb 2021 18:36:19 +0530 Subject: [PATCH 11/17] fix: ams integration breaks when error raised (#24383) --- .../doctype/amazon_mws_settings/amazon_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py index cc75a0afbe0..148c1a6a166 100644 --- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py +++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py @@ -117,7 +117,7 @@ def call_mws_method(mws_method, *args, **kwargs): return response except Exception as e: delay = math.pow(4, x) * 125 - frappe.log_error(message=e, title=str(mws_method)) + frappe.log_error(message=e, title=f'Method "{mws_method.__name__}" failed') time.sleep(delay) continue From 118a4ffb088feefb31660ca065480505393434e5 Mon Sep 17 00:00:00 2001 From: Anuja Pawar <60467153+Anuja-pawar@users.noreply.github.com> Date: Thu, 25 Feb 2021 18:44:44 +0530 Subject: [PATCH 12/17] fix: rounding error in finished goods qty (#24653) --- erpnext/stock/doctype/stock_entry/stock_entry.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 9cdc3cfa55c..ea1b3873ea7 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -276,9 +276,10 @@ class StockEntry(StockController): item_wise_qty.setdefault(d.item_code, []).append(d.qty) for item_code, qty_list in iteritems(item_wise_qty): - if self.fg_completed_qty != sum(qty_list): + total = flt(sum(qty_list), frappe.get_precision("Stock Entry Detail", "qty")) + if self.fg_completed_qty != total: frappe.throw(_("The finished product {0} quantity {1} and For Quantity {2} cannot be different") - .format(frappe.bold(item_code), frappe.bold(sum(qty_list)), frappe.bold(self.fg_completed_qty))) + .format(frappe.bold(item_code), frappe.bold(total), frappe.bold(self.fg_completed_qty))) def validate_difference_account(self): if not cint(erpnext.is_perpetual_inventory_enabled(self.company)): From 02f50a93e582fc425844442d576cd65a992fbb0d Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Thu, 25 Feb 2021 18:47:17 +0530 Subject: [PATCH 13/17] fix: copy variants property and Attributes whil duplicatinh item Tamplate (#24662) --- erpnext/stock/doctype/item/item.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index fcf7c2608ef..6886c1ba45f 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -521,8 +521,7 @@ "fieldname": "has_variants", "fieldtype": "Check", "in_standard_filter": 1, - "label": "Has Variants", - "no_copy": 1 + "label": "Has Variants" }, { "default": "Item Attribute", @@ -538,7 +537,6 @@ "fieldtype": "Table", "hidden": 1, "label": "Attributes", - "no_copy": 1, "options": "Item Variant Attribute" }, { @@ -1068,7 +1066,7 @@ "index_web_pages_for_search": 1, "links": [], "max_attachments": 1, - "modified": "2021-01-25 20:49:50.222976", + "modified": "2021-02-18 14:00:19.668049", "modified_by": "Administrator", "module": "Stock", "name": "Item", From 1be997beb42572b25195b4fa5f393d2702f0379c Mon Sep 17 00:00:00 2001 From: Afshan <33727827+AfshanKhan@users.noreply.github.com> Date: Thu, 25 Feb 2021 19:01:32 +0530 Subject: [PATCH 14/17] fix: reference variable in pricing rule (#24711) --- erpnext/accounts/doctype/pricing_rule/pricing_rule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index 05652642eb0..f0b4e2976d0 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py @@ -136,7 +136,7 @@ class PricingRule(Document): for d in self.items: max_discount = frappe.get_cached_value("Item", d.item_code, "max_discount") if max_discount and flt(self.discount_percentage) > flt(max_discount): - throw(_("Max discount allowed for item: {0} is {1}%").format(self.item_code, max_discount)) + throw(_("Max discount allowed for item: {0} is {1}%").format(d.item_code, max_discount)) def validate_price_list_with_currency(self): if self.currency and self.for_price_list: From 286e00bdf2c40d19a3a50bc9cc00334dc0446231 Mon Sep 17 00:00:00 2001 From: Syed Mujeer Hashmi Date: Thu, 25 Feb 2021 19:02:54 +0530 Subject: [PATCH 15/17] fix: Fetch Task subject from Task (#24729) --- .../doctype/project_template_task/project_template_task.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/projects/doctype/project_template_task/project_template_task.json b/erpnext/projects/doctype/project_template_task/project_template_task.json index 69530b15b40..16caaa20ae4 100644 --- a/erpnext/projects/doctype/project_template_task/project_template_task.json +++ b/erpnext/projects/doctype/project_template_task/project_template_task.json @@ -20,6 +20,7 @@ }, { "columns": 6, + "fetch_from": "task.subject", "fieldname": "subject", "fieldtype": "Read Only", "in_list_view": 1, @@ -28,7 +29,7 @@ ], "istable": 1, "links": [], - "modified": "2021-01-07 15:13:40.995071", + "modified": "2021-02-24 15:18:49.095071", "modified_by": "Administrator", "module": "Projects", "name": "Project Template Task", From dca307e7cc6b04f90cab9b24f1214c57b87aaad8 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 25 Feb 2021 19:05:07 +0530 Subject: [PATCH 16/17] feat: track changes to HR settings (#24739) related issue: FR-ISS-259927 --- erpnext/hr/doctype/hr_settings/hr_settings.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.json b/erpnext/hr/doctype/hr_settings/hr_settings.json index f99963504ab..d8aae667960 100644 --- a/erpnext/hr/doctype/hr_settings/hr_settings.json +++ b/erpnext/hr/doctype/hr_settings/hr_settings.json @@ -138,7 +138,7 @@ "idx": 1, "issingle": 1, "links": [], - "modified": "2020-08-27 14:30:28.995324", + "modified": "2021-02-25 12:31:14.947865", "modified_by": "Administrator", "module": "HR", "name": "HR Settings", @@ -155,5 +155,6 @@ } ], "sort_field": "modified", - "sort_order": "ASC" -} + "sort_order": "ASC", + "track_changes": 1 +} \ No newline at end of file From 27da2bb63a0a8e11b308f1d9134b4345c4c84cce Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 25 Feb 2021 22:39:47 +0530 Subject: [PATCH 17/17] fix: Remove unique check from represents company field --- erpnext/selling/doctype/customer/customer.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index a048928f72e..7d5e84df52f 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -212,8 +212,7 @@ "fieldtype": "Link", "ignore_user_permissions": 1, "label": "Represents Company", - "options": "Company", - "unique": 1 + "options": "Company" }, { "depends_on": "represents_company", @@ -500,7 +499,7 @@ "image_field": "image", "index_web_pages_for_search": 1, "links": [], - "modified": "2021-01-27 12:54:57.258959", + "modified": "2021-01-28 12:54:57.258959", "modified_by": "Administrator", "module": "Selling", "name": "Customer",