Newer
Older
##############################################################################
#
# Accounting periods, for Odoo
# Copyright (C) 2018 XCG Consulting <http://odoo.consulting>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
class AccountMove(models.Model):
"""Add a period & dates onto accounting documents.
"""
comodel_name="account.period",
string="Period",
help="The period this accounting document is in.",
ondelete="restrict",
states={"posted": [("readonly", True), ("required", True)]},
)
transaction_date = fields.Date(
"Invoicing date when provided; otherwise this is the accounting "
"date."
states={"posted": [("readonly", True)]},
)
@api.model
def create(self, vals):
"""Override to set a transaction date from invoices.
"""
if not vals.get("date"):
vals["date"] = fields.Date.context_today(self)
invoice = self.env.context.get("invoice")
if invoice and isinstance(invoice, models.BaseModel):
if not isinstance(vals, dict):
vals = {}
vals["transaction_date"] = invoice.date_invoice
return super(AccountMove, self).create(vals)
@api.model
def fields_get(self, allfields=None, attributes=None):
"""Override to tweak the default "date" field.
"""
ret = super(AccountMove, self).fields_get(
allfields=allfields, attributes=attributes
date_field.update(
{
"string": _("Accounting date"),
"help": _("Validation date of the accounting document."),
"readonly": True,
"states": {},
}
)
return ret
@api.multi
def post(self):
"""Override accounting document validation to:
- Set accounting dates (default "date" field).
- Also set the transaction date ("transaction_date" field) when empty.
"""
self.fill_accounting_dates()
return super(AccountMove, self).post()
@api.multi
def fill_accounting_dates(self):
"""- Set accounting dates (default "date" field).
- Also set the transaction date ("transaction_date" field) when empty.
- Force the period to always be around the current date.
- Only select open periods.
acc_date = datetime.date.today()
# Cache some data.
company = accdoc.company_id
# Set the acc_date only if the force_period_on_date
# context has provided.
if self.env.context.get("force_period_on_date"):
# If accounting document date is empty, get today date.
acc_date = fields.Date.from_string(accdoc.date) or acc_date
# Periods are ordered by date so selecting the first one is fine.
period = self.env["account.period"].search(
[
("company_id", "=", company.id),
("date_start", "<=", acc_date),
("date_effective_cutoff", ">=", acc_date),
raise exceptions.Warning(
_('No period found around %s in the "%s" company.')
% (acc_date, company.sudo().name)
# When we are between the period end and cut-off date, force the
# last day of the period.
in_cutoff = False
if accdoc.journal_id.type == "sale":
period_end = fields.Date.from_string(period.date_stop)
in_cutoff = acc_date > period_end
acc_date = period_end if in_cutoff else acc_date
# The data to update the accounting document with.
accdoc_values = {"date": acc_date, "period_id": period.id}
# Set a transaction date when no previous one set. Also, force it
# during cut-off.
if in_cutoff or not accdoc.transaction_date:
accdoc_values["transaction_date"] = acc_date
# Ready! Update the accounting document.
accdoc.write(accdoc_values)