[fix][#1808] Allow configurable AR/AP ageing dates

This commit is contained in:
ankitjavalkarwork 2014-10-03 15:27:53 +05:30
parent f065b756e5
commit 437af5b031
4 changed files with 68 additions and 12 deletions

View File

@ -28,6 +28,30 @@ frappe.query_reports["Accounts Payable"] = {
"fieldtype": "Select", "fieldtype": "Select",
"options": 'Posting Date' + NEWLINE + 'Due Date', "options": 'Posting Date' + NEWLINE + 'Due Date',
"default": "Posting Date" "default": "Posting Date"
},
{
"fieldtype": "Break",
},
{
"fieldname":"range1",
"label": __("Ageing Range 1"),
"fieldtype": "Int",
"default": "30",
"reqd": 1
},
{
"fieldname":"range2",
"label": __("Ageing Range 2"),
"fieldtype": "Int",
"default": "60",
"reqd": 1
},
{
"fieldname":"range3",
"label": __("Ageing Range 3"),
"fieldtype": "Int",
"default": "90",
"reqd": 1
} }
] ]
} }

View File

@ -3,14 +3,14 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe import _ from frappe.utils import getdate, nowdate, flt, cstr, cint
from frappe.utils import getdate, nowdate, flt, cstr from frappe import msgprint, _
from erpnext.accounts.report.accounts_receivable.accounts_receivable import get_ageing_data from erpnext.accounts.report.accounts_receivable.accounts_receivable import get_ageing_data
def execute(filters=None): def execute(filters=None):
if not filters: filters = {} if not filters: filters = {}
supplier_naming_by = frappe.db.get_value("Buying Settings", None, "supp_master_name") supplier_naming_by = frappe.db.get_value("Buying Settings", None, "supp_master_name")
columns = get_columns(supplier_naming_by) columns = get_columns(filters, supplier_naming_by)
entries = get_gl_entries(filters) entries = get_gl_entries(filters)
entries_after_report_date = [[gle.voucher_type, gle.voucher_no] entries_after_report_date = [[gle.voucher_type, gle.voucher_no]
@ -50,7 +50,8 @@ def execute(filters=None):
else: else:
ageing_based_on_date = gle.posting_date ageing_based_on_date = gle.posting_date
row += get_ageing_data(age_on, ageing_based_on_date, outstanding_amount) + \ row += get_ageing_data(cint(filters.get("range1")), cint(filters.get("range2")), \
cint(filters.get("range3")), age_on, ageing_based_on_date, outstanding_amount) + \
[supplier_details.get(gle.party).supplier_type, gle.remarks] [supplier_details.get(gle.party).supplier_type, gle.remarks]
data.append(row) data.append(row)
@ -70,8 +71,11 @@ def get_columns(supplier_naming_by):
columns +=[_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120", columns +=[_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120",
_("Due Date") + ":Date:80", _("Bill No") + "::80", _("Bill Date") + ":Date:80", _("Due Date") + ":Date:80", _("Bill No") + "::80", _("Bill Date") + ":Date:80",
_("Invoiced Amount") + ":Currency:100", _("Paid Amount") + ":Currency:100", _("Invoiced Amount") + ":Currency:100", _("Paid Amount") + ":Currency:100",
_("Outstanding Amount") + ":Currency:100", _("Age") + ":Int:50", "0-30:Currency:100", _("Outstanding Amount") + ":Currency:100", _("Age") + ":Int:50",
"30-60:Currency:100", "60-90:Currency:100", _("90-Above") + ":Currency:100", "0-" + filters.get("range1") + ":Currency:100",
filters.get("range1") + "-" + filters.get("range2") + ":Currency:100",
filters.get("range2") + "-" + filters.get("range3") + ":Currency:100",
filters.get("range3") + _("-Above") + ":Currency:100",
_("Supplier Type") + ":Link/Supplier Type:150", _("Remarks") + "::150" _("Supplier Type") + ":Link/Supplier Type:150", _("Remarks") + "::150"
] ]

View File

@ -28,6 +28,30 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldtype": "Select", "fieldtype": "Select",
"options": 'Posting Date' + NEWLINE + 'Due Date', "options": 'Posting Date' + NEWLINE + 'Due Date',
"default": "Posting Date" "default": "Posting Date"
},
{
"fieldtype": "Break",
},
{
"fieldname":"range1",
"label": __("Ageing Range 1"),
"fieldtype": "Int",
"default": "30",
"reqd": 1
},
{
"fieldname":"range2",
"label": __("Ageing Range 2"),
"fieldtype": "Int",
"default": "60",
"reqd": 1
},
{
"fieldname":"range3",
"label": __("Ageing Range 3"),
"fieldtype": "Int",
"default": "90",
"reqd": 1
} }
] ]
} }

