From 9209ec59c2216223bc1a7618bd95ec2424434849 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 21 Oct 2022 15:18:40 +0530 Subject: [PATCH 1/9] refactor: split delete gl utility function into two --- erpnext/accounts/utils.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index d7bf991688..103c154c5d 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -1146,10 +1146,10 @@ def repost_gle_for_stock_vouchers( if not existing_gle or not compare_existing_and_expected_gle( existing_gle, expected_gle, precision ): - _delete_gl_entries(voucher_type, voucher_no) + _delete_accounting_ledger_entries(voucher_type, voucher_no) voucher_obj.make_gl_entries(gl_entries=expected_gle, from_repost=True) else: - _delete_gl_entries(voucher_type, voucher_no) + _delete_accounting_ledger_entries(voucher_type, voucher_no) if not frappe.flags.in_test: frappe.db.commit() @@ -1161,18 +1161,28 @@ def repost_gle_for_stock_vouchers( ) -def _delete_gl_entries(voucher_type, voucher_no): - frappe.db.sql( - """delete from `tabGL Entry` - where voucher_type=%s and voucher_no=%s""", - (voucher_type, voucher_no), - ) +def _delete_pl_entries(voucher_type, voucher_no): ple = qb.DocType("Payment Ledger Entry") qb.from_(ple).delete().where( (ple.voucher_type == voucher_type) & (ple.voucher_no == voucher_no) ).run() +def _delete_gl_entries(voucher_type, voucher_no): + gle = qb.DocType("GL Entry") + qb.from_(gle).delete().where( + (gle.voucher_type == voucher_type) & (gle.voucher_no == voucher_no) + ).run() + + +def _delete_accounting_ledger_entries(voucher_type, voucher_no): + """ + Remove entries from both General and Payment Ledger for specified Voucher + """ + _delete_gl_entries(voucher_type, voucher_no) + _delete_pl_entries(voucher_type, voucher_no) + + def sort_stock_vouchers_by_posting_date( stock_vouchers: List[Tuple[str, str]] ) -> List[Tuple[str, str]]: From f8d2e276a5b235bb288551b7181c6bc90450688d Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Mon, 7 Nov 2022 17:19:03 +0530 Subject: [PATCH 2/9] fix: make `consumed_qty` read-only in SCR Supplied Items --- .../subcontracting_receipt_supplied_item.json | 411 +++++++++--------- 1 file changed, 206 insertions(+), 205 deletions(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json index ddbb80661a..d21bc22ad7 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json @@ -1,207 +1,208 @@ { - "actions": [], - "creation": "2022-04-18 10:45:16.538479", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "main_item_code", - "rm_item_code", - "item_name", - "bom_detail_no", - "col_break1", - "description", - "stock_uom", - "conversion_factor", - "reference_name", - "secbreak_1", - "rate", - "col_break2", - "amount", - "secbreak_2", - "available_qty_for_consumption", - "required_qty", - "col_break3", - "consumed_qty", - "current_stock", - "secbreak_3", - "batch_no", - "col_break4", - "serial_no", - "subcontracting_order" - ], - "fields": [ - { - "fieldname": "main_item_code", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Item Code", - "options": "Item", - "read_only": 1 - }, - { - "fieldname": "rm_item_code", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Raw Material Item Code", - "options": "Item", - "read_only": 1 - }, - { - "fieldname": "description", - "fieldtype": "Text Editor", - "in_global_search": 1, - "label": "Description", - "print_width": "300px", - "read_only": 1, - "width": "300px" - }, - { - "fieldname": "batch_no", - "fieldtype": "Link", - "label": "Batch No", - "no_copy": 1, - "options": "Batch" - }, - { - "fieldname": "serial_no", - "fieldtype": "Text", - "label": "Serial No", - "no_copy": 1 - }, - { - "fieldname": "col_break1", - "fieldtype": "Column Break" - }, - { - "fieldname": "required_qty", - "fieldtype": "Float", - "label": "Required Qty", - "print_hide": 1, - "read_only": 1 - }, - { - "columns": 2, - "fieldname": "consumed_qty", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Consumed Qty", - "reqd": 1 - }, - { - "fieldname": "stock_uom", - "fieldtype": "Link", - "label": "Stock Uom", - "options": "UOM", - "read_only": 1 - }, - { - "fieldname": "rate", - "fieldtype": "Currency", - "label": "Rate", - "options": "Company:company:default_currency", - "read_only": 1 - }, - { - "fieldname": "amount", - "fieldtype": "Currency", - "label": "Amount", - "options": "Company:company:default_currency", - "read_only": 1 - }, - { - "default": "1", - "fieldname": "conversion_factor", - "fieldtype": "Float", - "hidden": 1, - "label": "Conversion Factor", - "read_only": 1 - }, - { - "fieldname": "current_stock", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Current Stock", - "read_only": 1 - }, - { - "fieldname": "reference_name", - "fieldtype": "Data", - "hidden": 1, - "in_list_view": 1, - "label": "Reference Name", - "read_only": 1 - }, - { - "fieldname": "bom_detail_no", - "fieldtype": "Data", - "hidden": 1, - "in_list_view": 1, - "label": "BOM Detail No", - "read_only": 1 - }, - { - "fieldname": "secbreak_1", - "fieldtype": "Section Break" - }, - { - "fieldname": "col_break2", - "fieldtype": "Column Break" - }, - { - "fieldname": "secbreak_2", - "fieldtype": "Section Break" - }, - { - "fieldname": "col_break3", - "fieldtype": "Column Break" - }, - { - "fieldname": "secbreak_3", - "fieldtype": "Section Break" - }, - { - "fieldname": "col_break4", - "fieldtype": "Column Break" - }, - { - "fieldname": "item_name", - "fieldtype": "Data", - "label": "Item Name", - "read_only": 1 - }, - { - "fieldname": "subcontracting_order", - "fieldtype": "Link", - "hidden": 1, - "label": "Subcontracting Order", - "no_copy": 1, - "options": "Subcontracting Order", - "print_hide": 1, - "read_only": 1 - }, - { - "default": "0", - "fieldname": "available_qty_for_consumption", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Available Qty For Consumption", - "print_hide": 1, - "read_only": 1 - } - ], - "idx": 1, - "istable": 1, - "links": [], - "modified": "2022-09-02 22:28:53.392381", - "modified_by": "Administrator", - "module": "Subcontracting", - "name": "Subcontracting Receipt Supplied Item", - "naming_rule": "Autoincrement", - "owner": "Administrator", - "permissions": [], - "sort_field": "modified", - "sort_order": "DESC", - "states": [], - "track_changes": 1 + "actions": [], + "creation": "2022-04-18 10:45:16.538479", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "main_item_code", + "rm_item_code", + "item_name", + "bom_detail_no", + "col_break1", + "description", + "stock_uom", + "conversion_factor", + "reference_name", + "secbreak_1", + "rate", + "col_break2", + "amount", + "secbreak_2", + "available_qty_for_consumption", + "required_qty", + "col_break3", + "consumed_qty", + "current_stock", + "secbreak_3", + "batch_no", + "col_break4", + "serial_no", + "subcontracting_order" + ], + "fields": [ + { + "fieldname": "main_item_code", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Item Code", + "options": "Item", + "read_only": 1 + }, + { + "fieldname": "rm_item_code", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Raw Material Item Code", + "options": "Item", + "read_only": 1 + }, + { + "fieldname": "description", + "fieldtype": "Text Editor", + "in_global_search": 1, + "label": "Description", + "print_width": "300px", + "read_only": 1, + "width": "300px" + }, + { + "fieldname": "batch_no", + "fieldtype": "Link", + "label": "Batch No", + "no_copy": 1, + "options": "Batch" + }, + { + "fieldname": "serial_no", + "fieldtype": "Text", + "label": "Serial No", + "no_copy": 1 + }, + { + "fieldname": "col_break1", + "fieldtype": "Column Break" + }, + { + "fieldname": "required_qty", + "fieldtype": "Float", + "label": "Required Qty", + "print_hide": 1, + "read_only": 1 + }, + { + "columns": 2, + "fieldname": "consumed_qty", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Consumed Qty", + "read_only": 1, + "reqd": 1 + }, + { + "fieldname": "stock_uom", + "fieldtype": "Link", + "label": "Stock Uom", + "options": "UOM", + "read_only": 1 + }, + { + "fieldname": "rate", + "fieldtype": "Currency", + "label": "Rate", + "options": "Company:company:default_currency", + "read_only": 1 + }, + { + "fieldname": "amount", + "fieldtype": "Currency", + "label": "Amount", + "options": "Company:company:default_currency", + "read_only": 1 + }, + { + "default": "1", + "fieldname": "conversion_factor", + "fieldtype": "Float", + "hidden": 1, + "label": "Conversion Factor", + "read_only": 1 + }, + { + "fieldname": "current_stock", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Current Stock", + "read_only": 1 + }, + { + "fieldname": "reference_name", + "fieldtype": "Data", + "hidden": 1, + "in_list_view": 1, + "label": "Reference Name", + "read_only": 1 + }, + { + "fieldname": "bom_detail_no", + "fieldtype": "Data", + "hidden": 1, + "in_list_view": 1, + "label": "BOM Detail No", + "read_only": 1 + }, + { + "fieldname": "secbreak_1", + "fieldtype": "Section Break" + }, + { + "fieldname": "col_break2", + "fieldtype": "Column Break" + }, + { + "fieldname": "secbreak_2", + "fieldtype": "Section Break" + }, + { + "fieldname": "col_break3", + "fieldtype": "Column Break" + }, + { + "fieldname": "secbreak_3", + "fieldtype": "Section Break" + }, + { + "fieldname": "col_break4", + "fieldtype": "Column Break" + }, + { + "fieldname": "item_name", + "fieldtype": "Data", + "label": "Item Name", + "read_only": 1 + }, + { + "fieldname": "subcontracting_order", + "fieldtype": "Link", + "hidden": 1, + "label": "Subcontracting Order", + "no_copy": 1, + "options": "Subcontracting Order", + "print_hide": 1, + "read_only": 1 + }, + { + "default": "0", + "fieldname": "available_qty_for_consumption", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Available Qty For Consumption", + "print_hide": 1, + "read_only": 1 + } + ], + "idx": 1, + "istable": 1, + "links": [], + "modified": "2022-11-07 17:17:21.670761", + "modified_by": "Administrator", + "module": "Subcontracting", + "name": "Subcontracting Receipt Supplied Item", + "naming_rule": "Autoincrement", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [], + "track_changes": 1 } \ No newline at end of file From bf4b012cec46cc7df261303d0f5d3106bc61d97c Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Mon, 7 Nov 2022 17:20:52 +0530 Subject: [PATCH 3/9] fix: make `consumed_qty` editable when backflush based on Material Transfer --- .../subcontracting_receipt/subcontracting_receipt.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js index aff76eb50f..eb4d0ca24d 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js @@ -57,6 +57,18 @@ frappe.ui.form.on('Subcontracting Receipt', { filters: { 'company': frm.doc.company } }; }); + + frappe.db.get_single_value('Buying Settings', 'backflush_raw_materials_of_subcontract_based_on').then(val => { + if (val == "Material Transferred for Subcontract") { + cur_frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => { + grid_row.docfields.forEach((df) => { + if (df.fieldname == "consumed_qty") { + df.read_only = 0; + } + }); + }); + } + }); }, refresh: (frm) => { From 5e8a22be24ebd70b494a2dd7ec5af542798f1201 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Mon, 7 Nov 2022 17:37:22 +0530 Subject: [PATCH 4/9] fix: linter --- .../doctype/workstation/workstation.py | 4 +--- .../subcontracting_receipt.js | 14 +++++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/erpnext/manufacturing/doctype/workstation/workstation.py b/erpnext/manufacturing/doctype/workstation/workstation.py index 76795e3c56..3c256221be 100644 --- a/erpnext/manufacturing/doctype/workstation/workstation.py +++ b/erpnext/manufacturing/doctype/workstation/workstation.py @@ -100,9 +100,7 @@ def get_default_holiday_list(): def check_if_within_operating_hours(workstation, operation, from_datetime, to_datetime): if from_datetime and to_datetime: - if not cint( - frappe.db.get_value("Manufacturing Settings", None, "allow_production_on_holidays") - ): + if not frappe.db.get_single_value("Manufacturing Settings", "allow_production_on_holidays"): check_workstation_for_holiday(workstation, from_datetime, to_datetime) if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_overtime")): diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js index eb4d0ca24d..b6bef8c4a0 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js @@ -59,13 +59,13 @@ frappe.ui.form.on('Subcontracting Receipt', { }); frappe.db.get_single_value('Buying Settings', 'backflush_raw_materials_of_subcontract_based_on').then(val => { - if (val == "Material Transferred for Subcontract") { - cur_frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => { - grid_row.docfields.forEach((df) => { - if (df.fieldname == "consumed_qty") { - df.read_only = 0; - } - }); + if (val == 'Material Transferred for Subcontract') { + frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => { + grid_row.docfields.forEach((df) => { + if (df.fieldname == 'consumed_qty') { + df.read_only = 0; + } + }); }); } }); From 2b65b22aa2d9fd6d7ff4b407ecd1bd01f4bc43fa Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 7 Nov 2022 22:48:52 +0530 Subject: [PATCH 5/9] fix: Project filter in timesheet --- .../projects/doctype/timesheet/timesheet.js | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js index e1486de18c..a376bf46a5 100644 --- a/erpnext/projects/doctype/timesheet/timesheet.js +++ b/erpnext/projects/doctype/timesheet/timesheet.js @@ -92,18 +92,26 @@ frappe.ui.form.on("Timesheet", { frm.fields_dict["time_logs"].grid.toggle_enable("billing_hours", false); frm.fields_dict["time_logs"].grid.toggle_enable("is_billable", false); } + + let filters = { + "status": "Open" + }; + + if (frm.doc.customer) { + filters["customer"] = frm.doc.customer; + } + + frm.set_query('parent_project', function(doc) { + return { + filters: filters + }; + }); + frm.trigger('setup_filters'); frm.trigger('set_dynamic_field_label'); }, customer: function(frm) { - frm.set_query('parent_project', function(doc) { - return { - filters: { - "customer": doc.customer - } - }; - }); frm.set_query('project', 'time_logs', function(doc) { return { filters: { From 0448c0fa360183d31168cd9952df4ac8c6334eea Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 19 Oct 2022 22:00:40 +0530 Subject: [PATCH 6/9] feat: Repost Payment Ledger entries for vouchers primarily intended to manually correct PLE entries for vouchers affected by Item Value repost-https://github.com/frappe/erpnext/pull/32567 --- .../doctype/repost_payment_ledger/__init__.py | 0 .../repost_payment_ledger.js | 53 ++++++ .../repost_payment_ledger.json | 159 ++++++++++++++++++ .../repost_payment_ledger.py | 111 ++++++++++++ .../repost_payment_ledger_list.js | 12 ++ .../test_repost_payment_ledger.py | 9 + .../repost_payment_ledger_items/__init__.py | 0 .../repost_payment_ledger_items.json | 35 ++++ .../repost_payment_ledger_items.py | 9 + 9 files changed, 388 insertions(+) create mode 100644 erpnext/accounts/doctype/repost_payment_ledger/__init__.py create mode 100644 erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.js create mode 100644 erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json create mode 100644 erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.py create mode 100644 erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger_list.js create mode 100644 erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py create mode 100644 erpnext/accounts/doctype/repost_payment_ledger_items/__init__.py create mode 100644 erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.json create mode 100644 erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.py diff --git a/erpnext/accounts/doctype/repost_payment_ledger/__init__.py b/erpnext/accounts/doctype/repost_payment_ledger/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.js b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.js new file mode 100644 index 0000000000..6801408c7b --- /dev/null +++ b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.js @@ -0,0 +1,53 @@ +// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Repost Payment Ledger', { + setup: function(frm) { + frm.set_query("voucher_type", () => { + return { + filters: { + name: ['in', ['Purchase Invoice', 'Sales Invoice', 'Payment Entry', 'Journal Entry']] + } + }; + }); + + frm.fields_dict['repost_vouchers'].grid.get_field('voucher_type').get_query = function(doc) { + return { + filters: { + name: ['in', ['Purchase Invoice', 'Sales Invoice', 'Payment Entry', 'Journal Entry']] + } + } + } + + frm.fields_dict['repost_vouchers'].grid.get_field('voucher_no').get_query = function(doc) { + if (doc.company) { + return { + filters: { + company: doc.company, + docstatus: 1 + } + } + } + } + + }, + refresh: function(frm) { + + if (frm.doc.docstatus==1 && ['Queued', 'Failed'].find(x => x == frm.doc.repost_status)) { + frm.set_intro(__("Use 'Repost in background' button to trigger background job. Job can only be triggered when document is in Queued or Failed status.")); + var btn_label = __("Repost in background") + + frm.add_custom_button(btn_label, () => { + frappe.call({ + method: 'erpnext.accounts.doctype.repost_payment_ledger.repost_payment_ledger.execute_repost_payment_ledger', + args: { + docname: frm.doc.name, + } + }); + frappe.msgprint(__('Reposting in the background.')); + }); + } + + } +}); + diff --git a/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json new file mode 100644 index 0000000000..5175fd169f --- /dev/null +++ b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json @@ -0,0 +1,159 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2022-10-19 21:59:33.553852", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "filters_section", + "company", + "posting_date", + "column_break_4", + "voucher_type", + "add_manually", + "status_section", + "repost_status", + "repost_error_log", + "selected_vouchers_section", + "repost_vouchers", + "amended_from" + ], + "fields": [ + { + "default": "Today", + "fieldname": "posting_date", + "fieldtype": "Date", + "label": "Posting Date", + "reqd": 1 + }, + { + "fieldname": "voucher_type", + "fieldtype": "Link", + "label": "Voucher Type", + "options": "DocType" + }, + { + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Repost Payment Ledger", + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "company", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Company", + "options": "Company", + "reqd": 1 + }, + { + "fieldname": "selected_vouchers_section", + "fieldtype": "Section Break", + "label": "Vouchers" + }, + { + "fieldname": "filters_section", + "fieldtype": "Section Break", + "label": "Filters" + }, + { + "fieldname": "column_break_4", + "fieldtype": "Column Break" + }, + { + "fieldname": "repost_vouchers", + "fieldtype": "Table", + "label": "Selected Vouchers", + "options": "Repost Payment Ledger Items" + }, + { + "fieldname": "repost_status", + "fieldtype": "Select", + "label": "Repost Status", + "options": "\nQueued\nFailed\nCompleted", + "read_only": 1 + }, + { + "fieldname": "status_section", + "fieldtype": "Section Break", + "label": "Status" + }, + { + "default": "0", + "description": "Ignore Voucher Type filter and Select Vouchers Manually", + "fieldname": "add_manually", + "fieldtype": "Check", + "label": "Add Manually" + }, + { + "depends_on": "eval:doc.repost_error_log", + "fieldname": "repost_error_log", + "fieldtype": "Long Text", + "label": "Repost Error Log" + } + ], + "index_web_pages_for_search": 1, + "is_submittable": 1, + "links": [], + "modified": "2022-11-08 07:38:40.079038", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Repost Payment Ledger", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "submit": 1, + "write": 1 + }, + { + "create": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "share": 1, + "write": 1 + }, + { + "email": 1, + "export": 1, + "permlevel": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.py b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.py new file mode 100644 index 0000000000..9f6828fb73 --- /dev/null +++ b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.py @@ -0,0 +1,111 @@ +# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import copy + +import frappe +from frappe import _, qb +from frappe.model.document import Document +from frappe.query_builder.custom import ConstantColumn +from frappe.utils.background_jobs import is_job_queued + +from erpnext.accounts.utils import _delete_pl_entries, create_payment_ledger_entry + +VOUCHER_TYPES = ["Sales Invoice", "Purchase Invoice", "Payment Entry", "Journal Entry"] + + +def repost_ple_for_voucher(voucher_type, voucher_no, gle_map=None): + if voucher_type and voucher_no and gle_map: + _delete_pl_entries(voucher_type, voucher_no) + create_payment_ledger_entry(gle_map, cancel=0) + + +@frappe.whitelist() +def start_payment_ledger_repost(docname=None): + """ + Repost Payment Ledger Entries for Vouchers through Background Job + """ + if docname: + repost_doc = frappe.get_doc("Repost Payment Ledger", docname) + if repost_doc.docstatus == 1 and repost_doc.repost_status in ["Queued", "Failed"]: + try: + for entry in repost_doc.repost_vouchers: + doc = frappe.get_doc(entry.voucher_type, entry.voucher_no) + + if doc.doctype in ["Payment Entry", "Journal Entry"]: + gle_map = doc.build_gl_map() + else: + gle_map = doc.get_gl_entries() + + repost_ple_for_voucher(entry.voucher_type, entry.voucher_no, gle_map) + + frappe.db.set_value(repost_doc.doctype, repost_doc.name, "repost_error_log", "") + frappe.db.set_value(repost_doc.doctype, repost_doc.name, "repost_status", "Completed") + except Exception as e: + frappe.db.rollback() + + traceback = frappe.get_traceback() + if traceback: + message = "Traceback:
" + traceback + frappe.db.set_value(repost_doc.doctype, repost_doc.name, "repost_error_log", message) + + frappe.db.set_value(repost_doc.doctype, repost_doc.name, "repost_status", "Failed") + + +class RepostPaymentLedger(Document): + def __init__(self, *args, **kwargs): + super(RepostPaymentLedger, self).__init__(*args, **kwargs) + self.vouchers = [] + + def before_validate(self): + self.load_vouchers_based_on_filters() + self.set_status() + + def load_vouchers_based_on_filters(self): + if not self.add_manually: + self.repost_vouchers.clear() + self.get_vouchers() + self.extend("repost_vouchers", copy.deepcopy(self.vouchers)) + + def get_vouchers(self): + self.vouchers.clear() + + filter_on_voucher_types = [self.voucher_type] if self.voucher_type else VOUCHER_TYPES + + for vtype in filter_on_voucher_types: + doc = qb.DocType(vtype) + doctype_name = ConstantColumn(vtype) + query = ( + qb.from_(doc) + .select(doctype_name.as_("voucher_type"), doc.name.as_("voucher_no")) + .where( + (doc.docstatus == 1) + & (doc.company == self.company) + & (doc.posting_date.gte(self.posting_date)) + ) + ) + entries = query.run(as_dict=True) + self.vouchers.extend(entries) + + def set_status(self): + if self.docstatus == 0: + self.repost_status = "Queued" + + def on_submit(self): + execute_repost_payment_ledger(self.name) + frappe.msgprint(_("Repost started in the background")) + + +@frappe.whitelist() +def execute_repost_payment_ledger(docname): + """Repost Payment Ledger Entries by background job.""" + + job_name = "payment_ledger_repost_" + docname + + if not is_job_queued(job_name): + frappe.enqueue( + method="erpnext.accounts.doctype.repost_payment_ledger.repost_payment_ledger.start_payment_ledger_repost", + docname=docname, + is_async=True, + job_name=job_name, + ) diff --git a/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger_list.js b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger_list.js new file mode 100644 index 0000000000..e0451845ce --- /dev/null +++ b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger_list.js @@ -0,0 +1,12 @@ +frappe.listview_settings["Repost Payment Ledger"] = { + add_fields: ["repost_status"], + get_indicator: function(doc) { + var colors = { + 'Queued': 'orange', + 'Completed': 'green', + 'Failed': 'red', + }; + let status = doc.repost_status; + return [__(status), colors[status], 'status,=,'+status]; + }, +}; diff --git a/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py b/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py new file mode 100644 index 0000000000..781726a1e3 --- /dev/null +++ b/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py @@ -0,0 +1,9 @@ +# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestRepostPaymentLedger(FrappeTestCase): + pass diff --git a/erpnext/accounts/doctype/repost_payment_ledger_items/__init__.py b/erpnext/accounts/doctype/repost_payment_ledger_items/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.json b/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.json new file mode 100644 index 0000000000..93005ee137 --- /dev/null +++ b/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.json @@ -0,0 +1,35 @@ +{ + "actions": [], + "creation": "2022-10-20 10:44:18.796489", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "voucher_type", + "voucher_no" + ], + "fields": [ + { + "fieldname": "voucher_type", + "fieldtype": "Link", + "label": "Voucher Type", + "options": "DocType" + }, + { + "fieldname": "voucher_no", + "fieldtype": "Dynamic Link", + "label": "Voucher No", + "options": "voucher_type" + } + ], + "istable": 1, + "links": [], + "modified": "2022-10-28 14:47:11.838109", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Repost Payment Ledger Items", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.py b/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.py new file mode 100644 index 0000000000..fb19e84f26 --- /dev/null +++ b/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.py @@ -0,0 +1,9 @@ +# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class RepostPaymentLedgerItems(Document): + pass From 7b5cf6978ed11fa251dce7bbb961088ac20ab1d6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 8 Nov 2022 11:00:48 +0530 Subject: [PATCH 7/9] chore: Linting Issues --- erpnext/manufacturing/doctype/workstation/workstation.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/erpnext/manufacturing/doctype/workstation/workstation.py b/erpnext/manufacturing/doctype/workstation/workstation.py index 76795e3c56..471ea47710 100644 --- a/erpnext/manufacturing/doctype/workstation/workstation.py +++ b/erpnext/manufacturing/doctype/workstation/workstation.py @@ -100,9 +100,7 @@ def get_default_holiday_list(): def check_if_within_operating_hours(workstation, operation, from_datetime, to_datetime): if from_datetime and to_datetime: - if not cint( - frappe.db.get_value("Manufacturing Settings", None, "allow_production_on_holidays") - ): + if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_production_on_holidays")): check_workstation_for_holiday(workstation, from_datetime, to_datetime) if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_overtime")): From 84ab100d86a6003a1b58e4dac1ee1e5698093f39 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Tue, 8 Nov 2022 12:05:15 +0530 Subject: [PATCH 8/9] chore: remove `debugger` from `stock_entry_list.js` --- erpnext/stock/doctype/stock_entry/stock_entry_list.js | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry_list.js b/erpnext/stock/doctype/stock_entry/stock_entry_list.js index 4eb0da11d2..af29d495ff 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry_list.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry_list.js @@ -3,7 +3,6 @@ frappe.listview_settings['Stock Entry'] = { "`tabStock Entry`.`purpose`", "`tabStock Entry`.`work_order`", "`tabStock Entry`.`bom_no`", "`tabStock Entry`.`is_return`"], get_indicator: function (doc) { - debugger if(doc.is_return===1 && doc.purpose === "Material Transfer for Manufacture") { return [__("Material Returned from WIP"), "orange", "is_return,=,1|purpose,=,Material Transfer for Manufacture|docstatus,<,2"]; From 47248251e22315f6e4542c342619c2a22f1e98b5 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Tue, 8 Nov 2022 12:29:41 +0530 Subject: [PATCH 9/9] chore: link SCR Return in SCR Dashboard --- .../subcontracting_receipt_dashboard.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py index a9e51937d7..deb8342b83 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py @@ -4,6 +4,9 @@ from frappe import _ def get_data(): return { "fieldname": "subcontracting_receipt_no", + "non_standard_fieldnames": { + "Subcontracting Receipt": "return_against", + }, "internal_links": { "Subcontracting Order": ["items", "subcontracting_order"], "Project": ["items", "project"], @@ -11,5 +14,6 @@ def get_data(): }, "transactions": [ {"label": _("Reference"), "items": ["Subcontracting Order", "Quality Inspection", "Project"]}, + {"label": _("Returns"), "items": ["Subcontracting Receipt"]}, ], }