Skip to content
Snippets Groups Projects
hr_timesheet.py 11 KiB
Newer Older
  • Learn to ignore specific revisions
  • Benjamin's avatar
    Benjamin committed
    # © 2019 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, ValidationError
    
    Benjamin's avatar
    Benjamin committed
    
    
    class ScopHrTimesheet(models.Model):
        _inherit = "account.analytic.line"
    
    
        def _default_ur(self):
    
            return self.env["res.company"]._ur_default_get()
    
        # Inherited fields
    
    Benjamin's avatar
    Benjamin committed
        name = fields.Char(required=False)
    
        partner_id = fields.Many2one(required=True)
    
        # New fields
    
    Benjamin's avatar
    Benjamin committed
        cgscop_timesheet_code_id = fields.Many2one(
    
            related="project_id.cgscop_timesheet_code_id",
            string="Code Activité National",
            store=True,
        )
    
    Benjamin's avatar
    Benjamin committed
        ur_financial_system_id = fields.Many2one(
    
            comodel_name="ur.financial.system", string="Dispositif Financier"
        )
    
            comodel_name="ur.regional.convention", string="Convention Régionale"
        )
    
        ur_id = fields.Many2one(
    
            "union.regionale",
            string="Union Régionale",
    
            ondelete="restrict",
            default=_default_ur,
        )
    
            comodel_name="cgscop.timesheet.sheet",
    
            copy=False,
        )
        state = fields.Selection(
            [
                ("to_report", "A rapporter"),
                ("draft", "Brouillon"),
                ("submit", "Soumis"),
                ("valid", "Validé"),
            ],
            compute="_compute_state",
            string="Statut",
    
            string="Nb Dispositifs Financiers", compute="_compute_ur_system_nb"
        )
    
            string="Nb conventions régionales", compute="_compute_ur_system_nb"
        )
    
        is_present = fields.Boolean("Présentiel")
    
        location = fields.Selection(
            [
                ("R", "Rendez-vous"),
                ("D", "Déplacement"),
                ("B", "Bureau"),
            ],
            string="Lieu",
        )
    
        justificatifs = fields.Char(string="Justificatifs", required=False)
    
        is_overtime = fields.Boolean(
            string="Heures supplémentaires",
            default=False,
        )
        is_overtime_allowed = fields.Boolean(
            string="Heures supplémentaires autorisées",
            compute="_compute_overtime_allowed",
        )
    
        travel_time = fields.Float(
            string="Temps déplacement",
        )
        is_travel_time_allowed = fields.Boolean(
            string="Temps de déplacement autorisé",
            compute="_compute_travel_time_allowed",
        )
    
        calendar_l1 = fields.Char(
    
            string="Ligne 1 calendrier",
            compute="_compute_calendar_l1",
        )
    
        calendar_l2 = fields.Char(
    
            string="Ligne 2 calendrier",
            compute="_compute_calendar_l2",
        )
    
        # ------------------------------------------------------
        # Compute Functions
        # ------------------------------------------------------
    
        @api.depends("ur_id")
        def _compute_overtime_allowed(self):
            for rec in self:
                rec.is_overtime_allowed = self.env.company.overtime_working
    
    
        @api.depends("ur_id")
        def _compute_travel_time_allowed(self):
            for rec in self:
                rec.is_travel_time_allowed = self.env.company.use_travel_time
    
    
                financial_system = timesheet.env["ur.financial.system"].search(
                    [("ur_id", "=", timesheet.ur_id.id)]
                )
                timesheet.ur_financial_system_nb = len(financial_system)
    
                regional_convention = timesheet.env["ur.regional.convention"].search(
                    [("ur_id", "=", timesheet.ur_id.id)]
                )
    
                timesheet.ur_regional_convention_nb = len(regional_convention)
    
        @api.depends("sheet_id", "sheet_id.state")
    
        def _compute_state(self):
            for timesheet in self:
    
                if not timesheet.sheet_id:
                    timesheet.state = "to_report"
    
                else:
                    timesheet.state = timesheet.sheet_id.state
    
    Benjamin's avatar
    Benjamin committed
    
    
        @api.depends("project_id", "partner_id")
    
        def _compute_calendar_l1(self):
            for ts in self:
                ts.calendar_l1 = ""
                if ts.project_id:
    
                    ts.calendar_l1 += ts.project_id.name + ", "
    
                if ts.partner_id:
                    ts.calendar_l1 += ts.partner_id.name
    
    
        @api.depends("unit_amount")
    
        def _compute_calendar_l2(self):
            for ts in self:
                ts.calendar_l2 = "Durée : " + str(ts.unit_amount) + " heure(s)"
    
        # ------------------------------------------------------
        # Override le _rec_name
        # ------------------------------------------------------
    
        @api.depends("project_id", "partner_id")
    
        def name_get(self):
            result = []
            for ts in self:
                name = ts.calendar_l1
                result.append((ts.id, name))
            return result
    
    
    Benjamin's avatar
    Benjamin committed
        # ------------------------------------------------------
        # OnChange Functions
        # ------------------------------------------------------
    
        @api.onchange("project_id")
    
    Benjamin's avatar
    Benjamin committed
        def onchange_project_id(self):
            self.partner_id = self.project_id.partner_id
    
        @api.onchange("partner_id")
    
            # affiche le Dispositif Financier par défaut sur la LdT
            # si il n'y a pas de date limite du dispositif
            # ou si la date de la Ldt est inférieure à la date limite du dispositif
    
            if (
                not self.partner_id.ur_financial_system_date
                or self.date <= self.partner_id.ur_financial_system_date
            ):
    
                self.ur_financial_system_id = self.partner_id.ur_financial_system_id
    
            # affiche la Convention par défaut sur la LdT
            # si il n'y a pas de date limite de la convention
            # ou si la date de la LdT est inférieure à la date limite de la convention
    
            if (
                not self.partner_id.ur_regional_convention_date
                or self.date <= self.partner_id.ur_regional_convention_date
            ):
                self.ur_regional_convention_id = self.partner_id.ur_regional_convention_id
    
        # ------------------------------------------------------
        # Contrains
        # ------------------------------------------------------
    
        @api.constrains("unit_amount", "date")
    
                if record.project_id:
                    lines = self.search(
                        [
                            ("date", "=", record.date),
                            ("employee_id", "=", record.employee_id.id),
                        ]
    
                    total = sum(lines.mapped("unit_amount"))
                    if (
                        not self.env.company.day_working
                        and total > self.env.company.day_duration
                    ):
                        raise ValidationError(
                            _(
                                "Vous ne pouvez imputer plus de %sh sur la même journée.\n"
                                "Journée du %s"
                            )
                            % (
                                self.env.company.day_duration,
                                record.date.strftime("%d/%m/%Y"),
                            )
                        )
    
            for line in self:
                dt = datetime.combine(line.date, time(12, 00))
    
                holiday = self.env["resource.calendar.leaves"].search(
                    [
                        "|",
                        ("company_id", "=", False),
    
                        ("company_id", "=", self.env.company.id),
    
                        ("date_from", "<=", dt),
                        ("date_to", ">=", dt),
    
                if not line.holiday_id and (line.date.weekday() in (5, 6) or holiday):
    
                        _(
                            "Vous ne pouvez imputer du temps sur un weekend "
                            "ou un jour férié."
                        )
    
        # ------------------------------------------------------
        # Override ORM
        # ------------------------------------------------------
        def unlink(self):
            for timesheet in self:
    
                if timesheet.state in ["submit", "valid"]:
                    raise UserError(
    
                        _(
                            "Vous ne pouvez pas supprimer une "
                            "ligne de temps soumise ou validée"
                        )
    
        # ------------------------------------------------------
        # Actions
        # ------------------------------------------------------
        def action_submit_timesheet_lines(self):
    
            Crée une feuille de temps avec les lignes sélectionnées
    
            if any(time.state != "to_report" or time.sheet_id for time in self):
    
                raise UserError(_("Vous ne pouvez pas insérer 2 fois la même ligne !"))
    
            if len(self.mapped("employee_id")) != 1:
    
                    _(
                        "Il ne peut y avoir plusieurs employés dans une "
                        "même feuille de temps."
                    )
    
                "name": "New Expense Report",
                "type": "ir.actions.act_window",
                "view_mode": "form",
                "res_model": "cgscop.timesheet.sheet",
                "target": "current",
                "context": {
                    "default_timesheet_line_ids": self.ids,
                    "default_employee_id": self[0].employee_id.id,
                    "default_name": self[0].name if len(self) == 1 else "",
                },
    
    
        # ------------------------------------------------------
        # Modification du context pour cacher les colonnes
        # ------------------------------------------------------
        @api.model
        def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
            custom_context = self.env.context.copy()
    
            current_ur_id = self.env.context['current_ur_id']
            nbfs = self.env["ur.financial.system"].search([("ur_id", "=", current_ur_id)])
            if len(nbfs) == 0:
                custom_context['hide_financial_system'] = True
            nbrc = self.env["ur.regional.convention"].search([("ur_id", "=", current_ur_id)])
            if len(nbrc) == 0:
                custom_context['hide_regional_convention'] = True
    
    
            overtime_allowed = self.env.company.overtime_working
            if not overtime_allowed:
                custom_context['hide_overtime'] = True
    
            travel_time_allowed = self.env.company.use_travel_time
            if not travel_time_allowed:
                custom_context['hide_travel_time'] = True
    
            res = super(ScopHrTimesheet, self.with_context(custom_context)).fields_view_get(
                view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
    
            return res