Skip to content
Commits on Source (7)
......@@ -20,7 +20,7 @@
##############################################################################
{
'name': 'Project Timesheets',
'version': '10.0.3',
'version': '10.0.4',
'category': 'Human Resources',
'sequence': 80,
'summary': 'Timesheets, Activities',
......@@ -38,6 +38,7 @@
"report/report_timesheet_templates.xml",
'data/hr_timesheet_project_sheet_data.xml',
'data/hr_timesheet_action_data.xml',
'data/hr_timesheet_employee_tag.xml',
'views/hr_analytic_timesheet.xml',
'views/hr_timesheet_project_sheet_templates.xml',
'views/hr_timesheet_project_sheet_views.xml',
......
......@@ -8,49 +8,21 @@
<record id="email_template_timesheet" model="mail.template">
<field name="name">Timesheet - Send by Email</field>
<field name="email_from">${(object.user_id.email and '%s &lt;%s&gt;' % (object.user_id.name, object.user_id.email) or '')|safe}</field>
<field name="subject">${object.company_id.name} Timesheet (Ref ${object.number or 'n/a'})</field>
<field name="partner_to">${object.partner_id.id}</field>
<field name="subject">Timesheet (Ref ${object.number or 'n/a'})</field>
<field name="partner_to">${object.project_id.partner_id.id}</field>
<field name="model_id" ref="hr_timesheet_project_sheet.model_hr_timesheet_project_sheet_sheet"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="timesheet_project_report_sheet"/>
<field name="report_name">Timesheet_${(object.number or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="lang">${object.project_id.partner_id.lang}</field>
<field name="body_html"><![CDATA[
<p>Dear ${object.partner_id.name}
% set access_action = object.get_access_action()
% set access_url = access_action['type'] == 'ir.actions.act_url' and access_action['url'] or '/report/pdf/account.report_invoice/' + str(object.id)
% set is_online = access_action and access_action['type'] == 'ir.actions.act_url'
% if object.partner_id.parent_id:
(<i>${object.partner_id.parent_id.name}</i>)
% endif
,</p>
<p>Here is your invoice <strong>${object.number}</strong>
% if object.origin:
(with reference: ${object.origin} )
% endif
amounting in <strong>${object.amount_total} ${object.currency_id.name}</strong>
from ${object.company_id.name}.
</p>
% if is_online:
<br/><br/>
<center>
<a href="${access_url}" style="background-color: #1abc9c; padding: 20px; text-decoration: none; color: #fff; border-radius: 5px; font-size: 16px;" class="o_default_snippet_text">View Invoice</a>
</center>
% endif
<br/><br/>
% if object.state=='paid':
<p>This invoice is already paid.</p>
% else:
<p>Please remit payment at your earliest convenience.</p>
% endif
<p>Thank you,</p>
<p>Dear ${object.project_id.partner_id.name},
</p><p>Here is your timesheet.</p>
<p>Thank you,
%if object.user_id and object.user_id.signature:
${object.user_id.signature | safe}
%endif
</p>
]]></field>
</record>
......
<?xml version="1.0" ?>
<odoo>
<data>
<record id="employee_category_employee" model="hr.employee.category">
<field name="name">Employee</field>
<field name="color" eval="6" />
</record>
</data>
</odoo>
......@@ -123,16 +123,14 @@ class HrTimesheetSheet(models.Model):
message loaded by default.
"""
self.ensure_one()
template = self.env.ref('account.email_template_edi_invoice', False)
template = self.env.ref('hr_timesheet_project_sheet.email_template_timesheet', False)
compose_form = self.env.ref('mail.email_compose_message_wizard_form', False)
ctx = dict(
default_model='account.invoice',
default_model='hr_timesheet_project_sheet.sheet',
default_res_id=self.id,
default_use_template=bool(template),
default_template_id=template and template.id or False,
default_composition_mode='comment',
mark_invoice_as_sent=True,
custom_layout="account.mail_template_data_notification_email_account_invoice"
)
return {
'name': _('Compose Email'),
......
<odoo>
<record id="paperformat_us_timehseet" model="report.paperformat">
<field name="name">Timesheet US Letter</field>
<field name="default" eval="False" />
<field name="format">Letter</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Portrait</field>
<field name="margin_top">70</field>
<field name="margin_bottom">25</field>
<field name="margin_left">7</field>
<field name="margin_right">7</field>
<field name="header_line" eval="False" />
<field name="header_spacing">65</field>
<field name="dpi">90</field>
</record>
<template id="report_project_timesheet">
<t t-call="report.html_container">
<t t-call="report.external_layout">
<t t-foreach="docs" t-as="o">
<t t-set="show_draft" t-value="o.state in ['new', 'draft']" />
<!-- Multicompany -->
<t t-if="o and 'company_id' in o">
<t t-set="company" t-value="o.company_id"></t>
</t>
<t t-if="not o or not 'company_id' in o">
<t t-set="company" t-value="res_company"></t>
<t t-set="company" t-value="res_company" />
<t t-if="'company_id' in o and o.company_id">
<t t-set="company" t-value="o.company_id" />
</t>
<div class="page">
<div class="oe_structure"/>
<div class="header">
<img t-if="company.logo" t-att-src="'data:image/png;base64,%s' % company.logo" style="max-height: 45px;" />
<t t-foreach="docs" t-as="o">
<t t-set="show_draft" t-value="o.state in ['new', 'draft']"/>
<h2>
<span t-field="o.project_id.name"/>
</h2>
<h3 t-if="o.name">
<span t-field="o.name"/>
</h3>
<div>
<strong>Producer:</strong> <span t-field="o.project_id.name" class="h2"/>
</div>
<div t-if="o.name">
<strong>Event name:</strong> <span t-field="o.name" class="h3"/>
</div>
<div class="row mt32 mb32">
<div class="col-xs-4" t-if="o.date_from">
<div class="row mt16">
<div class="col-xs-3" t-if="o.date_from">
<strong>Timesheet Period</strong>
<p>
<span t-field="o.date_from" t-field-options="{&quot;format&quot;: &quot;d MMM y&quot;}"/> to
<span t-field="o.date_from" t-field-options="{&quot;format&quot;: &quot;d MMM y&quot;}" />
to
<span t-field="o.date_to" t-field-options="{&quot;format&quot;: &quot;d MMM y&quot;}" />
</p>
</div>
......@@ -35,15 +50,22 @@
<strong>Location</strong>
<p t-field="o.location" />
</div>
<div class="col-xs-2" t-if="o.user_id">
<strong>Responsible <t t-esc='company.name' /></strong>
<div class="col-xs-3" t-if="o.user_id">
<strong>
Responsible
<t t-esc="company.name" />
</strong>
<p>
<span t-field="o.user_id.name" />
<span t-if="o.user_id.phone">
<br/><i class="fa fa-phone" aria-hidden="true"/> <span t-field="o.user_id.phone"/>
<br />
<i class="fa fa-phone" aria-hidden="true" />
<span t-field="o.user_id.phone" />
</span>
<span t-if="o.user_id.mobile">
<br/><i class="fa fa-mobile" aria-hidden="true"/> <span t-field="o.user_id.mobile"/>
<br />
<i class="fa fa-mobile" aria-hidden="true" />
<span t-field="o.user_id.mobile" />
</span>
</p>
</div>
......@@ -52,29 +74,37 @@
<p>
<span t-field="o.contact_id.name" />
<span t-if="o.contact_id.phone">
<br/><i class="fa fa-phone" aria-hidden="true"/> <span t-field="o.contact_id.phone"/>
<br />
<i class="fa fa-phone" aria-hidden="true" />
<span t-field="o.contact_id.phone" />
</span>
<span t-if="o.contact_id.mobile">
<br/><i class="fa fa-mobile" aria-hidden="true"/> <span t-field="o.contact_id.mobile"/>
<br />
<i class="fa fa-mobile" aria-hidden="true" />
<span t-field="o.contact_id.mobile" />
</span>
</p>
</div>
</div>
</div>
<div class="page">
<div class="row">
<div class="col-md-12">
<table class="table table-condensed">
<table class="table table-bordered">
<thead>
<tr>
<th>Date</th>
<th>Employee</th>
<th>Technician</th>
<th>Position</th>
<th>Comments</th>
<th class="text-right">Begin</th>
<th class="text-right">End</th>
<th class="text-right">Break</th>
<th class="text-right">Total</th>
<th class="text-right" t-if="show_draft">Initial</th>
<th class="text-right" t-if="show_draft">Initial
</th>
</tr>
</thead>
<tbody>
......@@ -82,12 +112,17 @@
<t t-foreach="o.timesheet_ids.sorted(key=lambda r: (r.date, r.time_start, r.time_stop))" t-as="l">
<!-- Group by timerange for display for Draft -->
<t t-if="show_draft and prev_timerange != (l.date, l.time_start, l.time_stop)">
<tr><td colspan="9"><strong>
<span t-field="l.date" t-field-options="{&quot;format&quot;: &quot;d MMM y&quot;}"/> -
<tr>
<td colspan="9">
<strong>
<span t-field="l.date" t-field-options="{&quot;format&quot;: &quot;d MMM y&quot;}" />
-
<span t-esc="'%s:%02.0f' % tuple(int(round(x)) for x in divmod(l.time_start*60,60))" />
to
<span t-esc="'%s:%02.0f' % tuple(int(round(x)) for x in divmod(l.time_stop*60,60))" />
</strong></td></tr>
</strong>
</td>
</tr>
</t>
<t t-set="prev_timerange" t-value="(l.date, l.time_start, l.time_stop)" />
<tr>
......@@ -129,8 +164,12 @@
<td />
<td />
<td />
<td class="text-right"><strong>Total</strong></td>
<td class="text-right"><strong t-esc="'%s:%02.0f' % tuple(int(round(x)) for x in divmod(sum(o.timesheet_ids.mapped('unit_amount'))*60,60))"/></td>
<td class="text-right">
<strong>Total</strong>
</td>
<td class="text-right">
<strong t-esc="'%s:%02.0f' % tuple(int(round(x)) for x in divmod(sum(o.timesheet_ids.mapped('unit_amount'))*60,60))" />
</td>
</tr>
<tr t-if="show_draft">
<td colspan="9" />
......@@ -140,44 +179,54 @@
</div>
</div>
</div>
<div class="footer">
<div class="row" t-if="o.comment">
<div class="col-md-12">
<p>
<strong>Comment:</strong>
<span t-field="o.comment" />
</p>
</div>
</div>
<div class="row" t-if="show_draft">
<div class="row mt16" t-if="show_draft">
<div class="col-xs-6">
<p></p>
<p />
<p style="border-top:thin black solid">
<strong>Signature <t t-esc='company.name' /></strong>
<strong>
Signature
<t t-esc="company.name" />
</strong>
</p>
</div>
<div class="col-xs-6">
<p></p>
<p />
<p style="border-top:thin black solid">
<strong>Signature <t t-esc='o.project_id.partner_id and o.project_id.partner_id.name' /></strong>
<strong>
Signature Customer
</strong>
</p>
</div>
</div>
</t>
<ul class="list-inline">
<li>Page:</li>
<li>
<span class="page" />
</li>
<li>/</li>
<li>
<span class="topage" />
</li>
</ul>
<div class="oe_structure"/>
</div>
</t>
</t>
</template>
<report id="timesheet_project_report_sheet"
model="hr_timesheet_project_sheet.sheet"
string="Project Timesheet"
report_type="qweb-pdf"
name="hr_timesheet_project_sheet.report_project_timesheet"
file="report_project_timesheet"
/>
<report id="timesheet_project_report_sheet" model="hr_timesheet_project_sheet.sheet" string="Project Timesheet" report_type="qweb-pdf"
name="hr_timesheet_project_sheet.report_project_timesheet" file="report_project_timesheet" paperformat="hr_timesheet_project_sheet.paperformat_us_timehseet" />
</odoo>
\ No newline at end of file
......@@ -81,7 +81,7 @@
<field name="location" />
</group>
<group>
<field name="user_id" />
<field name="user_id" domain="[('employee_ids.category_ids', 'in', %(hr_timesheet_project_sheet.employee_category_employee)d)]" />
<field name="contact_id" />
<field name="sent" invisible="1"/>
</group>
......@@ -122,8 +122,7 @@
</page>
</notebook>
<div>
<label for="comment"/>
<field name="comment" placeholder="Additional notes..."/>
<field name="comment" placeholder="Terms and conditions..." context="{'default_comment':'COUCOU'}"/>
</div>
</sheet>
<div class="oe_chatter">
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Patrik Dufresne
# Copyright 2017 Patrik Dufresne Service Logiciel inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import models
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Patrik Dufresne
# Copyright 2017 Patrik Dufresne Service Logiciel inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Prospec Timesheets',
'version': '10.0.3',
'category': 'Human Resources',
'sequence': 80,
'summary': 'Timesheets, Activities',
'description': """Custom module for Pro-Spec. Define all the customization specific to Pro-Spec customer.""",
'author': 'Patrik Dufresne',
'website': 'http://www.patrikdufresne.com',
'company': 'Patrik Dufresne Service Logiciel inc.',
'depends': [
'hr_timesheet_project_sheet',
],
'data': [
],
'installable': True,
'auto_install': False,
'qweb': ['static/src/xml/timesheet.xml', ],
'license': 'AGPL-3',
}
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Patrik Dufresne
# Copyright 2017 Patrik Dufresne Service Logiciel inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import hr_timesheet_project_sheet
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Patrik Dufresne
# Copyright 2017 Patrik Dufresne Service Logiciel inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from odoo import fields, models
class HrTimesheetSheet(models.Model):
_inherit = 'hr_timesheet_project_sheet.sheet'
comment = fields.Text(default="À plus de 10 minutes de retard, arrondir l’heure d’arrivée à la demi-heure")