You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
7.3 KiB
Python

8 months ago
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields, _
from odoo.tools.misc import DEFAULT_SERVER_DATE_FORMAT
from datetime import timedelta
from odoo.tools import date_utils
class ResCompany(models.Model):
_inherit = 'res.company'
invoicing_switch_threshold = fields.Date(string="Invoicing Switch Threshold", help="Every payment and invoice before this date will receive the 'From Invoicing' status, hiding all the accounting entries related to it. Use this option after installing Accounting if you were using only Invoicing before, before importing all your actual accounting data in to Odoo.")
def write(self, vals):
old_threshold_vals = {}
for record in self:
old_threshold_vals[record] = record.invoicing_switch_threshold
rslt = super(ResCompany, self).write(vals)
for record in self:
if 'invoicing_switch_threshold' in vals and old_threshold_vals[record] != vals['invoicing_switch_threshold']:
self.env['account.move.line'].flush_model(['move_id', 'parent_state'])
self.env['account.move'].flush_model(['company_id', 'date', 'state', 'payment_state', 'payment_state_before_switch'])
if record.invoicing_switch_threshold:
# If a new date was set as threshold, we switch all the
# posted moves and payments before it to 'invoicing_legacy'.
# We also reset to posted all the moves and payments that
# were 'invoicing_legacy' and were posterior to the threshold
self.env.cr.execute("""
update account_move_line aml
set parent_state = 'posted'
from account_move move
where aml.move_id = move.id
and move.payment_state = 'invoicing_legacy'
and move.date >= %(switch_threshold)s
and move.company_id = %(company_id)s;
update account_move
set state = 'posted',
payment_state = payment_state_before_switch,
payment_state_before_switch = null
where payment_state = 'invoicing_legacy'
and date >= %(switch_threshold)s
and company_id = %(company_id)s;
update account_move_line aml
set parent_state = 'cancel'
from account_move move
where aml.move_id = move.id
and move.state = 'posted'
and move.date < %(switch_threshold)s
and move.company_id = %(company_id)s;
update account_move
set state = 'cancel',
payment_state_before_switch = payment_state,
payment_state = 'invoicing_legacy'
where state = 'posted'
and date < %(switch_threshold)s
and company_id = %(company_id)s;
""", {'company_id': record.id, 'switch_threshold': record.invoicing_switch_threshold})
else:
# If the threshold date has been emptied, we re-post all the
# invoicing_legacy entries.
self.env.cr.execute("""
update account_move_line aml
set parent_state = 'posted'
from account_move move
where aml.move_id = move.id
and move.payment_state = 'invoicing_legacy'
and move.company_id = %(company_id)s;
update account_move
set state = 'posted',
payment_state = payment_state_before_switch,
payment_state_before_switch = null
where payment_state = 'invoicing_legacy'
and company_id = %(company_id)s;
""", {'company_id': record.id})
self.env['account.move.line'].invalidate_model(['parent_state'])
self.env['account.move'].invalidate_model(['state', 'payment_state', 'payment_state_before_switch'])
return rslt
def compute_fiscalyear_dates(self, current_date):
"""Compute the start and end dates of the fiscal year where the given 'date' belongs to.
:param current_date: A datetime.date/datetime.datetime object.
:return: A dictionary containing:
* date_from
* date_to
* [Optionally] record: The fiscal year record.
"""
self.ensure_one()
date_str = current_date.strftime(DEFAULT_SERVER_DATE_FORMAT)
# Search a fiscal year record containing the date.
# If a record is found, then no need further computation, we get the dates range directly.
fiscalyear = self.env['account.fiscal.year'].search([
('company_id', '=', self.id),
('date_from', '<=', date_str),
('date_to', '>=', date_str),
], limit=1)
if fiscalyear:
return {
'date_from': fiscalyear.date_from,
'date_to': fiscalyear.date_to,
'record': fiscalyear,
}
date_from, date_to = date_utils.get_fiscal_year(
current_date, day=self.fiscalyear_last_day, month=int(self.fiscalyear_last_month))
date_from_str = date_from.strftime(DEFAULT_SERVER_DATE_FORMAT)
date_to_str = date_to.strftime(DEFAULT_SERVER_DATE_FORMAT)
# Search for fiscal year records reducing the delta between the date_from/date_to.
# This case could happen if there is a gap between two fiscal year records.
# E.g. two fiscal year records: 2017-01-01 -> 2017-02-01 and 2017-03-01 -> 2017-12-31.
# => The period 2017-02-02 - 2017-02-30 is not covered by a fiscal year record.
fiscalyear_from = self.env['account.fiscal.year'].search([
('company_id', '=', self.id),
('date_from', '<=', date_from_str),
('date_to', '>=', date_from_str),
], limit=1)
if fiscalyear_from:
date_from = fiscalyear_from.date_to + timedelta(days=1)
fiscalyear_to = self.env['account.fiscal.year'].search([
('company_id', '=', self.id),
('date_from', '<=', date_to_str),
('date_to', '>=', date_to_str),
], limit=1)
if fiscalyear_to:
date_to = fiscalyear_to.date_from - timedelta(days=1)
return {'date_from': date_from, 'date_to': date_to}
def _get_fiscalyear_lock_statement_lines_redirect_action(self, unreconciled_statement_lines):
# OVERRIDE account
return self.env['account.bank.statement.line']._action_open_bank_reconciliation_widget(
default_context={'search_default_not_matched': True},
extra_domain=[('id', 'in', unreconciled_statement_lines.ids)],
name=_('Unreconciled statements lines'),
)