Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • 212467a7d890bcfab96ed986af6a14f109cc25f2
  • 12.0 par défaut protégée
  • 12-RV-Quantity-default_value
3 résultats

hr_expense.py

Blame
  • Bifurcation depuis Le Filament / Confédération Générale des SCOP / cgscop_expense
    Le projet source a une visibilité limitée.
    hr_expense.py 7,04 Kio
        # © 2019 Le Filament (<http://www.le-filament.com>)
    # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
    
    import re
    import requests
    import logging
    
    from math import ceil
    
    from odoo import models, fields, api, exceptions
    
    _logger = logging.getLogger(__name__)
    
    
    class CGScopExpense(models.Model):
        _inherit = 'hr.expense'
    
        expense_gap = fields.Float(
            string="Plafond de dépense",
            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)
        ur_regional_convention_id = fields.Many2one(
            related="timesheet_id.ur_regional_convention_id",
            string='Convention Régionale',
            store=True)
        expense_formula = fields.Selection(
            related='product_id.expense_formula')
        is_ik = fields.Boolean(
            related='product_id.is_ik')
        quantity_computed = fields.Float(
            string="Quantité",
            compute="_compute_values")
        unit_amount_computed = fields.Float(
            string="Prix",
            compute="_compute_values")
        from_address = fields.Text(
            string="Adresse de départ",
            compute='_compute_from_address',
            store=True)
        to_address = fields.Text(
            string="Adresse d'arrivée",
            compute='_compute_to_address',
            store=True)
        is_return = fields.Boolean("Aller/Retour")
    
        # ------------------------------------------------------
        # Default Fields
        # ------------------------------------------------------
        def _default_from_address(self):
            return self.env.uid
    
        # ------------------------------------------------------
        # Computed Fields
        # ------------------------------------------------------
        @api.depends('quantity', 'unit_amount')
        def _compute_values(self):
            for expense in self:
                expense.quantity_computed = expense.quantity
                expense.unit_amount_computed = expense.unit_amount
    
        @api.depends('employee_id')
        def _compute_from_address(self):
            for expense in self:
                if expense.employee_id:
                    expense.from_address = expense._format_address(
                        expense.employee_id.address_id)
    
        @api.depends('timesheet_id')
        def _compute_to_address(self):
            for expense in self:
                if expense.timesheet_id:
                    expense.to_address = expense._format_address(
                        expense.timesheet_id.partner_id)
    
        # ------------------------------------------------------
        # Onchange Fields
        # ------------------------------------------------------
        @api.onchange('total_amount')
        def onchange_total_amount(self):
            """
            Lève une alerte si le montant dépasse le plafond
            """
            for exp in self:
                if exp.product_id.expense_gap > 0:
                    if exp.total_amount > exp.product_id.expense_gap:
                        return {
                            'warning': {
                                'title': "Plafond dépassé",
                                'message': "Attention, le montant est supérieur \
                                            au plafond autorisé"}}
    
        @api.onchange('product_id')
        def onchange_product_id(self):
            """
            Change l'intégration de la NDF en fonction du type de produite
            """
            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
    
        @api.onchange('is_return')
        def onchange_is_return(self):
            """
            Définit le comportement lorsqu'on coche Aller/Retour
            """
            if ((self.product_id.expense_formula == 'fixed_price') and 
                (self.product_id.is_ik)):
                if self.is_return:
                    self.quantity = self.quantity * 2
                elif not self.is_return:
                    self.quantity = self.quantity / 2
    
        # ------------------------------------------------------
        # Button function
        # ------------------------------------------------------
        def get_ik(self):
            if not self.from_address or not self.to_address:
                raise exceptions.Warning(
                    "Les adresses de départ et d'arrivée doivent être renseignées")
            else:
                # retourne la distance entre les 2 adresses
                distance = self._get_distance(
                    self._get_coord(self.from_address),
                    self._get_coord(self.to_address))
                quantity = ceil(distance/5)*5
                if self.is_return:
                    self.quantity = quantity * 2
                else:
                    self.quantity = quantity
    
        # ------------------------------------------------------
        # Global function
        # ------------------------------------------------------
        def _format_address(self, partner):
            address = partner.street or ''
            if partner.street2:
                address += '\n' + partner.street2
            if partner.street3:
                address += '\n' + partner.street3
            if partner.zip:
                address += '\n' + partner.zip
                if partner.city:
                    address += ' ' + partner.city
            elif partner.city:
                address += '\n' + partner.city
            return address
    
        def _get_coord(self, address):
            addr = re.sub(r"\W", "+", address, flags=re.I)
            url = 'https://api-adresse.data.gouv.fr/search/?q=' + addr
            try:
                response = requests.get(url)
                coord = response.json().get('features')[0].get('geometry').get('coordinates')
                return str(coord[0]) + ',' + str(coord[1])
            except Exception as err:
                _logger.warning(
                    "Erreur de connexion. URL: %s",
                    err.__str__(),
                )
                raise exceptions.Warning(
                    "Erreur de connexion avec l'API")
                return False
    
        def _get_distance(self, coord1, coord2):
            url = ('http://router.project-osrm.org/route/v1/car/' + coord1 +
                   ';' + coord2 + '?alternatives=false&overview=false')
            try:
                response = requests.get(url)
                dist = response.json().get('routes')[0].get('legs')[0].get('distance')
                return dist / 1000
            except Exception as err:
                _logger.warning(
                    "Erreur de connexion. URL: %s",
                    err.__str__(),
                )
                raise exceptions.Warning(
                    "Erreur de connexion avec l'API")
                return False