Newer
Older

Benjamin - Le Filament
a validé
# © 2020 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

Benjamin - Le Filament
a validé
from odoo.exceptions import UserError, ValidationError
class ScopHrTimesheetSheet(models.Model):
_name = "cgscop.timesheet.sheet"
_inherit = ["mail.thread", "mail.activity.mixin"]

Benjamin - Le Filament
a validé
_description = "Timesheet Report"
_order = "create_date desc, validation_date desc, id desc"
def _default_ur(self):
return self.env["res.company"]._ur_default_get()

Benjamin - Le Filament
a validé
name = fields.Char("Nom", required=True)

Benjamin - Le Filament
a validé
timesheet_line_ids = fields.One2many(
comodel_name="account.analytic.line",
inverse_name="sheet_id",
string="Lignes de temps",
states={"valid": [("readonly", True)]},
copy=False,
)
state = fields.Selection(
[("draft", "Brouillon"), ("submit", "Soumis"), ("valid", "Validé")],
string="Statut",

Benjamin - Le Filament
a validé
index=True,

Benjamin - Le Filament
a validé
copy=False,
default="draft",
required=True,
)

Benjamin - Le Filament
a validé
employee_id = fields.Many2one(
comodel_name="hr.employee",

Benjamin - Le Filament
a validé
string="Employé",
required=True,
readonly=True,
states={"draft": [("readonly", False)]},
default=lambda self: self.env["hr.employee"].search(
[("user_id", "=", self.env.uid)], limit=1
),
)
total_hour = fields.Float(string="Total", compute="_compute_hour", store=True)

Benjamin - Le Filament
a validé
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",

Benjamin - Le Filament
a validé
readonly=True,
states={"draft": [("readonly", False)]},

Benjamin - Le Filament
a validé
validation_date = fields.Date("Date de validation")
submit_date = fields.Date("Soumis le")
ur_id = fields.Many2one(
"union.regionale",
string="Union Régionale",

Benjamin - Le Filament
a validé
index=True,
ondelete="restrict",
default=_default_ur,
)
can_edit = fields.Boolean("Can Reset", compute="_compute_can_reset")

Benjamin - Le Filament
a validé
# ------------------------------------------------------
# Compute Functions
# ------------------------------------------------------
@api.depends("timesheet_line_ids", "timesheet_line_ids.unit_amount")

Benjamin - Le Filament
a validé
def _compute_hour(self):
for sheet in self:
sheet.total_hour = sum(sheet.timesheet_line_ids.mapped("unit_amount"))

Benjamin - Le Filament
a validé
def _compute_can_reset(self):
is_timesheet_user = self.user_has_groups("hr_timesheet.group_timesheet_manager")

Benjamin - Le Filament
a validé
for sheet in self:
if sheet.state == "draft" or is_timesheet_user:

Benjamin - Le Filament
a validé
sheet.can_edit = True
else:
sheet.can_edit = False
# ------------------------------------------------------
# Constain Functions
# ------------------------------------------------------
@api.constrains("timesheet_line_ids", "employee_id")

Benjamin - Le Filament
a validé
def _check_employee(self):
for sheet in self:
employee_ids = sheet.timesheet_line_ids.mapped("employee_id")
if len(employee_ids) > 1 or (
len(employee_ids) == 1 and employee_ids != sheet.employee_id
):

Benjamin - Le Filament
a validé
raise ValidationError(
_(
"Vous ne pouvez pas ajouter les lignes"
" de temps de plusieurs employés."
)

Benjamin - Le Filament
a validé
# ------------------------------------------------------
# Override ORM
# ------------------------------------------------------
def unlink(self):
for timesheet in self:
if timesheet.state in ["submit", "valid"]:
raise UserError(
_(
"Vous ne pouvez pas supprimer une "
"feuille de temps soumise ou validée"
)

Benjamin - Le Filament
a validé
super(ScopHrTimesheetSheet, self).unlink()
# ------------------------------------------------------
# Action button
# ------------------------------------------------------
def action_submit_timesheet(self):
self.write({"state": "submit", "submit_date": fields.Date.today()})

Benjamin - Le Filament
a validé
def approve_timesheet_sheets(self):
self.write({"state": "valid", "validation_date": fields.Date.today()})

Benjamin - Le Filament
a validé
def reset_timesheet_sheets(self):
self.write({"state": "draft", "submit_date": False, "validation_date": False})

Benjamin - Le Filament
a validé
def print_timesheet(self):
return self.env.ref(
"cgscop_timesheet.cgscop_timesheet_sheet_report"
).report_action(self)

Hervé Silvant - CGScop
a validé
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# ------------------------------------------------------
# Retourne les lignes de la Fdt avec les totaux par projet
# ------------------------------------------------------
def _to_duration(self, infloat):
return '{0:02.0f}:{1:02.0f}'.format(*divmod(infloat * 60, 60))
def _get_timesheet_line_act(self):
for sheet in self:
lines = sheet.timesheet_line_ids.sorted(key=lambda b: (b.project_id.name, b.date))
rows = []
last_project = False
tot_project = 0
for line in lines:
# On insère un total intermédiaire
if last_project != line.project_id.name and tot_project != 0:
rows.append({
'total': 1,
'name': False,
'partner': False,
'project': False,
'date': False,
'ur_financial_system': 'Total ' + last_project + ' : ' + self._to_duration(tot_project),
'unit_amount': False,
})
tot_project = 0
# On insère la ligne lue
rows.append({
'total': 0,
'name': line.name,
'partner': line.partner_id.name,
'project': line.project_id.name,
'date': line.date,
'ur_financial_system': line.ur_financial_system_id.name,
'unit_amount': self._to_duration(line.unit_amount),
})
last_project = line.project_id.name
tot_project = tot_project + line.unit_amount
# On insère le dernier total
rows.append({
'total': 1,
'name': False,
'partner': False,
'project': False,
'date': False,
'ur_financial_system': 'Total ' + last_project + ' : ' + self._to_duration(tot_project),
'unit_amount': False,
})
return rows