View File

@ -4,7 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe import _ from frappe import _
from frappe.utils import getdate, nowdate, flt from frappe.utils import getdate, nowdate, flt, cint
class AccountsReceivableReport(object): class AccountsReceivableReport(object):
def __init__(self, filters=None): def __init__(self, filters=None):
@ -27,8 +27,10 @@ class AccountsReceivableReport(object):
columns += [_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120", columns += [_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120",
_("Due Date") + ":Date:80", _("Invoiced Amount") + ":Currency:100", _("Due Date") + ":Date:80", _("Invoiced Amount") + ":Currency:100",
_("Payment Received") + ":Currency:100", _("Outstanding Amount") + ":Currency:100", _("Payment Received") + ":Currency:100", _("Outstanding Amount") + ":Currency:100",
_("Age") + ":Int:50", "0-30:Currency:100", "30-60:Currency:100", _("Age") + ":Int:50", "0-" + self.filters.range1 + ":Currency:100",
"60-90:Currency:100", _("90-Above") + ":Currency:100", self.filters.range1 + "-" + self.filters.range2 + ":Currency:100",
self.filters.range2 + "-" + self.filters.range3 + ":Currency:100",
self.filters.range3 + _("-Above") + ":Currency:100",
_("Territory") + ":Link/Territory:80", _("Remarks") + "::200" _("Territory") + ":Link/Territory:80", _("Remarks") + "::200"
] ]
@ -56,7 +58,8 @@ class AccountsReceivableReport(object):
payment_received, outstanding_amount] payment_received, outstanding_amount]
entry_date = due_date if self.filters.ageing_based_on == "Due Date" else gle.posting_date entry_date = due_date if self.filters.ageing_based_on == "Due Date" else gle.posting_date
row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount) + \ row += get_ageing_data(cint(self.filters.range1), cint(self.filters.range2), \
cint(self.filters.range3), self.age_as_on, entry_date, outstanding_amount) + \
[self.get_territory(gle.account), gle.remarks] [self.get_territory(gle.account), gle.remarks]
data.append(row) data.append(row)
@ -155,15 +158,16 @@ class AccountsReceivableReport(object):
def execute(filters=None): def execute(filters=None):
return AccountsReceivableReport(filters).run() return AccountsReceivableReport(filters).run()
def get_ageing_data(age_as_on, entry_date, outstanding_amount): def get_ageing_data(first_range, second_range, third_range, age_as_on, entry_date, outstanding_amount):
# [0-30, 30-60, 60-90, 90-above] # [0-30, 30-60, 60-90, 90-above]
outstanding_range = [0.0, 0.0, 0.0, 0.0] outstanding_range = [0.0, 0.0, 0.0, 0.0]
if not (age_as_on and entry_date): if not (age_as_on and entry_date):
return [0] + outstanding_range return [0] + outstanding_range
age = (getdate(age_as_on) - getdate(entry_date)).days or 0 age = (getdate(age_as_on) - getdate(entry_date)).days or 0
index = None index = None
for i, days in enumerate([30, 60, 90]): for i, days in enumerate([first_range, second_range, third_range]):
if age <= days: if age <= days:
index = i index = i
break break