Skip to content

Commit fd9872b

Browse files
committed
[ADD] fieldservice_check_worker_availability: New module fieldservice_check_worker_availability
1 parent 0a34e17 commit fd9872b

File tree

15 files changed

+868
-0
lines changed

15 files changed

+868
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
=======================================
2+
Field Service Check Worker Availability
3+
=======================================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:5b3558f4fb22769ee6a5155b5b9e72226b4cb6a4d7a176939fd4d8b32399dc74
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Ffield--service-lightgray.png?logo=github
20+
:target: https://github.com/OCA/field-service/tree/17.0/fieldservice_check_worker_availability
21+
:alt: OCA/field-service
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/field-service-17-0/field-service-17-0-fieldservice_check_worker_availability
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/field-service&target_branch=17.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This module raises an error when attempting to create a new FSM Order if
32+
the selected start date falls within a worker's non-working or leave
33+
period.
34+
35+
It also removes the group restriction on the Time Off smart button so it
36+
becomes visible without enabling debug mode.
37+
38+
**Table of contents**
39+
40+
.. contents::
41+
:local:
42+
43+
Configuration
44+
=============
45+
46+
To configure this module, you need to:
47+
48+
- Create a FSM Person
49+
- Configure its Working Schedule: Go to Field Service -> Master Data ->
50+
Workers -> Select the worker and stablish the field
51+
- To configure a worker's leave, go to the Working Schedule form and
52+
click the Time Off smart button.
53+
- Now create a new record for this resource
54+
- Create a new FSM Order and assign it to the configured worker
55+
- Select a Scheduled Start
56+
- If the scheduled start falls within a worker's leave or non-working
57+
period, an error will be raised.
58+
59+
Bug Tracker
60+
===========
61+
62+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/field-service/issues>`_.
63+
In case of trouble, please check there if your issue has already been reported.
64+
If you spotted it first, help us to smash it by providing a detailed and welcomed
65+
`feedback <https://github.com/OCA/field-service/issues/new?body=module:%20fieldservice_check_worker_availability%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
66+
67+
Do not contact contributors directly about support or help with technical issues.
68+
69+
Credits
70+
=======
71+
72+
Authors
73+
-------
74+
75+
* APSL - Nagarro
76+
77+
Maintainers
78+
-----------
79+
80+
This module is maintained by the OCA.
81+
82+
.. image:: https://odoo-community.org/logo.png
83+
:alt: Odoo Community Association
84+
:target: https://odoo-community.org
85+
86+
OCA, or the Odoo Community Association, is a nonprofit organization whose
87+
mission is to support the collaborative development of Odoo features and
88+
promote its widespread use.
89+
90+
.. |maintainer-mpascuall| image:: https://github.com/mpascuall.png?size=40px
91+
:target: https://github.com/mpascuall
92+
:alt: mpascuall
93+
94+
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
95+
96+
|maintainer-mpascuall|
97+
98+
This module is part of the `OCA/field-service <https://github.com/OCA/field-service/tree/17.0/fieldservice_check_worker_availability>`_ project on GitHub.
99+
100+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "Field Service Check Worker Availability",
3+
"summary": "Check worker availability when creating field service orders",
4+
"version": "17.0.1.0.0",
5+
"category": "Field Service",
6+
"author": "APSL - Nagarro, Odoo Community Association (OCA)",
7+
"website": "https://github.com/OCA/field-service",
8+
"depends": ["fieldservice", "hr"],
9+
"data": [
10+
"views/resource_calendar.xml",
11+
],
12+
"license": "AGPL-3",
13+
"maintainers": ["mpascuall"],
14+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Translation of Odoo Server.
2+
# This file contains the translation of the following modules:
3+
# * fieldservice_check_worker_availability
4+
#
5+
msgid ""
6+
msgstr ""
7+
"Project-Id-Version: Odoo Server 17.0\n"
8+
"Report-Msgid-Bugs-To: \n"
9+
"POT-Creation-Date: 2025-04-22 09:42+0000\n"
10+
"PO-Revision-Date: 2025-04-22 09:42+0000\n"
11+
"Last-Translator: \n"
12+
"Language-Team: \n"
13+
"MIME-Version: 1.0\n"
14+
"Content-Type: text/plain; charset=UTF-8\n"
15+
"Content-Transfer-Encoding: \n"
16+
"Plural-Forms: \n"
17+
18+
#. module: fieldservice_check_worker_availability
19+
#. odoo-python
20+
#: code:addons/fieldservice_check_worker_availability/models/fsm_order.py:0
21+
#, python-format
22+
msgid ""
23+
"%(name)s has a registered leave on this date %(date)s.\n"
24+
"Reason: %(reason)s"
25+
msgstr "%(name)s té una vacança registrada aquesta data %(date)s.\n"
26+
"Motiu: %(reason)s"
27+
28+
#. module: fieldservice_check_worker_availability
29+
#. odoo-python
30+
#: code:addons/fieldservice_check_worker_availability/models/fsm_order.py:0
31+
#, python-format
32+
msgid ""
33+
"%(name)s is not scheduled to work at the selected date and time: %(date)s."
34+
msgstr "%(name)s no fa feina aquest dia i hora %(date)s."
35+
36+
#. module: fieldservice_check_worker_availability
37+
#: model_terms:ir.ui.view,arch_db:fieldservice_check_worker_availability.view_resource_calendar_check_worker_availability
38+
msgid "<span class=\"o_stat_text\">Time Off</span>"
39+
msgstr ""
40+
41+
#. module: fieldservice_check_worker_availability
42+
#: model:ir.model,name:fieldservice_check_worker_availability.model_fsm_order
43+
msgid "Field Service Order"
44+
msgstr ""
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Translation of Odoo Server.
2+
# This file contains the translation of the following modules:
3+
# * fieldservice_check_worker_availability
4+
#
5+
msgid ""
6+
msgstr ""
7+
"Project-Id-Version: Odoo Server 17.0\n"
8+
"Report-Msgid-Bugs-To: \n"
9+
"POT-Creation-Date: 2025-04-22 09:46+0000\n"
10+
"PO-Revision-Date: 2025-04-22 09:46+0000\n"
11+
"Last-Translator: \n"
12+
"Language-Team: \n"
13+
"MIME-Version: 1.0\n"
14+
"Content-Type: text/plain; charset=UTF-8\n"
15+
"Content-Transfer-Encoding: \n"
16+
"Plural-Forms: \n"
17+
18+
#. module: fieldservice_check_worker_availability
19+
#. odoo-python
20+
#: code:addons/fieldservice_check_worker_availability/models/fsm_order.py:0
21+
#, python-format
22+
msgid ""
23+
"%(name)s has a registered leave on this date %(date)s.\n"
24+
"Reason: %(reason)s"
25+
msgstr "%(name)s tiene una vacación registrada esta fecha %(date)s.\n"
26+
"Motivo: %(reason)s"
27+
28+
#. module: fieldservice_check_worker_availability
29+
#. odoo-python
30+
#: code:addons/fieldservice_check_worker_availability/models/fsm_order.py:0
31+
#, python-format
32+
msgid ""
33+
"%(name)s is not scheduled to work at the selected date and time: %(date)s."
34+
msgstr "%(name)s no trabaja este día y hora %(date)s."
35+
36+
#. module: fieldservice_check_worker_availability
37+
#: model_terms:ir.ui.view,arch_db:fieldservice_check_worker_availability.view_resource_calendar_check_worker_availability
38+
msgid "<span class=\"o_stat_text\">Time Off</span>"
39+
msgstr ""
40+
41+
#. module: fieldservice_check_worker_availability
42+
#: model:ir.model,name:fieldservice_check_worker_availability.model_fsm_order
43+
msgid "Field Service Order"
44+
msgstr "Pedido de Servicio de Campo"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import fsm_order
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import pytz
2+
3+
from odoo import _, api, fields, models
4+
from odoo.exceptions import ValidationError
5+
6+
7+
class FSMOrder(models.Model):
8+
_inherit = "fsm.order"
9+
10+
def _check_worker_availability(self, scheduled_date, scheduled_date_end, person_id):
11+
person = self.env["fsm.person"].browse(person_id)
12+
calendar = person.calendar_id
13+
user_timezone = pytz.timezone(self.env.user.tz or "UTC")
14+
scheduled_date_dt = fields.Datetime.from_string(scheduled_date)
15+
scheduled_date_dt = pytz.utc.localize(scheduled_date_dt)
16+
scheduled_date_dt_utc = scheduled_date_dt.astimezone(user_timezone)
17+
scheduled_date_end_dt = fields.Datetime.from_string(scheduled_date_end)
18+
19+
employee = self.env["hr.employee"].search(
20+
[("work_contact_id", "=", person.partner_id.id)], limit=1
21+
)
22+
if employee and employee.resource_id:
23+
overlapping_leave = self.env["resource.calendar.leaves"].search(
24+
[
25+
("resource_id", "=", employee.resource_id.id),
26+
("date_from", "<=", scheduled_date_end_dt),
27+
("date_to", ">=", scheduled_date_dt),
28+
]
29+
)
30+
31+
if overlapping_leave:
32+
raise ValidationError(
33+
_(
34+
"%(name)s has a registered leave on "
35+
"this date %(date)s.\nReason: %(reason)s"
36+
)
37+
% {
38+
"name": person.name,
39+
"date": scheduled_date_dt_utc.strftime("%Y-%m-%d %H:%M"),
40+
"reason": overlapping_leave.name,
41+
}
42+
)
43+
44+
if calendar:
45+
weekday = scheduled_date_dt_utc.strftime("%A")
46+
float_hour = (
47+
scheduled_date_dt_utc.hour + scheduled_date_dt_utc.minute / 60.0
48+
)
49+
50+
matched = False
51+
for att in calendar.attendance_ids:
52+
day_label = dict(att._fields["dayofweek"].selection).get(att.dayofweek)
53+
if (
54+
day_label == weekday
55+
and att.hour_from <= float_hour < att.hour_to
56+
and att.day_period != "lunch"
57+
):
58+
matched = True
59+
break
60+
61+
if not matched:
62+
raise ValidationError(
63+
_(
64+
"%(name)s is not scheduled to work at "
65+
"the selected date and time: %(date)s."
66+
)
67+
% {
68+
"name": person.name,
69+
"date": scheduled_date_dt_utc.strftime("%Y-%m-%d %H:%M"),
70+
}
71+
)
72+
73+
@api.constrains("scheduled_date_start", "scheduled_date_end", "person_id")
74+
def check_worker_availability(self):
75+
for order in self:
76+
if order.scheduled_date_start and order.person_id:
77+
self._check_worker_availability(
78+
order.scheduled_date_start,
79+
order.scheduled_date_end,
80+
order.person_id.id,
81+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["whool"]
3+
build-backend = "whool.buildapi"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* `APSL-Nagarro <https://apsl.tech>`_:
2+
* Miquel Pascual <[email protected]>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
To configure this module, you need to:
2+
3+
- Create a FSM Person
4+
- Configure its Working Schedule: Go to Field Service -> Master Data -> Workers -> Select the worker and stablish the field
5+
- To configure a worker's leave, go to the Working Schedule form and click the Time Off smart button.
6+
- Now create a new record for this resource
7+
- Create a new FSM Order and assign it to the configured worker
8+
- Select a Scheduled Start
9+
- If the scheduled start falls within a worker's leave or non-working period, an error will be raised.

0 commit comments

Comments
 (0)