feat: discount configuration on early payments (#25089)
* feat: discount configuration on early payments Co-authored-by: Nabin Hait <nabinhait@gmail.com> * fix: remove duplicate patch call Co-authored-by: Nabin Hait <nabinhait@gmail.com>
This commit is contained in:
parent
4d0939de8d
commit
fb4051bddd
@ -637,13 +637,13 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
let to_field = fields[key][1];
|
let to_field = fields[key][1];
|
||||||
|
|
||||||
if (filters[from_field] && !filters[to_field]) {
|
if (filters[from_field] && !filters[to_field]) {
|
||||||
frappe.throw(__("Error: {0} is mandatory field",
|
frappe.throw(
|
||||||
[to_field.replace(/_/g, " ")]
|
__("Error: {0} is mandatory field", [to_field.replace(/_/g, " ")])
|
||||||
));
|
);
|
||||||
} else if (filters[from_field] && filters[from_field] > filters[to_field]) {
|
} else if (filters[from_field] && filters[from_field] > filters[to_field]) {
|
||||||
frappe.throw(__("{0}: {1} must be less than {2}",
|
frappe.throw(
|
||||||
[key, from_field.replace(/_/g, " "), to_field.replace(/_/g, " ")]
|
__("{0}: {1} must be less than {2}", [key, from_field.replace(/_/g, " "), to_field.replace(/_/g, " ")])
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -692,6 +692,8 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
c.total_amount = d.invoice_amount;
|
c.total_amount = d.invoice_amount;
|
||||||
c.outstanding_amount = d.outstanding_amount;
|
c.outstanding_amount = d.outstanding_amount;
|
||||||
c.bill_no = d.bill_no;
|
c.bill_no = d.bill_no;
|
||||||
|
c.payment_term = d.payment_term;
|
||||||
|
c.allocated_amount = d.allocated_amount;
|
||||||
|
|
||||||
if(!in_list(["Sales Order", "Purchase Order", "Expense Claim", "Fees"], d.voucher_type)) {
|
if(!in_list(["Sales Order", "Purchase Order", "Expense Claim", "Fees"], d.voucher_type)) {
|
||||||
if(flt(d.outstanding_amount) > 0)
|
if(flt(d.outstanding_amount) > 0)
|
||||||
@ -774,12 +776,15 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
||||||
if(paid_amount > total_negative_outstanding) {
|
if(paid_amount > total_negative_outstanding) {
|
||||||
if(total_negative_outstanding == 0) {
|
if(total_negative_outstanding == 0) {
|
||||||
frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice",
|
frappe.msgprint(
|
||||||
[frm.doc.payment_type,
|
__("Cannot {0} {1} {2} without any negative outstanding invoice", [frm.doc.payment_type,
|
||||||
(frm.doc.party_type=="Customer" ? "to" : "from"), frm.doc.party_type]));
|
(frm.doc.party_type=="Customer" ? "to" : "from"), frm.doc.party_type])
|
||||||
|
);
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
frappe.msgprint(__("Paid Amount cannot be greater than total negative outstanding amount {0}", [total_negative_outstanding]));
|
frappe.msgprint(
|
||||||
|
__("Paid Amount cannot be greater than total negative outstanding amount {0}", [total_negative_outstanding])
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -791,10 +796,13 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$.each(frm.doc.references || [], function(i, row) {
|
$.each(frm.doc.references || [], function(i, row) {
|
||||||
row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount
|
if (frappe.flags.allocate_payment_amount == 0) {
|
||||||
if(frappe.flags.allocate_payment_amount != 0){
|
//If allocate payment amount checkbox is unchecked, set zero to allocate amount
|
||||||
if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
|
row.allocated_amount = 0;
|
||||||
if(row.outstanding_amount >= allocated_positive_outstanding) {
|
|
||||||
|
} else if (frappe.flags.allocate_payment_amount != 0 && !row.allocated_amount) {
|
||||||
|
if (row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
|
||||||
|
if (row.outstanding_amount >= allocated_positive_outstanding) {
|
||||||
row.allocated_amount = allocated_positive_outstanding;
|
row.allocated_amount = allocated_positive_outstanding;
|
||||||
} else {
|
} else {
|
||||||
row.allocated_amount = row.outstanding_amount;
|
row.allocated_amount = row.outstanding_amount;
|
||||||
@ -802,9 +810,11 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
|
|
||||||
allocated_positive_outstanding -= flt(row.allocated_amount);
|
allocated_positive_outstanding -= flt(row.allocated_amount);
|
||||||
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
|
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
|
||||||
if(Math.abs(row.outstanding_amount) >= allocated_negative_outstanding)
|
if (Math.abs(row.outstanding_amount) >= allocated_negative_outstanding) {
|
||||||
row.allocated_amount = -1*allocated_negative_outstanding;
|
row.allocated_amount = -1*allocated_negative_outstanding;
|
||||||
else row.allocated_amount = row.outstanding_amount;
|
} else {
|
||||||
|
row.allocated_amount = row.outstanding_amount;
|
||||||
|
};
|
||||||
|
|
||||||
allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
|
allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
|
||||||
}
|
}
|
||||||
|
@ -333,33 +333,50 @@ class PaymentEntry(AccountsController):
|
|||||||
invoice_payment_amount_map = {}
|
invoice_payment_amount_map = {}
|
||||||
invoice_paid_amount_map = {}
|
invoice_paid_amount_map = {}
|
||||||
|
|
||||||
for reference in self.get('references'):
|
for ref in self.get('references'):
|
||||||
if reference.payment_term and reference.reference_name:
|
if ref.payment_term and ref.reference_name:
|
||||||
key = (reference.payment_term, reference.reference_name)
|
key = (ref.payment_term, ref.reference_name)
|
||||||
invoice_payment_amount_map.setdefault(key, 0.0)
|
invoice_payment_amount_map.setdefault(key, 0.0)
|
||||||
invoice_payment_amount_map[key] += reference.allocated_amount
|
invoice_payment_amount_map[key] += ref.allocated_amount
|
||||||
|
|
||||||
if not invoice_paid_amount_map.get(key):
|
if not invoice_paid_amount_map.get(key):
|
||||||
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
|
payment_schedule = frappe.get_all(
|
||||||
fields=['paid_amount', 'payment_amount', 'payment_term'])
|
'Payment Schedule',
|
||||||
|
filters={'parent': ref.reference_name},
|
||||||
|
fields=['paid_amount', 'payment_amount', 'payment_term', 'discount', 'outstanding']
|
||||||
|
)
|
||||||
for term in payment_schedule:
|
for term in payment_schedule:
|
||||||
invoice_key = (term.payment_term, reference.reference_name)
|
invoice_key = (term.payment_term, ref.reference_name)
|
||||||
invoice_paid_amount_map.setdefault(invoice_key, {})
|
invoice_paid_amount_map.setdefault(invoice_key, {})
|
||||||
invoice_paid_amount_map[invoice_key]['outstanding'] = term.payment_amount - term.paid_amount
|
invoice_paid_amount_map[invoice_key]['outstanding'] = term.outstanding
|
||||||
|
invoice_paid_amount_map[invoice_key]['discounted_amt'] = ref.total_amount * (term.discount / 100)
|
||||||
|
|
||||||
|
for key, allocated_amount in iteritems(invoice_payment_amount_map):
|
||||||
|
outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
|
||||||
|
discounted_amt = flt(invoice_paid_amount_map.get(key, {}).get('discounted_amt'))
|
||||||
|
|
||||||
for key, amount in iteritems(invoice_payment_amount_map):
|
|
||||||
if cancel:
|
if cancel:
|
||||||
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
|
frappe.db.sql("""
|
||||||
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
UPDATE `tabPayment Schedule`
|
||||||
|
SET
|
||||||
|
paid_amount = `paid_amount` - %s,
|
||||||
|
discounted_amount = `discounted_amount` - %s,
|
||||||
|
outstanding = `outstanding` + %s
|
||||||
|
WHERE parent = %s and payment_term = %s""",
|
||||||
|
(allocated_amount - discounted_amt, discounted_amt, allocated_amount, key[1], key[0]))
|
||||||
else:
|
else:
|
||||||
outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
|
if allocated_amount > outstanding:
|
||||||
|
|
||||||
if amount > outstanding:
|
|
||||||
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
|
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
|
||||||
|
|
||||||
if amount and outstanding:
|
if allocated_amount and outstanding:
|
||||||
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
|
frappe.db.sql("""
|
||||||
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
UPDATE `tabPayment Schedule`
|
||||||
|
SET
|
||||||
|
paid_amount = `paid_amount` + %s,
|
||||||
|
discounted_amount = `discounted_amount` + %s,
|
||||||
|
outstanding = `outstanding` - %s
|
||||||
|
WHERE parent = %s and payment_term = %s""",
|
||||||
|
(allocated_amount - discounted_amt, discounted_amt, allocated_amount, key[1], key[0]))
|
||||||
|
|
||||||
def set_status(self):
|
def set_status(self):
|
||||||
if self.docstatus == 2:
|
if self.docstatus == 2:
|
||||||
@ -704,6 +721,8 @@ def get_outstanding_reference_documents(args):
|
|||||||
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||||
args.get("party_account"), filters=args, condition=condition)
|
args.get("party_account"), filters=args, condition=condition)
|
||||||
|
|
||||||
|
outstanding_invoices = split_invoices_based_on_payment_terms(outstanding_invoices)
|
||||||
|
|
||||||
for d in outstanding_invoices:
|
for d in outstanding_invoices:
|
||||||
d["exchange_rate"] = 1
|
d["exchange_rate"] = 1
|
||||||
if party_account_currency != company_currency:
|
if party_account_currency != company_currency:
|
||||||
@ -731,6 +750,46 @@ def get_outstanding_reference_documents(args):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def split_invoices_based_on_payment_terms(outstanding_invoices):
|
||||||
|
invoice_ref_based_on_payment_terms = {}
|
||||||
|
for idx, d in enumerate(outstanding_invoices):
|
||||||
|
if d.voucher_type in ['Sales Invoice', 'Purchase Invoice']:
|
||||||
|
payment_term_template = frappe.db.get_value(d.voucher_type, d.voucher_no, 'payment_terms_template')
|
||||||
|
if payment_term_template:
|
||||||
|
allocate_payment_based_on_payment_terms = frappe.db.get_value(
|
||||||
|
'Payment Terms Template', payment_term_template, 'allocate_payment_based_on_payment_terms')
|
||||||
|
if allocate_payment_based_on_payment_terms:
|
||||||
|
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': d.voucher_no}, fields=["*"])
|
||||||
|
|
||||||
|
for payment_term in payment_schedule:
|
||||||
|
if payment_term.outstanding > 0.1:
|
||||||
|
invoice_ref_based_on_payment_terms.setdefault(idx, [])
|
||||||
|
invoice_ref_based_on_payment_terms[idx].append(frappe._dict({
|
||||||
|
'due_date': d.due_date,
|
||||||
|
'currency': d.currency,
|
||||||
|
'voucher_no': d.voucher_no,
|
||||||
|
'voucher_type': d.voucher_type,
|
||||||
|
'posting_date': d.posting_date,
|
||||||
|
'invoice_amount': flt(d.invoice_amount),
|
||||||
|
'outstanding_amount': flt(d.outstanding_amount),
|
||||||
|
'payment_amount': payment_term.payment_amount,
|
||||||
|
'payment_term': payment_term.payment_term,
|
||||||
|
'allocated_amount': payment_term.outstanding
|
||||||
|
}))
|
||||||
|
|
||||||
|
if invoice_ref_based_on_payment_terms:
|
||||||
|
for idx, ref in invoice_ref_based_on_payment_terms.items():
|
||||||
|
voucher_no = outstanding_invoices[idx]['voucher_no']
|
||||||
|
voucher_type = outstanding_invoices[idx]['voucher_type']
|
||||||
|
|
||||||
|
frappe.msgprint(_("Spliting {} {} into {} rows as per payment terms").format(
|
||||||
|
voucher_type, voucher_no, len(ref)), alert=True)
|
||||||
|
|
||||||
|
outstanding_invoices.pop(idx - 1)
|
||||||
|
outstanding_invoices += invoice_ref_based_on_payment_terms[idx]
|
||||||
|
|
||||||
|
return outstanding_invoices
|
||||||
|
|
||||||
def get_orders_to_be_billed(posting_date, party_type, party,
|
def get_orders_to_be_billed(posting_date, party_type, party,
|
||||||
company, party_account_currency, company_currency, cost_center=None, filters=None):
|
company, party_account_currency, company_currency, cost_center=None, filters=None):
|
||||||
if party_type == "Customer":
|
if party_type == "Customer":
|
||||||
@ -1083,6 +1142,8 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
paid_amount, received_amount = set_paid_amount_and_received_amount(
|
paid_amount, received_amount = set_paid_amount_and_received_amount(
|
||||||
dt, party_account_currency, bank, outstanding_amount, payment_type, bank_amount, doc)
|
dt, party_account_currency, bank, outstanding_amount, payment_type, bank_amount, doc)
|
||||||
|
|
||||||
|
paid_amount, received_amount, discount_amount = apply_early_payment_discount(paid_amount, received_amount, doc)
|
||||||
|
|
||||||
pe = frappe.new_doc("Payment Entry")
|
pe = frappe.new_doc("Payment Entry")
|
||||||
pe.payment_type = payment_type
|
pe.payment_type = payment_type
|
||||||
pe.company = doc.company
|
pe.company = doc.company
|
||||||
@ -1152,11 +1213,20 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
|
|
||||||
pe.setup_party_account_field()
|
pe.setup_party_account_field()
|
||||||
pe.set_missing_values()
|
pe.set_missing_values()
|
||||||
|
|
||||||
if party_account and bank:
|
if party_account and bank:
|
||||||
if dt == "Employee Advance":
|
if dt == "Employee Advance":
|
||||||
reference_doc = doc
|
reference_doc = doc
|
||||||
pe.set_exchange_rate(ref_doc=reference_doc)
|
pe.set_exchange_rate(ref_doc=reference_doc)
|
||||||
pe.set_amounts()
|
pe.set_amounts()
|
||||||
|
if discount_amount:
|
||||||
|
pe.set_gain_or_loss(account_details={
|
||||||
|
'account': frappe.get_cached_value('Company', pe.company, "default_discount_account"),
|
||||||
|
'cost_center': pe.cost_center or frappe.get_cached_value('Company', pe.company, "cost_center"),
|
||||||
|
'amount': discount_amount * (-1 if payment_type == "Pay" else 1)
|
||||||
|
})
|
||||||
|
pe.set_difference_amount()
|
||||||
|
|
||||||
return pe
|
return pe
|
||||||
|
|
||||||
def get_bank_cash_account(doc, bank_account):
|
def get_bank_cash_account(doc, bank_account):
|
||||||
@ -1272,6 +1342,33 @@ def set_paid_amount_and_received_amount(dt, party_account_currency, bank, outsta
|
|||||||
paid_amount = received_amount * doc.get('exchange_rate', 1)
|
paid_amount = received_amount * doc.get('exchange_rate', 1)
|
||||||
return paid_amount, received_amount
|
return paid_amount, received_amount
|
||||||
|
|
||||||
|
def apply_early_payment_discount(paid_amount, received_amount, doc):
|
||||||
|
total_discount = 0
|
||||||
|
if doc.doctype in ['Sales Invoice', 'Purchase Invoice'] and doc.payment_schedule:
|
||||||
|
for term in doc.payment_schedule:
|
||||||
|
if not term.discounted_amount and term.discount and getdate(nowdate()) <= term.discount_date:
|
||||||
|
if term.discount_type == 'Percentage':
|
||||||
|
discount_amount = flt(doc.get('grand_total')) * (term.discount / 100)
|
||||||
|
else:
|
||||||
|
discount_amount = term.discount
|
||||||
|
|
||||||
|
discount_amount_in_foreign_currency = discount_amount * doc.get('conversion_rate', 1)
|
||||||
|
|
||||||
|
if doc.doctype == 'Sales Invoice':
|
||||||
|
paid_amount -= discount_amount
|
||||||
|
received_amount -= discount_amount_in_foreign_currency
|
||||||
|
else:
|
||||||
|
received_amount -= discount_amount
|
||||||
|
paid_amount -= discount_amount_in_foreign_currency
|
||||||
|
|
||||||
|
total_discount += discount_amount
|
||||||
|
|
||||||
|
if total_discount:
|
||||||
|
money = frappe.utils.fmt_money(total_discount, currency=doc.get('currency'))
|
||||||
|
frappe.msgprint(_("Discount of {} applied as per Payment Term").format(money), alert=1)
|
||||||
|
|
||||||
|
return paid_amount, received_amount, total_discount
|
||||||
|
|
||||||
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
||||||
references = []
|
references = []
|
||||||
for payment_term in payment_schedule:
|
for payment_term in payment_schedule:
|
||||||
|
@ -193,6 +193,34 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
self.assertEqual(si.payment_schedule[0].paid_amount, 200.0)
|
self.assertEqual(si.payment_schedule[0].paid_amount, 200.0)
|
||||||
self.assertEqual(si.payment_schedule[1].paid_amount, 36.0)
|
self.assertEqual(si.payment_schedule[1].paid_amount, 36.0)
|
||||||
|
|
||||||
|
def test_payment_entry_against_payment_terms_with_discount(self):
|
||||||
|
si = create_sales_invoice(do_not_save=1, qty=1, rate=200)
|
||||||
|
create_payment_terms_template_with_discount()
|
||||||
|
si.payment_terms_template = 'Test Discount Template'
|
||||||
|
|
||||||
|
frappe.db.set_value('Company', si.company, 'default_discount_account', 'Write Off - _TC')
|
||||||
|
|
||||||
|
si.append('taxes', {
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"account_head": "_Test Account Service Tax - _TC",
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
"description": "Service Tax",
|
||||||
|
"rate": 18
|
||||||
|
})
|
||||||
|
si.save()
|
||||||
|
|
||||||
|
si.submit()
|
||||||
|
|
||||||
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||||
|
pe.submit()
|
||||||
|
si.load_from_db()
|
||||||
|
|
||||||
|
self.assertEqual(pe.references[0].payment_term, '30 Credit Days with 10% Discount')
|
||||||
|
self.assertEqual(si.payment_schedule[0].payment_amount, 236.0)
|
||||||
|
self.assertEqual(si.payment_schedule[0].paid_amount, 212.40)
|
||||||
|
self.assertEqual(si.payment_schedule[0].outstanding, 0)
|
||||||
|
self.assertEqual(si.payment_schedule[0].discounted_amount, 23.6)
|
||||||
|
|
||||||
|
|
||||||
def test_payment_against_purchase_invoice_to_check_status(self):
|
def test_payment_against_purchase_invoice_to_check_status(self):
|
||||||
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
||||||
@ -591,6 +619,26 @@ def create_payment_terms_template():
|
|||||||
}]
|
}]
|
||||||
}).insert()
|
}).insert()
|
||||||
|
|
||||||
|
def create_payment_terms_template_with_discount():
|
||||||
|
|
||||||
|
create_payment_term('30 Credit Days with 10% Discount')
|
||||||
|
|
||||||
|
if not frappe.db.exists('Payment Terms Template', 'Test Discount Template'):
|
||||||
|
payment_term_template = frappe.get_doc({
|
||||||
|
'doctype': 'Payment Terms Template',
|
||||||
|
'template_name': 'Test Discount Template',
|
||||||
|
'allocate_payment_based_on_payment_terms': 1,
|
||||||
|
'terms': [{
|
||||||
|
'doctype': 'Payment Terms Template Detail',
|
||||||
|
'payment_term': '30 Credit Days with 10% Discount',
|
||||||
|
'invoice_portion': 100,
|
||||||
|
'credit_days_based_on': 'Day(s) after invoice date',
|
||||||
|
'credit_days': 2,
|
||||||
|
'discount': 10,
|
||||||
|
'discount_validity_based_on': 'Day(s) after invoice date',
|
||||||
|
'discount_validity': 1
|
||||||
|
}]
|
||||||
|
}).insert()
|
||||||
|
|
||||||
def create_payment_term(name):
|
def create_payment_term(name):
|
||||||
if not frappe.db.exists('Payment Term', name):
|
if not frappe.db.exists('Payment Term', name):
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
"fieldname": "total_amount",
|
"fieldname": "total_amount",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Total Amount",
|
"label": "Grand Total",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@ -92,9 +92,10 @@
|
|||||||
"options": "Payment Term"
|
"options": "Payment Term"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-03-13 12:07:19.362539",
|
"modified": "2021-02-10 11:25:47.144392",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry Reference",
|
"name": "Payment Entry Reference",
|
||||||
|
@ -6,11 +6,23 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"payment_term",
|
"payment_term",
|
||||||
|
"section_break_15",
|
||||||
"description",
|
"description",
|
||||||
|
"section_break_4",
|
||||||
"due_date",
|
"due_date",
|
||||||
"invoice_portion",
|
|
||||||
"payment_amount",
|
|
||||||
"mode_of_payment",
|
"mode_of_payment",
|
||||||
|
"column_break_5",
|
||||||
|
"invoice_portion",
|
||||||
|
"section_break_6",
|
||||||
|
"discount_type",
|
||||||
|
"discount_date",
|
||||||
|
"column_break_9",
|
||||||
|
"discount",
|
||||||
|
"section_break_9",
|
||||||
|
"payment_amount",
|
||||||
|
"discounted_amount",
|
||||||
|
"column_break_3",
|
||||||
|
"outstanding",
|
||||||
"paid_amount"
|
"paid_amount"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
@ -25,6 +37,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 2,
|
"columns": 2,
|
||||||
|
"fetch_from": "payment_term.description",
|
||||||
"fieldname": "description",
|
"fieldname": "description",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -62,14 +75,82 @@
|
|||||||
"options": "Mode of Payment"
|
"options": "Mode of Payment"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "paid_amount",
|
||||||
"fieldname": "paid_amount",
|
"fieldname": "paid_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Paid Amount"
|
"label": "Paid Amount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_3",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "discounted_amount",
|
||||||
|
"fieldname": "discounted_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Discounted Amount",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "payment_amount",
|
||||||
|
"fieldname": "outstanding",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Outstanding",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_5",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "discount",
|
||||||
|
"fieldname": "discount_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"label": "Discount Date",
|
||||||
|
"mandatory_depends_on": "discount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Percentage",
|
||||||
|
"fetch_from": "payment_term.discount_type",
|
||||||
|
"fieldname": "discount_type",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Discount Type",
|
||||||
|
"options": "Percentage\nAmount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "payment_term.discount",
|
||||||
|
"fieldname": "discount",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Discount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_9",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "section_break_15",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_6",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_9",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_4",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-03-13 17:58:24.729526",
|
"modified": "2021-02-15 21:03:12.540546",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Schedule",
|
"name": "Payment Schedule",
|
||||||
|
@ -1,2 +1,22 @@
|
|||||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
frappe.ui.form.on('Payment Term', {
|
||||||
|
onload(frm) {
|
||||||
|
frm.trigger('set_dynamic_description');
|
||||||
|
},
|
||||||
|
discount(frm) {
|
||||||
|
frm.trigger('set_dynamic_description');
|
||||||
|
},
|
||||||
|
discount_type(frm) {
|
||||||
|
frm.trigger('set_dynamic_description');
|
||||||
|
},
|
||||||
|
set_dynamic_description(frm) {
|
||||||
|
if (frm.doc.discount) {
|
||||||
|
let description = __("{0}% of total invoice value will be given as discount.", [frm.doc.discount]);
|
||||||
|
if (frm.doc.discount_type == 'Amount') {
|
||||||
|
description = __("{0} will be given as discount.", [fmt_money(frm.doc.discount)]);
|
||||||
|
}
|
||||||
|
frm.set_df_property("discount", "description", description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -1,386 +1,166 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"allow_import": 1,
|
||||||
"allow_import": 1,
|
"allow_rename": 1,
|
||||||
"allow_rename": 1,
|
"autoname": "field:payment_term_name",
|
||||||
"autoname": "field:payment_term_name",
|
"creation": "2017-08-10 15:24:54.876365",
|
||||||
"beta": 0,
|
"doctype": "DocType",
|
||||||
"creation": "2017-08-10 15:24:54.876365",
|
"editable_grid": 1,
|
||||||
"custom": 0,
|
"engine": "InnoDB",
|
||||||
"docstatus": 0,
|
"field_order": [
|
||||||
"doctype": "DocType",
|
"payment_term_name",
|
||||||
"document_type": "",
|
"invoice_portion",
|
||||||
"editable_grid": 1,
|
"mode_of_payment",
|
||||||
"engine": "InnoDB",
|
"column_break_3",
|
||||||
|
"due_date_based_on",
|
||||||
|
"credit_days",
|
||||||
|
"credit_months",
|
||||||
|
"section_break_8",
|
||||||
|
"discount_type",
|
||||||
|
"discount",
|
||||||
|
"column_break_11",
|
||||||
|
"discount_validity_based_on",
|
||||||
|
"discount_validity",
|
||||||
|
"section_break_6",
|
||||||
|
"description"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"bold": 1,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "payment_term_name",
|
||||||
"bold": 1,
|
"fieldtype": "Data",
|
||||||
"collapsible": 0,
|
"label": "Payment Term Name",
|
||||||
"columns": 0,
|
"unique": 1
|
||||||
"fieldname": "payment_term_name",
|
},
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Payment Term Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "Provide the invoice portion in percent",
|
"bold": 1,
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "invoice_portion",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Float",
|
||||||
"bold": 1,
|
"label": "Invoice Portion (%)"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "invoice_portion",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Invoice Portion",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "mode_of_payment",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"label": "Mode of Payment",
|
||||||
"collapsible": 0,
|
"options": "Mode of Payment"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "mode_of_payment",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Mode of Payment",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Mode of Payment",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_3",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_3",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"bold": 1,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "due_date_based_on",
|
||||||
"bold": 1,
|
"fieldtype": "Select",
|
||||||
"collapsible": 0,
|
"label": "Due Date Based On",
|
||||||
"columns": 0,
|
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month"
|
||||||
"fieldname": "due_date_based_on",
|
},
|
||||||
"fieldtype": "Select",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Due Date Based On",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "Give number of days according to prior selection",
|
"bold": 1,
|
||||||
"allow_bulk_edit": 0,
|
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "credit_days",
|
||||||
"bold": 1,
|
"fieldtype": "Int",
|
||||||
"collapsible": 0,
|
"label": "Credit Days"
|
||||||
"columns": 0,
|
},
|
||||||
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
|
|
||||||
"fieldname": "credit_days",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Credit Days",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "credit_months",
|
||||||
"bold": 0,
|
"fieldtype": "Int",
|
||||||
"collapsible": 0,
|
"label": "Credit Months"
|
||||||
"columns": 0,
|
},
|
||||||
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
|
|
||||||
"fieldname": "credit_months",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Credit Months",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_6",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_6",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"bold": 1,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "description",
|
||||||
"bold": 1,
|
"fieldtype": "Small Text",
|
||||||
"collapsible": 0,
|
"label": "Description"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "description",
|
{
|
||||||
"fieldtype": "Small Text",
|
"fieldname": "section_break_8",
|
||||||
"hidden": 0,
|
"fieldtype": "Section Break",
|
||||||
"ignore_user_permissions": 0,
|
"label": "Discount Settings"
|
||||||
"ignore_xss_filter": 0,
|
},
|
||||||
"in_filter": 0,
|
{
|
||||||
"in_global_search": 0,
|
"default": "Percentage",
|
||||||
"in_list_view": 0,
|
"fieldname": "discount_type",
|
||||||
"in_standard_filter": 0,
|
"fieldtype": "Select",
|
||||||
"label": "Description",
|
"label": "Discount Type",
|
||||||
"length": 0,
|
"options": "Percentage\nAmount"
|
||||||
"no_copy": 0,
|
},
|
||||||
"permlevel": 0,
|
{
|
||||||
"precision": "",
|
"fieldname": "discount",
|
||||||
"print_hide": 0,
|
"fieldtype": "Float",
|
||||||
"print_hide_if_no_value": 0,
|
"label": "Discount"
|
||||||
"read_only": 0,
|
},
|
||||||
"remember_last_selected_value": 0,
|
{
|
||||||
"report_hide": 0,
|
"default": "Day(s) after invoice date",
|
||||||
"reqd": 0,
|
"depends_on": "discount",
|
||||||
"search_index": 0,
|
"fieldname": "discount_validity_based_on",
|
||||||
"set_only_once": 0,
|
"fieldtype": "Select",
|
||||||
"translatable": 0,
|
"label": "Discount Validity Based On",
|
||||||
"unique": 0
|
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "discount",
|
||||||
|
"fieldname": "discount_validity",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"label": "Discount Validity",
|
||||||
|
"mandatory_depends_on": "discount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_11",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"links": [],
|
||||||
"hide_heading": 0,
|
"modified": "2021-02-15 20:30:56.256403",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "Accounts",
|
||||||
"image_view": 0,
|
"name": "Payment Term",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2020-10-14 10:47:32.830478",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Payment Term",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "System Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "Accounts Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "Accounts User",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"sort_field": "modified",
|
||||||
"read_only_onload": 0,
|
"sort_order": "DESC",
|
||||||
"show_name_in_global_search": 0,
|
"track_changes": 1
|
||||||
"sort_field": "modified",
|
}
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
|
@ -3,11 +3,6 @@
|
|||||||
|
|
||||||
frappe.ui.form.on('Payment Terms Template', {
|
frappe.ui.form.on('Payment Terms Template', {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.add_fetch("payment_term", "description", "description");
|
|
||||||
frm.add_fetch("payment_term", "invoice_portion", "invoice_portion");
|
|
||||||
frm.add_fetch("payment_term", "due_date_based_on", "due_date_based_on");
|
|
||||||
frm.add_fetch("payment_term", "credit_days", "credit_days");
|
|
||||||
frm.add_fetch("payment_term", "credit_months", "credit_months");
|
|
||||||
frm.add_fetch("payment_term", "mode_of_payment", "mode_of_payment");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -13,7 +13,6 @@ from frappe import _
|
|||||||
class PaymentTermsTemplate(Document):
|
class PaymentTermsTemplate(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_invoice_portion()
|
self.validate_invoice_portion()
|
||||||
self.validate_credit_days()
|
|
||||||
self.check_duplicate_terms()
|
self.check_duplicate_terms()
|
||||||
|
|
||||||
def validate_invoice_portion(self):
|
def validate_invoice_portion(self):
|
||||||
@ -24,11 +23,6 @@ class PaymentTermsTemplate(Document):
|
|||||||
if flt(total_portion, 2) != 100.00:
|
if flt(total_portion, 2) != 100.00:
|
||||||
frappe.msgprint(_('Combined invoice portion must equal 100%'), raise_exception=1, indicator='red')
|
frappe.msgprint(_('Combined invoice portion must equal 100%'), raise_exception=1, indicator='red')
|
||||||
|
|
||||||
def validate_credit_days(self):
|
|
||||||
for term in self.terms:
|
|
||||||
if cint(term.credit_days) < 0:
|
|
||||||
frappe.msgprint(_('Credit Days cannot be a negative number'), raise_exception=1, indicator='red')
|
|
||||||
|
|
||||||
def check_duplicate_terms(self):
|
def check_duplicate_terms(self):
|
||||||
terms = []
|
terms = []
|
||||||
for term in self.terms:
|
for term in self.terms:
|
||||||
|
@ -1,278 +1,164 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"creation": "2017-08-10 15:34:09.409562",
|
||||||
"allow_import": 0,
|
"doctype": "DocType",
|
||||||
"allow_rename": 0,
|
"editable_grid": 1,
|
||||||
"autoname": "",
|
"engine": "InnoDB",
|
||||||
"beta": 0,
|
"field_order": [
|
||||||
"creation": "2017-08-10 15:34:09.409562",
|
"payment_term",
|
||||||
"custom": 0,
|
"section_break_13",
|
||||||
"docstatus": 0,
|
"description",
|
||||||
"doctype": "DocType",
|
"section_break_4",
|
||||||
"document_type": "",
|
"invoice_portion",
|
||||||
"editable_grid": 1,
|
"mode_of_payment",
|
||||||
"engine": "InnoDB",
|
"column_break_3",
|
||||||
|
"due_date_based_on",
|
||||||
|
"credit_days",
|
||||||
|
"credit_months",
|
||||||
|
"section_break_8",
|
||||||
|
"discount_type",
|
||||||
|
"discount",
|
||||||
|
"column_break_11",
|
||||||
|
"discount_validity_based_on",
|
||||||
|
"discount_validity"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "payment_term",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Payment Term",
|
||||||
"columns": 2,
|
"options": "Payment Term"
|
||||||
"fieldname": "payment_term",
|
},
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Payment Term",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Payment Term",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fetch_from": "payment_term.description",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "description",
|
||||||
"bold": 0,
|
"fieldtype": "Small Text",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Description"
|
||||||
"fieldname": "description",
|
},
|
||||||
"fieldtype": "Small Text",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fetch_from": "payment_term.invoice_portion",
|
||||||
"allow_on_submit": 0,
|
"fetch_if_empty": 1,
|
||||||
"bold": 0,
|
"fieldname": "invoice_portion",
|
||||||
"collapsible": 0,
|
"fieldtype": "Float",
|
||||||
"columns": 2,
|
"in_list_view": 1,
|
||||||
"default": "0",
|
"label": "Invoice Portion (%)",
|
||||||
"fieldname": "invoice_portion",
|
"reqd": 1
|
||||||
"fieldtype": "Percent",
|
},
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Invoice Portion",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fetch_from": "payment_term.due_date_based_on",
|
||||||
"allow_on_submit": 0,
|
"fetch_if_empty": 1,
|
||||||
"bold": 0,
|
"fieldname": "due_date_based_on",
|
||||||
"collapsible": 0,
|
"fieldtype": "Select",
|
||||||
"columns": 2,
|
"in_list_view": 1,
|
||||||
"fieldname": "due_date_based_on",
|
"label": "Due Date Based On",
|
||||||
"fieldtype": "Select",
|
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month",
|
||||||
"hidden": 0,
|
"reqd": 1
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Due Date Based On",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"default": "0",
|
||||||
"allow_on_submit": 0,
|
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
|
||||||
"bold": 0,
|
"fetch_from": "payment_term.credit_days",
|
||||||
"collapsible": 0,
|
"fetch_if_empty": 1,
|
||||||
"columns": 2,
|
"fieldname": "credit_days",
|
||||||
"default": "0",
|
"fieldtype": "Int",
|
||||||
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
|
"in_list_view": 1,
|
||||||
"fieldname": "credit_days",
|
"label": "Credit Days",
|
||||||
"fieldtype": "Int",
|
"non_negative": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Credit Days",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
|
||||||
"allow_on_submit": 0,
|
"fetch_from": "payment_term.credit_months",
|
||||||
"bold": 0,
|
"fetch_if_empty": 1,
|
||||||
"collapsible": 0,
|
"fieldname": "credit_months",
|
||||||
"columns": 0,
|
"fieldtype": "Int",
|
||||||
"default": "0",
|
"label": "Credit Months",
|
||||||
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
|
"non_negative": 1
|
||||||
"fieldname": "credit_months",
|
},
|
||||||
"fieldtype": "Int",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Credit Months",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "payment_term.mode_of_payment",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "mode_of_payment",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"label": "Mode of Payment",
|
||||||
"collapsible": 0,
|
"options": "Mode of Payment"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "mode_of_payment",
|
{
|
||||||
"fieldtype": "Link",
|
"fieldname": "column_break_3",
|
||||||
"hidden": 0,
|
"fieldtype": "Column Break"
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
{
|
||||||
"in_filter": 0,
|
"fieldname": "section_break_8",
|
||||||
"in_global_search": 0,
|
"fieldtype": "Section Break",
|
||||||
"in_list_view": 0,
|
"label": "Discount Settings"
|
||||||
"in_standard_filter": 0,
|
},
|
||||||
"label": "Mode of Payment",
|
{
|
||||||
"length": 0,
|
"default": "Percentage",
|
||||||
"no_copy": 0,
|
"fetch_from": "payment_term.discount_type",
|
||||||
"options": "Mode of Payment",
|
"fetch_if_empty": 1,
|
||||||
"permlevel": 0,
|
"fieldname": "discount_type",
|
||||||
"precision": "",
|
"fieldtype": "Select",
|
||||||
"print_hide": 0,
|
"label": "Discount Type",
|
||||||
"print_hide_if_no_value": 0,
|
"options": "Percentage\nAmount"
|
||||||
"read_only": 0,
|
},
|
||||||
"remember_last_selected_value": 0,
|
{
|
||||||
"report_hide": 0,
|
"fetch_from": "payment_term.discount",
|
||||||
"reqd": 0,
|
"fetch_if_empty": 1,
|
||||||
"search_index": 0,
|
"fieldname": "discount",
|
||||||
"set_only_once": 0,
|
"fieldtype": "Float",
|
||||||
"translatable": 0,
|
"label": "Discount"
|
||||||
"unique": 0
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_11",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Day(s) after invoice date",
|
||||||
|
"depends_on": "discount",
|
||||||
|
"fetch_from": "payment_term.discount_validity_based_on",
|
||||||
|
"fetch_if_empty": 1,
|
||||||
|
"fieldname": "discount_validity_based_on",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Discount Validity Based On",
|
||||||
|
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "section_break_13",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "discount",
|
||||||
|
"fetch_from": "payment_term.discount_validity",
|
||||||
|
"fetch_if_empty": 1,
|
||||||
|
"fieldname": "discount_validity",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"label": "Discount Validity",
|
||||||
|
"mandatory_depends_on": "discount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_4",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"index_web_pages_for_search": 1,
|
||||||
"hide_heading": 0,
|
"istable": 1,
|
||||||
"hide_toolbar": 0,
|
"links": [],
|
||||||
"idx": 0,
|
"modified": "2021-02-24 11:56:12.410807",
|
||||||
"image_view": 0,
|
"modified_by": "Administrator",
|
||||||
"in_create": 0,
|
"module": "Accounts",
|
||||||
"is_submittable": 0,
|
"name": "Payment Terms Template Detail",
|
||||||
"issingle": 0,
|
"owner": "Administrator",
|
||||||
"istable": 1,
|
"permissions": [],
|
||||||
"max_attachments": 0,
|
"quick_entry": 1,
|
||||||
"modified": "2018-08-21 16:15:55.143025",
|
"sort_field": "modified",
|
||||||
"modified_by": "Administrator",
|
"sort_order": "DESC",
|
||||||
"module": "Accounts",
|
"track_changes": 1
|
||||||
"name": "Payment Terms Template Detail",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -364,7 +364,7 @@ class ReceivablePayableReport(object):
|
|||||||
payment_terms_details = frappe.db.sql("""
|
payment_terms_details = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
si.name, si.party_account_currency, si.currency, si.conversion_rate,
|
si.name, si.party_account_currency, si.currency, si.conversion_rate,
|
||||||
ps.due_date, ps.payment_amount, ps.description, ps.paid_amount
|
ps.due_date, ps.payment_amount, ps.description, ps.paid_amount, ps.discounted_amount
|
||||||
from `tab{0}` si, `tabPayment Schedule` ps
|
from `tab{0}` si, `tabPayment Schedule` ps
|
||||||
where
|
where
|
||||||
si.name = ps.parent and
|
si.name = ps.parent and
|
||||||
@ -395,13 +395,13 @@ class ReceivablePayableReport(object):
|
|||||||
"invoiced": invoiced,
|
"invoiced": invoiced,
|
||||||
"invoice_grand_total": row.invoiced,
|
"invoice_grand_total": row.invoiced,
|
||||||
"payment_term": d.description,
|
"payment_term": d.description,
|
||||||
"paid": d.paid_amount,
|
"paid": d.paid_amount + d.discounted_amount,
|
||||||
"credit_note": 0.0,
|
"credit_note": 0.0,
|
||||||
"outstanding": invoiced - d.paid_amount
|
"outstanding": invoiced - d.paid_amount - d.discounted_amount
|
||||||
}))
|
}))
|
||||||
|
|
||||||
if d.paid_amount:
|
if d.paid_amount:
|
||||||
row['paid'] -= d.paid_amount
|
row['paid'] -= d.paid_amount + d.discounted_amount
|
||||||
|
|
||||||
def allocate_closing_to_term(self, row, term, key):
|
def allocate_closing_to_term(self, row, term, key):
|
||||||
if row[key]:
|
if row[key]:
|
||||||
|
@ -904,7 +904,8 @@ class AccountsController(TransactionBase):
|
|||||||
else:
|
else:
|
||||||
for d in self.get("payment_schedule"):
|
for d in self.get("payment_schedule"):
|
||||||
if d.invoice_portion:
|
if d.invoice_portion:
|
||||||
d.payment_amount = flt(grand_total * flt(d.invoice_portion) / 100, d.precision('payment_amount'))
|
d.payment_amount = flt(grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount'))
|
||||||
|
d.outstanding = d.payment_amount
|
||||||
|
|
||||||
def set_due_date(self):
|
def set_due_date(self):
|
||||||
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
||||||
@ -1219,18 +1220,24 @@ def get_payment_term_details(term, posting_date=None, grand_total=None, bill_dat
|
|||||||
term_details.description = term.description
|
term_details.description = term.description
|
||||||
term_details.invoice_portion = term.invoice_portion
|
term_details.invoice_portion = term.invoice_portion
|
||||||
term_details.payment_amount = flt(term.invoice_portion) * flt(grand_total) / 100
|
term_details.payment_amount = flt(term.invoice_portion) * flt(grand_total) / 100
|
||||||
|
term_details.discount_type = term.discount_type
|
||||||
|
term_details.discount = term.discount
|
||||||
|
# term_details.discounted_amount = flt(grand_total) * (term.discount / 100) if term.discount_type == 'Percentage' else discount
|
||||||
|
term_details.outstanding = term_details.payment_amount
|
||||||
|
term_details.mode_of_payment = term.mode_of_payment
|
||||||
|
|
||||||
if bill_date:
|
if bill_date:
|
||||||
term_details.due_date = get_due_date(term, bill_date)
|
term_details.due_date = get_due_date(term, bill_date)
|
||||||
|
term_details.discount_date = get_discount_date(term, bill_date)
|
||||||
elif posting_date:
|
elif posting_date:
|
||||||
term_details.due_date = get_due_date(term, posting_date)
|
term_details.due_date = get_due_date(term, posting_date)
|
||||||
|
term_details.discount_date = get_discount_date(term, posting_date)
|
||||||
|
|
||||||
if getdate(term_details.due_date) < getdate(posting_date):
|
if getdate(term_details.due_date) < getdate(posting_date):
|
||||||
term_details.due_date = posting_date
|
term_details.due_date = posting_date
|
||||||
term_details.mode_of_payment = term.mode_of_payment
|
|
||||||
|
|
||||||
return term_details
|
return term_details
|
||||||
|
|
||||||
|
|
||||||
def get_due_date(term, posting_date=None, bill_date=None):
|
def get_due_date(term, posting_date=None, bill_date=None):
|
||||||
due_date = None
|
due_date = None
|
||||||
date = bill_date or posting_date
|
date = bill_date or posting_date
|
||||||
@ -1242,6 +1249,16 @@ def get_due_date(term, posting_date=None, bill_date=None):
|
|||||||
due_date = add_months(get_last_day(date), term.credit_months)
|
due_date = add_months(get_last_day(date), term.credit_months)
|
||||||
return due_date
|
return due_date
|
||||||
|
|
||||||
|
def get_discount_date(term, posting_date=None, bill_date=None):
|
||||||
|
discount_validity = None
|
||||||
|
date = bill_date or posting_date
|
||||||
|
if term.discount_validity_based_on == "Day(s) after invoice date":
|
||||||
|
discount_validity = add_days(date, term.discount_validity)
|
||||||
|
elif term.discount_validity_based_on == "Day(s) after the end of the invoice month":
|
||||||
|
discount_validity = add_days(get_last_day(date), term.discount_validity)
|
||||||
|
elif term.discount_validity_based_on == "Month(s) after the end of the invoice month":
|
||||||
|
discount_validity = add_months(get_last_day(date), term.discount_validity)
|
||||||
|
return discount_validity
|
||||||
|
|
||||||
def get_supplier_block_status(party_name):
|
def get_supplier_block_status(party_name):
|
||||||
"""
|
"""
|
||||||
|
@ -750,6 +750,7 @@ erpnext.patches.v13_0.set_company_in_leave_ledger_entry
|
|||||||
erpnext.patches.v13_0.convert_qi_parameter_to_link_field
|
erpnext.patches.v13_0.convert_qi_parameter_to_link_field
|
||||||
erpnext.patches.v13_0.setup_patient_history_settings_for_standard_doctypes
|
erpnext.patches.v13_0.setup_patient_history_settings_for_standard_doctypes
|
||||||
erpnext.patches.v13_0.add_naming_series_to_old_projects # 1-02-2021
|
erpnext.patches.v13_0.add_naming_series_to_old_projects # 1-02-2021
|
||||||
|
erpnext.patches.v13_0.update_payment_terms_outstanding
|
||||||
erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl
|
erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl
|
||||||
erpnext.patches.v12_0.add_state_code_for_ladakh
|
erpnext.patches.v12_0.add_state_code_for_ladakh
|
||||||
erpnext.patches.v13_0.update_vehicle_no_reqd_condition
|
erpnext.patches.v13_0.update_vehicle_no_reqd_condition
|
||||||
|
15
erpnext/patches/v13_0/update_payment_terms_outstanding.py
Normal file
15
erpnext/patches/v13_0/update_payment_terms_outstanding.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# MIT License. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doc("accounts", "doctype", "Payment Schedule")
|
||||||
|
if frappe.db.count('Payment Schedule'):
|
||||||
|
frappe.db.sql('''
|
||||||
|
UPDATE
|
||||||
|
`tabPayment Schedule` ps
|
||||||
|
SET
|
||||||
|
ps.outstanding = (ps.payment_amount - ps.paid_amount)
|
||||||
|
''')
|
@ -259,6 +259,7 @@ erpnext.company.setup_queries = function(frm) {
|
|||||||
["default_payroll_payable_account", {"root_type": "Liability"}],
|
["default_payroll_payable_account", {"root_type": "Liability"}],
|
||||||
["round_off_account", {"root_type": "Expense"}],
|
["round_off_account", {"root_type": "Expense"}],
|
||||||
["write_off_account", {"root_type": "Expense"}],
|
["write_off_account", {"root_type": "Expense"}],
|
||||||
|
["default_discount_account", {}],
|
||||||
["discount_allowed_account", {"root_type": "Expense"}],
|
["discount_allowed_account", {"root_type": "Expense"}],
|
||||||
["discount_received_account", {"root_type": "Income"}],
|
["discount_received_account", {"root_type": "Income"}],
|
||||||
["exchange_gain_loss_account", {"root_type": "Expense"}],
|
["exchange_gain_loss_account", {"root_type": "Expense"}],
|
||||||
@ -275,7 +276,7 @@ erpnext.company.setup_queries = function(frm) {
|
|||||||
["expenses_included_in_asset_valuation", {"account_type": "Expenses Included In Asset Valuation"}],
|
["expenses_included_in_asset_valuation", {"account_type": "Expenses Included In Asset Valuation"}],
|
||||||
["capital_work_in_progress_account", {"account_type": "Capital Work in Progress"}],
|
["capital_work_in_progress_account", {"account_type": "Capital Work in Progress"}],
|
||||||
["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}],
|
["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}],
|
||||||
["unrealized_profit_loss_account", {"root_type": "Liability"}]
|
["unrealized_profit_loss_account", {"root_type": "Liability"},]
|
||||||
], function(i, v) {
|
], function(i, v) {
|
||||||
erpnext.company.set_custom_query(frm, v);
|
erpnext.company.set_custom_query(frm, v);
|
||||||
});
|
});
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
"default_deferred_expense_account",
|
"default_deferred_expense_account",
|
||||||
"default_payroll_payable_account",
|
"default_payroll_payable_account",
|
||||||
"default_expense_claim_payable_account",
|
"default_expense_claim_payable_account",
|
||||||
|
"default_discount_account",
|
||||||
"section_break_22",
|
"section_break_22",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"column_break_26",
|
"column_break_26",
|
||||||
@ -733,6 +734,12 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Unrealized Profit / Loss Account",
|
"label": "Unrealized Profit / Loss Account",
|
||||||
"options": "Account"
|
"options": "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "default_discount_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Default Payment Discount Account",
|
||||||
|
"options": "Account"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-building",
|
"icon": "fa fa-building",
|
||||||
|
Loading…
Reference in New Issue
Block a user