diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index f1c7c6c7c6..a1b737dffb 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -302,7 +302,7 @@ def get_due_date_from_template(template_name, posting_date): return due_date -def validate_due_date(posting_date, due_date, party_type, party, company): +def validate_due_date(posting_date, due_date, party_type, party): if getdate(due_date) < getdate(posting_date): frappe.throw(_("Due Date cannot be before Posting Date")) else: diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 25ec8637f5..d368d5a5ea 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -47,6 +47,9 @@ class AccountsController(TransactionBase): if self.get("payment_schedule"): self.set_due_date() self.validate_payment_schedule() + else: + self.set_payment_schedule() + self.set_due_date() self.validate_due_date() self.validate_advance_entries() @@ -125,9 +128,9 @@ class AccountsController(TransactionBase): if not self.due_date: frappe.throw(_("Due Date is mandatory")) - validate_due_date(self.posting_date, self.due_date, "Customer", self.customer, self.company) + validate_due_date(self.posting_date, self.due_date, "Customer", self.customer) elif self.doctype == "Purchase Invoice": - validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier, self.company) + validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier) def set_price_list_currency(self, buying_or_selling): if self.meta.get_field("posting_date"): @@ -617,16 +620,13 @@ class AccountsController(TransactionBase): for item in duplicate_list: self.remove(item) - def _set_payment_schedule(self): - if not self.get("payment_schedule"): - if self.due_date: - self.append("payment_schedule", { - "due_date": self.due_date, - "invoice_portion": 100, - "payment_amount": self.grand_total - }) - else: - self.due_date = max([d.due_date for d in self.get("payment_schedule")]) + def set_payment_schedule(self): + due_date = self.due_date or get_due_date(self.posting_date) + self.append("payment_schedule", { + "due_date": due_date, + "invoice_portion": 100, + "payment_amount": self.grand_total + }) def set_due_date(self): self.due_date = max([d.due_date for d in self.get("payment_schedule")]) @@ -643,7 +643,12 @@ class AccountsController(TransactionBase): total += flt(d.payment_amount) if total != self.grand_total: - frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand Total")) + # Try to recover if the Payment Term is a very simple one. + # If there is just one Payment Term and the invoice portion is 100: + if len(self.payment_schedule) == 1 and self.payment_schedule[0].invoice_portion == 100: + self.payment_schedule[0].update({'payment_amount': self.grand_total}) + else: + frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand Total")) @frappe.whitelist() diff --git a/erpnext/controllers/recurring_document.py b/erpnext/controllers/recurring_document.py index 713e9bac2f..6919434bd0 100644 --- a/erpnext/controllers/recurring_document.py +++ b/erpnext/controllers/recurring_document.py @@ -9,6 +9,7 @@ from frappe.utils import cint, cstr, getdate, nowdate, \ from frappe import _, msgprint, throw + month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12} date_field_map = { "Sales Order": "transaction_date", @@ -73,6 +74,7 @@ def manage_recurring_documents(doctype, next_date=None, commit=True): frappe.throw(exception_message) def make_new_document(reference_doc, date_field, posting_date): + from erpnext.controllers.accounts_controller import get_payment_terms new_document = frappe.copy_doc(reference_doc, ignore_no_copy=False) mcount = month_map[reference_doc.recurring_type] @@ -90,7 +92,8 @@ def make_new_document(reference_doc, date_field, posting_date): date_field: posting_date, "from_date": from_date, "to_date": to_date, - "next_date": get_next_date(reference_doc.next_date, mcount,cint(reference_doc.repeat_on_day_of_month)) + "next_date": get_next_date(reference_doc.next_date, mcount,cint(reference_doc.repeat_on_day_of_month)), + "payment_schedule": get_payment_terms("_Test Payment Term Template 3", posting_date, new_document.grand_total) }) if new_document.meta.get_field('set_posting_time'):