diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index 1bd42f5aba..0ebf0eb541 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -61,8 +61,10 @@ class AccountingDimension(Document): def on_update(self): frappe.flags.accounting_dimensions = None -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 @@ -82,13 +84,13 @@ 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")] + meta = frappe.get_meta(doctype, cached=False) + fieldnames = [d.fieldname for d in meta.get("fields")] - if df['fieldname'] not in fieldnames: + 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 @@ -178,15 +180,7 @@ def toggle_disabling(doc): frappe.clear_cache(doctype=doctype) def get_doctypes_with_dimensions(): - doclist = ["GL Entry", "Sales Invoice", "POS 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", "POS 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): if frappe.flags.accounting_dimensions is None: diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index 05652642eb..f0b4e2976d 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: diff --git a/erpnext/accounts/doctype/subscription/subscription.js b/erpnext/accounts/doctype/subscription/subscription.js index ba98eb9b2a..1a9066470a 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 afb94fe9c9..e80df2ab88 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 e023b47cac..826044a407 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.get('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 company field + 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")) + + 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/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py index c17fccdce0..7c58e9865f 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)) diff --git a/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.json b/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.json index f54e887f26..8a0d1de94c 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", diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index b42c0c61d9..dac0c216c8 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -196,7 +196,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({ @@ -208,6 +208,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 }) 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 cc75a0afbe..148c1a6a16 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 diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 39d3659b2b..59639ffc43 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -393,6 +393,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' diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.json b/erpnext/hr/doctype/hr_settings/hr_settings.json index f99963504a..d8aae66796 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 diff --git a/erpnext/hr/doctype/skill/skill.json b/erpnext/hr/doctype/skill/skill.json index 518297395b..a10381fac1 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": "2021-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 +} 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 69530b15b4..16caaa20ae 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", diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index a048928f72..7d5e84df52 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", diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index fcf7c2608e..6886c1ba45 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", diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 9cdc3cfa55..ea1b3873ea 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)):