Commit acb8bf59 by Arturo Jasso Origel

se han corregido cambios y se ha agregado apartado de permisos

parent 17db1b50
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
'data/maintenance_type.xml', 'data/maintenance_type.xml',
'views/portal_my.xml', 'views/portal_my.xml',
'views/portal_maintenance.xml', 'views/portal_maintenance.xml',
'views/portal_emergency.xml',
'views/helpdesk_ticket.xml',
], ],
'assets': { 'assets': {
'web.assets_frontend': [ 'web.assets_frontend': [
......
...@@ -29,6 +29,11 @@ class PortalCustomerMaintenence(CustomerPortal): ...@@ -29,6 +29,11 @@ class PortalCustomerMaintenence(CustomerPortal):
domain = [('team_id.id','=',request.env.ref('helpdesk_maintenance.maintenance').id)] domain = [('team_id.id','=',request.env.ref('helpdesk_maintenance.maintenance').id)]
return domain return domain
def prepare_maintenance_emergency(self):
domain = self.prepare_maintenance()
domain.append(('maintenance_type_id.id','=',request.env.ref('helpdesk_maintenance.emergency').id))
return domain
def _prepare_portal_layout_values(self): def _prepare_portal_layout_values(self):
values = super(PortalHelpdesk, self)._prepare_portal_layout_values() values = super(PortalHelpdesk, self)._prepare_portal_layout_values()
stage_close = request.env.ref('sh_all_in_one_helpdesk.close_stage').id stage_close = request.env.ref('sh_all_in_one_helpdesk.close_stage').id
...@@ -275,11 +280,11 @@ class PortalCustomerMaintenence(CustomerPortal): ...@@ -275,11 +280,11 @@ class PortalCustomerMaintenence(CustomerPortal):
maintenance_count = len(HelpdeskTicket.search(domain).filtered(lambda h: h.team_id.id == request.env.ref('helpdesk_morsa.techinnical_support').id)) maintenance_count = len(HelpdeskTicket.search(domain).filtered(lambda h: h.team_id.id == request.env.ref('helpdesk_maintenance.maintenance').id))
# pager # pager
pager = portal_pager(url="/my/soporte",url_args={'sortby': sortby,'search_in': search_in,'search': search,'filterby': filterby},total=maintenance_count,page=page,step=self._items_per_page) pager = portal_pager(url="/my/mantenimientos",url_args={'sortby': sortby,'search_in': search_in,'search': search,'filterby': filterby},total=maintenance_count,page=page,step=self._items_per_page)
if groupby == 'create_by': if groupby == 'create_by':
order = "create_uid, %s" % order order = "create_uid, %s" % order
elif groupby == 'ticket_type': elif groupby == 'ticket_type':
...@@ -366,10 +371,8 @@ class PortalCustomerMaintenence(CustomerPortal): ...@@ -366,10 +371,8 @@ class PortalCustomerMaintenence(CustomerPortal):
}) })
return request.render("helpdesk_maintenance.portal_my_maitenance",values) return request.render("helpdesk_maintenance.portal_my_maitenance",values)
@http.route('/portal-create-ticket-maintenance', type='http', auth='public', csrf=False) @http.route('/portal-create-ticket-maintenance', type='http', auth='public', csrf=False)
def portal_create_ticket_support(self, **kw): def portal_create_ticket_maintenance(self, **kw):
try: try:
login_user = request.env.user login_user = request.env.user
if login_user and login_user.login != 'public': if login_user and login_user.login != 'public':
...@@ -434,7 +437,7 @@ class PortalCustomerMaintenence(CustomerPortal): ...@@ -434,7 +437,7 @@ class PortalCustomerMaintenence(CustomerPortal):
if kw.get('portal_severity'): if kw.get('portal_severity'):
ticket_dic.update({ ticket_dic.update({
'severity_type': kw.get('portal_severity'), 'severity_type': str(kw.get('portal_severity')),
}) })
if kw.get('portal_date_fail'): if kw.get('portal_date_fail'):
...@@ -467,12 +470,416 @@ class PortalCustomerMaintenence(CustomerPortal): ...@@ -467,12 +470,416 @@ class PortalCustomerMaintenence(CustomerPortal):
ticket_id.attachment_ids = [(6, 0, attachment_ids)] ticket_id.attachment_ids = [(6, 0, attachment_ids)]
return request.redirect("/my/soporte?ctr=False") return request.redirect("/my/mantenimientos?ctr=False")
except Exception as e: except Exception as e:
_logger.exception('Something went wrong %s',str(e)) _logger.exception('Something went wrong %s',str(e))
@http.route(['/my/soporte/<int:ticket_id>'],type='http',auth="public",website=True) @http.route(['/my/manteniminetos/<int:ticket_id>'],type='http',auth="public",website=True)
def portal_my_ticket_detail_soporte(self,ticket_id,access_token=None,report_type=None,message=False,download=False,**kw): def portal_my_ticket_detail_maintenance(self,ticket_id,access_token=None,report_type=None,message=False,download=False,**kw):
try:
ticket_sudo = self._document_check_access('helpdesk.ticket', ticket_id, access_token=access_token)
except (AccessError, MissingError):
return request.redirect('/my')
if report_type in ('html', 'pdf', 'text'):
return self._show_report(model=ticket_sudo,report_type=report_type,report_ref='sh_all_in_one_helpdesk.action_portal_report_helpdesk_ticket',download=download)
if ticket_sudo:
if request.env.company.sh_receive_email_seeing_ticket:
body = _('Ticket visto por el cliente %s',ticket_sudo.partner_id.name)
_message_post_helper(
"helpdesk.ticket",
ticket_sudo.id,
body,
token=ticket_sudo.access_token,
message_type="notification",
subtype_xmlid="mail.mt_note",
partner_ids=ticket_sudo.user_id.sudo().partner_id.ids,
)
values = {
'token': access_token,
'maintenance': ticket_sudo,
'message': message,
'bootstrap_formatting': True,
'partner_id': ticket_sudo.partner_id.id,
'report_type': 'html',
}
return request.render("helpdesk_maintenance.portal_ticket_page_maintenance",values)
#apartado de emergencia
@http.route(['/my/mantenimientos/emergencias', '/my/mantenimientos/emergencias/page/<int:page>'],type='http',auth="user",website=True)
def portal_my_maintenance_emergency(self,ctr='show',page=1,sortby=None,filterby=None,search=None,search_in='all',groupby='create_by',**kw):
values = self._prepare_portal_layout_values()
HelpdeskTicket = request.env['helpdesk.ticket'].sudo()
searchbar_sortings = {
'create_date': {
'label': _('Newest'),
'order': 'create_date desc'
},
'name': {
'label': _('Name'),
'order': 'name'
},
}
searchbar_inputs = {
'all': {
'input': 'all',
'label': _('Search in All')
},
}
searchbar_groupby = {
'create_by': {
'input': 'create_by',
'label': _('Created By')
},
'ticket_type': {
'input': 'ticket_type',
'label': _('Ticket Type')
},
'status': {
'input': 'status',
'label': _('Status')
},
'customer': {
'input': 'customer',
'label': _('Customer')
},
'category': {
'input': 'category',
'label': _('Category')
},
'subcategory': {
'input': 'subcategory',
'label': _('Sub Category')
},
'subject': {
'input': 'subject',
'label': _('Subject')
},
'priority': {
'input': 'priority',
'label': _('Priority')
},
'state': {
'input': 'state',
'label': _('Reply Status')
},
}
today = fields.Date.today()
quarter_start, quarter_end = date_utils.get_quarter(today)
last_week = today + relativedelta(weeks=-1)
last_month = today + relativedelta(months=-1)
last_year = today + relativedelta(years=-1)
searchbar_filters = {
'all': {
'label': _('All'),
'domain': []
},
'today': {
'label': _('Today'),
'domain': [("create_date", "=", today)]
},
'week': {
'label':
_('This week'),
'domain':
[('create_date', '>=', date_utils.start_of(today, "week")),
('create_date', '<=', date_utils.end_of(today, 'week'))]
},
'month': {
'label':
_('This month'),
'domain':
[('create_date', '>=', date_utils.start_of(today, 'month')),
('create_date', '<=', date_utils.end_of(today, 'month'))]
},
'year': {
'label':
_('This year'),
'domain':
[('create_date', '>=', date_utils.start_of(today, 'year')),
('create_date', '<=', date_utils.end_of(today, 'year'))]
},
'quarter': {
'label':
_('This Quarter'),
'domain': [('create_date', '>=', quarter_start),
('create_date', '<=', quarter_end)]
},
'last_week': {
'label':
_('Last week'),
'domain':
[('create_date', '>=', date_utils.start_of(last_week, "week")),
('create_date', '<=', date_utils.end_of(last_week, 'week'))]
},
'last_month': {
'label':
_('Last month'),
'domain':
[('create_date', '>=',
date_utils.start_of(last_month, 'month')),
('create_date', '<=', date_utils.end_of(last_month, 'month'))]
},
'last_year': {
'label':
_('Last year'),
'domain':
[('create_date', '>=', date_utils.start_of(last_year, 'year')),
('create_date', '<=', date_utils.end_of(last_year, 'year'))]
},
}
# default sort by value
if not sortby:
sortby = 'create_date'
order = searchbar_sortings[sortby]['order']
# default filter by value
if not filterby:
filterby = 'all'
domain = AND([searchbar_filters[filterby]['domain']])
if search and search_in:
domain = AND([domain, [('name', 'ilike', search)]])
ticket_domain = self.prepare_maintenance_emergency()
if request.env.user.sh_portal_user_access and request.env.user.sh_portal_user_access == 'user':
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('user_id', '=', request.env.user.id))
ticket_domain.append(('sh_user_ids', 'in', [request.env.user.id]))
ticket_domain.append(
('partner_id', '=', request.env.user.partner_id.id))
elif request.env.user.sh_portal_user_access and request.env.user.sh_portal_user_access == 'leader':
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('sh_user_ids', 'in', [request.env.user.id]))
ticket_domain.append(('user_id', '=', request.env.user.id))
ticket_domain.append(
('partner_id', '=', request.env.user.partner_id.id))
ticket_domain.append(('team_head', '=', request.env.user.id))
elif request.env.user.sh_portal_user_access and request.env.user.sh_portal_user_access == 'manager':
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('sh_user_ids', 'in', [request.env.user.id]))
ticket_domain.append(('sh_user_ids', '=', False))
ticket_domain.append(('user_id', '=', request.env.user.id))
ticket_domain.append(('user_id', '=', False))
ticket_domain.append(
('partner_id', '=', request.env.user.partner_id.id))
ticket_domain.append(('team_head', '=', request.env.user.id))
ticket_domain.append(('team_head', '=', False))
else:
ticket_domain.append(('|'))
ticket_domain.append(('|'))
ticket_domain.append(('user_id', '=', request.env.user.id))
ticket_domain.append(('sh_user_ids', 'in', [request.env.user.id]))
ticket_domain.append(
('partner_id', '=', request.env.user.partner_id.id))
stage_close = request.env.ref('sh_all_in_one_helpdesk.close_stage').id
stage_done = request.env.ref('sh_all_in_one_helpdesk.done_stage').id
stage_cancel = request.env.ref('sh_all_in_one_helpdesk.cancel_stage').id
ticket_domain.append(('stage_id.id','not in',[stage_close,stage_done,stage_cancel]))
domain = AND([domain, ticket_domain])
maintenance_count = len(HelpdeskTicket.search(domain).filtered(lambda h: h.team_id.id == request.env.ref('helpdesk_maintenance.maintenance').id and h.maintenance_type_id.id == request.env.ref('helpdesk_maintenance.emergency'.id)))
# pager
pager = portal_pager(url="/my/mantenimientos/emergencias",url_args={'sortby': sortby,'search_in': search_in,'search': search,'filterby': filterby},total=maintenance_count,page=page,step=self._items_per_page)
if groupby == 'create_by':
order = "create_uid, %s" % order
elif groupby == 'ticket_type':
order = "ticket_type, %s" % order
elif groupby == 'status':
order = "stage_id, %s" % order
elif groupby == 'customer':
order = "partner_id, %s" % order
elif groupby == 'category':
order = "category_id, %s" % order
elif groupby == 'subcategory':
order = "sub_category_id, %s" % order
elif groupby == 'subject':
order = "subject_id, %s" % order
elif groupby == 'priority':
order = "priority, %s" % order
elif groupby == 'state':
order = 'state,%s' % order
tickets = HelpdeskTicket.search(domain,order=order,limit=self._items_per_page,offset=pager['offset'])
request.session['my_tickets_history'] = tickets.ids[:100]
if groupby == 'create_by':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('create_uid'))
]
elif groupby == 'ticket_type':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('ticket_type'))
]
elif groupby == 'status':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('stage_id'))
]
elif groupby == 'customer':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('partner_id'))
]
elif groupby == 'category':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('category_id'))
]
elif groupby == 'subcategory':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('sub_category_id'))
]
elif groupby == 'subject':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('subject_id'))
]
elif groupby == 'priority':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('priority'))
]
elif groupby == 'state':
grouped_tickets = [
HelpdeskTicket.concat(*g)
for k, g in groupbyelem(tickets, itemgetter('state'))
]
# content according to pager and archive selected
values.update({
'created': ctr,
'tickets':tickets,
'grouped_tickets':grouped_tickets,
'page_name':'m_emergency',
'default_url':'/my/mantenimientos/emergencias',
'maintenance_count':maintenance_count,
'pager':pager,
'searchbar_sortings':searchbar_sortings,
'search_in':search_in,
'sortby':sortby,
'groupby':groupby,
'searchbar_inputs':searchbar_inputs,
'searchbar_groupby':searchbar_groupby,
'searchbar_filters':OrderedDict(sorted(searchbar_filters.items())),
'filterby':filterby,
})
return request.render("helpdesk_maintenance.portal_my_maitenance_emergency",values)
@http.route('/portal-create-ticket-maintenance-emergency', type='http', auth='public', csrf=False)
def portal_create_ticket_maintenance_emergency(self, **kw):
try:
login_user = request.env.user
if login_user and login_user.login != 'public':
partner_id = False
if kw.get('partner_id') and kw.get('partner_id') != '':
partner_id = request.env['res.partner'].sudo().search(
[('id', '=', int(kw.get('partner_id')))], limit=1)
else:
partner_id = request.env['res.partner'].sudo().search(
[('email', '=', kw.get('portal_email'))], limit=1)
if not partner_id:
return json.dumps({"resp":"Error","message":"Colaborador no encontrado, favor de verificar que haya agregado uno"})
if partner_id:
unvalued_tickets = len(
request.env['helpdesk.ticket'].sudo().search([
('stage_id','=',request.env.ref('sh_all_in_one_helpdesk.done_stage').id),
('priority_new','=',False)])
)
if unvalued_tickets >= 3:
return json.dumps({"resp":"Error","message":"Tienes demasiados tickets sin evaluar, favor de evaluarlos"})
ticket_dic = {
'partner_id': partner_id.id,
'ticket_from_portal': True
}
if kw.get('portal_phone'):
partner_id.update({'phone': kw.get('portal_phone')})
ticket_dic.update({
'mobile_no':kw.get('portal_phone')
})
if kw.get('portal_contact_name'):
ticket_dic.update({
'person_name':
kw.get('portal_contact_name'),
})
if kw.get('portal_email'):
ticket_dic.update({
'email': kw.get('portal_email'),
})
team_id = request.env['helpdesk.team'].sudo().browse(request.env.ref('helpdesk_maintenance.maintenance').id)
if team_id:
ticket_dic.update({
'team_id': team_id.id,
'team_head': team_id.team_head.id,
})
if kw.get('portal_description'):
ticket_dic.update({
'description':
kw.get('portal_description'),
})
ticket_dic.update({
'maintenance_type_id': request.env.ref('helpdesk_maintenance.emergency').id,
'severity_type':'3',
})
if kw.get('portal_date_fail'):
ticket_dic.update({
'date_fail': datetime.strptime(kw.get('portal_date_fail'),FORMAT).date(),
})
if kw.get('portal_fail_type'):
ticket_dic.update({
'fail_type': kw.get('portal_fail_type'),
})
ticket_id = request.env['helpdesk.ticket'].sudo().create(ticket_dic)
if 'portal_file' in request.params:
attached_files = request.httprequest.files.getlist('portal_file')
attachment_ids = []
for attachment in attached_files:
result = base64.b64encode(attachment.read())
attachment_id = request.env['ir.attachment'].sudo(
).create({
'name': attachment.filename,
'res_model': 'helpdesk.ticket',
'res_id': ticket_id.id,
'display_name': attachment.filename,
'datas': result,
})
attachment_ids.append(attachment_id.id)
ticket_id.attachment_ids = [(6, 0, attachment_ids)]
return request.redirect("/my/mantenimientos?ctr=False")
except Exception as e:
_logger.exception('Something went wrong %s',str(e))
@http.route(['/my/manteniminetos/emergencias/<int:ticket_id>'],type='http',auth="public",website=True)
def portal_my_ticket_detail_maintenance_emergency(self,ticket_id,access_token=None,report_type=None,message=False,download=False,**kw):
try: try:
ticket_sudo = self._document_check_access('helpdesk.ticket', ticket_id, access_token=access_token) ticket_sudo = self._document_check_access('helpdesk.ticket', ticket_id, access_token=access_token)
except (AccessError, MissingError): except (AccessError, MissingError):
...@@ -492,14 +899,13 @@ class PortalCustomerMaintenence(CustomerPortal): ...@@ -492,14 +899,13 @@ class PortalCustomerMaintenence(CustomerPortal):
partner_ids=ticket_sudo.user_id.sudo().partner_id.ids, partner_ids=ticket_sudo.user_id.sudo().partner_id.ids,
) )
values = { values = {
'token': access_token, 'token': access_token,
'soporte': ticket_sudo, 'm_emergency': ticket_sudo,
'message': message, 'message': message,
'bootstrap_formatting': True, 'bootstrap_formatting': True,
'partner_id': ticket_sudo.partner_id.id, 'partner_id': ticket_sudo.partner_id.id,
'report_type': 'html', 'report_type': 'html',
} }
return request.render("helpdesk_morsa.portal_ticket_page_support",values) return request.render("helpdesk_maintenance.portal_ticket_page_maintenance_emergency",values)
\ No newline at end of file
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
</record> </record>
<record id="brickwork" model="maintenance.type"> <record id="brickwork" model="maintenance.type">
<field name="name">Aire acondicionado</field> <field name="name">Albañileria</field>
</record> </record>
<record id="electricity" model="maintenance.type"> <record id="electricity" model="maintenance.type">
......
...@@ -19,14 +19,24 @@ class HelpdeskTicket(models.Model): ...@@ -19,14 +19,24 @@ class HelpdeskTicket(models.Model):
('1','Leve'), ('1','Leve'),
('2','Medio'), ('2','Medio'),
('3','Grave'), ('3','Grave'),
]) ],string='Tipo de gravedad')
fail_type = fields.Selection([ fail_type = fields.Selection([
('fail','Falla'),('warranty','Garantía') ('fail','Falla'),('warranty','Garantía')
],string="Tipo de falla") ],string="Tipo de falla")
is_maintenance = fields.Boolean('Es mantenimiento',compute='_verify_ticket_type')
def _compute_access_url(self): def _compute_access_url(self):
super(HelpdeskTicket, self)._compute_access_url() super(HelpdeskTicket, self)._compute_access_url()
for ticket in self: for ticket in self:
if ticket.team_id.id == self.env.ref('helpdesk_maintenance.maintenance').id: if ticket.team_id.id == self.env.ref('helpdesk_maintenance.maintenance').id:
ticket.access_url = '/my/manteniminetos/%s' % (ticket.id) ticket.access_url = '/my/manteniminetos/%s' % (ticket.id)
if ticket.team_id.id == self.env.ref('helpdesk_maintenance.maintenance').id and ticket.maintenance_type_id.id == self.env.ref('helpdesk_maintenance.emergency').id:
\ No newline at end of file ticket.access_url = '/my/manteniminetos/emergencias/%s' % (ticket.id)
@api.depends('team_id')
def _verify_ticket_type(self):
for ticket in self:
if ticket.team_id.id == self.env.ref('helpdesk_maintenance.maintenance').id:
ticket.is_maintenance = True
else:
ticket.is_maintenance = False
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"> <g> <g> <polygon points="216 48 208 16 304 16 296 48 216 48" fill="#fc0808" id="id_123"></polygon> <path d="M304,288H208l13.55-70.83A19.991,19.991,0,0,1,241.35,200h28.46a20,20,0,0,1,19.77,17Z" fill="#f70000" id="id_124"></path> <rect x="168" y="416" width="176" height="32" fill="#000000" id="id_125"></rect> <polygon points="304 16 296 48 216 48 208 16 304 16" fill="#ff0000" id="id_126"></polygon> <rect x="168" y="416" width="176" height="32" fill="#ff0000" id="id_127"></rect> <path d="M304,288H208l13.55-70.83A19.991,19.991,0,0,1,241.35,200h28.46a20,20,0,0,1,19.77,17Z" fill="#ff0000" id="id_128"></path> <line x1="200" y1="192" x2="192" y2="184" fill="none" id="id_129"></line> <line x1="312" y1="192" x2="320" y2="184" fill="none" id="id_130"></line> </g> <g> <path d="M372,8H140a28.031,28.031,0,0,0-28,28V476a28.031,28.031,0,0,0,28,28H372a28.031,28.031,0,0,0,28-28V36A28.031,28.031,0,0,0,372,8ZM293.75,24l-4,16h-67.5l-4-16ZM384,476a12.01,12.01,0,0,1-12,12H140a12.01,12.01,0,0,1-12-12V36a12.01,12.01,0,0,1,12-12h61.75l6.49,25.94A8,8,0,0,0,216,56h80a8,8,0,0,0,7.76-6.06L310.25,24H372a12.01,12.01,0,0,1,12,12Z" fill="#000000" id="id_131"></path> <path d="M93.027,227.713a8,8,0,0,0-11.314,0,40.013,40.013,0,0,0,0,56.574,8,8,0,1,0,11.314-11.314,24.012,24.012,0,0,1,0-33.946A8,8,0,0,0,93.027,227.713Z" fill="#ff0000" id="id_132"></path> <path d="M51,256a63.58,63.58,0,0,1,18.747-45.253,8,8,0,1,0-11.314-11.314,79.993,79.993,0,0,0,0,113.134,8,8,0,0,0,11.314-11.314A63.58,63.58,0,0,1,51,256Z" fill="#ff0d0d" id="id_133"></path> <path d="M418.343,227.713a8,8,0,0,0,0,11.314,24.012,24.012,0,0,1,0,33.946,8,8,0,0,0,11.314,11.314,40.013,40.013,0,0,0,0-56.574A8,8,0,0,0,418.343,227.713Z" fill="#ff0f0f" id="id_134"></path> <path d="M455.937,199.433a8,8,0,1,0-11.314,11.314,63.991,63.991,0,0,1,0,90.506,8,8,0,0,0,11.314,11.314,79.993,79.993,0,0,0,0-113.134Z" fill="#ff0000" id="id_135"></path> <path d="M344,408H168a8,8,0,0,0-8,8v32a8,8,0,0,0,8,8H344a8,8,0,0,0,8-8V416A8,8,0,0,0,344,408Zm-8,32H176V424H336Z" fill="#000000" id="id_136"></path> <path d="M320,280h-9.46l-13.08-64.42A27.836,27.836,0,0,0,269.81,192H241.35a28.13,28.13,0,0,0-27.69,23.84L201.39,280H192a8,8,0,0,0-8,8v32a8,8,0,0,0,8,8H320a8,8,0,0,0,8-8V288A8,8,0,0,0,320,280Zm-90.6-61.33c.03-.12.05-.24.07-.37A12.056,12.056,0,0,1,241.35,208h28.46a11.935,11.935,0,0,1,11.86,10.2c.02.13.04.26.07.39L294.21,280H217.68ZM312,312H200V296H312Z" fill="#000000" id="id_137"></path> <path d="M256,184a8,8,0,0,0,8-8V152a8,8,0,0,0-16,0v24A8,8,0,0,0,256,184Z" fill="#ff2121" id="id_138"></path> <path d="M176,248h16a8,8,0,0,0,0-16H176a8,8,0,0,0,0,16Z" fill="#ff1717" id="id_139"></path> <path d="M312,240a8,8,0,0,0,8,8h16a8,8,0,0,0,0-16H320A8,8,0,0,0,312,240Z" fill="#ff0f0f" id="id_140"></path> <path d="M194.343,197.657a8,8,0,0,0,11.314-11.314l-8-8a8,8,0,0,0-11.314,11.314Z" fill="#ff0000" id="id_141"></path> <path d="M312,200a7.976,7.976,0,0,0,5.657-2.343l8-8a8,8,0,0,0-11.314-11.314l-8,8A8,8,0,0,0,312,200Z" fill="#ff0a0a" id="id_142"></path> <path d="M280,368a8,8,0,0,0,0-16H232a8,8,0,0,0,0,16Z" fill="#000000" id="id_143"></path> <path d="M184,384a8,8,0,0,0,8,8H320a8,8,0,0,0,0-16H192A8,8,0,0,0,184,384Z" fill="#0a0000" id="id_144"></path> </g> </g> </svg>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -20,9 +20,6 @@ $(document).ready(function(e) { ...@@ -20,9 +20,6 @@ $(document).ready(function(e) {
show_error("Es necesario llenar el campo de Tipo de mantenimiento"); show_error("Es necesario llenar el campo de Tipo de mantenimiento");
} }
if(req['portal_date_fail'] == ""){ if(req['portal_date_fail'] == ""){
e.preventDefault(); e.preventDefault();
show_error("Es necesario llenar el campo de Fecha de Falla"); show_error("Es necesario llenar el campo de Fecha de Falla");
} }
...@@ -44,6 +41,40 @@ $(document).ready(function(e) { ...@@ -44,6 +41,40 @@ $(document).ready(function(e) {
} }
} }
if (ticket_type == "emergencia_mantenimiento"){
var req = required_maintenance()
if(req['portal_contact_name'] == ""){
e.preventDefault();
show_error("Es necesario llenar el campo de Nombre");
}
if(req['portal_email'] == ""){
e.preventDefault();
show_error("Es necesario llenar el campo de Correo");
}
if(req['portal_phone'] == ""){
e.preventDefault();
show_error("Es necesario llenar el campo de Teléfono");
}
if(req['portal_date_fail'] == ""){
e.preventDefault();
show_error("Es necesario llenar el campo de Fecha de Falla");
}
if(req['portal_description'] == ""){
e.preventDefault();
show_error("Es necesario llenar el campo de Descripción");
}
if(req['portal_fail_type'] == ""){
e.preventDefault();
show_error("Es necesario llenar el campo de Tipo de Falla");
}
if(req['portal_file'] == 0){
e.preventDefault();
show_error("Es necesario agregar los archivos de evidencia|");
}
}
}); });
...@@ -54,7 +85,7 @@ $(document).ready(function(e) { ...@@ -54,7 +85,7 @@ $(document).ready(function(e) {
'portal_email': $("#portal_email").val(), 'portal_email': $("#portal_email").val(),
'portal_phone': $("#portal_phone").val(), 'portal_phone': $("#portal_phone").val(),
'portal_main_type': $("#portal_main_type").val(), 'portal_main_type': $("#portal_main_type").val(),
'portal_date_fail': validate_Date($("#portal_date_fail").val()), 'portal_date_fail':$("#portal_date_fail").val(),
'portal_severity': $("#portal_severity").val(), 'portal_severity': $("#portal_severity").val(),
'portal_description': $("#portal_description").val(), 'portal_description': $("#portal_description").val(),
'portal_fail_type': $("#portal_fail_type").val(), 'portal_fail_type': $("#portal_fail_type").val(),
...@@ -62,6 +93,19 @@ $(document).ready(function(e) { ...@@ -62,6 +93,19 @@ $(document).ready(function(e) {
} }
} }
function required_maintenance_emergency(){
return {
'partner_id': $("#partner_id").val(),
'portal_contact_name': $("#portal_contact_name").val(),
'portal_email': $("#portal_email").val(),
'portal_phone': $("#portal_phone").val(),
'portal_date_fail': $("#portal_date_fail").val(),
'portal_description': $("#portal_description").val(),
'portal_fail_type': $("#portal_fail_type").val(),
'portal_file': document.getElementById('portal_file').files.length
}
}
function show_error(message){ function show_error(message){
return swal({ return swal({
title:"Error", title:"Error",
...@@ -71,32 +115,37 @@ $(document).ready(function(e) { ...@@ -71,32 +115,37 @@ $(document).ready(function(e) {
}) })
} }
function validate_Date(date){
$(document).on("change", "#portal_date_fail", function (e) {
let dateformat = /^(0?[1-9]|[1-2][0-9]|3[01])[\/](0?[1-9]|1[0-2])/; let dateformat = /^(0?[1-9]|[1-2][0-9]|3[01])[\/](0?[1-9]|1[0-2])/;
var date = $("#portal_date_fail").val();
if (date.match(dateformat)){ if (date.match(dateformat)){
let ListofDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; var response = validate_Date(date)
dt = date.split("/"); console.log(response)
day = parseInt(dt[0]) if (response == ""){
month = parseInt(dt[1]) $("#portal_date_fail").val("");
year = parseInt(dt[2]) show_error("Favor de ingresar el formato de fecha valido");
}
}else{
console.log('formato aún no valido')
}
});
if (month > 0 && month <= ListofDays.length){ function validate_Date(date){
if( day > 0 && day <= ListofDays[month-1]){ let ListofDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
return date dt = date.split("/");
}else{ day = parseInt(dt[0]);
return ""; month = parseInt(dt[1]);
} year = parseInt(dt[2]);
if (month > 0 && month <= ListofDays.length && Number.isInteger(year)){
if( day > 0 && day <= ListofDays[month-1]){
return date
}else{ }else{
return ""; return "";
} }
}else{ }else{
return ""; return "";
} }
} }
}); });
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="helpdesk_ticket_form_maintenance" model="ir.ui.view">
<field name="name">helpdesk.ticket.form.inherit.maintenance</field>
<field name="model">helpdesk.ticket</field>
<field name="inherit_id" ref="sh_all_in_one_helpdesk.helpdesk_ticket_form_view"/>
<field name="priority" eval="18"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='priority']" position="after">
<field name="is_maintenance" invisible="1"/>
<field name="maintenance_type_id" attrs="{'invisible':[('is_maintenance', '=', False)]}"/>
<field name="date_fail" attrs="{'invisible':[('is_maintenance', '=', False)]}"/>
<field name="fail_type" attrs="{'invisible':[('is_maintenance', '=', False)]}"/>
</xpath>
</field>
</record>
</data>
</odoo>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="portal_my_maitenance_emergency" name="Mis Tickets">
<t t-call="portal.portal_layout">
<t t-set="breadcrumbs_searchbar" t-value="True" />
<t t-call="portal.portal_searchbar">
<t t-set="title">Emergencias</t>
</t>
<input type="hidden" name="mdl_shw" id="mdl_shw" t-att-value="created"/>
<div id="createticketModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content" style="max-height:650px;">
<div class="modal-body">
<div class="row">
<div class="col-sm-12 col-md-6 col-lg-6 border-right">
<h4>Crear Ticket</h4>
<form action="/portal-create-ticket-maintenance-emergency" method="POST" id="form_id" class="form-horizontal mt32" enctype="multipart/form-data">
<input type="hidden" name="sh_file_size" id="sh_file_size" t-att-value="request.env.company.sh_file_size"/>
<input type="hidden" name="tck_type" id="tck_type" value="emergencia_mantenimiento"/>
<div class="form-group">
<t t-if="request.env.user.has_group('base.group_portal') and request.env.user.sh_portal_user_access or not request.env.user.has_group('base.group_portal')">
<label class="control-label" for="partner">Usuario:</label>
<input class="form-control " list="partner_ids" name="partner" id="partner" />
<input type="hidden" name="partner_id" id="partner_id" />
<datalist id="partner_ids"> </datalist>
</t>
</div>
<t t-if="request.env.user.has_group('base.group_portal') and not request.env.user.sh_portal_user_access">
<div t-attf-class="form-group #{error and 'portal_contact_name' in error and 'has-error' or ''}">
<label class="control-label" for="portal_contact_name">Nombre:</label>
<input type="text" class="form-control" id="portal_contact_name" name="portal_contact_name" t-att-value="request.env.user.partner_id.name" readonly="True" />
</div>
<div name="portal_email_from_container" t-attf-class="form-group #{error and 'portal_email' in error and 'has-error' or ''}">
<label class="control-label" for="portal_email">Correo:</label>
<input type="email" class="form-control" id="portal_email" name="portal_email" t-att-value="request.env.user.partner_id.email" readonly="True" />
</div>
</t>
<t t-else="">
<div t-attf-class="form-group #{error and 'portal_contact_name' in error and 'has-error' or ''}">
<label class="control-label" for="portal_contact_name">Nombre:</label>
<input type="text" class="form-control" id="portal_contact_name" name="portal_contact_name" required="True" />
</div>
<div name="portal_email_from_container" t-attf-class="form-group #{error and 'portal_email' in error and 'has-error' or ''}">
<label class="control-label" for="portal_email">Correo:</label>
<input type="email" class="form-control" id="portal_email" name="portal_email" required="True" />
</div>
</t>
<div t-attf-class="form-group s_website_form_required">
<label class="control-label s_website_form_required" for="portal_phone">Teléfono:</label>
<input type="text" class="form-control form-field s_website_form_required" id="portal_phone" name="portal_phone" required="" />
</div>
<!--fecha de decteción de falla-->
<div t-attf-class="form-group o_website_form_required_custom #{error and 'portal_date_fail' in error and 'has-error' or ''}">
<label class="control-label" for="portal_date_fail">¿Cuando detecto la falla?</label>
<input type="text" class="form-control form-field s_website_form_required" id="portal_date_fail" name="portal_date_fail" placeholder="(dd/mm/yyyy)" required="" />
</div>
<!--Descripción detallada de falla-->
<div t-attf-class="form-group o_website_form_required_custom #{error and 'portal_description' in error and 'has-error' or ''}">
<label class="control-label" for="portal_description">Descripción</label>
<textarea id="description" name="portal_description" class="form-control form-field o_website_form_required_custom" placeholder="Description" required=""/>
</div>
<!--Tipo de falla-->
<div t-attf-class="form-group o_website_form_required_custom #{error and 'portal_fail_type' in error and 'has-error' or ''}">
<strong><span class="control-label" >Selecciona el tipo de falla:</span></strong><br/><br/>
<input type="radio" class="mr5" name="portal_fail_type" id="portal_fail_type" value="fail">Falla</input>
<input type="radio" class="mr5" name="portal_fail_type" id="portal_fail_type" value="warranty">Garantía</input>
</div>
<div name="portal_file_container" t-attf-class="form-group #{error and 'portal_file' in error and 'has-error' or ''}">
<label class="control-label" for="portal_file">Evidencias:</label>
<label class="custom-file">
<input name="portal_file" id="portal_file" type="file" multiple="true" />
<span class="custom-file-control" />
</label>
</div>
<div class="row mb-2">
<div class="col-12 text-center border-top ">
<button type="submit" id="create_helpdesk_ticket" class="btn btn-primary mt-2 rounded">Crear Ticket</button>
</div>
</div>
</form>
</div>
<div class="col-sm-12 col-md-6 col-lg-6 o_center_object mt-2">
<button type="button" class="btn btn-secondary rounded" data-dismiss="modal">Ver mis tickets</button>
</div>
</div>
</div>
</div>
</div>
</div>
<t t-if="not tickets">
<p>No hay tickets relacionados.</p>
</t>
<t t-if="grouped_tickets" t-call="portal.portal_table">
<t t-foreach="grouped_tickets" t-as="ticket">
<thead>
<tr t-attf-class="{{'thead-light' if not groupby == 'none' else ''}}">
<th t-if="groupby == 'create_by'">
<em class="font-weight-normal text-muted">Creado por:</em>
<span t-field="ticket[0].create_uid.name" />
</th>
<th t-if="groupby == 'ticket_type'">
<em class="font-weight-normal text-muted">Tipo de Ticket:</em>
<span t-field="ticket[0].ticket_type.name" />
</th>
<th t-if="groupby == 'status'">
<em class="font-weight-normal text-muted">Estado:</em>
<span t-esc="ticket[0].stage_id.name" />
</th>
<th t-if="groupby == 'priority'">
<em class="font-weight-normal text-muted">Prioridad:</em>
<span t-esc="ticket[0].priority.name" />
</th>
<th t-if="groupby == 'state'">
<em class="font-weight-normal text-muted">Estatus de Respuesta:</em>
<span t-esc="ticket[0].state" />
</th>
<th>Fecha de creación</th>
<th>Última actualización</th>
<th>Tipo de Ticket</th>
<th>Estado</th>
</tr>
</thead>
<tbody>
<t t-foreach="ticket" t-as="t">
<tr>
<td>
<a t-att-href="t.get_portal_url()" t-att-title="t.name">
<t t-esc="t.name" t-if="t.name" />
<em t-else="">Ticket</em>
</a>
</td>
<td><span t-field="t.create_date" t-options='{"widget": "date"}' /></td>
<td><span t-field="t.write_date" t-options='{"widget": "date"}' /></td>
<td><span t-field="t.ticket_type" /></td>
<td><span t-field="t.stage_id" /></td>
</tr>
</t>
</tbody>
</t>
</t>
</t>
</template>
<template id="portal_ticket_page_maintenance_emergency" name="Ticket Portal Template" inherit_id="portal.portal_sidebar" primary="True">
<xpath expr="//div[hasclass('o_portal_sidebar')]" position="inside">
<div class="row mt16 o_portal_ticket_sidebar">
<!-- Sidebar -->
<t t-call="portal.portal_record_sidebar">
<t t-set="classes" t-value="'col-12 col-lg flex-lg-grow-0 d-print-none'" />
<t t-set="title">
<h2 class="mb-0">
<b t-if="m_emergency" t-field="m_emergency.name" />
<b t-else="" >TICKET</b>
</h2>
</t>
<t t-set="entries">
<ul class="list-group list-group-flush flex-wrap flex-row flex-lg-column">
<li class="list-group-item flex-grow-1">
<div class="o_download_pdf btn-toolbar flex-sm-nowrap">
<div class="btn-group flex-grow-1 mr-1 mb-1">
<a class="btn btn-secondary btn-block o_download_btn" t-att-href="m_emergency.get_portal_url(report_type='pdf', download=True)" title="Download"><i class="fa fa-download" /> Descargar</a>
</div>
</div>
</li>
<li t-if="m_emergency.user_id" class="list-group-item flex-grow-1">
<div class="small mb-1"><strong class="text-muted">Contacto:</strong></div>
<div class="row">
<div class="col flex-grow-0 pr-2">
<img t-if="m_emergency.user_id.image_128" class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(maintenance.user_id.image_128)" alt="Contact" />
<img t-else="" class="rounded-circle mt-1 o_portal_contact_img" src="/web/static/src/img/user_menu_avatar.png" alt="Contact" />
</div>
<div class="col pl-0" style="min-width: 150px;">
<span t-field="m_emergency.user_id" t-options='{"widget": "contact", "fields": ["name", "phone"], "no_marker": True}' />
<a href="#discussion" class="small"><i class="fa fa-comment"></i> Mandar Mensaje</a>
</div>
</div>
</li>
</ul>
</t>
</t>
<!-- Page Content -->
<div id="ticket_content" class="col-12 col-lg justify-content-end">
<div t-attf-class="card #{'pb-5' if report_type == 'html' else ''}">
<div t-call="helpdesk_maintenance.helpdesk_ticket_portal_content_maintenance_emergency" />
</div>
<!-- chatter -->
<div id="ticket_communication" class="mt-4">
<h2>Historia</h2>
<t t-call="portal.message_thread">
<t t-set="object" t-value="m_emergency" />
</t>
</div>
</div>
</div>
</xpath>
</template>
<template id="helpdesk_ticket_portal_content_maintenance_emergency" name="Helpdesk Ticket Portal Content">
<!-- Intro -->
<div id="introduction" t-attf-class="pb-2 pt-3 #{'card-header bg-white' if report_type == 'html' else ''}">
<h2 class="my-0">
<strong><em t-esc="m_emergency.name" /></strong>
</h2>
</div>
<div t-attf-class="#{'card-body' if report_type == 'html' else ''}">
<div id="informations">
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Tipo de Ticket: </strong>
</div>
<div class="col-6">
<span t-field="m_emergency.ticket_type" />
</div>
</div>
</div>
<div class=" col-6">
<div class="row mb-3">
<div class="col-6">
<strong>Fecha de creación:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.create_date" />
</div>
</div>
</div>
</div>
<div class="row">
<div class=" col-6">
<div class="row mb-3">
<div class="col-6">
<strong>Última actualización:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.write_date" />
</div>
</div>
</div>
<div class="col-6">
<div class="row mb-3">
<div class="col-6">
<strong>Nombre:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.person_name" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Correo electrónico:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.email" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
<div class="row mb-3 ">
<div class="col-6">
<strong>Fecha de replica:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.replied_date" />
</div>
</div>
</div>
<div class="col-6">
<div class="row mb-3 ">
<div class="col-6">
<strong>Fecha de cierre</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.close_date" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
<div class="row mb-3">
<div class="col-6">
<strong>Tipo de mantenimiento:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.maintenance_type_id.name"/>
</div>
</div>
<div class="row mb-3">
<div class="col-6">
<strong>Tipo de gravedad</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.severity_type" />
</div>
</div>
</div>
<div class="col-6">
<div class="row mb-3">
<div class="col-6">
<strong>Fecha en que detecto la falla:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.date_fail" />
</div>
</div>
<div class="row mb-3">
<div class="col-6">
<strong>Tipo de Falla:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.fail_type" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Prioridad:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.priority" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Cerrado por: </strong>
</div>
<div class="col-6">
<span t-field="m_emergency.close_by" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Fecha de cancelación:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.cancel_date" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Cancelado por:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.cancel_by" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Estado:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.stage_id" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Razón de cancelación:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.cancel_reason" />
</div>
</div>
</div>
</div>
<t t-if="m_emergency.comment">
<div class="row">
<div class="mb-3 col-12">
<strong>Comentario de cierre:</strong>
</div>
</div>
<div class="row">
<div class="mb-3 col-12">
<span t-field="m_emergency.comment" />
</div>
</div>
</t>
<t t-if="m_emergency.description">
<div class="row">
<div class="mb-3 col-12">
<strong>Descripción:</strong>
</div>
</div>
<div class="row">
<div class="mb-3 col-12">
<span t-field="m_emergency.description" />
</div>
</div>
</t>
<t t-if="m_emergency.priority_new and m_emergency.customer_comment">
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Calificación del cliente:</strong>
</div>
<div class="col-6">
<span class="float-right" title="Rating" role="img" t-attf-aria-label="Rating: #{m_emergency.priority_new} on 3">
<t t-foreach="range(2, 7)" t-as="i">
<span t-attf-class="fa fa-lg fa-star#{'' if i &lt;= int(m_emergency.priority_new) else '-o'}" />
</t>
</span>
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Comentario del cliente:</strong>
</div>
<div class="col-6">
<span t-field="m_emergency.customer_comment" />
</div>
</div>
</div>
</div>
</t>
</div>
</div>
</template>
</odoo>
\ No newline at end of file
...@@ -176,5 +176,313 @@ ...@@ -176,5 +176,313 @@
</t> </t>
</template> </template>
<template id="portal_ticket_page_maintenance" name="Ticket Portal Template" inherit_id="portal.portal_sidebar" primary="True">
<xpath expr="//div[hasclass('o_portal_sidebar')]" position="inside">
<div class="row mt16 o_portal_ticket_sidebar">
<!-- Sidebar -->
<t t-call="portal.portal_record_sidebar">
<t t-set="classes" t-value="'col-12 col-lg flex-lg-grow-0 d-print-none'" />
<t t-set="title">
<h2 class="mb-0">
<b t-if="maintenance" t-field="maintenance.name" />
<b t-else="" >TICKET</b>
</h2>
</t>
<t t-set="entries">
<ul class="list-group list-group-flush flex-wrap flex-row flex-lg-column">
<li class="list-group-item flex-grow-1">
<div class="o_download_pdf btn-toolbar flex-sm-nowrap">
<div class="btn-group flex-grow-1 mr-1 mb-1">
<a class="btn btn-secondary btn-block o_download_btn" t-att-href="maintenance.get_portal_url(report_type='pdf', download=True)" title="Download"><i class="fa fa-download" /> Descargar</a>
</div>
</div>
</li>
<li t-if="maintenance.user_id" class="list-group-item flex-grow-1">
<div class="small mb-1"><strong class="text-muted">Contacto:</strong></div>
<div class="row">
<div class="col flex-grow-0 pr-2">
<img t-if="maintenance.user_id.image_128" class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(maintenance.user_id.image_128)" alt="Contact" />
<img t-else="" class="rounded-circle mt-1 o_portal_contact_img" src="/web/static/src/img/user_menu_avatar.png" alt="Contact" />
</div>
<div class="col pl-0" style="min-width: 150px;">
<span t-field="maintenance.user_id" t-options='{"widget": "contact", "fields": ["name", "phone"], "no_marker": True}' />
<a href="#discussion" class="small"><i class="fa fa-comment"></i> Mandar Mensaje</a>
</div>
</div>
</li>
</ul>
</t>
</t>
<!-- Page Content -->
<div id="ticket_content" class="col-12 col-lg justify-content-end">
<div t-attf-class="card #{'pb-5' if report_type == 'html' else ''}">
<div t-call="helpdesk_maintenance.helpdesk_ticket_portal_content_maintenance" />
</div>
<!-- chatter -->
<div id="ticket_communication" class="mt-4">
<h2>Historia</h2>
<t t-call="portal.message_thread">
<t t-set="object" t-value="maintenance" />
</t>
</div>
</div>
</div>
</xpath>
</template>
<template id="helpdesk_ticket_portal_content_maintenance" name="Helpdesk Ticket Portal Content">
<!-- Intro -->
<div id="introduction" t-attf-class="pb-2 pt-3 #{'card-header bg-white' if report_type == 'html' else ''}">
<h2 class="my-0">
<strong><em t-esc="maintenance.name" /></strong>
</h2>
</div>
<div t-attf-class="#{'card-body' if report_type == 'html' else ''}">
<div id="informations">
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Tipo de Ticket: </strong>
</div>
<div class="col-6">
<span t-field="maintenance.ticket_type" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Fecha de creación:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.create_date" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Última actualización:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.write_date" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Nombre:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.person_name" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Correo electrónico:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.email" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Fecha de replica:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.replied_date" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Fecha de cierre</strong>
</div>
<div class="col-6">
<span t-field="maintenance.close_date" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Tipo de mantenimiento:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.maintenance_type_id.name"/>
</div>
</div>
<div class="row">
<div class="col-6">
<strong>Tipo de gravedad</strong>
</div>
<div class="col-6">
<span t-field="maintenance.severity_type" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Fecha de falla:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.date_fail" />
</div>
</div>
<div class="row">
<div class="col-6">
<strong>Tipo de Falla:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.fail_type" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Prioridad:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.priority" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Cerrado por: </strong>
</div>
<div class="col-6">
<span t-field="maintenance.close_by" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Fecha de cancelación:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.cancel_date" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Cancelado por:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.cancel_by" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Estado:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.stage_id" />
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Razón de cancelación:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.cancel_reason" />
</div>
</div>
</div>
</div>
<t t-if="maintenance.comment">
<div class="row">
<div class="mb-3 col-12">
<strong>Comentario de cierre:</strong>
</div>
</div>
<div class="row">
<div class="mb-3 col-12">
<span t-field="maintenance.comment" />
</div>
</div>
</t>
<t t-if="maintenance.description">
<div class="row">
<div class="mb-3 col-12">
<strong>Descripción:</strong>
</div>
</div>
<div class="row">
<div class="mb-3 col-12">
<span t-field="maintenance.description" />
</div>
</div>
</t>
<t t-if="maintenance.priority_new and maintenance.customer_comment">
<div class="row">
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Calificación del cliente:</strong>
</div>
<div class="col-6">
<span class="float-right" title="Rating" role="img" t-attf-aria-label="Rating: #{maintenance.priority_new} on 3">
<t t-foreach="range(2, 7)" t-as="i">
<span t-attf-class="fa fa-lg fa-star#{'' if i &lt;= int(maintenance.priority_new) else '-o'}" />
</t>
</span>
</div>
</div>
</div>
<div class="mb-3 col-6">
<div class="row">
<div class="col-6">
<strong>Comentario del cliente:</strong>
</div>
<div class="col-6">
<span t-field="maintenance.customer_comment" />
</div>
</div>
</div>
</div>
</t>
</div>
</div>
</template>
</odoo> </odoo>
\ No newline at end of file
...@@ -13,13 +13,21 @@ ...@@ -13,13 +13,21 @@
<template id="portal_my_home_menu_ticket" name="Portal layout : ticket menu entries" inherit_id="portal.portal_breadcrumbs" priority="60"> <template id="portal_my_home_menu_ticket" name="Portal layout : ticket menu entries" inherit_id="portal.portal_breadcrumbs" priority="60">
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside"> <xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
<li t-if="page_name == 'maintenance' or maintenance" t-attf-class="breadcrumb-item #{'active ' if not soporte else ''}"> <li t-if="page_name == 'maintenance' or maintenance" t-attf-class="breadcrumb-item #{'active ' if not soporte else ''}">
<a t-if="maintenance" t-attf-href="/my/soporte?{{ keep_query() }}">Soporte Mantenimiento</a> <a t-if="maintenance" t-attf-href="/my/mantenimientos?{{ keep_query() }}">Mantenimiento</a>
<t t-else="">Mantenimiento</t> <t t-else="">Mantenimiento</t>
</li> </li>
<li t-if="maintenance" class="breadcrumb-item active"> <li t-if="maintenance" class="breadcrumb-item active">
<t t-esc="maintenance.name" t-if="maintenance.name" /> <t t-esc="maintenance.name" t-if="maintenance.name" />
<t t-else=""><em>Mantenimiento</em></t> <t t-else=""><em>Mantenimiento</em></t>
</li> </li>
<li t-if="page_name == 'm_emergency' or m_emergency" t-attf-class="breadcrumb-item #{'active ' if not soporte else ''}">
<a t-if="m_emergency" t-attf-href="/my/mantienimiento/emergencia?{{ keep_query() }}">Emergencia</a>
<t t-else="">Emergencia</t>
</li>
<li t-if="m_emergency" class="breadcrumb-item active">
<t t-esc="maintenance.name" t-if="maintenance.name" />
<t t-else=""><em>Mantenimiento</em></t>
</li>
</xpath> </xpath>
</template> </template>
...@@ -40,11 +48,11 @@ ...@@ -40,11 +48,11 @@
</t> </t>
<t t-call="portal.portal_docs_entry"> <t t-call="portal.portal_docs_entry">
<t t-set="title">Emergencias</t> <t t-set="title">Emergencias</t>
<t t-set="url" t-value="'/my/erp'" /> <t t-set="url" t-value="'/my/mantenimientos/emergencias'" />
<t t-set="count" t-value="erp_count" /> <t t-set="count" t-value="maintenance_count" />
<t t-set="desc" t-value="'Soporte y Mejoras Odoo'"/> <t t-set="desc" t-value="'Seguridad física o Patrimonial Comprometida'"/>
<t t-set="avatar" t-value="'/helpdesk_morsa/static/src/img/erp.svg'"/> <t t-set="avatar" t-value="'/helpdesk_maintenance/static/src/img/emergency_icon.svg'"/>
<t t-set="background" t-value="'/helpdesk_morsa/static/src/img/erp_back.svg'"/> <t t-set="background" t-value="'/helpdesk_maintenance/static/src/img/emergency_back.svg'"/>
</t> </t>
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
], ],
"data": [ "data": [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'security/groups.xml',
'data/region.xml', 'data/region.xml',
'data/helpdesk_team.xml', 'data/helpdesk_team.xml',
'data/helpdesk_stage.xml', 'data/helpdesk_stage.xml',
...@@ -33,7 +34,7 @@ ...@@ -33,7 +34,7 @@
'views/portal/portal_page.xml', 'views/portal/portal_page.xml',
'views/portal/portal_feedback.xml', 'views/portal/portal_feedback.xml',
'views/odoo/helpdesk_settings.xml', 'views/odoo/helpdesk_settings.xml',
'views/odoo/helpdesk_ticket.xml', #'views/odoo/helpdesk_ticket.xml',
'views/odoo/helpdesk_team.xml', 'views/odoo/helpdesk_team.xml',
'views/odoo/helpdesk_warehouse.xml', 'views/odoo/helpdesk_warehouse.xml',
'views/odoo/helpdesk_module.xml', 'views/odoo/helpdesk_module.xml',
...@@ -49,13 +50,8 @@ ...@@ -49,13 +50,8 @@
'https://unpkg.com/sweetalert/dist/sweetalert.min.js', 'https://unpkg.com/sweetalert/dist/sweetalert.min.js',
('replace', 'sh_all_in_one_helpdesk/static/src/js/portal.js', 'helpdesk_morsa/static/src/js/portal.js'), ('replace', 'sh_all_in_one_helpdesk/static/src/js/portal.js', 'helpdesk_morsa/static/src/js/portal.js'),
], ],
}, },
'images': [
'static/img/morsa.png'
],
"application":False, "application":False,
"auto_install":False, "auto_install":False,
"installable":True, "installable":True,
'images': [],
} }
...@@ -2,4 +2,4 @@ from . import portal ...@@ -2,4 +2,4 @@ from . import portal
from . import portal_soporte from . import portal_soporte
from . import portal_erp from . import portal_erp
from . import portal_emergency from . import portal_emergency
from . import main from . import main
\ No newline at end of file
...@@ -71,4 +71,5 @@ class PortalHelpdeskMorsa(PortalHelpdesk): ...@@ -71,4 +71,5 @@ class PortalHelpdeskMorsa(PortalHelpdesk):
return json.dumps({"resp":"Success","message":""}) return json.dumps({"resp":"Success","message":""})
else: else:
return json.dumps({"resp":"Error","message":"Favor de agregar un contacto valido"}) return json.dumps({"resp":"Error","message":"Favor de agregar un contacto valido"})
\ No newline at end of file
\ No newline at end of file
...@@ -14,6 +14,7 @@ _logger = logging.getLogger(__name__) ...@@ -14,6 +14,7 @@ _logger = logging.getLogger(__name__)
class HelpdeskTicket(models.Model): class HelpdeskTicket(models.Model):
_inherit = 'helpdesk.ticket' _inherit = 'helpdesk.ticket'
erp_id = fields.Many2one('erp.modules','ERP') erp_id = fields.Many2one('erp.modules','ERP')
incidence_type = fields.Selection([ incidence_type = fields.Selection([
('odoo', 'Falla Odoo Nacional'), ('odoo', 'Falla Odoo Nacional'),
...@@ -35,18 +36,10 @@ class HelpdeskTicket(models.Model): ...@@ -35,18 +36,10 @@ class HelpdeskTicket(models.Model):
is_support = fields.Boolean('Es soporte',compute='_compute_ticket_type') is_support = fields.Boolean('Es soporte',compute='_compute_ticket_type')
is_erp = fields.Boolean('Es ERP',compute='_compute_ticket_type') is_erp = fields.Boolean('Es ERP',compute='_compute_ticket_type')
is_emergency = fields.Boolean('Es 911',compute='_compute_ticket_type') is_emergency = fields.Boolean('Es 911',compute='_compute_ticket_type')
user_branch_id = fields.Many2one('warehouse.helpdesk',related="partner_id.user_ids.warehouse_id",store=True) user_branch_id = fields.Many2one('warehouse.helpdesk',string='Usuario Sucursal',store=True)
#user_region_id = fields.Many2one('region.helpdesk',string="Región")
@api.onchange('partner_id')
def get_user_warehouse(self):
if self.partner_id:
user = self.env['res.users'].sudo().search([('partner_id','=',self.partner_id.id)],limit=1)
if user:
self.user_branch_id = user.warehouse_id.id
def _get_color(self): def _get_color(self):
in_progress_stage = self.env.ref('sh_all_in_one_helpdesk.in_progress_stage').id in_progress_stage = self.env.ref('sh_all_in_one_helpdesk.in_progress_stage').id
new_stage = self.env.ref('sh_all_in_one_helpdesk.new_stage').id new_stage = self.env.ref('sh_all_in_one_helpdesk.new_stage').id
...@@ -101,14 +94,7 @@ class HelpdeskTicket(models.Model): ...@@ -101,14 +94,7 @@ class HelpdeskTicket(models.Model):
self.team_id = self.env['helpdesk.team'].search([('helpdesk_ticket_type_id','=',self.ticket_type.id)]).id self.team_id = self.env['helpdesk.team'].search([('helpdesk_ticket_type_id','=',self.ticket_type.id)]).id
elif self.team_id and self.ticket_type: elif self.team_id and self.ticket_type:
self.team_id = self.env['helpdesk.team'].search([('helpdesk_ticket_type_id','=',self.ticket_type.id)]).id self.team_id = self.env['helpdesk.team'].search([('helpdesk_ticket_type_id','=',self.ticket_type.id)]).id
@api.onchange('not_super')
def onchange_ticket_id_value(self):
if self.ticket_id:
self.ticket_id = False
@api.onchange('partner_id') @api.onchange('partner_id')
def onchange_partner_simple_info(self): def onchange_partner_simple_info(self):
...@@ -175,8 +161,7 @@ class HelpdeskTicket(models.Model): ...@@ -175,8 +161,7 @@ class HelpdeskTicket(models.Model):
vals['stage_id'] = company_id.new_stage_id.id vals['stage_id'] = company_id.new_stage_id.id
vals['color'] = 10 vals['color'] = 10
#if res.team_id.sequence_id:
# res.name =
res = super(HelpdeskTicket, self).create(vals) res = super(HelpdeskTicket, self).create(vals)
if res.sh_sla_status_ids: if res.sh_sla_status_ids:
...@@ -316,7 +301,6 @@ class HelpdeskTicket(models.Model): ...@@ -316,7 +301,6 @@ class HelpdeskTicket(models.Model):
self.env['sh.helpdesk.ticket.stage.info'].sudo().create(stage_history) self.env['sh.helpdesk.ticket.stage.info'].sudo().create(stage_history)
def append_sla_policies(self): def append_sla_policies(self):
sla = self.env['sh.helpdesk.sla'].search([ sla = self.env['sh.helpdesk.sla'].search([
('sh_team_id','=',self.team_id.id), ('sh_team_id','=',self.team_id.id),
...@@ -329,9 +313,6 @@ class HelpdeskTicket(models.Model): ...@@ -329,9 +313,6 @@ class HelpdeskTicket(models.Model):
'sh_sla_policy_ids':[(6,0,sla)] 'sh_sla_policy_ids':[(6,0,sla)]
}) })
def write(self,vals): def write(self,vals):
if "stage_id" in vals: if "stage_id" in vals:
if self.description == '<p><br></p>' or self.description==False: if self.description == '<p><br></p>' or self.description==False:
...@@ -343,16 +324,12 @@ class HelpdeskTicket(models.Model): ...@@ -343,16 +324,12 @@ class HelpdeskTicket(models.Model):
return super(HelpdeskTicket, self).write(vals) return super(HelpdeskTicket, self).write(vals)
def action_approve(self): def action_approve(self):
if self.description == '<p><br></p>' or self.description==False: if self.description == '<p><br></p>' or self.description==False:
raise ValidationError (_("Para cambiar de etapa, es necesario agregar una descripción")) raise ValidationError (_("Para cambiar de etapa, es necesario agregar una descripción"))
else: else:
return super(HelpdeskTicket, self).action_approve() return super(HelpdeskTicket, self).action_approve()
...@@ -6,6 +6,7 @@ class RegionHelpdesk(models.Model): ...@@ -6,6 +6,7 @@ class RegionHelpdesk(models.Model):
_rec_name = 'name' _rec_name = 'name'
name = fields.Char('Nombre') name = fields.Char('Nombre')
warehouse_ids = fields.One2many('warehouse.helpdesk','region_id',string="Sucursales")
\ No newline at end of file
...@@ -6,5 +6,5 @@ class WarehouseHelpdesk(models.Model): ...@@ -6,5 +6,5 @@ class WarehouseHelpdesk(models.Model):
_rec_name = "name" _rec_name = "name"
name = fields.Char('Nombre') name = fields.Char('Nombre')
region_id = fields.Many2one('region.helpdesk','Región') region_id = fields.Many2one('region.helpdesk',string='Región')
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="user_ti" model="res.groups">
<field name="category_id" ref="sh_all_in_one_helpdesk.module_helpdesk_category"/>
<field name="name">Usuario de TI</field>
<field name="implied_ids" eval="[(6,0,[ref('sh_all_in_one_helpdesk.helpdesk_group_user')])]"/>
</record>
<record id="only_see_ti" model="ir.rule">
<field name="name">Ver tickets de TI</field>
<field name="model_id" ref="sh_all_in_one_helpdesk.model_helpdesk_ticket"/>
<field name="groups" eval="[(6,0,[ref('user_ti')])]"/>
<field name="perm_read" eval="1"/>
<field name="perm_write" eval="1"/>
<field name="perm_create" eval="1"/>
<field name="perm_unlink" eval="0"/>
<field name="domain_force">
[('team_id','in',[ref('helpdesk_morsa.techinnical_support'),ref('helpdesk_morsa.erp_asistense'),ref('helpdesk_morsa.ti_emergency')])]
</field>
</record>
</data>
</odoo>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data> <data>
<record model="ir.ui.view" id="helpdesk_ticket_morsa_inherit"> <record model="ir.ui.view" id="helpdesk_ticket_morsa_inherit">
<field name="name">helpdesk.ticket.form.inherit</field> <field name="name">helpdesk.ticket.form.inherit</field>
<field name="model">helpdesk.ticket</field> <field name="model">helpdesk.ticket</field>
<field name="inherit_id" ref="sh_all_in_one_helpdesk.helpdesk_ticket_form_view"/> <field name="inherit_id" ref="sh_all_in_one_helpdesk.helpdesk_ticket_form_view"/>
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
<field name="warehouse_id" attrs="{'invisible':[('is_erp', '=', False)]}"/> <field name="warehouse_id" attrs="{'invisible':[('is_erp', '=', False)]}"/>
<field name="incidence_type" attrs="{'invisible':[('is_emergency', '=', False)]}"/> <field name="incidence_type" attrs="{'invisible':[('is_emergency', '=', False)]}"/>
</xpath> </xpath>
<xpath expr="//header" position="replace"> <xpath expr="//header" position="replace">
<header> <header>
<button name="assign_me" type="object" string="Assignar a mi" class="oe_highlight" /> <button name="assign_me" type="object" string="Assignar a mi" class="oe_highlight" />
<button name="action_approve" type="object" string="Siguiente etapa" class="oe_highlight" attrs="{'invisible':['|','|',('cancel_stage_boolean','=',True),('done_stage_boolean','=',True),('closed_stage_boolean','=',True)]}"/> <button name="action_approve" type="object" string="Siguiente etapa" class="oe_highlight" attrs="{'invisible':['|',('cancel_stage_boolean','=',True),'|',('done_stage_boolean','=',True),('closed_stage_boolean','=',True)]}"/>
<button name="action_reply" type="object" string="Respuesta" class="oe_highlight"/> <button name="action_reply" type="object" string="Respuesta" class="oe_highlight"/>
<button name="action_done" type="object" string="Resolver Ticket" class="oe_highlight" attrs="{'invisible':[('done_button_boolean','=',False)]}"/> <button name="action_done" type="object" string="Resolver Ticket" class="oe_highlight" attrs="{'invisible':[('done_button_boolean','=',False)]}"/>
<button name="action_closed" type="object" string="Cerrar Ticket" class="oe_highlight" attrs="{'invisible':[('done_stage_boolean','=',False)]}"/> <button name="action_closed" type="object" string="Cerrar Ticket" class="oe_highlight" attrs="{'invisible':[('done_stage_boolean','=',False)]}"/>
...@@ -53,10 +53,10 @@ ...@@ -53,10 +53,10 @@
<field name="begin_before_ten_min"/> <field name="begin_before_ten_min"/>
</xpath> </xpath>
<xpath expr="//field[@name='sub_category_id']" position="after"> <xpath expr="//field[@name='sub_category_id']" position="after">
<field name="ticket_reason"/> <field name="ticket_reason" attrs="{'invisible':['|'('is_support', '=', False),'|',('is_erp', '=', False),('is_emergency', '=', False)]}"/>
</xpath> </xpath>
<xpath expr="//field[@name='partner_id']" position="after"> <xpath expr="//field[@name='partner_id']" position="after">
<field name="user_branch_id" force_save="1" readonly="1"/> <field name="user_branch_id"/>
</xpath> </xpath>
</field> </field>
</record> </record>
......
...@@ -171,8 +171,8 @@ ...@@ -171,8 +171,8 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="mb-3 col-6"> <div class="col-6">
<div class="row"> <div class="row mb-3 ">
<div class="col-6"> <div class="col-6">
<strong>Fecha de cancelación:</strong> <strong>Fecha de cancelación:</strong>
</div> </div>
...@@ -181,8 +181,8 @@ ...@@ -181,8 +181,8 @@
</div> </div>
</div> </div>
</div> </div>
<div class="mb-3 col-6"> <div class=" col-6">
<div class="row"> <div class="row mb-3 ">
<div class="col-6"> <div class="col-6">
<strong>Cancelado por:</strong> <strong>Cancelado por:</strong>
</div> </div>
...@@ -194,7 +194,7 @@ ...@@ -194,7 +194,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="mb-3 col-6"> <div class="mb-3 col-6">
<div class="row"> <div class="row mb-3 ">
<div class="col-6"> <div class="col-6">
<strong>Estado:</strong> <strong>Estado:</strong>
</div> </div>
...@@ -204,7 +204,7 @@ ...@@ -204,7 +204,7 @@
</div> </div>
</div> </div>
<div class="mb-3 col-6"> <div class="mb-3 col-6">
<div class="row"> <div class="row mb-3 ">
<div class="col-6"> <div class="col-6">
<strong>Razón de cancelación:</strong> <strong>Razón de cancelación:</strong>
</div> </div>
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
<xpath expr="//div[@t-attf-class='col-12 col-md col-lg-6']" position="attributes"> <xpath expr="//div[@t-attf-class='col-12 col-md col-lg-6']" position="attributes">
<attribute name="t-attf-class">col-lg-10 col-md-12 col-sm-12</attribute> <attribute name="t-attf-class">col-lg-10 col-md-12 col-sm-12</attribute>
</xpath> </xpath>
<xpath expr="//div[@class='row align-items-center bg-white no-gutters border rounded']" position="attributes">
<attribute name="class">row align-items-center bg-white no-gutters border navbar-rounded</attribute>
</xpath>
</template> </template>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment