Skip to content
Extraits de code Groupes Projets
Valider d25ce504 rédigé par Benjamin - Le Filament's avatar Benjamin - Le Filament
Parcourir les fichiers

[add] revenue assign on invoices

parent 6030985c
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
# Copyright 2020 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models
from . import models, report
......@@ -7,7 +7,13 @@
"license": "AGPL-3",
"depends": ["account"],
"data": [
"views/account_invoice_views.xml",
# security
"security/ir.model.access.csv",
# templates
"templates/account_invoice_templates.xml",
# templates
"report/account_invoice_employee_report.xml",
# views
"views/account_invoice_views.xml",
],
}
......@@ -2,4 +2,5 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import account_invoice
from . import account_invoice_employee_assign
from . import account_journal_dashboard
# Copyright 2022 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
from odoo import api, fields, models
class AccountInvoice(models.Model):
_inherit = "account.invoice"
with_detail = fields.Boolean("Facture avec détail", default=False)
employee_allocation_ids = fields.One2many(
comodel_name="account.invoice.employee.assign",
inverse_name="invoice_id",
string="Ventilation facture",
)
is_allocated = fields.Boolean(
string="Facture ventilée",
compute="_compute_allocation",
store=True,
default=False,
)
is_allocation_error = fields.Boolean(
string="Erreur de ventilation",
compute="_compute_allocation",
store=True,
default=False,
)
# ------------------------------------------------------
# Computed field
# ------------------------------------------------------
@api.depends("employee_allocation_ids", "employee_allocation_ids.percentage")
@api.multi
def _compute_allocation(self):
for invoice in self:
if invoice.employee_allocation_ids:
invoice.is_allocated = True
if sum(invoice.employee_allocation_ids.mapped("percentage")) != 100:
invoice.is_allocation_error = True
else:
invoice.is_allocation_error = False
else:
invoice.is_allocated = False
invoice.is_allocation_error = False
# Copyright 2022 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class AccountInvoiceEmployeeAssign(models.Model):
_name = "account.invoice.employee.assign"
_description = "Ventilation des factures par employé"
@api.model
def _get_partner_domain(self):
partner_ids = self.env.ref("base.main_partner")
partner_ids += self.env["hr.employee"].search(
[]).mapped("user_id").mapped("partner_id")
return [("id", "in", partner_ids.ids)]
invoice_id = fields.Many2one(
comodel_name="account.invoice",
string="Facture",
required=True
)
partner_id = fields.Many2one(
comodel_name="res.partner",
string="Employé",
domain=_get_partner_domain,
required=True
)
percentage = fields.Float("Pourcentage", default=0.0, required=True)
# ------------------------------------------------------
# Constrains
# ------------------------------------------------------
@api.constrains("percentage")
def _check_percentage(self):
for record in self:
if record.percentage < 0 or record.percentage > 100:
raise UserError(_(
"Le pourcentage doit être entre 0 et 100"
))
# © 2020 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import account_invoice_employee_report
# © 2022 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import tools
from odoo import models, fields, api
class AccountInvoiceEmployeeReport(models.Model):
_name = "account.invoice.employee.report"
_description = "Vue facturation par employé"
_auto = False
# invoice fields
date_invoice = fields.Date("Date", readonly=True)
invoice_id = fields.Many2one(
comodel_name="account.invoice",
string="Facture",
readonly=True,
)
amount_untaxed_signed = fields.Monetary("Montant H.T", readonly=True)
state = fields.Selection(
[
("open", "Ouverte"),
("in_payment", "En paiement"),
("paid", "Payée"),
],
string="Statut",
readonly=True,
)
user_id = fields.Many2one(
comodel_name="res.users",
string="Vendeur",
readonly=True,
)
currency_id = fields.Many2one("res.currency", string='Currency', readonly=True)
# employee fields
partner_id = fields.Many2one(
comodel_name="res.partner",
string="Employé",
readonly=True,
)
percentage = fields.Float("Pourcentage", readonly=True)
revenue = fields.Monetary("Affectation CA", readonly=True)
_depends = {
"account.invoice": [
"state", "user_id", "amount_untaxed_signed", "date_invoice",
],
"account.invoice.employee.assign": [
"partner_id", "percentage",
],
}
# ------------------------------------------------------
# Main Query
# ------------------------------------------------------
def _query(self):
query = """
SELECT
e.id,
i.id as "invoice_id",
i.date_invoice,
i.amount_untaxed_signed,
i.state,
i.user_id,
i.currency_id,
e.partner_id,
e.percentage,
i.amount_untaxed_signed * e.percentage / 100 as "revenue"
FROM
account_invoice_employee_assign e
LEFT JOIN
account_invoice i on i.id = e.invoice_id
WHERE
i.date_invoice is not null
and i.state in ('open', 'in_payment', 'paid')
and i.type in ('out_invoice', 'out_refund')
"""
return query
@api.model_cr
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (
%s
)""" % (
self._table, self._query()))
# ------------------------------------------------------
# Computed fields
# ------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- SEARCH VIEW -->
<record model="ir.ui.view" id="account_invoice_employee_report_search">
<field name="name">account.invoice.employee.report.search</field>
<field name="model">account.invoice.employee.report</field>
<field name="arch" type="xml">
<search string="Facturation par employé">
<field name="partner_id"/>
<field name="invoice_id"/>
<field name="user_id"/>
<group expand="0" string="Group By">
<filter name="group_by_date" string="Date de facturation" context="{'group_by':'date_invoice'}"/>
<filter name="group_by_employee" string="Employé" context="{'group_by':'partner_id'}"/>
<filter name="group_by_state" string="Statut" context="{'group_by':'state'}"/>
</group>
</search>
</field>
</record>
<!-- TREE VIEW -->
<record model="ir.ui.view" id="account_invoice_employee_report_tree">
<field name="name">account.invoice.employee.report.tree</field>
<field name="model">account.invoice.employee.report</field>
<field name="arch" type="xml">
<tree string="Facturation par employé">
<field name="currency_id" invisible="1" />
<field name="date_invoice"/>
<field name="partner_id"/>
<field name="percentage"/>
<field name="revenue" widget="monetary" />
<field name="user_id"/>
<field name="invoice_id"/>
<field name="amount_untaxed_signed"/>
<field name="state"/>
</tree>
</field>
</record>
<!-- PIVOT VIEW -->
<record model="ir.ui.view" id="account_invoice_employee_report_pivot">
<field name="name">account.invoice.employee.report.pivot</field>
<field name="model">account.invoice.employee.report</field>
<field name="arch" type="xml">
<pivot string="Facturation par employé">
<field name="currency_id" invisible="1" />
<field name="partner_id" type="row"/>
<field name="date_invoice" type="col"/>
<field name="revenue" type="measure"/>
</pivot>
</field>
</record>
<!-- GRAPH VIEW -->
<record model="ir.ui.view" id="account_invoice_employee_report_graph">
<field name="name">account.invoice.employee.report.graph</field>
<field name="model">account.invoice.employee.report</field>
<field name="arch" type="xml">
<graph string="Facturation par employé">
<field name="partner_id" />
<field name="revenue" type="measure"/>
</graph>
</field>
</record>
<!-- ACTION -->
<record id="account_invoice_employee_report_action" model="ir.actions.act_window">
<field name="name">Rapports Legicoop</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.invoice.employee.report</field>
<field name="view_mode">pivot,graph,tree</field>
</record>
<!-- Menu -->
<menuitem
id="account_invoice_employee_report_menu"
name="CA par employé"
parent="account.account_reports_management_menu"
action="legicoop_account.account_invoice_employee_report_action"
sequence="50"
/>
</data>
</odoo>
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_invoice_employee_assign,access_account_invoice_employee_assign,model_account_invoice_employee_assign,account.group_account_invoice,1,1,1,1
access_account_invoice_employee_report,access_account_invoice_employee_report,model_account_invoice_employee_report,account.group_account_invoice,1,1,1,1
\ No newline at end of file
......@@ -8,6 +8,7 @@
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form" />
<field name="arch" type="xml">
<!-- Détail de la facture -->
<xpath expr="//field[@name='payment_term_id']" position="after">
<field name="with_detail" />
</xpath>
......@@ -17,9 +18,32 @@
>
<attribute name="attrs">{}</attribute>
</xpath>
<!-- Ventilation de la facture -->
<xpath expr="//notebook" position="inside">
<page name="employee_assign" string="Répartition par employé">
<field name="is_allocation_error" invisible="1" />
<div
class="alert alert-danger"
role="alert"
attrs="{'invisible': [('is_allocation_error', '!=', True)]}"
>
La répartition pour cette facture n'est pas égale à 100%.
</div>
<field name="employee_allocation_ids">
<tree editable="top" create="1" edit="1" delete="1">
<field
name="partner_id"
options="{'no_create': 1, 'no_edit': 1}"
/>
<field name="percentage" />
</tree>
</field>
</page>
</xpath>
</field>
</record>
<!-- Tree view -->
<record id="legicoop_invoice_tree" model="ir.ui.view">
<field name="name">legicoop.account.invoice.tree</field>
<field name="model">account.invoice</field>
......@@ -44,5 +68,27 @@
</field>
</record>
<!-- Search view -->
<record id="legicoop_invoice_search" model="ir.ui.view">
<field name="name">legicoop.account.invoice.search</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.view_account_invoice_filter" />
<field name="arch" type="xml">
<xpath expr="//filter[@name='late']" position="after">
<separator />
<filter
string="Factures à répartir"
name="assign_ok"
domain="[('is_allocated', '=', False)]"
/>
<filter
string="Répartition en erreur"
name="assign_error"
domain="[('is_allocation_error', '=', True)]"
/>
</xpath>
</field>
</record>
</data>
</odoo>
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter