[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
|
||||
return [('date', '>=', date_start), ('date', '<=', date_end)]
|
||||
|
||||
def get_aml_domain_for_periods(self, period_start, period_end, mode):
|
||||
period_obj = self.env['account.period']
|
||||
move_obj = self.env['account.move']
|
||||
domain_list = []
|
||||
if mode == MODE_VARIATION:
|
||||
compute_period_ids = period_obj.build_ctx_periods(
|
||||
period_start.id,
|
||||
period_end.id)
|
||||
domain_list.extend([('period_id', 'in', compute_period_ids)])
|
||||
else:
|
||||
period_to = period_end
|
||||
if mode == MODE_INITIAL:
|
||||
# Processing to get the first period which isn't special
|
||||
# before end period
|
||||
move = move_obj\
|
||||
.search([('period_id.special', '=', False),
|
||||
('period_id.date_start', '<',
|
||||
period_to.date_start)],
|
||||
order="period_id desc", limit=1)
|
||||
if move.id:
|
||||
computed_period_to = move.period_id
|
||||
else:
|
||||
computed_period_to = period_obj.search(
|
||||
[('company_id', '=', period_start.company_id.id)],
|
||||
order='date_start desc', limit=1)
|
||||
# Change start period to search correctly period from
|
||||
period_to = computed_period_to
|
||||
move = move_obj.search(
|
||||
[('period_id.special', '=', True),
|
||||
('period_id.date_start', '<=',
|
||||
period_to.date_start)],
|
||||
order="period_id desc", limit=1)
|
||||
if move.id:
|
||||
computed_period_from = move.period_id
|
||||
def _period_has_moves(self, period):
|
||||
move_model = self.env['account.move']
|
||||
return bool(move_model.search([('period_id', '=', period.id)],
|
||||
limit=1))
|
||||
|
||||
def _get_previous_opening_period(self, period, company_id):
|
||||
period_model = self.env['account.period']
|
||||
periods = period_model.search(
|
||||
[('date_start', '<=', period.date_start),
|
||||
('special', '=', True),
|
||||
('company_id', '=', company_id)],
|
||||
order="date_start desc",
|
||||
limit=1)
|
||||
return periods and periods[0]
|
||||
|
||||
def _get_previous_normal_period(self, period, company_id):
|
||||
period_model = self.env['account.period']
|
||||
periods = period_model.search(
|
||||
[('date_start', '<', period.date_start),
|
||||
('special', '=', False),
|
||||
('company_id', '=', company_id)],
|
||||
order="date_start desc",
|
||||
limit=1)
|
||||
return periods and periods[0]
|
||||
|
||||
def _get_first_normal_period(self, company_id):
|
||||
period_model = self.env['account.period']
|
||||
periods = period_model.search(
|
||||
[('special', '=', False),
|
||||
('company_id', '=', company_id)],
|
||||
order="date_start asc",
|
||||
limit=1)
|
||||
return periods and periods[0]
|
||||
|
||||
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:
|
||||
computed_period_from = period_obj.search(
|
||||
[('company_id', '=', period_start.company_id.id)],
|
||||
order='date_start', limit=1)
|
||||
compute_period_ids = period_obj.build_ctx_periods(
|
||||
computed_period_from.id, period_to.id)
|
||||
domain_list.extend([('period_id', 'in', compute_period_ids)])
|
||||
return domain_list
|
||||
if mode == MODE_INITIAL:
|
||||
period_to = self._get_previous_normal_period(
|
||||
period_from, company_id)
|
||||
# look for opening period with moves
|
||||
opening_period = self._get_previous_opening_period(
|
||||
period_from, company_id)
|
||||
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):
|
||||
aml_model = self.env['account.move.line']
|
||||
|
|
|
@ -412,8 +412,8 @@ class mis_report_instance_period(orm.Model):
|
|||
res[c.id] = {
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'period_from': period_ids and period_ids[0],
|
||||
'period_to': period_ids and period_ids[-1],
|
||||
'period_from': period_ids and period_ids[0] or False,
|
||||
'period_to': period_ids and period_ids[-1] or False,
|
||||
}
|
||||
return res
|
||||
|
||||
|
|
Loading…
Reference in New Issue