Browse Source

[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 balance
pull/90/head
Stéphane Bidoul 10 years ago
parent
commit
4101adb125
  1. 129
      mis_builder/models/aep.py
  2. 4
      mis_builder/models/mis_builder.py

129
mis_builder/models/aep.py

@ -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):
period_obj = self.env['account.period']
move_obj = self.env['account.move']
domain_list = []
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: 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)])
period_ids.extend(self._get_period_ids_between(
period_from, period_to, company_id))
else: else:
period_to = period_end
if mode == MODE_INITIAL: 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
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: 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
# 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']

4
mis_builder/models/mis_builder.py

@ -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_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 return res

Loading…
Cancel
Save