Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
661 changes: 661 additions & 0 deletions fieldservice_appointment_confirmation/LICENSE

Large diffs are not rendered by default.

226 changes: 226 additions & 0 deletions fieldservice_appointment_confirmation/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
========================================
Field Service - Appointment Confirmation
========================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:70bbf3e7fa9daee09b1fac1be2eb565505b97471d96be22258a9d58ecc9b219b
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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/licence-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%2Ffield--service-lightgray.png?logo=github
:target: https://github.com/OCA/field-service/tree/18.0/fieldservice_appointment_confirmation
:alt: OCA/field-service
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/field-service-18-0/field-service-18-0-fieldservice_appointment_confirmation
: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/field-service&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module automates the confirmation of field service appointments
with the final customer.

From a field service order the coordinator can request a confirmation
from the customer through a pre-filled, editable email (standard mail
composer). The customer confirms or reschedules the visit from a secure
tokenized link, without any login or portal user, and the order is
updated accordingly:

- the appointment status is tracked (Pending, Requested, Confirmed) with
a badge, a ribbon and calendar/list decorations; a confirmed
appointment that was rescheduled is shown as "Confirmed
(rescheduled)";
- confirming and rescheduling are logged in the chatter and notify the
order followers and the assigned worker; the customer also receives a
confirmation email;
- picking an available slot when rescheduling is treated as the
customer's acceptance, so the appointment is automatically confirmed
on the new date;
- on confirmation (or reschedule) the customer can download an RFC 5545
``.ics`` file to add the visit to Google Calendar, Outlook or Apple
Calendar;
- rescheduling only offers slots where the assigned worker is actually
available, based on their working schedule and existing orders;
- an appointment whose date has already passed can no longer be
confirmed online, only rescheduled to a future slot.

The module is designed as a generic OCA contribution and only depends on
``fieldservice``, ``mail``, ``resource`` and ``portal``.

The appointment status is shown as a coloured badge in the list view and
as a coloured event (prefixed with a check mark once confirmed) in the
calendar:

|Appointment status in the list view|

|Confirmed appointments in the calendar|

.. |Appointment status in the list view| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/05_list_statuses.png
.. |Confirmed appointments in the calendar| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/07_calendar.png

**Table of contents**

.. contents::
:local:

Configuration
=============

To configure this module you need to:

1. Go to *Field Service > Configuration > Stages* and tick **Allow
Appointment Confirmation Request** on the stages where the
confirmation button should be available.
2. Optionally adjust, under *Settings > Field Service Appointments*:

- **Reschedule Window** – how many days ahead the customer is offered
available slots when rescheduling (default 14). A larger value lets
the customer book further into the future.
- **Reschedule Slot Duration** – the granularity, in hours, of the
slots offered to the customer; for example 1 hour produces 08:00,
09:00, 10:00… while 2 hours produces 08:00, 10:00, 12:00… (default
1).

3. The request, confirmation and reschedule emails can be edited without
touching code in *Settings > Technical > Email Templates*
(``FSM Appointment: ...``).

The customer email is taken from the partner linked to the order
location, so make sure that partner has a valid email address.

For rescheduling to offer time slots, the assigned worker must have a
working schedule (*Working Hours* / ``resource.calendar``); the company
working schedule is used as a fallback.

|Enable "Allow Appointment Confirmation Request" on a stage|

|Field Service Appointments settings|

.. |Enable "Allow Appointment Confirmation Request" on a stage| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/14_stage_allow_request.png
.. |Field Service Appointments settings| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/08_settings.png

Usage
=====

The **Request Confirmation** button only appears on a field service
order that has an assigned worker, a scheduled date, a customer email,
and is in a stage where **Allow Appointment Confirmation Request** is
ticked (see *Configuration*):

1. Press **Request Confirmation**. A mail composer opens with the
pre-filled request template; edit it if needed and send it. The
appointment status becomes *Requested* and the customer receives the
email.

|Request Confirmation button on the order|

|Pre-filled mail composer|

|Confirmation request email|

2. From the email (secure link, no login) the customer can:

- **Confirm Appointment**: the status becomes *Confirmed*, a note is
logged, the followers and the assigned worker are notified and the
customer is offered an ``.ics`` download.

|Customer confirmation page|

|Confirmation success with the .ics download|

- **Reschedule**: the customer picks an available slot of the
assigned worker; the order date is updated and the appointment is
**automatically confirmed** on the new date (shown as *Confirmed
(rescheduled)*). The customer receives a confirmation email and can
download the ``.ics``.

|Reschedule page with the worker available slots|

|Confirmed (rescheduled) badge on the order|

3. If the appointment date has already passed, the confirmation link
redirects the customer to the reschedule page to pick a new future
slot. An invalid or expired token shows a friendly page instead:

|Invalid or expired link|

Confirmed appointments are highlighted on the order form with a ribbon,
and can be filtered or grouped by appointment status from the list view:

|Confirmed ribbon on the order form|

|Filters and group by appointment status|

.. |Request Confirmation button on the order| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/01_request_button.png
.. |Pre-filled mail composer| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/02_request_wizard.png
.. |Confirmation request email| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/13_email_request.png
.. |Customer confirmation page| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/09_portal_confirm.png
.. |Confirmation success with the .ics download| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/11_portal_confirmed.png
.. |Reschedule page with the worker available slots| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/10_portal_reschedule.png
.. |Confirmed (rescheduled) badge on the order| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/04_confirmed_rescheduled.png
.. |Invalid or expired link| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/12_portal_invalid.png
.. |Confirmed ribbon on the order form| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/03_confirmed_ribbon.png
.. |Filters and group by appointment status| image:: https://raw.githubusercontent.com/OCA/field-service/18.0/fieldservice_appointment_confirmation/static/img/readme/06_filters_groupby.png

Known issues / Roadmap
======================

- Worker availability relies on the worker ``resource.calendar`` (with a
company fallback). Workers without any working schedule will not
expose slots.
- Appointments are shown in the Field Service calendar only; they are
not pushed to the general Odoo calendar (``calendar.event`` /
Meetings).

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/field-service/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/field-service/issues/new?body=module:%20fieldservice_appointment_confirmation%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
-------

* Binhex

Contributors
------------

- `Binhex <https://www.binhex.cloud>`__:

- Edilio Escalona Almira e.escalona@binhex.cloud

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.

This module is part of the `OCA/field-service <https://github.com/OCA/field-service/tree/18.0/fieldservice_appointment_confirmation>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions fieldservice_appointment_confirmation/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import models
from . import wizard
from . import controllers
31 changes: 31 additions & 0 deletions fieldservice_appointment_confirmation/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2026 Binhex
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Field Service - Appointment Confirmation",
"summary": "Request, confirm and reschedule field service appointments "
"with the customer through a secure tokenized link.",
"version": "18.0.1.0.0",
"category": "Field Service",
"author": "Binhex, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/field-service",
"license": "AGPL-3",
"depends": [
"fieldservice",
"mail",
"resource",
"portal",
],
"data": [
"security/ir.model.access.csv",
"data/mail_template_data.xml",
"views/fsm_stage_views.xml",
"views/fsm_order_views.xml",
"wizard/fsm_appointment_confirmation_wizard_views.xml",
"wizard/res_config_settings_views.xml",
"templates/appointment_portal.xml",
],
"installable": True,
"development_status": "Beta",
"maintainers": [],
"application": False,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import appointment
Loading
Loading