From d019d28bc9e5337f241753d30340a8306740cadd Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 17 Sep 2019 18:45:59 +0530 Subject: [PATCH 01/12] fix: Customer Ledger Summary report not working on python 3 (#19092) --- .../report/customer_ledger_summary/customer_ledger_summary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py index 7872dbe7b1..2cb10b11e1 100644 --- a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py +++ b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py @@ -286,14 +286,14 @@ class PartyLedgerSummaryReport(object): if parties and accounts: if len(parties) == 1: - party = parties.keys()[0] + party = list(parties.keys())[0] for account, amount in iteritems(accounts): self.party_adjustment_accounts.add(account) self.party_adjustment_details.setdefault(party, {}) self.party_adjustment_details[party].setdefault(account, 0) self.party_adjustment_details[party][account] += amount elif len(accounts) == 1 and not has_irrelevant_entry: - account = accounts.keys()[0] + account = list(accounts.keys())[0] self.party_adjustment_accounts.add(account) for party, amount in iteritems(parties): self.party_adjustment_details.setdefault(party, {}) From 780fb8a4e520472eebf4374479378c5013ba8836 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 17 Sep 2019 18:46:50 +0530 Subject: [PATCH 02/12] fix: set stock adjustment account for the raw materials instead of COGS (#19090) --- erpnext/manufacturing/doctype/bom/bom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 8eb4c9c28c..f82afb766c 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -648,7 +648,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite item_dict[item.item_code] = item for item, item_details in item_dict.items(): - for d in [["Account", "expense_account", "default_expense_account"], + for d in [["Account", "expense_account", "stock_adjustment_account"], ["Cost Center", "cost_center", "cost_center"], ["Warehouse", "default_warehouse", ""]]: company_in_record = frappe.db.get_value(d[0], item_details.get(d[1]), "company") if not item_details.get(d[1]) or (company_in_record and company != company_in_record): From aeaf416d6dc27d0b07ce913a4cb0de3d30f92167 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Wed, 18 Sep 2019 13:11:30 +0530 Subject: [PATCH 03/12] fix: upload attendance template not marking attendance --- erpnext/hr/doctype/upload_attendance/upload_attendance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.py b/erpnext/hr/doctype/upload_attendance/upload_attendance.py index f452155681..1707e3578b 100644 --- a/erpnext/hr/doctype/upload_attendance/upload_attendance.py +++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.py @@ -60,8 +60,8 @@ def get_data(args): existing_attendance = {} if existing_attendance_records \ and tuple([getdate(date), employee.name]) in existing_attendance_records \ - and getdate(employee.date_of_joining) >= getdate(date) \ - and getdate(employee.relieving_date) <= getdate(date): + and getdate(employee.date_of_joining) <= getdate(date) \ + and getdate(employee.relieving_date) >= getdate(date): existing_attendance = existing_attendance_records[tuple([getdate(date), employee.name])] row = [ existing_attendance and existing_attendance.name or "", From d793e39b6decd988f644a05e7d3a6ca87abc36db Mon Sep 17 00:00:00 2001 From: Marica Date: Wed, 18 Sep 2019 19:59:31 +0530 Subject: [PATCH 04/12] fix: Customer Credit Balance Report query fix (#19104) --- .../customer_credit_balance/customer_credit_balance.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py b/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py index cd50568cf9..f396705460 100644 --- a/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py +++ b/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py @@ -60,7 +60,7 @@ def get_details(filters): conditions = "" if filters.get("customer"): - conditions += " AND c.name = " + filters.get("customer") + conditions += " AND c.name = '" + filters.get("customer") + "'" return frappe.db.sql("""SELECT c.name, c.customer_name, @@ -69,6 +69,6 @@ def get_details(filters): FROM `tabCustomer` c, `tabCustomer Credit Limit` ccl WHERE c.name = ccl.parent - AND ccl.company = %s - {0} - """.format(conditions), (filters.get("company")), as_dict=1) #nosec + AND ccl.company = '{0}' + {1} + """.format( filters.get("company"),conditions), as_dict=1) #nosec From 1ba83427e51d956e0ecdfb563df82c1cce34ba9f Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Wed, 18 Sep 2019 20:04:15 +0530 Subject: [PATCH 05/12] fix: asset maintenance TypeError during date comparisons (#19098) --- .../assets/doctype/asset_maintenance/asset_maintenance.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py index 7551eae229..ecb55dde9a 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py @@ -57,7 +57,7 @@ def calculate_next_due_date(periodicity, start_date = None, end_date = None, las if not start_date and not last_completion_date: start_date = frappe.utils.now() - if last_completion_date and (last_completion_date > start_date or not start_date): + if last_completion_date and ((start_date and last_completion_date > start_date) or not start_date): start_date = last_completion_date if periodicity == 'Daily': next_due_date = add_days(start_date, 1) @@ -71,10 +71,11 @@ def calculate_next_due_date(periodicity, start_date = None, end_date = None, las next_due_date = add_years(start_date, 2) if periodicity == 'Quarterly': next_due_date = add_months(start_date, 3) - if end_date and (start_date >= end_date or last_completion_date >= end_date or next_due_date): + if end_date and ((start_date and start_date >= end_date) or (last_completion_date and last_completion_date >= end_date) or next_due_date): next_due_date = "" return next_due_date + def update_maintenance_log(asset_maintenance, item_code, item_name, task): asset_maintenance_log = frappe.get_value("Asset Maintenance Log", {"asset_maintenance": asset_maintenance, "task": task.maintenance_task, "maintenance_status": ('in',['Planned','Overdue'])}) From 8a097c862713f93c5ab7eaeafca7da3d2063bb7f Mon Sep 17 00:00:00 2001 From: Rohan Date: Wed, 18 Sep 2019 20:05:49 +0530 Subject: [PATCH 06/12] fix: only set times if job card is filled (#19107) --- erpnext/manufacturing/doctype/job_card/job_card.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index a8faa13241..9d2e620e58 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -105,7 +105,6 @@ class JobCard(Document): for_quantity, time_in_mins = 0, 0 from_time_list, to_time_list = [], [] - for d in frappe.get_all('Job Card', filters = {'docstatus': 1, 'operation_id': self.operation_id}): doc = frappe.get_doc('Job Card', d.name) @@ -125,8 +124,8 @@ class JobCard(Document): if data.name == self.operation_id: data.completed_qty = for_quantity data.actual_operation_time = time_in_mins - data.actual_start_time = min(from_time_list) - data.actual_end_time = max(to_time_list) + data.actual_start_time = min(from_time_list) if from_time_list else None + data.actual_end_time = max(to_time_list) if to_time_list else None wo.flags.ignore_validate_update_after_submit = True wo.update_operation_status() From 28d182af15ee3b8780925832b71c43bff258c0d7 Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Thu, 19 Sep 2019 11:13:22 +0530 Subject: [PATCH 07/12] fix: Permission issue in Total Stock Summary report (#19110) Data in "Total Stock Summary" report were not getting filtered based on applied user permissions because some link fields had wrong options --- .../stock/report/total_stock_summary/total_stock_summary.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/report/total_stock_summary/total_stock_summary.py b/erpnext/stock/report/total_stock_summary/total_stock_summary.py index b25e096974..41e2f86f29 100644 --- a/erpnext/stock/report/total_stock_summary/total_stock_summary.py +++ b/erpnext/stock/report/total_stock_summary/total_stock_summary.py @@ -15,8 +15,8 @@ def execute(filters=None): def get_columns(): columns = [ - _("Company") + ":Link/Item:250", - _("Warehouse") + ":Link/Item:150", + _("Company") + ":Link/Company:250", + _("Warehouse") + ":Link/Warehouse:150", _("Item") + ":Link/Item:150", _("Description") + "::300", _("Current Qty") + ":Float:100", @@ -30,7 +30,7 @@ def get_total_stock(filters): if filters.get("group_by") == "Warehouse": if filters.get("company"): - conditions += " AND warehouse.company = %s" % frappe.db.escape(filters.get("company"), percent=False) + conditions += " AND warehouse.company = '%s'" % frappe.db.escape(filters.get("company"), percent=False) conditions += " GROUP BY ledger.warehouse, item.item_code" columns += "'' as company, ledger.warehouse" From 51eabfe352f46244e8c362a1810f5a8287bb959b Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Thu, 19 Sep 2019 16:57:03 +0530 Subject: [PATCH 08/12] fix: subcontracting material transfer dialog in Purchase Order (#19111) * fix: subcontracting material transfer dialog in Purchase Order * fix: dialog title --- erpnext/buying/doctype/purchase_order/purchase_order.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index b2a2f01f44..ae52437069 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -196,10 +196,10 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( if(items.length >= 1){ me.raw_material_data = []; me.show_dialog = 1; - let title = ""; + let title = __('Transfer Material to Supplier'); let fields = [ {fieldtype:'Section Break', label: __('Raw Materials')}, - {fieldname: 'sub_con_rm_items', fieldtype: 'Table', + {fieldname: 'sub_con_rm_items', fieldtype: 'Table', label: __('Items'), fields: [ { fieldtype:'Data', @@ -271,7 +271,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( 'item_code': item.main_item_code, 'rm_item_code': item.rm_item_code, 'item_name': item.rm_item_code, - 'qty': item.required_qty, + 'qty': item.required_qty - item.supplied_qty, 'warehouse':item.reserve_warehouse, 'rate':item.rate, 'amount':item.amount, From 6daab3ca896ef38c5b0ac66681b88640cec374fc Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 19 Sep 2019 17:01:26 +0530 Subject: [PATCH 09/12] fix: get_bin_details_and_serial_nos() takes at least 3 arguments (4 given) --- erpnext/selling/sales_common.js | 2 +- erpnext/stock/get_item_details.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 000d666d36..e508476576 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -234,7 +234,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ args: { item_code: item.item_code, warehouse: item.warehouse, - has_batch_no: has_batch_no, + has_batch_no: has_batch_no || 0, stock_qty: item.stock_qty, serial_no: item.serial_no || "", }, diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 35c0bb6165..7c2e09e463 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -808,7 +808,7 @@ def get_serial_no_details(item_code, warehouse, stock_qty, serial_no): return {'serial_no': serial_no} @frappe.whitelist() -def get_bin_details_and_serial_nos(item_code, warehouse, has_batch_no, stock_qty=None, serial_no=None): +def get_bin_details_and_serial_nos(item_code, warehouse, has_batch_no=None, stock_qty=None, serial_no=None): bin_details_and_serial_nos = {} bin_details_and_serial_nos.update(get_bin_details(item_code, warehouse)) if flt(stock_qty) > 0: From 8590112faa69fcee1679d0909dff302007c77192 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 19 Sep 2019 17:33:18 +0530 Subject: [PATCH 10/12] fix: Report 'Payment Period based On Invoice Date' --- .../accounts_receivable.py | 4 +++ .../payment_period_based_on_invoice_date.py | 29 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index a7279f75f1..8cbf845863 100755 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -446,6 +446,10 @@ class ReceivablePayableReport(object): row.age = (getdate(self.age_as_on) - getdate(entry_date)).days or 0 index = None + + if not (self.filters.range1 and self.filters.range2 and self.filters.range3 and self.filters.range4): + self.filters.range1, self.filters.range2, self.filters.range3, self.filters.range4 = 30, 60, 90, 120 + for i, days in enumerate([self.filters.range1, self.filters.range2, self.filters.range3, self.filters.range4]): if row.age <= days: index = i diff --git a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py index 24b5d87b5b..57a1231f5a 100644 --- a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py +++ b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py @@ -4,11 +4,14 @@ from __future__ import unicode_literals import frappe from frappe import _ -from erpnext.accounts.report.accounts_receivable.accounts_receivable import get_ageing_data +from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport from frappe.utils import getdate, flt + def execute(filters=None): - if not filters: filters = {} + if not filters: + filters = {} + validate_filters(filters) columns = get_columns(filters) @@ -19,18 +22,28 @@ def execute(filters=None): for d in entries: invoice = invoice_details.get(d.against_voucher) or frappe._dict() - if d.reference_type=="Purchase Invoice": + if d.reference_type == "Purchase Invoice": payment_amount = flt(d.debit) or -1 * flt(d.credit) else: payment_amount = flt(d.credit) or -1 * flt(d.debit) - row = [d.voucher_type, d.voucher_no, d.party_type, d.party, d.posting_date, d.against_voucher, - invoice.posting_date, invoice.due_date, d.debit, d.credit, d.remarks] + d.update({ + "range1": 0, + "range2": 0, + "range3": 0, + "range4": 0, + "outstanding": payment_amount + }) if d.against_voucher: - row += get_ageing_data(30, 60, 90, 120, d.posting_date, invoice.posting_date, payment_amount) - else: - row += ["", "", "", "", ""] + ReceivablePayableReport(filters).get_ageing_data(invoice.posting_date, d) + + row = [ + d.voucher_type, d.voucher_no, d.party_type, d.party, d.posting_date, d.against_voucher, + invoice.posting_date, invoice.due_date, d.debit, d.credit, d.remarks, + d.age, d.range1, d.range2, d.range3, d.range4 + ] + if invoice.due_date: row.append((getdate(d.posting_date) - getdate(invoice.due_date)).days or 0) From c16fb9eb9da0298fb68c5b5280bb8222a684d118 Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Thu, 19 Sep 2019 18:12:39 +0530 Subject: [PATCH 11/12] fix: dashboard button not working (#19094) --- erpnext/buying/doctype/purchase_order/purchase_order.js | 3 ++- erpnext/selling/doctype/sales_order/sales_order.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index ae52437069..c5fa98da09 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -10,7 +10,8 @@ frappe.ui.form.on("Purchase Order", { frm.custom_make_buttons = { 'Purchase Receipt': 'Receipt', 'Purchase Invoice': 'Invoice', - 'Stock Entry': 'Material to Supplier' + 'Stock Entry': 'Material to Supplier', + 'Payment Entry': 'Payment' } frm.set_query("reserve_warehouse", "supplied_items", function() { diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index e86caddb87..d6fd8a1f6f 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -11,7 +11,8 @@ frappe.ui.form.on("Sales Order", { 'Sales Invoice': 'Invoice', 'Material Request': 'Material Request', 'Purchase Order': 'Purchase Order', - 'Project': 'Project' + 'Project': 'Project', + 'Payment Entry': "Payment" } frm.add_fetch('customer', 'tax_id', 'tax_id'); From 0c665e5638c6737b0570648e4a78ca5fb2caea64 Mon Sep 17 00:00:00 2001 From: Sahil Khan Date: Fri, 20 Sep 2019 15:37:21 +0550 Subject: [PATCH 12/12] bumped to version 12.1.4 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index fbf230a971..ff08a726b3 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '12.1.3' +__version__ = '12.1.4' def get_default_company(user=None): '''Get default company for user'''