feat: rework dunning frontend
diff --git a/erpnext/accounts/doctype/dunning/dunning.js b/erpnext/accounts/doctype/dunning/dunning.js
index 2f997ba..5158cc2 100644
--- a/erpnext/accounts/doctype/dunning/dunning.js
+++ b/erpnext/accounts/doctype/dunning/dunning.js
@@ -23,14 +23,12 @@
}
};
});
+
+ // cannot add rows manually, only via button "Fetch Overdue Payments"
+ frm.set_df_property("overdue_payments", "cannot_add_rows", true);
},
refresh: function (frm) {
frm.set_df_property("company", "read_only", frm.doc.__islocal ? 0 : 1);
- frm.set_df_property(
- "sales_invoice",
- "read_only",
- frm.doc.__islocal ? 0 : 1
- );
if (frm.doc.docstatus === 1 && frm.doc.status === "Unresolved") {
frm.add_custom_button(__("Resolve"), () => {
frm.set_value("status", "Resolved");
@@ -58,25 +56,27 @@
frappe.set_route("query-report", "General Ledger");
}, __('View'));
}
- },
- overdue_days: function (frm) {
- frappe.db.get_value(
- "Dunning Type",
- {
- start_day: ["<", frm.doc.overdue_days],
- end_day: [">=", frm.doc.overdue_days],
- },
- "dunning_type",
- (r) => {
- if (r) {
- frm.set_value("dunning_type", r.dunning_type);
- } else {
- frm.set_value("dunning_type", "");
- frm.set_value("rate_of_interest", "");
- frm.set_value("dunning_fee", "");
- }
- }
- );
+
+ if(frm.doc.docstatus === 0) {
+ frm.add_custom_button(__("Fetch Overdue Payments"), function() {
+ erpnext.utils.map_current_doc({
+ method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.create_dunning",
+ source_doctype: "Sales Invoice",
+ target: frm,
+ setters: {
+ customer: frm.doc.customer || undefined,
+ },
+ get_query_filters: {
+ docstatus: 1,
+ status: "Overdue",
+ company: frm.doc.company
+ },
+ allow_child_item_selection: true,
+ child_fielname: "payment_schedule",
+ child_columns: ["due_date", "outstanding"]
+ });
+ });
+ }
},
dunning_type: function (frm) {
frm.trigger("get_dunning_letter_text");
@@ -107,42 +107,43 @@
});
}
},
- due_date: function (frm) {
- frm.trigger("calculate_overdue_days");
- },
posting_date: function (frm) {
frm.trigger("calculate_overdue_days");
},
rate_of_interest: function (frm) {
- frm.trigger("calculate_interest_and_amount");
- },
- outstanding_amount: function (frm) {
- frm.trigger("calculate_interest_and_amount");
- },
- interest_amount: function (frm) {
- frm.trigger("calculate_interest_and_amount");
+ frm.trigger("calculate_interest_amount");
},
dunning_fee: function (frm) {
- frm.trigger("calculate_interest_and_amount");
- },
- sales_invoice: function (frm) {
- frm.trigger("calculate_overdue_days");
+ frm.trigger("calculate_totals");
},
calculate_overdue_days: function (frm) {
- if (frm.doc.posting_date && frm.doc.due_date) {
- const overdue_days = moment(frm.doc.posting_date).diff(
- frm.doc.due_date,
- "days"
- );
- frm.set_value("overdue_days", overdue_days);
- }
+ frm.doc.overdue_payments.forEach((row) => {
+ if (frm.doc.posting_date && row.due_date) {
+ const overdue_days = moment(frm.doc.posting_date).diff(
+ row.due_date,
+ "days"
+ );
+ frappe.model.set_value(row.doctype, row.name, "overdue_days", overdue_days);
+ }
+ });
},
- calculate_interest_and_amount: function (frm) {
- const interest_per_year = frm.doc.outstanding_amount * frm.doc.rate_of_interest / 100;
- const interest_amount = flt((interest_per_year * cint(frm.doc.overdue_days)) / 365 || 0, precision('interest_amount'));
- const dunning_amount = flt(interest_amount + frm.doc.dunning_fee, precision('dunning_amount'));
- const grand_total = flt(frm.doc.outstanding_amount + dunning_amount, precision('grand_total'));
- frm.set_value("interest_amount", interest_amount);
+ calculate_interest_amount: function (frm) {
+ frm.doc.overdue_payments.forEach((row) => {
+ const interest_per_year = row.outstanding * frm.doc.rate_of_interest / 100;
+ const interest_amount = flt((interest_per_year * cint(row.overdue_days)) / 365 || 0, precision("interest_amount"));
+ frappe.model.set_value(row.doctype, row.name, "interest_amount", interest_amount);
+ });
+ },
+ calculate_totals: function (frm) {
+ const total_interest = frm.doc.overdue_payments
+ .reduce((prev, cur) => prev + cur.interest_amount, 0);
+ const total_outstanding = frm.doc.overdue_payments
+ .reduce((prev, cur) => prev + cur.outstanding, 0);
+ const dunning_amount = flt(total_interest + frm.doc.dunning_fee, precision('dunning_amount'));
+ const grand_total = flt(total_outstanding + dunning_amount, precision('grand_total'));
+
+ frm.set_value("total_outstanding", total_outstanding);
+ frm.set_value("total_interest", total_interest);
frm.set_value("dunning_amount", dunning_amount);
frm.set_value("grand_total", grand_total);
},
@@ -161,3 +162,9 @@
});
},
});
+
+frappe.ui.form.on("Overdue Payment", {
+ interest_amount: function(frm, cdt, cdn) {
+ frm.trigger("calculate_totals");
+ }
+});
\ No newline at end of file