diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 22a63139942..aa70f957191 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -302,4 +302,5 @@ erpnext.patches.v13_0.create_custom_field_for_finance_book erpnext.patches.v13_0.modify_invalid_gain_loss_gl_entries erpnext.patches.v13_0.fix_additional_cost_in_mfg_stock_entry erpnext.patches.v13_0.set_status_in_maintenance_schedule_table -erpnext.patches.v13_0.add_default_interview_notification_templates \ No newline at end of file +erpnext.patches.v13_0.add_default_interview_notification_templates +erpnext.patches.v13_0.single_to_multi_dunning \ No newline at end of file diff --git a/erpnext/patches/v13_0/single_to_multi_dunning.py b/erpnext/patches/v13_0/single_to_multi_dunning.py new file mode 100644 index 00000000000..40fba041ef1 --- /dev/null +++ b/erpnext/patches/v13_0/single_to_multi_dunning.py @@ -0,0 +1,46 @@ +import frappe +from erpnext.accounts.general_ledger import make_reverse_gl_entries + +def execute(): + frappe.reload_doc("accounts", "doctype", "overdue_payment") + frappe.reload_doc("accounts", "doctype", "dunning") + + all_dunnings = frappe.get_all("Dunning", pluck="name") + for dunning_name in all_dunnings: + dunning = frappe.get_doc("Dunning", dunning_name) + if not dunning.sales_invoice: + # nothing we can do + continue + + if dunning.overdue_payments: + # something's already here, doesn't need patching + continue + + payment_schedules = frappe.get_all("Payment Schedule", + filters={"parent": dunning.sales_invoice}, + fields=[ + "parent as sales_invoice", + "name as payment_schedule", + "payment_term", + "due_date", + "invoice_portion", + "payment_amount", + # at the time of creating this dunning, the full amount was outstanding + "payment_amount as outstanding", + "'0' as paid_amount", + "discounted_amount" + ] + ) + + dunning.extend("overdue_payments", payment_schedules) + dunning.validate() + + dunning.flags.ignore_validate_update_after_submit = True + dunning.save() + + if dunning.status != "Resolved": + # With the new logic, dunning amount gets recorded as additional income + # at time of payment. We don't want to record the dunning amount twice, + # so we reverse previous GL Entries that recorded the dunning amount at + # time of submission of the Dunning. + make_reverse_gl_entries(voucher_type="Dunning", voucher_no=dunning.name)