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

[cgscop #129] refonte module timesheet : mise en place workflow validation

parent d9bb3dfa
Branches
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import models from . import models
from . import wizard
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
"security/security_rules.xml", "security/security_rules.xml",
"views/assets.xml", "views/assets.xml",
"views/cgscop_timesheet_code.xml", "views/cgscop_timesheet_code.xml",
"views/cgscop_timesheet_sheet.xml",
"views/hr_timesheet.xml", "views/hr_timesheet.xml",
"views/hr_timesheet_cgscop.xml", "views/hr_timesheet_cgscop.xml",
"views/res_partner.xml", "views/res_partner.xml",
"views/ur_financial_system.xml", "views/ur_financial_system.xml",
"wizard/print_timesheet.xml", "report/report_hr_timesheet.xml",
"wizard/report_hr_timesheet.xml",
"datas/cgscop_timesheet_code_data.xml", "datas/cgscop_timesheet_code_data.xml",
] ]
} }
Ce diff est replié.
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import cgscop_timesheet_code from . import cgscop_timesheet_code
from . import cgscop_timesheet_sheet
from . import hr_timesheet from . import hr_timesheet
from . import project from . import project
from . import ur_financial_system from . import ur_financial_system
......
# © 2020 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, api
from odoo.exceptions import UserError, ValidationError
class ScopHrTimesheetSheet(models.Model):
_name = "cgscop.timesheet.sheet"
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Timesheet Report"
_order = "create_date desc, validation_date desc, id desc"
def _default_ur(self):
return self.env['res.company']._ur_default_get()
name = fields.Char('Nom', required=True)
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',
index=True,
track_visibility='onchange',
copy=False,
default='draft',
required=True)
employee_id = fields.Many2one(
comodel_name='hr.employee',
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)
company_id = fields.Many2one(
comodel_name='res.company',
string='Company',
readonly=True,
states={'draft': [('readonly', False)]},
default=lambda self: self.env.user.company_id)
validation_date = fields.Date("Date de validation")
submit_date = fields.Date("Soumis le")
ur_id = fields.Many2one(
'union.regionale',
string='Union Régionale',
index=True,
on_delete='restrict',
default=_default_ur)
can_edit = fields.Boolean('Can Reset', compute='_compute_can_reset')
# ------------------------------------------------------
# Compute Functions
# ------------------------------------------------------
@api.depends(
'timesheet_line_ids',
'timesheet_line_ids.unit_amount')
def _compute_hour(self):
for sheet in self:
sheet.total_hour = sum(
sheet.timesheet_line_ids.mapped('unit_amount'))
@api.multi
def _compute_can_reset(self):
is_timesheet_user = self.user_has_groups(
'hr_timesheet.group_timesheet_manager')
for sheet in self:
if sheet.state == 'draft' or is_timesheet_user:
sheet.can_edit = True
else:
sheet.can_edit = False
# ------------------------------------------------------
# Constain Functions
# ------------------------------------------------------
@api.constrains('timesheet_line_ids', 'employee_id')
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):
raise ValidationError(
'Vous ne pouvez pas ajouter les lignes'
' de temps de plusieurs employés.')
# ------------------------------------------------------
# Override ORM
# ------------------------------------------------------
@api.multi
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')
super(ScopHrTimesheetSheet, self).unlink()
# ------------------------------------------------------
# Action button
# ------------------------------------------------------
@api.multi
def action_submit_timesheet(self):
self.write({
'state': 'submit',
'submit_date': fields.Date.today()})
@api.multi
def approve_timesheet_sheets(self):
self.write({
'state': 'valid',
'validation_date': fields.Date.today()})
@api.multi
def reset_timesheet_sheets(self):
self.write({
'state': 'draft',
'submit_date': False,
'validation_date': False})
@api.multi
def print_timesheet(self):
return self.env.ref(
'cgscop_timesheet.cgscop_timesheet_sheet_report').report_action(self)
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api from odoo import models, fields, api
from odoo.exceptions import UserError, ValidationError
class ScopHrTimesheet(models.Model): class ScopHrTimesheet(models.Model):
...@@ -24,6 +25,32 @@ class ScopHrTimesheet(models.Model): ...@@ -24,6 +25,32 @@ class ScopHrTimesheet(models.Model):
index=True, index=True,
on_delete='restrict', on_delete='restrict',
default=_default_ur) default=_default_ur)
sheet_id = fields.Many2one(
comodel_name='cgscop.timesheet.sheet',
string="Feuille de temps",
readonly=True,
copy=False)
state = fields.Selection([
('draft', 'Brouillon'),
('submit', 'Soumis'),
('valid', 'Validé')],
compute='_compute_state',
string='Statut',
copy=False,
index=True,
readonly=True,
store=True,)
# ------------------------------------------------------
# Compute Functions
# ------------------------------------------------------
@api.depends('sheet_id', 'sheet_id.state')
def _compute_state(self):
for timesheet in self:
if not timesheet.sheet_id or timesheet.sheet_id.state == 'draft':
timesheet.state = "draft"
else:
timesheet.state = timesheet.sheet_id.state
# ------------------------------------------------------ # ------------------------------------------------------
# OnChange Functions # OnChange Functions
...@@ -31,3 +58,29 @@ class ScopHrTimesheet(models.Model): ...@@ -31,3 +58,29 @@ class ScopHrTimesheet(models.Model):
@api.onchange('project_id') @api.onchange('project_id')
def onchange_project_id(self): def onchange_project_id(self):
self.partner_id = self.project_id.partner_id self.partner_id = self.project_id.partner_id
# ------------------------------------------------------
# Actions
# ------------------------------------------------------
@api.multi
def action_submit_timesheet_lines(self):
if any(time.state != 'draft' 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:
raise UserError(
"Il ne peut y avoir plusieurs employés dans une "
"même feuille de temps.")
return {
'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 ''
}
}
...@@ -3,24 +3,30 @@ ...@@ -3,24 +3,30 @@
<data> <data>
<template id="report_timesheet_document"> <template id="report_timesheet_document">
<t t-call="web.external_layout"> <t t-call="web.external_layout">
<t t-set="o" t-value="o.with_context(lang=lang)" />
<div class="page"> <div class="page">
<h2> <h2>
Feuille de Temps Feuille de Temps <t t-if="o.state == 'draft'"> - Brouillon</t>
</h2> </h2>
<h3>
<t t-esc="o.name"/>
</h3>
<div id="informations" class="row mt32 mb32"> <div id="informations" class="row mt32 mb32">
<div class="col-auto mw-100 mb-2" name="employee"> <div class="col-auto mw-100 mb-2" name="employee">
<strong>Employé</strong> <strong>Employé</strong>
<p class="m-0" t-field="o.user_id.name"/> <p class="m-0" t-field="o.employee_id.name"/>
</div> </div>
<div class="col-auto mw-100 mb-2" > <div class="col-auto mw-100 mb-2" >
<strong>Date de début</strong> <strong>Soumis le</strong>
<p class="m-0" t-field="o.date_start"/> <p class="m-0" t-field="o.submit_date"/>
</div> </div>
<div class="col-auto mw-100 mb-2" name="date_end"> <div class="col-auto mw-100 mb-2" name="date_end">
<strong>Date de fin</strong> <strong>Validé le</strong>
<p class="m-0" t-field="o.date_end"/> <p class="m-0" t-field="o.validation_date"/>
</div>
<div class="col-auto mw-100 mb-2" name="date_end">
<strong>Total</strong>
<p class="m-0" t-field="o.total_hour" t-options="{'widget': 'duration', 'digital': True, 'unit': 'hour', 'round': 'minute'}"/>
</div> </div>
</div> </div>
...@@ -35,7 +41,7 @@ ...@@ -35,7 +41,7 @@
</tr> </tr>
</thead> </thead>
<tbody class="invoice_tbody"> <tbody class="invoice_tbody">
<t t-foreach="o.timesheet_ids" t-as="line"> <t t-foreach="o.timesheet_line_ids" t-as="line">
<tr> <tr>
<td><span t-field="line.date"/></td> <td><span t-field="line.date"/></td>
<td><span t-field="line.project_id"/></td> <td><span t-field="line.project_id"/></td>
...@@ -49,31 +55,31 @@ ...@@ -49,31 +55,31 @@
<td /> <td />
<td /> <td />
<td class="text-right"><strong>Total</strong></td> <td class="text-right"><strong>Total</strong></td>
<td class="text-right"><strong t-esc="sum(o.timesheet_ids.mapped('unit_amount'))" t-options="{'widget': 'duration', 'digital': True, 'unit': 'hour', 'round': 'minute'}"/></td> <td class="text-right"><strong t-esc="o.total_hour" t-options="{'widget': 'duration', 'digital': True, 'unit': 'hour', 'round': 'minute'}"/></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div t-if="o.state == 'draft'">Cette feuille de temps a été éditée en brouillon.</div>
</div> </div>
</t> </t>
</template> </template>
<template id="report_timesheet"> <template id="report_timesheet_sheet">
<t t-call="web.html_container"> <t t-call="web.html_container">
<t t-foreach="docs" t-as="o"> <t t-foreach="docs" t-as="o">
<t t-set="lang" t-value="o.user_id.lang"/> <t t-call="cgscop_timesheet.report_timesheet_document"/>
<t t-call="cgscop_timesheet.report_timesheet_document" t-lang="lang"/>
</t> </t>
</t> </t>
</template> </template>
<!-- QWeb Reports --> <!-- QWeb Reports -->
<report <report
id="cgscop_timesheet_report" id="cgscop_timesheet_sheet_report"
model="cgscop.timesheet.print" model="cgscop.timesheet.sheet"
string="Feuilles de Temps" string="Feuille de Temps"
report_type="qweb-pdf" report_type="qweb-pdf"
name="cgscop_timesheet.report_timesheet" name="cgscop_timesheet.report_timesheet_sheet"
file="cgscop_timesheet.report_timesheet" file="cgscop_timesheet.report_timesheet_sheet"
menu="False" menu="False"
/> />
......
...@@ -8,3 +8,5 @@ access_project_project_ur_manager,access_project_project_ur,model_project_projec ...@@ -8,3 +8,5 @@ access_project_project_ur_manager,access_project_project_ur,model_project_projec
access_project_project_cg_manager,access_project_project_cg,model_project_project,cgscop_partner.group_cg_administrator,1,1,1,1 access_project_project_cg_manager,access_project_project_cg,model_project_project,cgscop_partner.group_cg_administrator,1,1,1,1
access_account_analytic_account_ur_manager,access_account_analytic_account_ur,analytic.model_account_analytic_account,cgscop_partner.group_ur_list_modif,1,1,1,1 access_account_analytic_account_ur_manager,access_account_analytic_account_ur,analytic.model_account_analytic_account,cgscop_partner.group_ur_list_modif,1,1,1,1
access_account_analytic_account_cg_manager,access_account_analytic_account_cg,analytic.model_account_analytic_account,cgscop_partner.group_cg_administrator,1,1,1,1 access_account_analytic_account_cg_manager,access_account_analytic_account_cg,analytic.model_account_analytic_account,cgscop_partner.group_cg_administrator,1,1,1,1
access_cgscop_timesheet_sheet_user,access_cgscop_timesheet_sheet_user,model_cgscop_timesheet_sheet,hr_timesheet.group_hr_timesheet_user,1,1,1,1
access_cgscop_timesheet_sheet_manager,access_cgscop_timesheet_sheet_user,model_cgscop_timesheet_sheet,hr_timesheet.group_timesheet_manager,1,1,1,1
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--
Vues
-->
<!-- Tree view -->
<record id="view_cgscop_timesheet_sheet_tree" model="ir.ui.view">
<field name="name">cgscop.timesheet.sheet.tree</field>
<field name="model">cgscop.timesheet.sheet</field>
<field name="arch" type="xml">
<tree string="Timesheet Reports" decoration-warning="state=='draft'">
<field name="name" />
<field name="employee_id"/>
<field name="create_date"/>
<field name="validation_date" />
<field name="total_hour" sum="Total"/>
<field name="state"/>
</tree>
</field>
</record>
<!-- Form view -->
<record id="view_cgscop_timesheet_sheet_form" model="ir.ui.view">
<field name="name">cgscop.timesheet.sheet.form</field>
<field name="model">cgscop.timesheet.sheet</field>
<field eval="25" name="priority"/>
<field name="arch" type="xml">
<form>
<header>
<button name="action_submit_timesheet" states="draft" string="Soumettre" type="object" class="oe_highlight"/>
<button name="approve_timesheet_sheets" states="submit" string="Valider" type="object" groups="hr_timesheet.group_timesheet_manager" class="oe_highlight"/>
<button name="print_timesheet" string="Imprimer" type="objet" />
<button name="reset_timesheet_sheets" string="Remettre en brouillon" type="object" attrs="{'invisible': [('state', '=', 'draft')]}" groups="hr_timesheet.group_timesheet_manager"/>
<field name="state" widget="statusbar" statusbar_visible="draft,submit,valid"/>
</header>
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="employee_id" groups="hr_timesheet.group_timesheet_manager"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group>
<field name="create_date" readonly="1"/>
<field name="submit_date" readonly="1"/>
<field name="validation_date" readonly="1"/>
<field name="total_hour" widget="float_time"/>
</group>
</group>
<field name="can_edit" invisible="1"/>
<field name="timesheet_line_ids" widget="many2many" domain="[('sheet_id', '=', False), ('employee_id', '=', employee_id)]" options="{'reload_on_button': True}" attrs="{'readonly': [('can_edit','=', False)]}" context="{'form_view_ref' : 'hr_timesheet.timesheet_view_form_user'}">
<tree editable="top">
<field name="date"/>
<field name="employee_id" readonly="1"/>
<field name="state" invisible="1"/>
<field name="sheet_id" invisible="1"/>
<field name="project_id"/>
<field name="partner_id" />
<field name="name"/>
<field name="unit_amount" widget="float_time" />
<field name="ur_financial_system_id"/>
</tree>
</field>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Search view -->
<record id="view_cgscop_timesheet_sheet_filter" model="ir.ui.view">
<field name="name">cgscop.timesheet.sheet.filter</field>
<field name="model">cgscop.timesheet.sheet</field>
<field name="arch" type="xml">
<search string="Feuille de temps">
<field name="name"/>
<field name="state"/>
<separator />
<field name="employee_id"/>
<filter string="Mes feuilles de temps" name="my_reports" domain="[('employee_id.user_id', '=', uid)]"/>
<filter string="Mon équipe" name="my_team_reports" domain="[('employee_id.parent_id.user_id', '=', uid)]" groups="hr_timesheet.group_timesheet_manager" help="Expenses of Your Team Member"/>
<separator />
<filter domain="[('state', '=', 'draft')]" string="Brouillon" name="draft" />
<filter domain="[('state', '=', 'submit')]" string="Soumis" name="submitted"/>
<filter domain="[('state', '=', 'valid')]" string="Validé" name="valid"/>
<group expand="0" string="Group By">
<filter string="Employé" name="employee" domain="[]" context="{'group_by': 'employee_id'}"/>
<filter string="Statut" domain="[]" context="{'group_by': 'state'}" name="state"/>
</group>
</search>
</field>
</record>
<!--
Actions
-->
<record id="action_cgscop_timesheet_sheet_my_all" model="ir.actions.act_window">
<field name="name">Mes feuilles de temps</field>
<field name="res_model">cgscop.timesheet.sheet</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_cgscop_timesheet_sheet_filter"/>
<field name="domain">[('employee_id.user_id', '=', uid)]</field>
<field name="context">{'search_default_my_reports': 1}</field>
</record>
<record id="action_cgscop_timesheet_sheet_to_approve" model="ir.actions.act_window">
<field name="name">Feuilles de temps à valider</field>
<field name="res_model">cgscop.timesheet.sheet</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_cgscop_timesheet_sheet_filter"/>
<field name="domain">[]</field>
<field name="context">{'search_default_submitted': 1}</field>
</record>
<record id="action_cgscop_timesheet_sheet_all" model="ir.actions.act_window">
<field name="name">Toutes les feuilles de temps</field>
<field name="res_model">cgscop.timesheet.sheet</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_cgscop_timesheet_sheet_filter"/>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>
<!--
Menus
-->
<menuitem id="timesheet_sheet_menu"
parent="hr_timesheet.timesheet_menu_root"
name="Feuilles de temps"
sequence="25"/>
<menuitem id="menu_hr_timesheet_my_timesheet"
name="Mes feuilles de temps"
sequence="1"
action="cgscop_timesheet.action_cgscop_timesheet_sheet_my_all"
parent="cgscop_timesheet.timesheet_sheet_menu"/>
<menuitem id="menu_hr_timesheet_to_approve"
name="À valider"
sequence="1"
action="cgscop_timesheet.action_cgscop_timesheet_sheet_to_approve"
parent="cgscop_timesheet.timesheet_sheet_menu"
groups="hr_timesheet.group_timesheet_manager"/>
<menuitem id="menu_hr_timesheet_all"
name="Toutes les feuilles de temps"
sequence="1"
action="cgscop_timesheet.action_cgscop_timesheet_sheet_all"
parent="cgscop_timesheet.timesheet_sheet_menu"
groups="hr_timesheet.group_timesheet_manager"/>
</odoo>
...@@ -5,12 +5,20 @@ ...@@ -5,12 +5,20 @@
<odoo> <odoo>
<data noupdate="0"> <data noupdate="0">
<!--
Vues
-->
<record id="cgscop_hr_timesheet_line_search" model="ir.ui.view"> <record id="cgscop_hr_timesheet_line_search" model="ir.ui.view">
<field name="name">cgscop.hr.timesheet.line.search</field> <field name="name">cgscop.hr.timesheet.line.search</field>
<field name="model">account.analytic.line</field> <field name="model">account.analytic.line</field>
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_search"/> <field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_search"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="task_id" position="replace"/> <field name="task_id" position="replace"/>
<xpath expr="//filter[@name='mine']" position="after">
<separator></separator>
<filter domain="[('sheet_id', '=', False)]" string="A soumettre" name="no_report"/>
<filter domain="[('sheet_id', '!=', False)]" string="Soumis" name="submitted"/>
</xpath>
<xpath expr="//filter[@name='groupby_task']" position="replace"> <xpath expr="//filter[@name='groupby_task']" position="replace">
<filter string="Contact" name="groupby_partner" domain="[]" context="{'group_by':'partner_id'}"/> <filter string="Contact" name="groupby_partner" domain="[]" context="{'group_by':'partner_id'}"/>
</xpath> </xpath>
...@@ -38,6 +46,9 @@ ...@@ -38,6 +46,9 @@
<field name="task_id" position="attributes"> <field name="task_id" position="attributes">
<attribute name="invisible">True</attribute> <attribute name="invisible">True</attribute>
</field> </field>
<field name="amount" position="attributes">
<attribute name="invisible">True</attribute>
</field>
</field> </field>
</record> </record>
...@@ -53,7 +64,7 @@ ...@@ -53,7 +64,7 @@
<attribute name="string">Code activité UR</attribute> <attribute name="string">Code activité UR</attribute>
</field> </field>
<field name="project_id" position="after" > <field name="project_id" position="after" >
<field name="partner_id" domain="[('is_company', '=', True)]" required="True" class="td-ellipsis" options="{'no_open': True, 'no_create': True}" string="Contact"/> <field name="partner_id" domain="[('is_company', '=', True)]" required="True" class="td-ellipsis" options="{'no_open': True, 'no_create': True}" context="{'search_default_my_ur': True,}" string="Contact"/>
<field name="name" class="td-minwidth" /> <field name="name" class="td-minwidth" />
</field> </field>
<field name="task_id" position="attributes"> <field name="task_id" position="attributes">
...@@ -64,6 +75,7 @@ ...@@ -64,6 +75,7 @@
</field> </field>
<field name="unit_amount" position="after"> <field name="unit_amount" position="after">
<field name="ur_financial_system_id" options="{'no_open': True, 'no_create': True}"/> <field name="ur_financial_system_id" options="{'no_open': True, 'no_create': True}"/>
<field name="state" />
</field> </field>
</field> </field>
</record> </record>
...@@ -82,26 +94,19 @@ ...@@ -82,26 +94,19 @@
</field> </field>
</record> </record>
<!--
Actions
-->
<!-- Hérite l'action de la fenetre --> <!-- Hérite l'action de la fenetre -->
<record id="hr_timesheet.menu_hr_time_tracking" model="ir.actions.act_window">
<field name="name">Lignes de temps</field>
</record>
<record id="hr_timesheet.act_hr_timesheet_line" model="ir.actions.act_window"> <record id="hr_timesheet.act_hr_timesheet_line" model="ir.actions.act_window">
<field name="name">Mes lignes de temps</field> <field name="name">Mes lignes de temps</field>
<field name="view_mode">tree,form,pivot,graph</field> <field name="view_mode">tree,form,pivot,graph</field>
</record> <field name="context">{'search_default_no_report': 1}</field>
<record id="hr_timesheet.timesheet_action_all" model="ir.actions.act_window">
<field name="name">Toutes les lignes de temps</field>
</record>
<!-- ajoute des droits sur le menu Configuration -->
<record model="ir.ui.menu" id="hr_timesheet.hr_timesheet_menu_configuration">
<field name="groups_id" eval="[(6,0, [ref('hr_timesheet.group_timesheet_manager'), ref('cgscop_partner.group_cg_administrator'), ref('cgscop_partner.group_ur_list_modif')])]"/>
</record>
<!-- ajoute des droits pour gestionnaire uniquement sur le menu Toutes les feuilles de temps -->
<record model="ir.ui.menu" id="hr_timesheet.timesheet_menu_activity_all">
<field name="groups_id" eval="[(6,0, [ref('hr_timesheet.group_timesheet_manager'), ref('cgscop_partner.group_cg_administrator')])]"/>
</record>
<record model="ir.ui.menu" id="hr_timesheet.timesheet_menu_report_timesheet_by_project">
<field name="name">Par code activité UR</field>
</record> </record>
<!-- Report View per Contact --> <!-- Report View per Contact -->
...@@ -117,11 +122,39 @@ ...@@ -117,11 +122,39 @@
(0, 0, {'view_mode': 'form', 'sequence': 15, 'view_id': ref('cgscop_timesheet.view_cgscop_hr_timesheet_line_form')})]"/> (0, 0, {'view_mode': 'form', 'sequence': 15, 'view_id': ref('cgscop_timesheet.view_cgscop_hr_timesheet_line_form')})]"/>
</record> </record>
<record id="hr_timesheet_submit_action_server" model="ir.actions.server">
<field name="name">Insérer dans une feuille de temps</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_account_analytic_line"/>
<field name="binding_model_id" ref="model_account_analytic_line"/>
<field name="state">code</field>
<field name="code">
if records:
action = records.action_submit_timesheet_lines()
</field>
</record>
<!--
Menus
-->
<!-- ajoute des droits sur le menu Configuration -->
<record model="ir.ui.menu" id="hr_timesheet.hr_timesheet_menu_configuration">
<field name="groups_id" eval="[(6,0, [ref('hr_timesheet.group_timesheet_manager'), ref('cgscop_partner.group_cg_administrator'), ref('cgscop_partner.group_ur_list_modif')])]"/>
</record>
<!-- ajoute des droits pour gestionnaire uniquement sur le menu Toutes les feuilles de temps -->
<record model="ir.ui.menu" id="hr_timesheet.timesheet_menu_activity_all">
<field name="groups_id" eval="[(6,0, [ref('hr_timesheet.group_timesheet_manager'), ref('cgscop_partner.group_cg_administrator')])]"/>
</record>
<menuitem id="timesheet_menu_report_timesheet_by_contact" <menuitem id="timesheet_menu_report_timesheet_by_contact"
parent="hr_timesheet.menu_timesheets_reports_timesheet" parent="hr_timesheet.menu_timesheets_reports_timesheet"
action="timesheet_action_report_by_contact" action="timesheet_action_report_by_contact"
name="Par Contact" name="Par Contact"
sequence="25"/> sequence="25"/>
</data> </data>
<data noupdate="1"> <data noupdate="1">
<delete id="hr_timesheet.timesheet_menu_report_timesheet_by_task" model="ir.ui.menu"/>/> <delete id="hr_timesheet.timesheet_menu_report_timesheet_by_task" model="ir.ui.menu"/>/>
......
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import print_timesheet
# Copyright 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
class CGscopTimesheetPrintWizard(models.TransientModel):
_name = "cgscop.timesheet.print"
_description = "Wizard Timesheet Impression"
date_start = fields.Date('Date de début', required=True)
date_end = fields.Date('Date de fin', required=True)
user_id = fields.Many2one(
comodel_name="res.users",
string="Employé",
default=lambda self: self.env.user,
required=True)
timesheet_ids = fields.Many2many(
comodel_name="account.analytic.line")
@api.multi
def print_timesheet(self):
self.timesheet_ids = self.env['account.analytic.line'].sudo().search([
['user_id', '=', self.user_id.id],
['date', '>=', self.date_start],
['date', '<=', self.date_end]])
return self.env.ref(
'cgscop_timesheet.cgscop_timesheet_report').report_action(self)
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="cgscop_timesheet_print_view_form" model="ir.ui.view">
<field name="name">cgscop.timesheet.print.form</field>
<field name="model">cgscop.timesheet.print</field>
<field name="arch" type="xml">
<form string="Impression feuille de temps">
<group>
<group>
<field name="date_start"/>
</group>
<group>
<field name="date_end"/>
</group>
</group>
<group>
<group>
<field name="user_id" />
</group>
</group>
<footer>
<button class="btn btn-sm btn-primary" name="print_timesheet" string="Imprimer" type="object"/>
<button class="btn btn-sm btn-default" special="cancel" string="Fermer"/>
</footer>
</form>
</field>
</record>
<record id="cgscop_timesheet_print_action" model="ir.actions.act_window">
<field name="name">Imprimer Feuille de Temps</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">cgscop.timesheet.print</field>
<field name="view_mode">form</field>
<field name="view_id" ref="cgscop_timesheet_print_view_form"/>
<field name="target">new</field>
</record>
<menuitem action="cgscop_timesheet_print_action" id="menu_cgscop_timesheet_print" name="Imprimer Feuille de Temps" parent="hr_timesheet.menu_hr_time_tracking" sequence="50" />
</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