beginnings of new module fsm_visit_confirmation, fix to bemad_partner_email_domain and incrementing_sequence_mixin
This commit is contained in:
parent
5b696e8eab
commit
c1a2129359
10 changed files with 144 additions and 3 deletions
|
|
@ -57,8 +57,11 @@ class Partner(models.Model):
|
||||||
FROM res_partner
|
FROM res_partner
|
||||||
WHERE email_domain IS NOT NULL
|
WHERE email_domain IS NOT NULL
|
||||||
AND email_domain = RIGHT(%s, LENGTH(email_domain))
|
AND email_domain = RIGHT(%s, LENGTH(email_domain))
|
||||||
|
AND company_id = %s
|
||||||
"""
|
"""
|
||||||
self.env.cr.execute(SQL(sql, email_domain))
|
self.env.cr.execute(
|
||||||
|
SQL(sql, email_domain, self.env.company and self.env.company.id or None)
|
||||||
|
)
|
||||||
res = self.env.cr.fetchall()
|
res = self.env.cr.fetchall()
|
||||||
if len(res) > 1:
|
if len(res) > 1:
|
||||||
rec._send_selection_email(
|
rec._send_selection_email(
|
||||||
|
|
|
||||||
2
fsm_visit_confirmation/__init__.py
Normal file
2
fsm_visit_confirmation/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
from . import controllers
|
||||||
|
from . import models
|
||||||
33
fsm_visit_confirmation/__manifest__.py
Normal file
33
fsm_visit_confirmation/__manifest__.py
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#
|
||||||
|
# Bemade Inc.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2023-June Bemade Inc. (<https://www.bemade.org>).
|
||||||
|
# Author: Marc Durepos (Contact : marc@bemade.org)
|
||||||
|
#
|
||||||
|
# This program is under the terms of the GNU Lesser General Public License,
|
||||||
|
# version 3.
|
||||||
|
#
|
||||||
|
# For full license details, see https://www.gnu.org/licenses/lgpl-3.0.en.html.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
{
|
||||||
|
"name": "FSM Visit Confirmation",
|
||||||
|
"version": "17.0.0.1.0",
|
||||||
|
"summary": "Have clients confirm tentatively booked visits",
|
||||||
|
"category": "Services/Field Service",
|
||||||
|
"author": "Bemade Inc.",
|
||||||
|
"website": "http://www.bemade.org",
|
||||||
|
"license": "LGPL-3",
|
||||||
|
"depends": ["industry_fsm"],
|
||||||
|
"data": ["data/mail_templates.xml"],
|
||||||
|
"assets": {},
|
||||||
|
"installable": True,
|
||||||
|
"auto_install": False,
|
||||||
|
}
|
||||||
1
fsm_visit_confirmation/controllers/__init__.py
Normal file
1
fsm_visit_confirmation/controllers/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
from . import portal
|
||||||
35
fsm_visit_confirmation/controllers/portal.py
Normal file
35
fsm_visit_confirmation/controllers/portal.py
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
from odoo.addons.portal.controllers.portal import CustomerPortal
|
||||||
|
from odoo.http import request, route
|
||||||
|
from odoo.exceptions import AccessError, MissingError
|
||||||
|
|
||||||
|
|
||||||
|
class FsmCustomerPortal(CustomerPortal):
|
||||||
|
@route(
|
||||||
|
"/my/tasks/approve_booking/<int:task_id>",
|
||||||
|
type="http",
|
||||||
|
auth="public",
|
||||||
|
website=True,
|
||||||
|
)
|
||||||
|
def portal_approve_booking(self, task_id, access_token=None):
|
||||||
|
try:
|
||||||
|
visit_sudo = self._document_check_access(
|
||||||
|
"project.task", task_id, access_token=access_token
|
||||||
|
)
|
||||||
|
except (AccessError, MissingError):
|
||||||
|
return request.redirect("/my")
|
||||||
|
|
||||||
|
visit_sudo.action_approve_booking()
|
||||||
|
request.session["visit_confirmation_accepted"] = True
|
||||||
|
request.redirect(f"/my/tasks/{task_id}")
|
||||||
|
|
||||||
|
def _task_get_page_view_values(self, task, access_token, **kwargs):
|
||||||
|
vals = super()._task_get_page_view_values(task, access_token, **kwargs)
|
||||||
|
if request.session.pop("visit_confirmation_accepted", False):
|
||||||
|
vals.update(visit_confirmation_accepted=True)
|
||||||
|
return vals
|
||||||
|
|
||||||
|
def _prepare_home_portal_values(self, counters):
|
||||||
|
vals = super()._prepare_home_portal_values(counters)
|
||||||
|
if request.session.pop("visit_confirmation_accepted", False):
|
||||||
|
vals.update(visit_confirmation_accepted=True)
|
||||||
|
return vals
|
||||||
47
fsm_visit_confirmation/data/mail_templates.xml
Normal file
47
fsm_visit_confirmation/data/mail_templates.xml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<record id="request_fsm_task_date_confirmation" model="mail.template">
|
||||||
|
<field name="name">Field Service Visit Confirmation Request</field>
|
||||||
|
<field name="model_id" ref="project.model_project_task"/>
|
||||||
|
<field name="subject">Please confirm the date for your upcoming Durpro service visit</field>
|
||||||
|
<field name="email_from">{{ object.company_id.email_formatted }}</field>
|
||||||
|
<field name="body_html">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td scope="row">Summary</td>
|
||||||
|
<td>{{ object.name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td scope="row">Technician Arrival</td>
|
||||||
|
<td>{{ object.planned_date_begin }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td scope="row">Intervention address</td>
|
||||||
|
<td>
|
||||||
|
<span t-esc="object.partner_id.street"/><br/>
|
||||||
|
<span t-if="object.partner_id.street2" t-esc="object.partner_id.street2"/><br/>
|
||||||
|
<span t-esc="object.partner_id.city"/><br/>
|
||||||
|
<span t-esc="object.partner_id.state"/><br/>
|
||||||
|
<span t-esc="object.partner_id.zip"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td scope="row">
|
||||||
|
Assigned Technician(s):
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<t t-foreach="object.user_ids" t-as="technician">
|
||||||
|
<t t-esc="technician.name"/><br/>
|
||||||
|
</t>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>To confirm this visit, <a href="{{ user.company_id.website }}/my/tasks/approve_booking/?task_id={{ object.id }}&access_token={{ object.access_token}}">click here</a>.</p>
|
||||||
|
<p>If you would like to propose another time for this visit, please reply to this email.</p>
|
||||||
|
<p>Best regards,</p>
|
||||||
|
<p>The {{ object.company_id.name }} service management team.</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
1
fsm_visit_confirmation/models/__init__.py
Normal file
1
fsm_visit_confirmation/models/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
from . import project_task
|
||||||
9
fsm_visit_confirmation/models/project_task.py
Normal file
9
fsm_visit_confirmation/models/project_task.py
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
from odoo import models, fields, api
|
||||||
|
|
||||||
|
|
||||||
|
class Task(models.Model):
|
||||||
|
_inherit = "project.task"
|
||||||
|
|
||||||
|
def action_approve_booking(self):
|
||||||
|
self.ensure_one()
|
||||||
|
self.state = "03_approved"
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<template id="portal_my_task" inherit_id="project.portal_my_task">
|
||||||
|
<xpath expr="//div[@id='task_content']" position="before">
|
||||||
|
<div t-if="visit_confirmation_accepted" class="alert alert-success" role="alert">
|
||||||
|
<strong>Success!</strong> We've received your confirmation. Thank you!
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -21,7 +21,7 @@ class IncrementingSequenceMixin(models.AbstractModel):
|
||||||
res = super().create(vals_list)
|
res = super().create(vals_list)
|
||||||
for rec in res:
|
for rec in res:
|
||||||
if rec.sequence == 0:
|
if rec.sequence == 0:
|
||||||
group_field = rec._sequence_group
|
group_field = getattr(rec, "_sequence_group")
|
||||||
group_field_data = getattr(rec, group_field)
|
group_field_data = getattr(rec, group_field)
|
||||||
if hasattr(group_field_data, "id"):
|
if hasattr(group_field_data, "id"):
|
||||||
group_field_data = group_field_data.id
|
group_field_data = group_field_data.id
|
||||||
|
|
@ -35,7 +35,7 @@ class IncrementingSequenceMixin(models.AbstractModel):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _default_sequence(self):
|
def _default_sequence(self):
|
||||||
group_field = self._sequence_group
|
group_field = getattr(self, "_sequence_group")
|
||||||
group_field_data = getattr(self, group_field)
|
group_field_data = getattr(self, group_field)
|
||||||
if hasattr(group_field_data, "id"):
|
if hasattr(group_field_data, "id"):
|
||||||
group_field_data = group_field_data.id
|
group_field_data = group_field_data.id
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue