From d6bc121999352d300dc3aa188d14092a226d8e60 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 25 Nov 2021 13:15:25 +0530 Subject: [PATCH 01/12] fix: Validate Finished Goods for Independent Manufacture entries as well - Check if FG exists even if WO is absent - Check if multiple FGs are there, block. --- .../stock/doctype/stock_entry/stock_entry.py | 53 +++++++++++++------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index d31e65a4cc5..bc722b31b20 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -719,21 +719,34 @@ class StockEntry(StockController): return finished_item def validate_finished_goods(self): - """validation: finished good quantity should be same as manufacturing quantity""" - if not self.work_order: return + """ + 1. Check if FG exists + 2. Check if Multiple FG Items are present + 3. Check FG Item and Qty against WO if present + """ + production_item, wo_qty, finished_items = None, 0, [] - production_item, wo_qty = frappe.db.get_value("Work Order", - self.work_order, ["production_item", "qty"]) + wo_details = frappe.db.get_value( + "Work Order", self.work_order, ["production_item", "qty"] + ) + if wo_details: + production_item, wo_qty = wo_details - finished_items = [] for d in self.get('items'): if d.is_finished_item: + if not self.work_order: + finished_items.append(d.item_code) + continue # Independent Manufacture Entry, no WO to match against + if d.item_code != production_item: frappe.throw(_("Finished Item {0} does not match with Work Order {1}") - .format(d.item_code, self.work_order)) + .format(d.item_code, self.work_order) + ) elif flt(d.transfer_qty) > flt(self.fg_completed_qty): - frappe.throw(_("Quantity in row {0} ({1}) must be same as manufactured quantity {2}"). \ - format(d.idx, d.transfer_qty, self.fg_completed_qty)) + frappe.throw(_("Quantity in row {0} ({1}) must be same as manufactured quantity {2}") + .format(d.idx, d.transfer_qty, self.fg_completed_qty) + ) + finished_items.append(d.item_code) if len(set(finished_items)) > 1: @@ -741,16 +754,24 @@ class StockEntry(StockController): if self.purpose == "Manufacture": if not finished_items: - frappe.throw(_('Finished Good has not set in the stock entry {0}') - .format(self.name)) + frappe.throw( + msg=_("There must be atleast 1 Finished Good in this Stock Entry").format(self.name), + title=_("Missing Finished Good") + ) - allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings", - "overproduction_percentage_for_work_order")) + allowance_percentage = flt( + frappe.db.get_single_value( + "Manufacturing Settings","overproduction_percentage_for_work_order" + ) + ) + allowed_qty = wo_qty + ((allowance_percentage/100) * wo_qty) - allowed_qty = wo_qty + (allowance_percentage/100 * wo_qty) - if self.fg_completed_qty > allowed_qty: - frappe.throw(_("For quantity {0} should not be greater than work order quantity {1}") - .format(flt(self.fg_completed_qty), wo_qty)) + # No work order could mean independent Manufacture entry, if so skip validation + if self.work_order and self.fg_completed_qty > allowed_qty: + frappe.throw( + _("For quantity {0} should not be greater than work order quantity {1}") + .format(flt(self.fg_completed_qty), wo_qty) + ) def update_stock_ledger(self): sl_entries = [] From 8c9779d69dca3744fc057aafeecdf2c31f622d60 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 25 Nov 2021 13:23:10 +0530 Subject: [PATCH 02/12] fix: Dont auto set is finished item or is scrap itm checkbox for independent entry - System cant differentiate between scrap and FG when WO is absent, so dont auto set - User must set it manually - `validate_finished_goods` checks this --- erpnext/stock/doctype/stock_entry/stock_entry.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index bc722b31b20..d3295d61592 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -699,6 +699,11 @@ class StockEntry(StockController): finished_item = self.get_finished_item() + if not finished_item: + # In case of independent Manufacture entry, don't auto set + # user must decide and set + return + for d in self.items: if d.t_warehouse and not d.s_warehouse: if self.purpose=="Repack" or d.item_code == finished_item: From affb29194bc68a2faf1f16bb40cefc4bc307cec1 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 26 Nov 2021 13:19:04 +0530 Subject: [PATCH 03/12] test: Independent Manufacture Entry - Check validations - Check if FG basic rate is calculated correctly --- .../stock/doctype/stock_entry/stock_entry.py | 10 ++++-- .../doctype/stock_entry/test_stock_entry.py | 34 ++++++++++++++++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index d3295d61592..30e0bb84556 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -35,6 +35,7 @@ from erpnext.stock.stock_ledger import NegativeStockError, get_previous_sle, get from erpnext.stock.utils import get_bin, get_incoming_rate +class FinishedGoodError(frappe.ValidationError): pass class IncorrectValuationRateError(frappe.ValidationError): pass class DuplicateEntryForWorkOrderError(frappe.ValidationError): pass class OperationsNotCompleteError(frappe.ValidationError): pass @@ -755,13 +756,18 @@ class StockEntry(StockController): finished_items.append(d.item_code) if len(set(finished_items)) > 1: - frappe.throw(_("Multiple items cannot be marked as finished item")) + frappe.throw( + msg=_("Multiple items cannot be marked as finished item"), + title=_("Note"), + exc=FinishedGoodError + ) if self.purpose == "Manufacture": if not finished_items: frappe.throw( msg=_("There must be atleast 1 Finished Good in this Stock Entry").format(self.name), - title=_("Missing Finished Good") + title=_("Missing Finished Good"), + exc=FinishedGoodError ) allowance_percentage = flt( diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 067946785a9..59cadc4d705 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -15,7 +15,7 @@ from erpnext.stock.doctype.item.test_item import ( set_item_variant_settings, ) from erpnext.stock.doctype.serial_no.serial_no import * # noqa -from erpnext.stock.doctype.stock_entry.stock_entry import move_sample_to_retention_warehouse +from erpnext.stock.doctype.stock_entry.stock_entry import (move_sample_to_retention_warehouse, FinishedGoodError) from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry from erpnext.stock.doctype.stock_ledger_entry.stock_ledger_entry import StockFreezeError from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import ( @@ -868,6 +868,38 @@ class TestStockEntry(unittest.TestCase): distributed_costs = [d.additional_cost for d in se.items] self.assertEqual([40.0, 60.0], distributed_costs) + def test_independent_manufacture_entry(self): + "Test FG items and incoming rate calculation in Maniufacture Entry without WO or BOM linked." + se = frappe.get_doc( + doctype="Stock Entry", + purpose="Manufacture", + stock_entry_type="Manufacture", + company="_Test Company", + items=[ + frappe._dict(item_code="_Test Item", qty=1, basic_rate=200, s_warehouse="_Test Warehouse - _TC"), + frappe._dict(item_code="_Test FG Item", qty=4, t_warehouse="_Test Warehouse 1 - _TC") + ] + ) + # SE must have atleast one FG + self.assertRaises(FinishedGoodError, se.save) + + se.items[0].is_finished_item = 1 + se.items[1].is_finished_item = 1 + # SE cannot have multiple FGs + self.assertRaises(FinishedGoodError, se.save) + + se.items[0].is_finished_item = 0 + se.save() + + # Check if FG cost is calculated based on RM total cost + # RM total cost = 200, FG rate = 200/4(FG qty) = 50 + self.assertEqual(se.items[1].basic_rate, 50) + self.assertEqual(se.value_difference, 0.0) + self.assertEqual(se.total_incoming_value, se.total_outgoing_value) + + # teardown + se.delete() + def make_serialized_item(**args): args = frappe._dict(args) se = frappe.copy_doc(test_records[0]) From dfff972a78e802e3364548bf6378361e51a4c46a Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 26 Nov 2021 13:25:23 +0530 Subject: [PATCH 04/12] fix: Linter (imports) --- erpnext/stock/doctype/stock_entry/test_stock_entry.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 59cadc4d705..1d59e5d6e07 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -15,7 +15,10 @@ from erpnext.stock.doctype.item.test_item import ( set_item_variant_settings, ) from erpnext.stock.doctype.serial_no.serial_no import * # noqa -from erpnext.stock.doctype.stock_entry.stock_entry import (move_sample_to_retention_warehouse, FinishedGoodError) +from erpnext.stock.doctype.stock_entry.stock_entry import ( + FinishedGoodError, + move_sample_to_retention_warehouse, +) from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry from erpnext.stock.doctype.stock_ledger_entry.stock_ledger_entry import StockFreezeError from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import ( From 7d0340e660780e3e678e110ef36b9afc2b51c98e Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 28 Dec 2021 13:06:35 +0530 Subject: [PATCH 05/12] fix: Sider --- erpnext/stock/doctype/stock_entry/stock_entry.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index eae509e9277..fc686d17815 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -35,11 +35,16 @@ from erpnext.stock.stock_ledger import NegativeStockError, get_previous_sle, get from erpnext.stock.utils import get_bin, get_incoming_rate -class FinishedGoodError(frappe.ValidationError): pass -class IncorrectValuationRateError(frappe.ValidationError): pass -class DuplicateEntryForWorkOrderError(frappe.ValidationError): pass -class OperationsNotCompleteError(frappe.ValidationError): pass -class MaxSampleAlreadyRetainedError(frappe.ValidationError): pass +class FinishedGoodError(frappe.ValidationError): + pass +class IncorrectValuationRateError(frappe.ValidationError): + pass +class DuplicateEntryForWorkOrderError(frappe.ValidationError): + pass +class OperationsNotCompleteError(frappe.ValidationError): + pass +class MaxSampleAlreadyRetainedError(frappe.ValidationError): + pass from erpnext.controllers.stock_controller import StockController From 22809a28381ac92336b1fbdb0b1caca2c7b3de7e Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 28 Dec 2021 13:23:27 +0530 Subject: [PATCH 06/12] fix: Avoid Impact on Repack Entry - Repack entries must be considered for fg/scrap checkbox auto set - This must be avoided only for Manufacture entries, due to confusion between scrap and fg - No scrap in repack, so its straight forward --- erpnext/stock/doctype/stock_entry/stock_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index fc686d17815..93e303c9a7f 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -707,7 +707,7 @@ class StockEntry(StockController): finished_item = self.get_finished_item() - if not finished_item: + if not finished_item and self.purpose == "Manufacture": # In case of independent Manufacture entry, don't auto set # user must decide and set return From d807d7831333df9ef462b130ab0b0def229f26e5 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 22 Dec 2021 18:04:49 +0530 Subject: [PATCH 07/12] fix: Issues in Bank Reconciliation tool (cherry picked from commit ff183ee895fb0dd1ca595eb76e2286695063315a) --- .../bank_reconciliation_tool.py | 16 ++++++++-------- .../doctype/bank_transaction/bank_transaction.py | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py index e7371fbe436..4211bd0169d 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py @@ -218,6 +218,8 @@ def reconcile_vouchers(bank_transaction_name, vouchers): # updated clear date of all the vouchers based on the bank transaction vouchers = json.loads(vouchers) transaction = frappe.get_doc("Bank Transaction", bank_transaction_name) + company_account = frappe.db.get_value('Bank Account', transaction.bank_account, 'account') + if transaction.unallocated_amount == 0: frappe.throw(_("This bank transaction is already fully reconciled")) total_amount = 0 @@ -226,7 +228,7 @@ def reconcile_vouchers(bank_transaction_name, vouchers): total_amount += get_paid_amount(frappe._dict({ 'payment_document': voucher['payment_doctype'], 'payment_entry': voucher['payment_name'], - }), transaction.currency) + }), transaction.currency, company_account) if total_amount > transaction.unallocated_amount: frappe.throw(_("The Sum Total of Amounts of All Selected Vouchers Should be Less than the Unallocated Amount of the Bank Transaction")) @@ -261,7 +263,7 @@ def get_linked_payments(bank_transaction_name, document_types = None): return matching def check_matching(bank_account, company, transaction, document_types): - # combine all types of vocuhers + # combine all types of vouchers subquery = get_queries(bank_account, company, transaction, document_types) filters = { "amount": transaction.unallocated_amount, @@ -343,13 +345,11 @@ def get_pe_matching_query(amount_condition, account_from_to, transaction): def get_je_matching_query(amount_condition, transaction): # get matching journal entry query + # We have mapping at the bank level + # So one bank could have both types of bank accounts like asset and liability + # So cr_or_dr should be judged only on basis of withdrawal and deposit and not account type company_account = frappe.get_value("Bank Account", transaction.bank_account, "account") - root_type = frappe.get_value("Account", company_account, "root_type") - - if root_type == "Liability": - cr_or_dr = "debit" if transaction.withdrawal > 0 else "credit" - else: - cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit" + cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit" return f""" diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 46200873044..e877765fe6d 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -102,7 +102,7 @@ def get_total_allocated_amount(payment_entry): AND bt.docstatus = 1""", (payment_entry.payment_document, payment_entry.payment_entry), as_dict=True) -def get_paid_amount(payment_entry, currency): +def get_paid_amount(payment_entry, currency, bank_account): if payment_entry.payment_document in ["Payment Entry", "Sales Invoice", "Purchase Invoice"]: paid_amount_field = "paid_amount" @@ -115,7 +115,7 @@ def get_paid_amount(payment_entry, currency): payment_entry.payment_entry, paid_amount_field) elif payment_entry.payment_document == "Journal Entry": - return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_credit") + return frappe.db.get_value('Journal Entry Account', {'parent': payment_entry.payment_entry, 'account': bank_account}, "sum(credit_in_account_currency)", debug=1) elif payment_entry.payment_document == "Expense Claim": return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_amount_reimbursed") From 057cfb22d693a289a9d01559d8c175c4bdf1a293 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 28 Dec 2021 13:18:17 +0530 Subject: [PATCH 08/12] fix: Remove debug statement (cherry picked from commit becb39da902e7e113c3dacb7eee7921144b8e99d) --- erpnext/accounts/doctype/bank_transaction/bank_transaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index e877765fe6d..44cea31ed38 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -115,7 +115,7 @@ def get_paid_amount(payment_entry, currency, bank_account): payment_entry.payment_entry, paid_amount_field) elif payment_entry.payment_document == "Journal Entry": - return frappe.db.get_value('Journal Entry Account', {'parent': payment_entry.payment_entry, 'account': bank_account}, "sum(credit_in_account_currency)", debug=1) + return frappe.db.get_value('Journal Entry Account', {'parent': payment_entry.payment_entry, 'account': bank_account}, "sum(credit_in_account_currency)") elif payment_entry.payment_document == "Expense Claim": return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_amount_reimbursed") From 095a6e186f4ace26bf8e71bb0d91c43bdaa26d67 Mon Sep 17 00:00:00 2001 From: Development for People <47140294+developmentforpeople@users.noreply.github.com> Date: Tue, 28 Dec 2021 08:38:22 +0000 Subject: [PATCH 09/12] fix: rename non existent doctype field to the right one (#29055) --- erpnext/non_profit/doctype/membership/membership.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index beb38e21108..f9b295a223d 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -409,7 +409,7 @@ def get_plan_from_razorpay_id(plan_id): def set_expired_status(): frappe.db.sql(""" UPDATE - `tabMembership` SET `status` = 'Expired' + `tabMembership` SET `membership_status` = 'Expired' WHERE - `status` not in ('Cancelled') AND `to_date` < %s + `membership_status` not in ('Cancelled') AND `to_date` < %s """, (nowdate())) From 6f933db3cc03b48e9eaf904d42a5ab31a36a76d7 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 28 Dec 2021 14:16:19 +0530 Subject: [PATCH 10/12] fix: Deferred revenue test case --- .../accounts/doctype/purchase_invoice/test_purchase_invoice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index aa2408e092e..cb18dd3b176 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -986,7 +986,7 @@ class TestPurchaseInvoice(unittest.TestCase): pi = make_purchase_invoice(item=item.name, qty=1, rate=100, do_not_save=True) pi.set_posting_time = 1 - pi.posting_date = '2019-03-15' + pi.posting_date = '2019-01-10' pi.items[0].enable_deferred_expense = 1 pi.items[0].service_start_date = "2019-01-10" pi.items[0].service_end_date = "2019-03-15" From 087ebcae5a6ac6c8f4bafde9a46c0bda735247bb Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Tue, 28 Dec 2021 15:34:50 +0530 Subject: [PATCH 11/12] Merge pull request #29014 from ankush/rename_sr_no fix!: disable renaming on serial nos --- erpnext/stock/doctype/serial_no/serial_no.json | 5 +++-- erpnext/stock/doctype/serial_no/serial_no.py | 17 ----------------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/erpnext/stock/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json index a3d44af4945..6e1e0d461ab 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.json +++ b/erpnext/stock/doctype/serial_no/serial_no.json @@ -1,7 +1,6 @@ { "actions": [], "allow_import": 1, - "allow_rename": 1, "autoname": "field:serial_no", "creation": "2013-05-16 10:59:15", "description": "Distinct unit of an Item", @@ -434,10 +433,11 @@ "icon": "fa fa-barcode", "idx": 1, "links": [], - "modified": "2021-01-08 14:31:15.375996", + "modified": "2021-12-23 10:44:30.299450", "modified_by": "Administrator", "module": "Stock", "name": "Serial No", + "naming_rule": "By fieldname", "owner": "Administrator", "permissions": [ { @@ -476,5 +476,6 @@ "show_name_in_global_search": 1, "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 38291d19ec3..2947fafe525 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -194,23 +194,6 @@ class SerialNo(StockController): if sle_exists: frappe.throw(_("Cannot delete Serial No {0}, as it is used in stock transactions").format(self.name)) - def before_rename(self, old, new, merge=False): - if merge: - frappe.throw(_("Sorry, Serial Nos cannot be merged")) - - def after_rename(self, old, new, merge=False): - """rename serial_no text fields""" - for dt in frappe.db.sql("""select parent from tabDocField - where fieldname='serial_no' and fieldtype in ('Text', 'Small Text', 'Long Text')"""): - - for item in frappe.db.sql("""select name, serial_no from `tab%s` - where serial_no like %s""" % (dt[0], frappe.db.escape('%' + old + '%'))): - - serial_nos = map(lambda i: new if i.upper()==old.upper() else i, item[1].split('\n')) - frappe.db.sql("""update `tab%s` set serial_no = %s - where name=%s""" % (dt[0], '%s', '%s'), - ('\n'.join(list(serial_nos)), item[0])) - def update_serial_no_reference(self, serial_no=None): last_sle = self.get_last_sle(serial_no) self.set_purchase_details(last_sle.get("purchase_sle")) From 88df5ce5306552739315be78ed5f667054c7b1f8 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Tue, 28 Dec 2021 17:09:46 +0530 Subject: [PATCH 12/12] fix: tests (#29051) * fix(test): create salary slip as per timesheet dates for Project Profitability * fix(test): reload salary slip before checking for payment days --- erpnext/payroll/doctype/salary_slip/test_salary_slip.py | 1 + .../project_profitability/test_project_profitability.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py index 3052a2b7278..6e8fae0c1a6 100644 --- a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py +++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py @@ -171,6 +171,7 @@ class TestSalarySlip(unittest.TestCase): salary_slip.end_date = month_end_date salary_slip.save() salary_slip.submit() + salary_slip.reload() no_of_days = self.get_no_of_days() days_in_month = no_of_days[0] diff --git a/erpnext/projects/report/project_profitability/test_project_profitability.py b/erpnext/projects/report/project_profitability/test_project_profitability.py index 04156902f7f..1eb3d0d717b 100644 --- a/erpnext/projects/report/project_profitability/test_project_profitability.py +++ b/erpnext/projects/report/project_profitability/test_project_profitability.py @@ -25,6 +25,7 @@ class TestProjectProfitability(unittest.TestCase): self.timesheet = make_timesheet(emp, is_billable=1) self.salary_slip = make_salary_slip(self.timesheet.name) + self.salary_slip.start_date = self.timesheet.start_date holidays = self.salary_slip.get_holidays_for_employee(date, date) if holidays: @@ -41,8 +42,8 @@ class TestProjectProfitability(unittest.TestCase): def test_project_profitability(self): filters = { 'company': '_Test Company', - 'start_date': add_days(getdate(), -3), - 'end_date': getdate() + 'start_date': add_days(self.timesheet.start_date, -3), + 'end_date': self.timesheet.start_date } report = execute(filters)