Initial commit: Odoo 18.0-20251222 extra-addons
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

View File

@@ -0,0 +1,133 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association
===================================
Maintenance Timesheets Time Control
===================================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:8d8e480449f86c6e8ae181710f191c3d8df99ab861fca14ae8b56e5c4d3c5b97
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmaintenance-lightgray.png?logo=github
:target: https://github.com/OCA/maintenance/tree/18.0/maintenance_timesheet_time_control
:alt: OCA/maintenance
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/maintenance-18-0/maintenance-18-0-maintenance_timesheet_time_control
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/maintenance&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
It allows to track the exact moment when a timesheet line is started
(not only the day, but also the minute and second) and let users start
and stop timers easily.
**Table of contents**
.. contents::
:local:
Installation
============
This module is auto-installed when ``maintenance_timesheet`` and
``project_timesheet_time_control`` are installed.
This module depends on modules found in these repositories:
- `OCA/timesheet <https://github.com/OCA/timesheet>`__
- `OCA/web <https://github.com/OCA/web>`__
- `OCA/project <https://github.com/OCA/project>`__
Configuration
=============
Maintenance request must have a project defined for seeing the
start/stop buttons.
Usage
=====
In general the usage instructions from
``project_timesheet_time_control`` apply with the following additions.
Via maintenance requests:
1. Go to *Maintenance > Maintenance > Maintenance Requests*.
2. If a request has a running timesheet line, it will display a *Stop*
button.
3. Other requests that have enabled timesheets will display a *Start*
button that will open the same wizard as the timesheet lines,
duplicating task's last timesheet line.
4. You can see the same in list view.
5. Click on any existing request or create a new one.
6. You can see the same feature in the action buttons box.
Note: All the *Start/Resume/Stop* features are disabled if you don't
belong to the *Timesheets/User* group or if you are viewing a timesheet
that belongs to another user.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/maintenance/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/maintenance/issues/new?body=module:%20maintenance_timesheet_time_control%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Tecnativa
Contributors
------------
- `Tecnativa <https://www.tecnativa.com>`__:
- Víctor Martínez
- Pedro M. Baeza
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-victoralmau| image:: https://github.com/victoralmau.png?size=40px
:target: https://github.com/victoralmau
:alt: victoralmau
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-victoralmau|
This module is part of the `OCA/maintenance <https://github.com/OCA/maintenance/tree/18.0/maintenance_timesheet_time_control>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1,2 @@
from . import models
from . import wizards

View File

@@ -0,0 +1,16 @@
# Copyright 2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Maintenance Timesheets Time Control",
"summary": "Maintenance Timesheets Timesheet Time Control",
"version": "18.0.1.0.0",
"license": "AGPL-3",
"category": "Hidden",
"author": "Tecnativa,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/maintenance",
"depends": ["maintenance_timesheet", "project_timesheet_time_control"],
"data": ["views/maintenance_request_view.xml"],
"auto_install": True,
"maintainers": ["victoralmau"],
}

View File

@@ -0,0 +1,63 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * maintenance_timesheet_time_control
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-12-21 10:34+0000\n"
"PO-Revision-Date: 2023-07-06 20:08+0000\n"
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
msgid "Date"
msgstr "Fecha"
#. module: maintenance_timesheet_time_control
#: model:ir.model,name:maintenance_timesheet_time_control.model_hr_timesheet_switch
msgid "Helper to quickly switch between timesheet lines"
msgstr "Ayudante para cambiar rápidamente de línea del parte de horas"
#. module: maintenance_timesheet_time_control
#: model:ir.model.fields,help:maintenance_timesheet_time_control.field_maintenance_request__show_time_control
msgid "Indicate which time control button to show, if any."
msgstr "Indicar qué botón de control de tiempo se debe mostrar, si lo hay."
#. module: maintenance_timesheet_time_control
#: model:ir.model,name:maintenance_timesheet_time_control.model_maintenance_request
msgid "Maintenance Request"
msgstr "Petición de mantenimiento"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
msgid "Resume work"
msgstr "Resumen del trabajo"
#. module: maintenance_timesheet_time_control
#: model:ir.model.fields,field_description:maintenance_timesheet_time_control.field_maintenance_request__show_time_control
msgid "Show Time Control"
msgstr "Mostrar control de tiempo"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_kanban
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_tree
msgid "Start work"
msgstr "Iniciar trabajo"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_kanban
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_tree
msgid "Stop work"
msgstr "Detener trabajo"

View File

@@ -0,0 +1,62 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * maintenance_timesheet_time_control
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-12-31 16:06+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.6.2\n"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
msgid "Date"
msgstr "Data"
#. module: maintenance_timesheet_time_control
#: model:ir.model,name:maintenance_timesheet_time_control.model_hr_timesheet_switch
msgid "Helper to quickly switch between timesheet lines"
msgstr "Assistente per spostarsi velocemente tra righe del foglio ore"
#. module: maintenance_timesheet_time_control
#: model:ir.model.fields,help:maintenance_timesheet_time_control.field_maintenance_request__show_time_control
msgid "Indicate which time control button to show, if any."
msgstr "Indica se e quale pulsante di controllo tempo visualizzare."
#. module: maintenance_timesheet_time_control
#: model:ir.model,name:maintenance_timesheet_time_control.model_maintenance_request
msgid "Maintenance Request"
msgstr "Richiesta manutenzione"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
msgid "Resume work"
msgstr "Riprendi lavoro"
#. module: maintenance_timesheet_time_control
#: model:ir.model.fields,field_description:maintenance_timesheet_time_control.field_maintenance_request__show_time_control
msgid "Show Time Control"
msgstr "Visualizza controllo orario"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_kanban
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_tree
msgid "Start work"
msgstr "Avvia lavoro"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_kanban
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_tree
msgid "Stop work"
msgstr "Ferma lavoro"

View File

@@ -0,0 +1,59 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * maintenance_timesheet_time_control
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
msgid "Date"
msgstr ""
#. module: maintenance_timesheet_time_control
#: model:ir.model,name:maintenance_timesheet_time_control.model_hr_timesheet_switch
msgid "Helper to quickly switch between timesheet lines"
msgstr ""
#. module: maintenance_timesheet_time_control
#: model:ir.model.fields,help:maintenance_timesheet_time_control.field_maintenance_request__show_time_control
msgid "Indicate which time control button to show, if any."
msgstr ""
#. module: maintenance_timesheet_time_control
#: model:ir.model,name:maintenance_timesheet_time_control.model_maintenance_request
msgid "Maintenance Request"
msgstr ""
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
msgid "Resume work"
msgstr ""
#. module: maintenance_timesheet_time_control
#: model:ir.model.fields,field_description:maintenance_timesheet_time_control.field_maintenance_request__show_time_control
msgid "Show Time Control"
msgstr ""
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_kanban
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_tree
msgid "Start work"
msgstr ""
#. module: maintenance_timesheet_time_control
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_form
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_kanban
#: model_terms:ir.ui.view,arch_db:maintenance_timesheet_time_control.hr_equipment_request_view_tree
msgid "Stop work"
msgstr ""

View File

@@ -0,0 +1 @@
from . import maintenance_request

View File

@@ -0,0 +1,34 @@
# Copyright 2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models
class MaintenanceRequest(models.Model):
_name = "maintenance.request"
_inherit = ["maintenance.request", "hr.timesheet.time_control.mixin"]
@api.model
def _relation_with_timesheet_line(self):
return "maintenance_request_id"
@api.depends(
"project_id.allow_timesheets",
"timesheet_ids.employee_id",
"timesheet_ids.unit_amount",
)
def _compute_show_time_control(self):
result = super()._compute_show_time_control()
for item in self.filtered(lambda x: not x.project_id.allow_timesheets):
item.show_time_control = False
return result
def button_start_work(self):
result = super().button_start_work()
result["context"].update(
{
"default_project_id": self.project_id.id,
"default_task_id": self.task_id.id,
}
)
return result

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1,2 @@
Maintenance request must have a project defined for seeing the
start/stop buttons.

View File

@@ -0,0 +1,3 @@
- [Tecnativa](https://www.tecnativa.com):
- Víctor Martínez
- Pedro M. Baeza

View File

@@ -0,0 +1,3 @@
It allows to track the exact moment when a timesheet line is started
(not only the day, but also the minute and second) and let users start
and stop timers easily.

View File

@@ -0,0 +1,8 @@
This module is auto-installed when `maintenance_timesheet` and
`project_timesheet_time_control` are installed.
This module depends on modules found in these repositories:
- [OCA/timesheet](https://github.com/OCA/timesheet)
- [OCA/web](https://github.com/OCA/web)
- [OCA/project](https://github.com/OCA/project)

View File

@@ -0,0 +1,18 @@
In general the usage instructions from `project_timesheet_time_control`
apply with the following additions.
Via maintenance requests:
1. Go to *Maintenance \> Maintenance \> Maintenance Requests*.
2. If a request has a running timesheet line, it will display a *Stop*
button.
3. Other requests that have enabled timesheets will display a *Start*
button that will open the same wizard as the timesheet lines,
duplicating task's last timesheet line.
4. You can see the same in list view.
5. Click on any existing request or create a new one.
6. You can see the same feature in the action buttons box.
Note: All the *Start/Resume/Stop* features are disabled if you don't
belong to the *Timesheets/User* group or if you are viewing a timesheet
that belongs to another user.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,476 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="maintenance-timesheets-time-control">
<h1>Maintenance Timesheets Time Control</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:8d8e480449f86c6e8ae181710f191c3d8df99ab861fca14ae8b56e5c4d3c5b97
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/maintenance/tree/18.0/maintenance_timesheet_time_control"><img alt="OCA/maintenance" src="https://img.shields.io/badge/github-OCA%2Fmaintenance-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/maintenance-18-0/maintenance-18-0-maintenance_timesheet_time_control"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/maintenance&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>It allows to track the exact moment when a timesheet line is started
(not only the day, but also the minute and second) and let users start
and stop timers easily.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#installation" id="toc-entry-1">Installation</a></li>
<li><a class="reference internal" href="#configuration" id="toc-entry-2">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-3">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-8">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="installation">
<h2><a class="toc-backref" href="#toc-entry-1">Installation</a></h2>
<p>This module is auto-installed when <tt class="docutils literal">maintenance_timesheet</tt> and
<tt class="docutils literal">project_timesheet_time_control</tt> are installed.</p>
<p>This module depends on modules found in these repositories:</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/OCA/timesheet">OCA/timesheet</a></li>
<li><a class="reference external" href="https://github.com/OCA/web">OCA/web</a></li>
<li><a class="reference external" href="https://github.com/OCA/project">OCA/project</a></li>
</ul>
</div>
<div class="section" id="configuration">
<h2><a class="toc-backref" href="#toc-entry-2">Configuration</a></h2>
<p>Maintenance request must have a project defined for seeing the
start/stop buttons.</p>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#toc-entry-3">Usage</a></h2>
<p>In general the usage instructions from
<tt class="docutils literal">project_timesheet_time_control</tt> apply with the following additions.</p>
<p>Via maintenance requests:</p>
<ol class="arabic simple">
<li>Go to <em>Maintenance &gt; Maintenance &gt; Maintenance Requests</em>.</li>
<li>If a request has a running timesheet line, it will display a <em>Stop</em>
button.</li>
<li>Other requests that have enabled timesheets will display a <em>Start</em>
button that will open the same wizard as the timesheet lines,
duplicating tasks last timesheet line.</li>
<li>You can see the same in list view.</li>
<li>Click on any existing request or create a new one.</li>
<li>You can see the same feature in the action buttons box.</li>
</ol>
<p>Note: All the <em>Start/Resume/Stop</em> features are disabled if you dont
belong to the <em>Timesheets/User</em> group or if you are viewing a timesheet
that belongs to another user.</p>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h2>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/maintenance/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/maintenance/issues/new?body=module:%20maintenance_timesheet_time_control%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-5">Credits</a></h2>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-6">Authors</a></h3>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
<ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Víctor Martínez</li>
<li>Pedro M. Baeza</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/victoralmau"><img alt="victoralmau" src="https://github.com/victoralmau.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/maintenance/tree/18.0/maintenance_timesheet_time_control">OCA/maintenance</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,3 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0
from . import test_maintenance_timesheet_time_control

View File

@@ -0,0 +1,59 @@
# Copyright 2022-2024 Tecnativa - Víctor Martínez
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0
from odoo import exceptions, fields
from odoo.tests.common import users
from odoo.addons.project_timesheet_time_control.tests import (
test_project_timesheet_time_control,
)
class TestMaintenanceTimesheetTimeControl(
test_project_timesheet_time_control.TestProjectTimesheetTimeControlBase
):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.user.groups_id |= cls.env.ref("maintenance.group_equipment_manager")
cls.category = cls.env["maintenance.equipment.category"].create(
{"name": "Test category"}
)
cls.team = cls.env["maintenance.team"].create({"name": "Test team"})
cls.equipment = cls.env["maintenance.equipment"].create(
{
"name": "Test computer",
"category_id": cls.category.id,
"project_id": cls.project.id,
"maintenance_team_id": cls.team.id,
}
)
cls.request = cls.env["maintenance.request"].create(
{"name": "Test computer request", "equipment_id": cls.equipment.id}
)
cls.line.maintenance_request_id = cls.request
@users("test-user")
def test_maintenance_request_time_control_flow(self):
# Running line found, stop the timer
self.line.button_end_work()
with self.assertRaises(exceptions.UserError):
self.request.button_end_work()
# All lines stopped, start new one
self.assertEqual(self.request.show_time_control, "start")
start_action = self.request.button_start_work()
wizard = self._create_wizard(start_action, self.line)
self.assertLessEqual(wizard.date_time, fields.Datetime.now())
self.assertEqual(wizard.name, self.line.name)
self.assertEqual(wizard.project_id, self.request.project_id)
self.assertEqual(
wizard.analytic_line_id.account_id, self.request.project_id.account_id
)
self.assertEqual(wizard.analytic_line_id, self.line)
new_act = wizard.with_context(show_created_timer=True).action_switch()
new_line = self.env[new_act["res_model"]].browse(new_act["res_id"])
self.assertEqual(new_line.employee_id, self.env.user.employee_id)
self.assertEqual(new_line.project_id, self.project)
self.assertEqual(new_line.maintenance_request_id, self.request)
self.assertEqual(new_line.unit_amount, 0)
self.assertTrue(self.line.unit_amount)

View File

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="hr_equipment_request_view_form" model="ir.ui.view">
<field
name="name"
>hr.maintenance.request.form (in maintenance_timesheet_time_control)</field>
<field name="model">maintenance.request</field>
<field
name="inherit_id"
ref="maintenance_timesheet.equipment_request_view_form"
/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button
name="button_start_work"
string="Start work"
type="object"
icon="fa-play-circle text-success"
invisible="show_time_control != 'start'"
class="oe_stat_button"
groups="hr_timesheet.group_hr_timesheet_user"
/>
<button
name="button_end_work"
string="Stop work"
type="object"
icon="fa-stop-circle text-warning"
invisible="show_time_control != 'stop'"
class="oe_stat_button"
groups="hr_timesheet.group_hr_timesheet_user"
/>
</div>
</field>
</record>
<record id="equipment_request_view_form" model="ir.ui.view">
<field
name="name"
>maintenance.request.form (in maintenance_timesheet_time_control)</field>
<field name="model">maintenance.request</field>
<field
name="inherit_id"
ref="maintenance_timesheet.equipment_request_view_form"
/>
<field name="arch" type="xml">
<!-- Sub-tree view for timesheet_ids -->
<xpath
expr="//field[@name='timesheet_ids']/list//field[@name='date']"
position="attributes"
>
<attribute name="column_invisible">1</attribute>
</xpath>
<xpath
expr="//field[@name='timesheet_ids']/list//field[@name='date']"
position="after"
>
<field name="date_time" string="Date" required="1" />
</xpath>
<xpath expr="//field[@name='timesheet_ids']/list" position="inside">
<button
name="button_resume_work"
title="Resume work"
tabindex="-1"
type="object"
icon="fa-play-circle text-success"
invisible="show_time_control != 'resume'"
class="oe_stat_button"
groups="hr_timesheet.group_hr_timesheet_user"
/>
<button
name="button_end_work"
title="Stop work"
tabindex="-1"
type="object"
icon="fa-stop-circle text-warning"
invisible="show_time_control != 'stop'"
class="oe_stat_button"
groups="hr_timesheet.group_hr_timesheet_user"
/>
</xpath>
<xpath expr="//field[@name='timesheet_ids']/list" position="attributes">
<attribute name="default_order">date_time</attribute>
</xpath>
</field>
</record>
<record id="hr_equipment_request_view_kanban" model="ir.ui.view">
<field
name="name"
>maintenance.request.kanban (in maintenance_timesheet_time_control)</field>
<field name="model">maintenance.request</field>
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_kanban" />
<field name="arch" type="xml">
<xpath expr="//footer//field[@name='activity_ids']" position="after">
<a
name="button_start_work"
invisible="show_time_control != 'start'"
class="o_kanban_inline_block fa fa-lg fa-play-circle text-success"
title="Start work"
tabindex="-1"
type="object"
groups="hr_timesheet.group_hr_timesheet_user"
/>
<a
name="button_end_work"
invisible="show_time_control != 'stop'"
class="o_kanban_inline_block fa fa-lg fa-stop-circle text-warning"
title="Stop work"
tabindex="-1"
type="object"
groups="hr_timesheet.group_hr_timesheet_user"
/>
</xpath>
</field>
</record>
<record id="hr_equipment_request_view_tree" model="ir.ui.view">
<field
name="name"
>maintenance.request.tree (in maintenance_timesheet_time_control)</field>
<field name="model">maintenance.request</field>
<field
name="inherit_id"
ref="maintenance_timesheet.hr_equipment_request_view_tree"
/>
<field name="arch" type="xml">
<field name="timesheet_total_hours" position="after">
<button
name="button_start_work"
title="Start work"
tabindex="-1"
type="object"
icon="fa-play-circle text-success"
invisible="show_time_control != 'start'"
class="oe_stat_button"
groups="hr_timesheet.group_hr_timesheet_user"
/>
<button
name="button_end_work"
title="Stop work"
tabindex="-1"
type="object"
icon="fa-stop-circle text-warning"
invisible="show_time_control != 'stop'"
class="oe_stat_button"
groups="hr_timesheet.group_hr_timesheet_user"
/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1 @@
from . import hr_timesheet_switch

View File

@@ -0,0 +1,23 @@
# Copyright 2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models
class HrTimesheetSwitch(models.TransientModel):
_inherit = "hr.timesheet.switch"
@api.model
def _closest_suggestion(self):
"""Allow to search the best suggestion by maintenance.request."""
result = super()._closest_suggestion()
if not result and self.env.context["active_model"] == "maintenance.request":
return self.env["account.analytic.line"].search(
[
("user_id", "=", self.env.user.id),
("maintenance_request_id", "=", self.env.context["active_id"]),
],
order="date_time DESC",
limit=1,
)
return result