From 7d9f3f23dde6efd6fc3f218d48a3828dd9aa1133 Mon Sep 17 00:00:00 2001 From: Solufyin <34390782+Solufyin@users.noreply.github.com> Date: Mon, 26 Dec 2022 10:15:10 +0530 Subject: [PATCH 01/12] fix: Customer Primary Contact (#33424) Co-authored-by: Nihantra C. Patel --- erpnext/selling/doctype/customer/customer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 12ecb0112a..d9dab33501 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -737,7 +737,7 @@ def get_customer_primary_contact(doctype, txt, searchfield, start, page_len, fil qb.from_(con) .join(dlink) .on(con.name == dlink.parent) - .select(con.name, con.full_name, con.email_id) + .select(con.name, con.email_id) .where((dlink.link_name == customer) & (con.name.like(f"%{txt}%"))) .run() ) From 8a79efab4b9a804a3c943edebf6e98c5f1985580 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 26 Dec 2022 10:17:55 +0530 Subject: [PATCH 02/12] feat: Accounting Dimension updation in Payment Request and Entry (#33411) --- .../doctype/payment_entry/payment_entry.py | 14 +++++++++ .../payment_request/payment_request.json | 28 ++++++++++++++++- .../payment_request/payment_request.py | 25 +++++++++++++++ erpnext/patches.txt | 3 +- ...counting_dimensions_for_payment_request.py | 31 +++++++++++++++++++ 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 erpnext/patches/v14_0/create_accounting_dimensions_for_payment_request.py diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 79fab6480c..26192eca2e 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1758,6 +1758,8 @@ def get_payment_entry( pe.setup_party_account_field() pe.set_missing_values() + update_accounting_dimensions(pe, doc) + if party_account and bank: pe.set_exchange_rate(ref_doc=reference_doc) pe.set_amounts() @@ -1775,6 +1777,18 @@ def get_payment_entry( return pe +def update_accounting_dimensions(pe, doc): + """ + Updates accounting dimensions in Payment Entry based on the accounting dimensions in the reference document + """ + from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( + get_accounting_dimensions, + ) + + for dimension in get_accounting_dimensions(): + pe.set(dimension, doc.get(dimension)) + + def get_bank_cash_account(doc, bank_account): bank = get_default_bank_cash_account( doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"), account=bank_account diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json index 2f3516e135..381f3fb531 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.json +++ b/erpnext/accounts/doctype/payment_request/payment_request.json @@ -32,6 +32,10 @@ "iban", "branch_code", "swift_number", + "accounting_dimensions_section", + "cost_center", + "dimension_col_break", + "project", "recipient_and_message", "print_format", "email_to", @@ -362,13 +366,35 @@ "label": "Payment Channel", "options": "\nEmail\nPhone", "read_only": 1 + }, + { + "collapsible": 1, + "fieldname": "accounting_dimensions_section", + "fieldtype": "Section Break", + "label": "Accounting Dimensions" + }, + { + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" + }, + { + "fieldname": "dimension_col_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "project", + "fieldtype": "Link", + "label": "Project", + "options": "Project" } ], "in_create": 1, "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2022-09-30 16:19:43.680025", + "modified": "2022-12-21 16:56:40.115737", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Request", diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index fc938014b3..4fc12dbc16 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -10,6 +10,9 @@ from frappe.model.document import Document from frappe.utils import flt, get_url, nowdate from frappe.utils.background_jobs import enqueue +from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( + get_accounting_dimensions, +) from erpnext.accounts.doctype.payment_entry.payment_entry import ( get_company_defaults, get_payment_entry, @@ -270,6 +273,17 @@ class PaymentRequest(Document): } ) + # Update dimensions + payment_entry.update( + { + "cost_center": self.get("cost_center"), + "project": self.get("project"), + } + ) + + for dimension in get_accounting_dimensions(): + payment_entry.update({dimension: self.get(dimension)}) + if payment_entry.difference_amount: company_details = get_company_defaults(ref_doc.company) @@ -449,6 +463,17 @@ def make_payment_request(**args): } ) + # Update dimensions + pr.update( + { + "cost_center": ref_doc.get("cost_center"), + "project": ref_doc.get("project"), + } + ) + + for dimension in get_accounting_dimensions(): + pr.update({dimension: ref_doc.get(dimension)}) + if args.order_type == "Shopping Cart" or args.mute_email: pr.flags.mute_email = True diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 0aad1d34e5..2420a23bb0 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -318,4 +318,5 @@ erpnext.patches.v13_0.update_schedule_type_in_loans erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization erpnext.patches.v14_0.update_partial_tds_fields erpnext.patches.v14_0.create_incoterms_and_migrate_shipment -erpnext.patches.v14_0.setup_clear_repost_logs \ No newline at end of file +erpnext.patches.v14_0.setup_clear_repost_logs +erpnext.patches.v14_0.create_accounting_dimensions_for_payment_request \ No newline at end of file diff --git a/erpnext/patches/v14_0/create_accounting_dimensions_for_payment_request.py b/erpnext/patches/v14_0/create_accounting_dimensions_for_payment_request.py new file mode 100644 index 0000000000..bede419ad2 --- /dev/null +++ b/erpnext/patches/v14_0/create_accounting_dimensions_for_payment_request.py @@ -0,0 +1,31 @@ +import frappe +from frappe.custom.doctype.custom_field.custom_field import create_custom_field + + +def execute(): + accounting_dimensions = frappe.db.get_all( + "Accounting Dimension", fields=["fieldname", "label", "document_type", "disabled"] + ) + + if not accounting_dimensions: + return + + doctype = "Payment Request" + + for d in accounting_dimensions: + field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname}) + + if field: + continue + + df = { + "fieldname": d.fieldname, + "label": d.label, + "fieldtype": "Link", + "options": d.document_type, + "insert_after": "accounting_dimensions_section", + } + + create_custom_field(doctype, df, ignore_validate=True) + + frappe.clear_cache(doctype=doctype) From 67a7ccf3cead654e66a3d1b5ccb253d90b19c43b Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Mon, 26 Dec 2022 11:39:58 +0530 Subject: [PATCH 03/12] fix: `shipping_address` for non-drop shipping item --- .../doctype/sales_order/sales_order.py | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index efe1f8eb17..7c0601e3dd 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -1024,6 +1024,15 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): ] items_to_map = list(set(items_to_map)) + def is_drop_ship_order(target): + drop_ship = True + for item in target.items: + if not item.delivered_by_supplier: + drop_ship = False + break + + return drop_ship + def set_missing_values(source, target): target.supplier = "" target.apply_discount_on = "" @@ -1031,6 +1040,14 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): target.discount_amount = 0.0 target.inter_company_order_reference = "" target.shipping_rule = "" + + if is_drop_ship_order(target): + target.customer = source.customer + target.customer_name = source.customer_name + target.shipping_address = source.shipping_address_name + else: + target.customer = target.customer_name = target.shipping_address = None + target.run_method("set_missing_values") target.run_method("calculate_taxes_and_totals") @@ -1057,11 +1074,9 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): "contact_email", "contact_person", "taxes_and_charges", + "shipping_address", "terms", ], - "field_map": [ - ["shipping_address_name", "shipping_address"], - ], "validation": {"docstatus": ["=", 1]}, }, "Sales Order Item": { From 8263bf9a9a716f7651386633fd6f26686f2008bd Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 27 Dec 2022 14:59:35 +0530 Subject: [PATCH 04/12] fix: Random behaviour while picking items using picklist (#33449) --- erpnext/stock/doctype/pick_list/pick_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index aff5e0539c..8704b6718b 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -441,7 +441,7 @@ def get_available_item_locations_for_batched_item( sle.`batch_no`, sle.`item_code` HAVING `qty` > 0 - ORDER BY IFNULL(batch.`expiry_date`, '2200-01-01'), batch.`creation` + ORDER BY IFNULL(batch.`expiry_date`, '2200-01-01'), batch.`creation`, sle.`batch_no`, sle.`warehouse` """.format( warehouse_condition=warehouse_condition ), From d2686ce75bb39bffff4fd1b56ad4880444efb72e Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 27 Dec 2022 17:42:03 +0530 Subject: [PATCH 05/12] fix: Multiple rows for same warehouse and batches in pick list (#33456) --- erpnext/stock/doctype/pick_list/pick_list.js | 10 ++++++++- erpnext/stock/doctype/pick_list/pick_list.py | 22 +++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.js b/erpnext/stock/doctype/pick_list/pick_list.js index 799406cd79..8213adb89b 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.js +++ b/erpnext/stock/doctype/pick_list/pick_list.js @@ -51,7 +51,15 @@ frappe.ui.form.on('Pick List', { if (!(frm.doc.locations && frm.doc.locations.length)) { frappe.msgprint(__('Add items in the Item Locations table')); } else { - frm.call('set_item_locations', {save: save}); + frappe.call({ + method: "set_item_locations", + doc: frm.doc, + args: { + "save": save, + }, + freeze: 1, + freeze_message: __("Setting Item Locations..."), + }); } }, get_item_locations: (frm) => { diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 8704b6718b..953fca7419 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -135,6 +135,7 @@ class PickList(Document): # reset self.delete_key("locations") + updated_locations = frappe._dict() for item_doc in items: item_code = item_doc.item_code @@ -155,7 +156,26 @@ class PickList(Document): for row in locations: location = item_doc.as_dict() location.update(row) - self.append("locations", location) + key = ( + location.item_code, + location.warehouse, + location.uom, + location.batch_no, + location.serial_no, + location.sales_order_item or location.material_request_item, + ) + + if key not in updated_locations: + updated_locations.setdefault(key, location) + else: + updated_locations[key].qty += location.qty + updated_locations[key].stock_qty += location.stock_qty + + for location in updated_locations.values(): + if location.picked_qty > location.stock_qty: + location.picked_qty = location.stock_qty + + self.append("locations", location) # If table is empty on update after submit, set stock_qty, picked_qty to 0 so that indicator is red # and give feedback to the user. This is to avoid empty Pick Lists. From 0b75aa53907e67d440884a2ea0084044265994a5 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 27 Dec 2022 17:53:43 +0530 Subject: [PATCH 06/12] fix: Default dimensions on fetching items from BOM (#33439) --- erpnext/stock/doctype/stock_entry/stock_entry.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index b9102445e0..d4b4efa4cd 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -112,6 +112,10 @@ frappe.ui.form.on('Stock Entry', { } }); attach_bom_items(frm.doc.bom_no); + + if(!check_should_not_attach_bom_items(frm.doc.bom_no)) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + } }, setup_quality_inspection: function(frm) { @@ -326,7 +330,11 @@ frappe.ui.form.on('Stock Entry', { } frm.trigger("setup_quality_inspection"); - attach_bom_items(frm.doc.bom_no) + attach_bom_items(frm.doc.bom_no); + + if(!check_should_not_attach_bom_items(frm.doc.bom_no)) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + } }, before_save: function(frm) { @@ -939,7 +947,10 @@ erpnext.stock.StockEntry = class StockEntry extends erpnext.stock.StockControlle method: "get_items", callback: function(r) { if(!r.exc) refresh_field("items"); - if(me.frm.doc.bom_no) attach_bom_items(me.frm.doc.bom_no) + if(me.frm.doc.bom_no) { + attach_bom_items(me.frm.doc.bom_no); + erpnext.accounts.dimensions.update_dimension(me.frm, me.frm.doctype); + } } }); } From 8e271fd7190447577fa15e1d180c33524576d529 Mon Sep 17 00:00:00 2001 From: Sabu Siyad Date: Wed, 28 Dec 2022 08:11:28 +0530 Subject: [PATCH 07/12] feat(exotel): make use of `CustomField` in API (#33338) * feat(exotel): pass kwargs for `make_a_call` https://developer.exotel.com/api/make-a-call-api#call-agent Signed-off-by: Sabu Siyad * feat(exotel): map custom field to doctype Signed-off-by: Sabu Siyad Signed-off-by: Sabu Siyad --- .../exotel_settings/exotel_settings.json | 34 +++++++++++++++++-- .../exotel_integration.py | 23 +++++++++++-- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/exotel_settings/exotel_settings.json b/erpnext/erpnext_integrations/doctype/exotel_settings/exotel_settings.json index 72f47b53ec..0d42ca8c85 100644 --- a/erpnext/erpnext_integrations/doctype/exotel_settings/exotel_settings.json +++ b/erpnext/erpnext_integrations/doctype/exotel_settings/exotel_settings.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2019-05-21 07:41:53.536536", "doctype": "DocType", "engine": "InnoDB", @@ -7,10 +8,14 @@ "section_break_2", "account_sid", "api_key", - "api_token" + "api_token", + "section_break_6", + "map_custom_field_to_doctype", + "target_doctype" ], "fields": [ { + "default": "0", "fieldname": "enabled", "fieldtype": "Check", "label": "Enabled" @@ -18,7 +23,8 @@ { "depends_on": "enabled", "fieldname": "section_break_2", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "label": "Credentials" }, { "fieldname": "account_sid", @@ -34,10 +40,31 @@ "fieldname": "api_key", "fieldtype": "Data", "label": "API Key" + }, + { + "depends_on": "enabled", + "fieldname": "section_break_6", + "fieldtype": "Section Break", + "label": "Custom Field" + }, + { + "default": "0", + "fieldname": "map_custom_field_to_doctype", + "fieldtype": "Check", + "label": "Map Custom Field to DocType" + }, + { + "depends_on": "map_custom_field_to_doctype", + "fieldname": "target_doctype", + "fieldtype": "Link", + "label": "Target DocType", + "mandatory_depends_on": "map_custom_field_to_doctype", + "options": "DocType" } ], "issingle": 1, - "modified": "2019-05-22 06:25:18.026997", + "links": [], + "modified": "2022-12-14 17:24:50.176107", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "Exotel Settings", @@ -57,5 +84,6 @@ "quick_entry": 1, "sort_field": "modified", "sort_order": "ASC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/erpnext_integrations/exotel_integration.py b/erpnext/erpnext_integrations/exotel_integration.py index fd0f783575..0d40667e32 100644 --- a/erpnext/erpnext_integrations/exotel_integration.py +++ b/erpnext/erpnext_integrations/exotel_integration.py @@ -72,6 +72,24 @@ def get_call_log(call_payload): return frappe.get_doc("Call Log", call_log_id) +def map_custom_field(call_payload, call_log): + field_value = call_payload.get("CustomField") + + if not field_value: + return call_log + + settings = get_exotel_settings() + target_doctype = settings.target_doctype + mapping_enabled = settings.map_custom_field_to_doctype + + if not mapping_enabled or not target_doctype: + return call_log + + call_log.append("links", {"link_doctype": target_doctype, "link_name": field_value}) + + return call_log + + def create_call_log(call_payload): call_log = frappe.new_doc("Call Log") call_log.id = call_payload.get("CallSid") @@ -79,6 +97,7 @@ def create_call_log(call_payload): call_log.medium = call_payload.get("To") call_log.status = "Ringing" setattr(call_log, "from", call_payload.get("CallFrom")) + map_custom_field(call_payload, call_log) call_log.save(ignore_permissions=True) frappe.db.commit() return call_log @@ -93,10 +112,10 @@ def get_call_status(call_id): @frappe.whitelist() -def make_a_call(from_number, to_number, caller_id): +def make_a_call(from_number, to_number, caller_id, **kwargs): endpoint = get_exotel_endpoint("Calls/connect.json?details=true") response = requests.post( - endpoint, data={"From": from_number, "To": to_number, "CallerId": caller_id} + endpoint, data={"From": from_number, "To": to_number, "CallerId": caller_id, **kwargs} ) return response.json() From 6f5824cb213cdda10e225322dd417e0258e0a3ce Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Tue, 27 Dec 2022 14:54:23 +0530 Subject: [PATCH 08/12] fix: `fg_item_qty` in non-subcontracted PO --- .../doctype/purchase_order/purchase_order.py | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 4c10b4812e..5a4168a573 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -207,31 +207,36 @@ class PurchaseOrder(BuyingController): ) def validate_fg_item_for_subcontracting(self): - if self.is_subcontracted and not self.is_old_subcontracting_flow: + if self.is_subcontracted: + if not self.is_old_subcontracting_flow: + for item in self.items: + if not item.fg_item: + frappe.throw( + _("Row #{0}: Finished Good Item is not specified for service item {1}").format( + item.idx, item.item_code + ) + ) + else: + if not frappe.get_value("Item", item.fg_item, "is_sub_contracted_item"): + frappe.throw( + _( + "Row #{0}: Finished Good Item {1} must be a sub-contracted item for service item {2}" + ).format(item.idx, item.fg_item, item.item_code) + ) + elif not frappe.get_value("Item", item.fg_item, "default_bom"): + frappe.throw( + _("Row #{0}: Default BOM not found for FG Item {1}").format(item.idx, item.fg_item) + ) + if not item.fg_item_qty: + frappe.throw( + _("Row #{0}: Finished Good Item Qty is not specified for service item {0}").format( + item.idx, item.item_code + ) + ) + else: for item in self.items: - if not item.fg_item: - frappe.throw( - _("Row #{0}: Finished Good Item is not specified for service item {1}").format( - item.idx, item.item_code - ) - ) - else: - if not frappe.get_value("Item", item.fg_item, "is_sub_contracted_item"): - frappe.throw( - _( - "Row #{0}: Finished Good Item {1} must be a sub-contracted item for service item {2}" - ).format(item.idx, item.fg_item, item.item_code) - ) - elif not frappe.get_value("Item", item.fg_item, "default_bom"): - frappe.throw( - _("Row #{0}: Default BOM not found for FG Item {1}").format(item.idx, item.fg_item) - ) - if not item.fg_item_qty: - frappe.throw( - _("Row #{0}: Finished Good Item Qty is not specified for service item {0}").format( - item.idx, item.item_code - ) - ) + item.set("fg_item", None) + item.set("fg_item_qty", 0) def get_schedule_dates(self): for d in self.get("items"): From cabaed9ed2526e2649d173c806f6987d3377b0c3 Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Wed, 28 Dec 2022 18:05:55 +0530 Subject: [PATCH 09/12] fix(pricing rule): consider child tables in condition (#33469) --- erpnext/accounts/doctype/pricing_rule/utils.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index 3989f8a8ac..1ce780eac8 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -252,10 +252,15 @@ def get_other_conditions(conditions, values, args): if args.get("doctype") in [ "Quotation", + "Quotation Item", "Sales Order", + "Sales Order Item", "Delivery Note", + "Delivery Note Item", "Sales Invoice", + "Sales Invoice Item", "POS Invoice", + "POS Invoice Item", ]: conditions += """ and ifnull(`tabPricing Rule`.selling, 0) = 1""" else: From e3a0ce5d6328d2ef68fb00419775ce113889c133 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 29 Dec 2022 09:34:51 +0530 Subject: [PATCH 10/12] fix: use base_net_amount in case of missing stock qty (#33457) --- .../item_wise_purchase_register.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index c04b9c7125..d34c21348c 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -53,9 +53,6 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum item_details = get_item_details() for d in item_list: - if not d.stock_qty: - continue - item_record = item_details.get(d.item_code) purchase_receipt = None @@ -94,7 +91,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum "expense_account": expense_account, "stock_qty": d.stock_qty, "stock_uom": d.stock_uom, - "rate": d.base_net_amount / d.stock_qty, + "rate": d.base_net_amount / d.stock_qty if d.stock_qty else d.base_net_amount, "amount": d.base_net_amount, } ) From 123920d0bc7b1d3c0e465d09d569ed2d08687a0b Mon Sep 17 00:00:00 2001 From: Devin Slauenwhite Date: Thu, 29 Dec 2022 00:01:26 -0500 Subject: [PATCH 11/12] feat: add after_refresh hook to item dashboard (#33372) * fix: return promise * fix: use after_refresh hook instead of promise # Because there is already a before_refresh hook. I think it makes sense to do the same for after. --- erpnext/stock/dashboard/item_dashboard.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index 6e7622c067..1be528f1dd 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -102,6 +102,9 @@ erpnext.stock.ItemDashboard = class ItemDashboard { args: args, callback: function (r) { me.render(r.message); + if(me.after_refresh) { + me.after_refresh(); + } } }); } From 617518389ac0c6459197e27f94efbcb14d409dbf Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 29 Dec 2022 10:41:36 +0530 Subject: [PATCH 12/12] fix: Conversion factor error for invoices without item code (petty expenses) (#32714) * fix: Set default uom conversion factor to 1 for invoices * chore: set default conversion_factor as 1 * chore: remove print statements --- .../doctype/sales_invoice_item/sales_invoice_item.json | 2 +- erpnext/controllers/accounts_controller.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index 62c3ced76a..35d19ed843 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -890,7 +890,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2022-11-02 12:53:12.693217", + "modified": "2022-12-28 16:17:33.484531", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 334a2d806d..788dc4982e 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -584,7 +584,12 @@ class AccountsController(TransactionBase): if bool(uom) != bool(stock_uom): # xor item.stock_uom = item.uom = uom or stock_uom - item.conversion_factor = get_uom_conv_factor(item.get("uom"), item.get("stock_uom")) + # UOM cannot be zero so substitute as 1 + item.conversion_factor = ( + get_uom_conv_factor(item.get("uom"), item.get("stock_uom")) + or item.get("conversion_factor") + or 1 + ) if self.doctype == "Purchase Invoice": self.set_expense_account(for_validate)