Sélectionner une révision Git
Bifurcation depuis
Le Filament / Confédération Générale des SCOP / cgscop_partner
Le projet source a une visibilité limitée.
acc_account.py 9,41 Kio
# Copyright 2021 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from dateutil.relativedelta import relativedelta
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class AccAccount(models.Model):
_name = "acc.account"
_inherit = ["portal.mixin", "mail.thread"]
_description = "Factures"
_order = "date desc, name desc, id desc"
def _get_default_currency_id(self):
return self.env.company.currency_id.id
# ------------------------------------------------------
# Fields declaration
# ------------------------------------------------------
name = fields.Char(
string="Number",
copy=False,
readonly=False,
store=True,
index=True,
tracking=True,
default="/",
)
date = fields.Date(
string="Date",
required=True,
index=True,
readonly=True,
copy=False,
default=fields.Date.context_today,
)
start_date = fields.Date(string="Date de début", default=fields.Date.context_today)
end_date = fields.Date(string="Date de fin", default=fields.Date.context_today)
currency_id = fields.Many2one(
"res.currency", string="Devise", required=True, default=_get_default_currency_id
)
is_account_buyer = fields.Boolean("Est une facture Surplus")
acc_operation_id = fields.Many2one("acc.operation", string="Opération")
pmo_id = fields.Many2one(
"res.partner",
string="PMO",
related="acc_operation_id.pmo_id",
)
acc_injection_id = fields.Many2one(
"acc.counter",
domain=[("is_injection", "=", True)],
string="Point d'injection",
ondelete="cascade",
)
producer_id = fields.Many2one(
comodel_name="res.partner",
related="acc_injection_id.partner_id",
string="Producteur",
)
is_tva = fields.Boolean("Assujetti à la TVA", related="producer_id.is_tva")
tax_id = fields.Many2one("acc.account.tax", "Taxe", related="producer_id.tax_id")
acc_delivery_id = fields.Many2one(
"acc.counter",
domain=[("is_delivery", "=", True)],
string="Point de soutirage",
ondelete="cascade",
)
consumer_id = fields.Many2one(
comodel_name="res.partner",
related="acc_delivery_id.partner_id",
string="Consommateur",
)
buyer_id = fields.Many2one(
comodel_name="res.partner",
domain=[("is_buyer_surplus", "=", True)],
ondelete="cascade",
string="Acheteur",
)
line_ids = fields.One2many(
"acc.account.line",
"acc_account_id",
string="Lignes de facturation mensuelle",
copy=True,
)
amount_untaxed = fields.Monetary(
string="Montant H.T.",
store=True,
readonly=True,
tracking=True,
compute="_compute_amount",
)
amount_tax = fields.Monetary(
string="Taxe", store=True, readonly=True, compute="_compute_amount"
)
amount_total = fields.Monetary(
string="Total", store=True, readonly=True, compute="_compute_amount"
)
amount_tcfe = fields.Monetary(
string="Montant TCFE", store=True, readonly=True, compute="_compute_amount"
)
amount_without_tcfe = fields.Monetary(
string="Montant hors TCFE", store=True, readonly=True, compute="_compute_amount"
)
# inverse='_inverse_amount_total')
power_cons = fields.Float(
"Consommation locale (index Enedis)", digits="Unité de Mesure"
)
url = fields.Char("URL", compute="_compute_url", store=True)
state = fields.Selection(
selection=[
("draft", "Brouillon"),
("published", "Publié"),
],
string="Statut",
required=True,
copy=False,
tracking=True,
default="draft",
)
@api.model_create_multi
def create(self, vals_list):
res = super(AccAccount, self).create(vals_list)
for rec in res:
if res.is_account_buyer:
seq = str(rec.acc_injection_id.acc_account_surplus_count).zfill(3)
rec.name = (
"FS-"
+ rec.acc_operation_id.name
+ "-"
+ rec.acc_injection_id.name
+ "-"
+ seq
)
else:
seq = str(rec.acc_injection_id.acc_account_injection_count).zfill(3)
rec.name = (
"F-"
+ rec.acc_operation_id.name
+ "-"
+ rec.acc_injection_id.name
+ "-"
+ seq
)
return res
def _compute_access_url(self):
super(AccAccount, self)._compute_access_url()
for move in self:
move.access_url = "/invoice/%s" % (move.id)
def _get_report_base_filename(self):
self.ensure_one()
return "Facture %s" % (self.name,)
@api.depends(
"line_ids",
"line_ids.price_total",
"line_ids.price_unit",
"line_ids.quantity",
)
def _compute_amount(self):
for move in self:
total_tax = 0.0
total = 0.0
tot_qty = 0.0
tot_tcfe = 0.0
tot_tcfe_off = 0.0
for line in move.line_ids:
total += line.price_total
tot_qty += line.quantity
if line.is_tax:
tot_tcfe += line.price_total
else:
tot_tcfe_off += line.price_total
if move.is_tva and move.tax_id:
total_tax = (total * move.tax_id.amount) / 100
move.amount_untaxed = total
move.amount_tax = total_tax
move.amount_total = total + total_tax
move.amount_tcfe = tot_tcfe
move.amount_without_tcfe = tot_tcfe_off
def _compute_url(self):
for account in self:
account.url = account.get_portal_url(report_type="pdf", download=True)
class AccAccountLine(models.Model):
_name = "acc.account.line"
_description = "Lignes de facturation"
_order = "start_date asc"
acc_account_id = fields.Many2one(
"acc.account",
string="Facture",
index=True,
required=True,
readonly=True,
auto_join=True,
ondelete="cascade",
)
acc_account_name = fields.Char(
string="Numéro", related="acc_account_id.name", store=True, index=True
)
acc_operation_id = fields.Many2one(
"acc.operation",
string="Opération",
related="acc_account_id.acc_operation_id",
store=True,
)
date = fields.Date(
related="acc_account_id.date", store=True, readonly=True, index=True, copy=False
)
quantity = fields.Float(string="Quantité", default=1.0, digits="Unité de Mesure")
price_unit = fields.Float(string="Prix unitaire", digits="Sale Price")
currency_id = fields.Many2one(
"res.currency", string="Devise", related="acc_account_id.currency_id"
)
price_total = fields.Monetary(
string="Total",
store=True,
readonly=True,
currency_field="currency_id",
compute="_compute_amount",
)
tax_id = fields.Many2one(
comodel_name="acc.account.tax", string="Taxes", related="acc_account_id.tax_id"
)
start_date = fields.Date("Début de la période")
end_date = fields.Date("Fin de la période")
description = fields.Text("Description de la ligne")
is_tva = fields.Boolean(related="acc_account_id.is_tva")
is_tax = fields.Boolean("Est une taxe")
@api.depends("quantity", "price_unit")
def _compute_amount(self):
for line in self:
line.price_total = line.quantity * line.price_unit
class AccAccountTax(models.Model):
_name = "acc.account.tax"
_description = "Taxe"
name = fields.Char(string="Nom", required=True)
amount = fields.Float(required=True, digits=(16, 4), default=0.0, string="Montant")
class AccAccountTaxTcfe(models.Model):
_name = "acc.account.tax.tcfe"
_description = "Taxe TCFE"
def _get_default_currency_id(self):
return self.env.company.currency_id.id
start_date = fields.Date("Début de la période")
end_date = fields.Date("Fin de la période")
currency_id = fields.Many2one(
"res.currency", "Devise", default=_get_default_currency_id
)
price = fields.Float("Tarif", digits="Sale Price")
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if "start_date" in vals:
start_date = fields.Date.to_date(vals["start_date"])
# Si une période existe après la date renseignée
price_ids = self.env["acc.account.tax.tcfe"].search(
[
("start_date", "<=", start_date),
("end_date", ">", start_date),
]
)
if price_ids:
raise ValidationError(
_("Un prix de vente existe déjà pour cette date là")
)
price_id = self.env["acc.account.tax.tcfe"].search(
[],
limit=1,
order="create_date desc",
)
if price_id:
price_id.end_date = start_date - relativedelta(days=1)
res = super(AccAccountTaxTcfe, self).create(vals_list)
return res