[IMP] mis_builder: rework periods computation
* readability of algorithm * attempt to be correct in presence of multiple companies * attempt to be correct with initial balance computation * handle corner cases for initial balancepull/86/head
parent
44499e620d
commit
45d3477ded
|
@ -178,48 +178,101 @@ class AccountingExpressionProcessor(object):
|
||||||
raise RuntimeError("") # TODO
|
raise RuntimeError("") # TODO
|
||||||
return [('date', '>=', date_start), ('date', '<=', date_end)]
|
return [('date', '>=', date_start), ('date', '<=', date_end)]
|
||||||
|
|
||||||
def get_aml_domain_for_periods(self, period_start, period_end, mode):
|
def _period_has_moves(self, period):
|
||||||
period_obj = self.env['account.period']
|
move_model = self.env['account.move']
|
||||||
move_obj = self.env['account.move']
|
return bool(move_model.search([('period_id', '=', period.id)],
|
||||||
domain_list = []
|
limit=1))
|
||||||
if mode == MODE_VARIATION:
|
|
||||||
compute_period_ids = period_obj.build_ctx_periods(
|
def _get_previous_opening_period(self, period, company_id):
|
||||||
period_start.id,
|
period_model = self.env['account.period']
|
||||||
period_end.id)
|
periods = period_model.search(
|
||||||
domain_list.extend([('period_id', 'in', compute_period_ids)])
|
[('date_start', '<=', period.date_start),
|
||||||
else:
|
('special', '=', True),
|
||||||
period_to = period_end
|
('company_id', '=', company_id)],
|
||||||
if mode == MODE_INITIAL:
|
order="date_start desc",
|
||||||
# Processing to get the first period which isn't special
|
limit=1)
|
||||||
# before end period
|
return periods and periods[0]
|
||||||
move = move_obj\
|
|
||||||
.search([('period_id.special', '=', False),
|
def _get_previous_normal_period(self, period, company_id):
|
||||||
('period_id.date_start', '<',
|
period_model = self.env['account.period']
|
||||||
period_to.date_start)],
|
periods = period_model.search(
|
||||||
order="period_id desc", limit=1)
|
[('date_start', '<', period.date_start),
|
||||||
if move.id:
|
('special', '=', False),
|
||||||
computed_period_to = move.period_id
|
('company_id', '=', company_id)],
|
||||||
else:
|
order="date_start desc",
|
||||||
computed_period_to = period_obj.search(
|
limit=1)
|
||||||
[('company_id', '=', period_start.company_id.id)],
|
return periods and periods[0]
|
||||||
order='date_start desc', limit=1)
|
|
||||||
# Change start period to search correctly period from
|
def _get_first_normal_period(self, company_id):
|
||||||
period_to = computed_period_to
|
period_model = self.env['account.period']
|
||||||
move = move_obj.search(
|
periods = period_model.search(
|
||||||
[('period_id.special', '=', True),
|
[('special', '=', False),
|
||||||
('period_id.date_start', '<=',
|
('company_id', '=', company_id)],
|
||||||
period_to.date_start)],
|
order="date_start asc",
|
||||||
order="period_id desc", limit=1)
|
limit=1)
|
||||||
if move.id:
|
return periods and periods[0]
|
||||||
computed_period_from = move.period_id
|
|
||||||
|
def _get_period_ids_between(self, period_from, period_to, company_id):
|
||||||
|
period_model = self.env['account.period']
|
||||||
|
periods = period_model.search(
|
||||||
|
[('date_start', '>=', period_from.date_start),
|
||||||
|
('date_stop', '<=', period_to.date_stop),
|
||||||
|
('special', '=', False),
|
||||||
|
('company_id', '=', company_id)])
|
||||||
|
period_ids = [p.id for p in periods]
|
||||||
|
if period_from.special:
|
||||||
|
period_ids.append(period_from.id)
|
||||||
|
return period_ids
|
||||||
|
|
||||||
|
def _get_period_company_ids(self, period_from, period_to):
|
||||||
|
period_model = self.env['account.period']
|
||||||
|
periods = period_model.search(
|
||||||
|
[('date_start', '>=', period_from.date_start),
|
||||||
|
('date_stop', '<=', period_to.date_stop),
|
||||||
|
('special', '=', False)])
|
||||||
|
return set([p.company_id.id for p in periods])
|
||||||
|
|
||||||
|
def _get_period_ids_for_mode(self, period_from, period_to, mode):
|
||||||
|
assert not period_from.special
|
||||||
|
assert not period_to.special
|
||||||
|
assert period_from.company_id == period_to.company_id
|
||||||
|
assert period_from.date_start <= period_to.date_start
|
||||||
|
period_ids = []
|
||||||
|
for company_id in self._get_period_company_ids(period_from, period_to):
|
||||||
|
if mode == MODE_VARIATION:
|
||||||
|
period_ids.extend(self._get_period_ids_between(
|
||||||
|
period_from, period_to, company_id))
|
||||||
else:
|
else:
|
||||||
computed_period_from = period_obj.search(
|
if mode == MODE_INITIAL:
|
||||||
[('company_id', '=', period_start.company_id.id)],
|
period_to = self._get_previous_normal_period(
|
||||||
order='date_start', limit=1)
|
period_from, company_id)
|
||||||
compute_period_ids = period_obj.build_ctx_periods(
|
# look for opening period with moves
|
||||||
computed_period_from.id, period_to.id)
|
opening_period = self._get_previous_opening_period(
|
||||||
domain_list.extend([('period_id', 'in', compute_period_ids)])
|
period_from, company_id)
|
||||||
return domain_list
|
if opening_period and \
|
||||||
|
self._period_has_moves(opening_period[0]):
|
||||||
|
# found opening period with moves
|
||||||
|
if opening_period.date_start == period_from.date_start and \
|
||||||
|
mode == MODE_INITIAL:
|
||||||
|
# if the opening period has the same start date as
|
||||||
|
# period_from, the we'll find the initial balance
|
||||||
|
# in the initial period and that's it
|
||||||
|
period_ids.append(opening_period[0].id)
|
||||||
|
continue
|
||||||
|
period_from = opening_period[0]
|
||||||
|
else:
|
||||||
|
# no opening period with moves,
|
||||||
|
# use very first normal period
|
||||||
|
period_from = self._get_first_normal_period(company_id)
|
||||||
|
if period_to:
|
||||||
|
period_ids.extend(self._get_period_ids_between(
|
||||||
|
period_from, period_to, company_id))
|
||||||
|
return period_ids
|
||||||
|
|
||||||
|
def get_aml_domain_for_periods(self, period_from, period_to, mode):
|
||||||
|
period_ids = self._get_period_ids_for_mode(
|
||||||
|
period_from, period_to, mode)
|
||||||
|
return [('period_id', 'in', period_ids)]
|
||||||
|
|
||||||
def do_queries(self, period_domain, period_domain_i, period_domain_e):
|
def do_queries(self, period_domain, period_domain_i, period_domain_e):
|
||||||
aml_model = self.env['account.move.line']
|
aml_model = self.env['account.move.line']
|
||||||
|
|
|
@ -412,8 +412,8 @@ class mis_report_instance_period(orm.Model):
|
||||||
res[c.id] = {
|
res[c.id] = {
|
||||||
'date_from': date_from,
|
'date_from': date_from,
|
||||||
'date_to': date_to,
|
'date_to': date_to,
|
||||||
'period_from': period_ids and period_ids[0],
|
'period_from': period_ids and period_ids[0] or False,
|
||||||
'period_to': period_ids and period_ids[-1],
|
'period_to': period_ids and period_ids[-1] or False,
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue