|
@ -28,7 +28,14 @@ from .webkit_parser_header_fix import HeaderFooterTextWebKitParser |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_ranges(top, offset): |
|
|
def make_ranges(top, offset): |
|
|
"""Return sorted days ranges""" |
|
|
|
|
|
|
|
|
"""Return sorted days ranges |
|
|
|
|
|
|
|
|
|
|
|
:param top: maximum overdue day |
|
|
|
|
|
:param offset: offset for ranges |
|
|
|
|
|
|
|
|
|
|
|
:returns: list of sorted ranges tuples in days |
|
|
|
|
|
eg. [(-100000, 0), (0, offset), (offset, n*offset), ... (top, 100000)] |
|
|
|
|
|
""" |
|
|
ranges = [(n, min(n + offset, top)) for n in xrange(0, top, offset)] |
|
|
ranges = [(n, min(n + offset, top)) for n in xrange(0, top, offset)] |
|
|
ranges.insert(0, (-100000000000, 0)) |
|
|
ranges.insert(0, (-100000000000, 0)) |
|
|
ranges.append((top, 100000000000)) |
|
|
ranges.append((top, 100000000000)) |
|
@ -39,7 +46,7 @@ RANGES = make_ranges(120, 30) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_ranges_titles(): |
|
|
def make_ranges_titles(): |
|
|
"""Generates title to be used by Mako""" |
|
|
|
|
|
|
|
|
"""Generates title to be used by mako""" |
|
|
titles = [_('Due')] |
|
|
titles = [_('Due')] |
|
|
titles += [_(u'Overdue ≤ %s d.') % x[1] for x in RANGES[1:-1]] |
|
|
titles += [_(u'Overdue ≤ %s d.') % x[1] for x in RANGES[1:-1]] |
|
|
titles.append(_('Older')) |
|
|
titles.append(_('Older')) |
|
@ -55,8 +62,10 @@ INV_TYPE = REC_PAY_TYPE + REFUND_TYPE |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
|
|
|
"""Compute Aged Partner Balance based on result of Open Invoices""" |
|
|
|
|
|
|
|
|
def __init__(self, cursor, uid, name, context=None): |
|
|
def __init__(self, cursor, uid, name, context=None): |
|
|
|
|
|
"""Constructor, refer to :class:`openerp.report.report_sxw.rml_parse`""" |
|
|
super(AccountAgedTrialBalanceWebkit, self).__init__(cursor, uid, name, |
|
|
super(AccountAgedTrialBalanceWebkit, self).__init__(cursor, uid, name, |
|
|
context=context) |
|
|
context=context) |
|
|
self.pool = pooler.get_pool(self.cr.dbname) |
|
|
self.pool = pooler.get_pool(self.cr.dbname) |
|
@ -100,12 +109,14 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
|
|
|
|
|
|
def set_context(self, objects, data, ids, report_type=None): |
|
|
def set_context(self, objects, data, ids, report_type=None): |
|
|
"""Populate aged_lines, aged_balance, aged_percents attributes |
|
|
"""Populate aged_lines, aged_balance, aged_percents attributes |
|
|
on each browse record that will be used by mako template |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
on each account browse record that will be used by mako template |
|
|
|
|
|
The browse record are store in :attr:`objects` |
|
|
|
|
|
|
|
|
The computation are based on the ledger_lines attribute set on account |
|
|
The computation are based on the ledger_lines attribute set on account |
|
|
contained by :attr:`objects` |
|
|
contained by :attr:`objects` |
|
|
|
|
|
|
|
|
self.object were previously set by parent class |
|
|
|
|
|
|
|
|
:attr:`objects` values were previously set by parent class |
|
|
:class: `.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
:class: `.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
:returns: parent :class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
:returns: parent :class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
@ -137,13 +148,16 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
|
|
|
|
|
|
def compute_aged_lines(self, partner_id, ledger_lines, data): |
|
|
def compute_aged_lines(self, partner_id, ledger_lines, data): |
|
|
"""Add property aged_lines to accounts browse records |
|
|
"""Add property aged_lines to accounts browse records |
|
|
|
|
|
|
|
|
contained in :attr:`objects` for a given partner |
|
|
contained in :attr:`objects` for a given partner |
|
|
|
|
|
|
|
|
:params: partner_id current partner |
|
|
:params: partner_id current partner |
|
|
:params: ledger_lines generated by parent |
|
|
:params: ledger_lines generated by parent |
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
:return computed ledger lines |
|
|
|
|
|
|
|
|
:returns: dict of computed aged lines |
|
|
|
|
|
eg {'balance': 1000.0, |
|
|
|
|
|
'aged_lines': {(90, 120): 0.0, ...} |
|
|
|
|
|
|
|
|
""" |
|
|
""" |
|
|
lines_to_age = self.filter_lines(partner_id, ledger_lines) |
|
|
lines_to_age = self.filter_lines(partner_id, ledger_lines) |
|
@ -164,9 +178,10 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
|
|
|
|
|
|
def _get_end_date(self, data): |
|
|
def _get_end_date(self, data): |
|
|
"""Retrieve end date to be used to compute delay. |
|
|
"""Retrieve end date to be used to compute delay. |
|
|
|
|
|
|
|
|
:param data: data dict send to report contains form dict |
|
|
:param data: data dict send to report contains form dict |
|
|
|
|
|
|
|
|
:returns: end date to be used to compute overdur delay |
|
|
|
|
|
|
|
|
:returns: end date to be used to compute overdue delay |
|
|
|
|
|
|
|
|
""" |
|
|
""" |
|
|
end_date = None |
|
|
end_date = None |
|
@ -191,6 +206,7 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
|
|
|
|
|
|
def _compute_delay_from_key(self, key, line, end_date): |
|
|
def _compute_delay_from_key(self, key, line, end_date): |
|
|
"""Compute overdue delay delta in days for line using attribute in key |
|
|
"""Compute overdue delay delta in days for line using attribute in key |
|
|
|
|
|
|
|
|
delta = end_date - date of key |
|
|
delta = end_date - date of key |
|
|
|
|
|
|
|
|
:param line: current ledger line |
|
|
:param line: current ledger line |
|
@ -206,10 +222,13 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
|
|
|
|
|
|
def compute_delay_from_maturity(self, line, end_date, ledger_lines): |
|
|
def compute_delay_from_maturity(self, line, end_date, ledger_lines): |
|
|
"""Compute overdue delay delta in days for line using attribute in key |
|
|
"""Compute overdue delay delta in days for line using attribute in key |
|
|
|
|
|
|
|
|
delta = end_date - maturity date |
|
|
delta = end_date - maturity date |
|
|
|
|
|
|
|
|
:param line: current ledger line |
|
|
:param line: current ledger line |
|
|
:param end_date: end_date computed for wizard data |
|
|
:param end_date: end_date computed for wizard data |
|
|
|
|
|
:params: ledger_lines generated by parent |
|
|
|
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
:returns: delta in days |
|
|
:returns: delta in days |
|
|
""" |
|
|
""" |
|
@ -219,10 +238,13 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
|
|
|
|
|
|
def compute_delay_from_date(self, line, end_date, ledger_lines): |
|
|
def compute_delay_from_date(self, line, end_date, ledger_lines): |
|
|
"""Compute overdue delay delta in days for line using attribute in key |
|
|
"""Compute overdue delay delta in days for line using attribute in key |
|
|
delta = end_date - maturity date |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
delta = end_date - date |
|
|
|
|
|
|
|
|
:param line: current ledger line |
|
|
:param line: current ledger line |
|
|
:param end_date: end_date computed for wizard data |
|
|
:param end_date: end_date computed for wizard data |
|
|
|
|
|
:params: ledger_lines generated by parent |
|
|
|
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
:returns: delta in days |
|
|
:returns: delta in days |
|
|
""" |
|
|
""" |
|
@ -231,6 +253,17 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
end_date) |
|
|
end_date) |
|
|
|
|
|
|
|
|
def compute_delay_from_partial_rec(self, line, end_date, ledger_lines): |
|
|
def compute_delay_from_partial_rec(self, line, end_date, ledger_lines): |
|
|
|
|
|
"""Compute overdue delay delta in days for the case where move line |
|
|
|
|
|
|
|
|
|
|
|
is related to a partial reconcile with more than one reconcile line |
|
|
|
|
|
|
|
|
|
|
|
:param line: current ledger line |
|
|
|
|
|
:param end_date: end_date computed for wizard data |
|
|
|
|
|
:params: ledger_lines generated by parent |
|
|
|
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
|
|
|
:returns: delta in days |
|
|
|
|
|
""" |
|
|
sale_lines = [x for x in ledger_lines if x['jtype'] in REC_PAY_TYPE and |
|
|
sale_lines = [x for x in ledger_lines if x['jtype'] in REC_PAY_TYPE and |
|
|
line['rec_id'] == x['rec_id']] |
|
|
line['rec_id'] == x['rec_id']] |
|
|
refund_lines = [x for x in ledger_lines if x['jtype'] in REFUND_TYPE and |
|
|
refund_lines = [x for x in ledger_lines if x['jtype'] in REFUND_TYPE and |
|
@ -246,6 +279,17 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
end_date) |
|
|
end_date) |
|
|
|
|
|
|
|
|
def get_compute_method(self, reconcile_lookup, partner_id, line): |
|
|
def get_compute_method(self, reconcile_lookup, partner_id, line): |
|
|
|
|
|
"""Get the function that should compute the delay for a given line |
|
|
|
|
|
|
|
|
|
|
|
:param reconcile_lookup: dict of reconcile group by id and count |
|
|
|
|
|
{rec_id: count of line related to reconcile} |
|
|
|
|
|
:param partner_id: current partner_id |
|
|
|
|
|
:param line: current ledger line generated by parent |
|
|
|
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
|
|
|
:returns: function bounded to :class:`.AccountAgedTrialBalanceWebkit` |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
if reconcile_lookup.get(line['rec_id'], 0.0) > 1: |
|
|
if reconcile_lookup.get(line['rec_id'], 0.0) > 1: |
|
|
return self.compute_delay_from_partial_rec |
|
|
return self.compute_delay_from_partial_rec |
|
|
if line['jtype'] in INV_TYPE: |
|
|
if line['jtype'] in INV_TYPE: |
|
@ -256,24 +300,40 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
return self.compute_delay_from_date |
|
|
return self.compute_delay_from_date |
|
|
|
|
|
|
|
|
def line_is_valid(self, partner_id, line): |
|
|
def line_is_valid(self, partner_id, line): |
|
|
"""Predicate that tells if line has to be treated""" |
|
|
|
|
|
# waiting some spec here maybe dead code |
|
|
|
|
|
|
|
|
"""Predicate hook that allows to filter line to be treated |
|
|
|
|
|
|
|
|
|
|
|
:param partner_id: current partner_id |
|
|
|
|
|
:param line: current ledger line generated by parent |
|
|
|
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
|
|
|
:returns: boolean True if line is allowed |
|
|
|
|
|
""" |
|
|
return True |
|
|
return True |
|
|
|
|
|
|
|
|
def filter_lines(self, partner_id, lines): |
|
|
def filter_lines(self, partner_id, lines): |
|
|
# vaiting specs |
|
|
|
|
|
|
|
|
"""Filter ledger lines that have to be treated |
|
|
|
|
|
|
|
|
|
|
|
:param partner_id: current partner_id |
|
|
|
|
|
:param lines: ledger_lines related to current partner |
|
|
|
|
|
and generated by parent |
|
|
|
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
|
|
|
:returns: list of allowed lines |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
return [x for x in lines if self.line_is_valid(partner_id, x)] |
|
|
return [x for x in lines if self.line_is_valid(partner_id, x)] |
|
|
|
|
|
|
|
|
def classify_line(self, partner_id, overdue_days): |
|
|
def classify_line(self, partner_id, overdue_days): |
|
|
"""Return the range index for a number of overdue days |
|
|
|
|
|
|
|
|
"""Return the overdue range for a given delay |
|
|
|
|
|
|
|
|
We loop from smaller range to higher |
|
|
We loop from smaller range to higher |
|
|
This should be the most effective solution as generaly |
|
|
This should be the most effective solution as generaly |
|
|
customer tend to have one or two month of delay |
|
|
customer tend to have one or two month of delay |
|
|
|
|
|
|
|
|
:param overdue_days: int representing the lenght in days of delay |
|
|
|
|
|
|
|
|
:param overdue_days: delay in days |
|
|
|
|
|
:param partner_id: current partner_id |
|
|
|
|
|
|
|
|
:returns: the index of the correct range in ´´RANGES´´ |
|
|
|
|
|
|
|
|
:returns: the correct range in :const:`RANGES` |
|
|
|
|
|
|
|
|
""" |
|
|
""" |
|
|
for drange in RANGES: |
|
|
for drange in RANGES: |
|
@ -282,9 +342,19 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
return drange |
|
|
return drange |
|
|
|
|
|
|
|
|
def compute_balance(self, res, aged_lines): |
|
|
def compute_balance(self, res, aged_lines): |
|
|
|
|
|
"""Compute the total balance of aged line |
|
|
|
|
|
for given account""" |
|
|
res['balance'] = sum(aged_lines.values()) |
|
|
res['balance'] = sum(aged_lines.values()) |
|
|
|
|
|
|
|
|
def compute_totals(self, aged_lines): |
|
|
def compute_totals(self, aged_lines): |
|
|
|
|
|
"""Compute the totals for an account |
|
|
|
|
|
|
|
|
|
|
|
:param aged_lines: dict of aged line taken from the |
|
|
|
|
|
property added to account record |
|
|
|
|
|
|
|
|
|
|
|
:returns: dict of total {'balance':1000.00, (30, 60): 3000,...} |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
totals = {} |
|
|
totals = {} |
|
|
totals['balance'] = sum(x.get('balance', 0.0) for |
|
|
totals['balance'] = sum(x.get('balance', 0.0) for |
|
|
x in aged_lines) |
|
|
x in aged_lines) |
|
@ -301,6 +371,17 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit): |
|
|
return percents |
|
|
return percents |
|
|
|
|
|
|
|
|
def get_reconcile_count_lookup(self, lines): |
|
|
def get_reconcile_count_lookup(self, lines): |
|
|
|
|
|
"""Compute an lookup dict |
|
|
|
|
|
|
|
|
|
|
|
It contains has partial reconcile id as key and the count of lines |
|
|
|
|
|
related to the reconcile id |
|
|
|
|
|
|
|
|
|
|
|
:param: a list of ledger lines generated by parent |
|
|
|
|
|
:class:`.open_invoices.PartnersOpenInvoicesWebkit` |
|
|
|
|
|
|
|
|
|
|
|
:retuns: lookup dict {ṛec_id: count} |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
# possible bang if l_ids is really long. |
|
|
# possible bang if l_ids is really long. |
|
|
# We have the same weakness in common_report ... |
|
|
# We have the same weakness in common_report ... |
|
|
# but it seems not really possible for a partner |
|
|
# but it seems not really possible for a partner |
|
|