diff --git a/__manifest__.py b/__manifest__.py index 4fe5ba1cbc07cd04c240c46a0923aabf0bf8a312..2f41aa19dacf63e782e99ed2eacc5f8ccc0c141d 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -10,9 +10,11 @@ 'hr_expense', 'l10n_fr', 'hr_timesheet', + 'cgscop_timesheet', ], "data": [ "views/hr_expense.xml", + "views/hr_timesheet.xml", "views/product.xml", ], 'qweb': [ diff --git a/models/__init__.py b/models/__init__.py index d44ebc30f53de7ef1d2fb35c5429e24b94ee46f4..680d3de5c9a505ec30e2a86ee94bf5dc803e959e 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,5 +1,7 @@ # © 2019 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import hr_employee from . import hr_expense +from . import hr_timesheet from . import product diff --git a/models/hr_expense.py b/models/hr_expense.py index 80ac7a73554a84b29e6110fc63e1cab09251fb72..8bf0938d069ad9b6a44513a49d8338ba607a98bf 100644 --- a/models/hr_expense.py +++ b/models/hr_expense.py @@ -2,7 +2,6 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import models, fields, api -from odoo.exceptions import RedirectWarning class CGScopExpense(models.Model): @@ -10,8 +9,43 @@ class CGScopExpense(models.Model): expense_gap = fields.Float( string="Plafond de dépense", - related='product_id.expense_gap') + related="product_id.expense_gap") + timesheet_id = fields.Many2one( + comodel_name="account.analytic.line", + string="Ligne de Temps", + ondelete="restrict") + analytic_account_id = fields.Many2one( + related="timesheet_id.account_id", + string="Code Activité UR", + store=True) + coop_id = fields.Many2one( + related="timesheet_id.partner_id", + string="Contact", + store=True) + ur_financial_system_id = fields.Many2one( + related="timesheet_id.ur_financial_system_id", + string='Dispositif Financier', + store=True) + expense_formula = fields.Selection( + related='product_id.expense_formula') + quantity_computed = fields.Float( + string="Quantité", + compute="_compute_values") + unit_amount_computed = fields.Float( + string="Prix", + compute="_compute_values") + # ------------------------------------------------------ + # Computed Fields + # ------------------------------------------------------ + @api.depends('quantity', 'unit_amount') + def _compute_values(self): + self.quantity_computed = self.quantity + self.unit_amount_computed = self.unit_amount + + # ------------------------------------------------------ + # Onchange Fields + # ------------------------------------------------------ @api.onchange('total_amount') def onchange_total_amount(self): for exp in self: @@ -20,5 +54,16 @@ class CGScopExpense(models.Model): return { 'warning': { 'title': "Plafond dépassé", - 'message': "Attention, le montant est supérieur au plafond autorisé"}} + 'message': "Attention, le montant est supérieur \ + au plafond autorisé"}} + @api.onchange('product_id') + def onchange_product_id(self): + if self.product_id.expense_formula == 'fixed_price': + self.unit_amount = self.product_id.standard_price + self.update({ + 'unit_amount': self.product_id.standard_price + }) + elif self.product_id.expense_formula == 'fixed_rate': + self.quantity = 1.0 + self.product_id.unit_amount = self.product_id.standard_price diff --git a/models/product.py b/models/product.py index 7d1589df8b50cea009b4bd76c048843ba0eaa39e..39fb388cc86756465c6774e262e7ecce5025349a 100644 --- a/models/product.py +++ b/models/product.py @@ -1,10 +1,37 @@ # © 2019 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import models, fields +from odoo import models, fields, api +from odoo.exceptions import ValidationError class CGScopProductTemplate(models.Model): _inherit = 'product.template' expense_gap = fields.Float("Plafond de dépense") + expense_formula = fields.Selection([ + ('free', 'Libre'), + ('fixed_rate', 'Forfait'), + ('fixed_price', 'Prix fixe')], + string="Type de calcul", + default="free", + help=""" + Défini l'option de calcul dans la note de frais : + - Libre : permet à l'utilisateur de définir le prix et la quantité + - Forfait : l'utilisateur n'a pas la possibilité de modifier le + prix ni la quantité égale à 1 par défaut + - Prix fixe : le prix est fixe, mais l'utilisateur peut modifier + la quantité (pour les km par exemple) + """) + + +class CGScopProductProduct(models.Model): + _inherit = 'product.product' + + @api.one + @api.constrains('expense_formula', 'standard_price') + def _check_expense_formula(self): + if self.expense_formula != 'free' and self.standard_price == 0.0: + raise ValidationError( + "Le coût doit être supérieur à 0 si la formule de \ + calcul n'est pas Libre") diff --git a/views/hr_expense.xml b/views/hr_expense.xml index c4bfe6ecf61da54d2caa9a56c88a1eb29b3c0c5c..7bc7bf7231a039d7d043d29e7ceaeaa510bd3244 100644 --- a/views/hr_expense.xml +++ b/views/hr_expense.xml @@ -24,18 +24,55 @@ <field name="model">hr.expense</field> <field name="inherit_id" ref="hr_expense.hr_expense_view_form"/> <field name="arch" type="xml"> + <xpath expr="//widget[@name='attach_document']" position="attributes"> + <attribute name="invisible">True</attribute> + </xpath> + <xpath expr="//widget[2]" position="attributes"> + <attribute name="invisible">True</attribute> + </xpath> + <field name="reference" position="attributes"> <attribute name="invisible">True</attribute> </field> <field name="date" position="attributes"> <attribute name="required">True</attribute> </field> + <field name="product_id" position="attributes"> + <attribute name="options">{'no_open': True}</attribute> + </field> + <field name="employee_id" position="attributes"> + <attribute name="options">{'no_open': True}</attribute> + </field> + <field name="unit_amount" position="attributes"> + <attribute name="attrs">{'invisible': [('expense_formula', '!=', 'free')]}</attribute> + </field> + <field name="unit_amount" position="after"> + <field name="unit_amount_computed" attrs="{'invisible': [('expense_formula', '=', 'free')]}" /> + <field name="quantity_computed" attrs="{'invisible': [('expense_formula', '!=', 'fixed_rate')]}" /> + </field> + <label for="quantity" position="attributes"> + <attribute name="attrs">{'invisible': [('expense_formula', '=', 'fixed_rate')]}</attribute> + </label> + <field name="quantity" position="attributes"> + <attribute name="attrs">{'invisible': [('expense_formula', '=', 'fixed_rate')]}</attribute> + </field> + <field name="tax_ids" position="before"> + <field name="expense_gap" attrs="{'invisible': [('expense_gap', '=', 0.0)]}" readonly="True" /> + <field name="expense_formula" invisible="True" /> + </field> + <field name="analytic_account_id" position="before"> + <field name="timesheet_id" options="{'no_create_edit': True, 'no_open': True}" /> + </field> <field name="analytic_account_id" position="attributes"> - <attribute name="string">Code activité CG</attribute> + <attribute name="string">Code activité UR</attribute> <attribute name="groups"></attribute> + <attribute name="readonly">True</attribute> + <attribute name="options">{'no_open': True}</attribute> + <attribute name="attrs">{'invisible': [('timesheet_id', '=', False)]}</attribute> </field> <field name="analytic_account_id" position="after"> - <field name="expense_gap" /> + <field name="coop_id" attrs="{'invisible': [('timesheet_id', '=', False)]}" readonly="True" options="{'no_open': True}" /> + <field name="ur_financial_system_id" attrs="{'invisible': [('timesheet_id', '=', False)]}" readonly="True" options="{'no_open': True}"/> </field> <label for="payment_mode" position="attributes"> <attribute name="invisible">True</attribute> diff --git a/views/product.xml b/views/product.xml index 343812fd4b0836ebdc6400a015e5aac5a0094e07..2d318ba6678e506abd223fae11765bba00e90045 100644 --- a/views/product.xml +++ b/views/product.xml @@ -4,6 +4,29 @@ <odoo> <data> + + <!-- Produit Note de Frais Form View --> + <record id="view_product_expense_cgscop_kanban_inherited" model="ir.ui.view"> + <field name="name">product.product.expense.cgscop.form</field> + <field name="model">product.product</field> + <field name="inherit_id" ref="product.product_kanban_view"/> + <field name="arch" type="xml"> + <field name="lst_price" position="after"> + <field name="standard_price"/> + <field name="can_be_expensed" /> + <field name="expense_formula" /> + </field> + <xpath expr="//templates/t/div/div/ul/li" position="replace" > + <t t-if="record.can_be_expensed"> + <li><strong>Coût : <field name="standard_price"/></strong></li> + <li><strong><field name="expense_formula"/></strong></li> + </t> + <t t-if="record.sale_ok"> + <li><strong>Prix : <field name="lst_price"/></strong></li> + </t> + </xpath> + </field> + </record> <!-- Produit Note de Frais Form View --> <record id="view_product_expense_cgscop_form_inherited" model="ir.ui.view"> @@ -11,6 +34,20 @@ <field name="model">product.product</field> <field name="inherit_id" ref="hr_expense.product_product_expense_form_view"/> <field name="arch" type="xml"> + <field name="type" position="attributes"> + <attribute name="invisible">True</attribute> + </field> + <field name="type" position="after"> + <field name="expense_formula" required="True" /> + </field> + <field name="list_price" position="attributes"> + <attribute name="invisible">True</attribute> + </field> + <field name="standard_price" position="attributes"> + <attribute name="attrs"> + {'required': [('expense_formula', '!=', 'free')]} + </attribute> + </field> <field name="uom_po_id" position="after"> <field name="expense_gap" /> </field>