trytonpsk-crm_fiduprevisora/customer_service.py

528 lines
19 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from __future__ import with_statement
from datetime import datetime, timedelta, time
from trytond.model import Workflow, ModelView, ModelSQL, fields
from trytond.pyson import Eval, If, In, Get, Or, Bool, Not
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from trytond.wizard import Wizard, StateView, Button, StateReport, StateTransition
from trytond.report import Report
from .exceptions import MessageUserError
STATES = {
'readonly': (Eval('state') != 'draft'),
}
NEW_MEDIA = new_sel = [
('', ''),
('sede', 'Sede'),
('web', 'Web'),
('supersalud', 'Supersalud'),
]
CLASSIFICATION = new_sel = [
('', ''),
('riesgo_vida', 'Riesgo de Vida'),
('regular', 'Regular'),
]
class ReceiverService(ModelSQL, ModelView):
'Receicer Service'
__name__ = 'crm.receiver_service'
_rec_name = 'name'
name = fields.Char('Name', required=True)
# email = fields.Char('Email', required=True)
emails = fields.One2Many('crm.receiver_service.email',
'receiver', 'Emails')
def get_rec_name(self, name):
self._rec_name = self.name
return (self._rec_name)
@classmethod
def search_rec_name(cls, name, clause):
if clause[1].startswith('!') or clause[1].startswith('not '):
bool_op = 'AND'
else:
bool_op = 'OR'
return [bool_op,
('name',) + tuple(clause[1:]),
]
class ReceiverEmail(ModelSQL, ModelView):
'Receiver - Emails'
__name__ = 'crm.receiver_service.email'
receiver = fields.Many2One('crm.receiver_service', 'Receiver', required=True)
email = fields.Char('Email')
class HealthProvider(ModelSQL, ModelView):
'Health Provider'
__name__ = 'crm.health_provider'
_rec_name = 'party'
name = fields.Function(fields.Char('Name'), 'get_rec_name')
party = fields.Many2One('party.party', 'Party')
city = fields.Many2One('party.city_code', 'City')
asset = fields.Boolean('Asset', help="¡Check this if the provider is active!")
def get_rec_name(self, name):
self._rec_name = self.party.name
return (self._rec_name)
@classmethod
def search_rec_name(cls, name, clause):
if clause[1].startswith('!') or clause[1].startswith('not '):
bool_op = 'AND'
else:
bool_op = 'OR'
return [bool_op,
('party.name',) + tuple(clause[1:]),
]
class CustomerService(metaclass=PoolMeta):
__name__ = 'crm.customer_service'
receiver = fields.Many2One('crm.receiver_service', 'Receiver', states={
'required': (Eval('state') == 'open'),
})
region = fields.Many2One('crm.region_fiduprevisora', 'Region')
department_region = fields.Many2One('party.department_code', 'Department', domain=[
('region', '=', Eval('region'))
])
city_region = fields.Many2One('party.city_code', 'City', depends=['party'],
# domain=[
# ('department', '=', Eval('department_region'))
# ]
)
other_city = fields.Char('Other City', states={
'required': (Not(Bool(Eval('city_region')))),
'invisible': (Bool(Eval('city_region'))),
})
health_provider = fields.Many2One('crm.health_provider', 'Health Provider', domain=[
('city', '=', Eval('city_region')),
('asset', '=', True)
])
id_document = fields.Char('Document')
email = fields.Char('Email')
sended_mail = fields.Boolean('Sended Email')
attach_customer_1 = fields.Char('Attach Customer Web...', readonly=True)
attach_customer_2 = fields.Char('Attach Customer Web...', readonly=True)
attachments = fields.One2Many('crm.fiduprevisora.attachments',
'service', 'Attachments')
others_receivers = fields.One2Many('crm.customer_receiver',
'customer_service', 'Receivers')
others_receivers_string = fields.Function(fields.Char('Others Receicers'),
'get_others_receivers_string')
classification = fields.Selection(CLASSIFICATION, 'Classification', states={
'required': (Eval('media') == 'supersalud'),
'invisible': (Eval('media') != 'supersalud'),
})
@classmethod
def __setup__(cls):
super(CustomerService, cls).__setup__()
cls.party.required = True
cls.media.states = {
'readonly': (Eval('state') == 'cancelled'),
}
if new_sel not in cls.media.selection:
cls.media.selection = NEW_MEDIA
cls._buttons.update({
'send_email': {
'invisible': Or(
Eval('state') != 'open',
Bool(Eval('sended_mail')),
)},
})
cls._error_messages.update({
'message': '%s',
})
@classmethod
@ModelView.button
def send_email(cls, records):
for service in records:
if not service.response:
service.get_message('Debe existir una respuesta.')
config = Pool().get('crm.configuration')(1)
template = config.response_mail_template
if not template:
service.get_message('No se ha definido una plantilla para el envío del correo.')
_attachments = []
if service.attachments:
for att in service.attachments:
q = str(att.attach_response)[1:10]
ext_ = service.get_extension(q)
_attachments.append({
'attachment': att.attach_response,
'file_name': 'Respuesta',
'extension': ext_,
})
service.send_email_customer(template, _attachments)
service.send_emails_receivers(template, _attachments)
@staticmethod
def default_region():
Configuration = Pool().get('crm.configuration')
config = Configuration(1)
if config and config.region_defect:
return config.region_defect.id
@fields.depends('party', 'address', 'phone')
def on_change_party(self):
super(CustomerService, self).on_change_party()
if self.party:
self.email = self.party.email
self.phone = self.party.phone
self.address = self.party.street
if self.party.city_attention:
self.city_region = self.party.city_attention.id
self.department_region = self.party.city_attention.department.id
@fields.depends('effective_date', 'response')
def on_change_with_effective_date(self):
if self.response:
return datetime.now()
@classmethod
def create(cls, services):
services = super(CustomerService, cls).create(services)
for service in services:
if not service.department_region and service.city_region:
cls.write([service], {'department_region': service.city_region.department})
return services
@classmethod
@ModelView.button
@Workflow.transition('open')
def open(cls, services):
if not services:
return
res = cls.validate_service(services)
service = services[0]
if res['status'] == 'success':
super(CustomerService, cls).open(services)
if service.email or service.party.email:
service.send_email_notification(
service.email or service.party.email
)
service.send_emails_department()
else:
cls.write([service], {'state': 'cancelled', 'notes': res['msg']})
if service.media == 'web':
res['customer'] = service.party.name
res['media'] = 'web'
res['city_region'] = {
'id': service.party.city_attention.id,
'name': service.party.city_attention.name,
}
return res
@classmethod
def validate_service(cls, services):
res = {
'status': 'success',
'msg': 'Requerimiento enviado satifactoriamente !!',
}
if not services:
return res
service = services[0]
if service.party and service.party.affiliation_state == 'retirado':
message = 'El proceso no se pudo completar, el usuario: ' + service.party.name + ' Se encuentra en estado retirado'
res['status'] = 'error'
res['msg'] = message
if service.media != 'web':
service.get_message(message)
return res
if service.media == 'web':
Attachment = Pool().get('ir.attachment')
attachments = Attachment.search([
('resource', '=', 'crm.customer_service,' + str(service.id))
])
attach = attachments or service.attach_customer_1 or service.attach_customer_2 or None
if service.case.required_attach and not attach:
message = 'El proceso no se pudo completar, por favor adjuntar: \n' + \
service.case.attach_description
res['status'] = 'info'
res['msg'] = message
if service.media != 'web':
service.get_message(message)
return res
date_ = service.cs_date - timedelta(days=30)
services_ = cls.search([
('id', '!=', service.id),
('cs_date', '>=', date_),
('case', '=', service.case.id),
('party.id_number', '=', service.party.id_number),
('state', '=', 'open'),
])
if services_:
message = 'El proceso no se pudo completar, ya existe un PQR para el usuario:' + \
service.party.name + ' con el caso: ' + service.case.name + ' en los últimos 30 días '
res['status'] = 'error'
res['msg'] = message
if service.media != 'web':
service.get_message(message)
return res
def get_others_receivers_string(self, name):
string_ = ''
for r in self.others_receivers:
if r.receiver:
string_ += r.receiver.name + ' /n'
return string_
def get_extension(self, string_):
ext_ = ''
if string_.find('PDF') > 0:
ext_ = 'PDF'
elif string_.find('PNG') > 0:
ext_ = 'PNG'
elif string_.find('JPEG') > 0:
ext_ = 'JPEG'
elif string_.find('JPG') > 0:
ext_ = 'JPG'
elif string_.find('DOC') > 0:
ext_ = 'DOC'
elif string_.find('ODS') > 0:
ext_ = 'ODS'
elif string_.find('ODT') > 0:
ext_ = 'ODT'
return ext_
def send_email_customer(self, template, attachments=[]):
if self.department_region and self.department_region.emails:
dmt_email = self.department_region.emails[0].email
template.from_email = dmt_email
template.subject = template.subject + self.company.party.name
if attachments:
response = self._send_mails(template, self, self.email or self.party.email, True, attachments)
else:
response = self._send_mails(template, self, self.email or self.party.email, False, [])
if response.status_code == 202:
self.write([self], {'sended_mail': True})
else:
self.get_message('Error de Envío.')
def send_email_notification(self, email):
pool = Pool()
Template = pool.get('email.template')
config = pool.get('crm.configuration')(1)
template = config.notification_mail_template
if template:
attach_dict = {}
template.subject = template.subject + self.company.party.name
response = Template.send(template, self, email,
attach=False, attachments=[])
if not response or response.status_code != 202:
print(email)
self.write({self}, {'notes': 'Fallo envio al correo: ' + email})
def send_emails_department(self):
if self.department_region:
for email in self.department_region.emails:
self.send_email_notification(email.email)
def send_emails_receivers(self, template, attachments=[]):
attach = False
if attachments:
attach= True
template.subject = template.subject + self.company.party.name
if self.department_region and self.department_region.emails:
dmt_email = self.department_region.emails[0].email
template.from_email = dmt_email
if self.receiver:
for email in self.receiver.emails:
response = self._send_mails(template, self, email.email, attach, attachments)
if response.status_code != 202:
self.write({self}, {'notes': 'Fallo envio al correo: ' + email})
for rec in self.others_receivers:
for email in rec.receiver.emails:
response = self._send_mails(template, self, email.email, attach, attachments)
if response.status_code != 202:
self.write({self}, {'notes': 'Fallo envio al correo: ' + email})
def _send_mails(self, template, crm, email, attach, attachments):
Template = Pool().get('email.template')
response = Template.send(template, crm, email,
attach=attach, attachments=attachments)
return response
def get_message(self, message):
raise MessageUserError('message', message)
@classmethod
def dash_on_change_user(cls, args, ctx):
if not args.get('party'):
return {}
Party = Pool().get('party.party')
parties = Party.browse([args['party']['id']])
if not parties:
return {}
res = {
'customer': parties[0].name,
'media': 'web',
'city_region': {
'id': parties[0].city_attention.id,
'name': parties[0].city_attention.name,
},
'state': 'draft',
}
return res
class FiduprevisoraAttachments(ModelSQL, ModelView):
'Fiduprevisora - Attachments'
__name__ = 'crm.fiduprevisora.attachments'
service = fields.Many2One('crm.customer_service', 'Service', required=True)
attach_response = fields.Binary('Attach Response', required=True)
class FiduprevisoraReportStart(ModelView):
'Fiduprevisora Report Start'
__name__ = 'crm_fiduprevisora.fiduprevisora_report.start'
company = fields.Many2One('company.company', 'Company', required=True)
start_date = fields.Date('Start Date')
end_date = fields.Date('End Date')
party = fields.Many2One('party.party', 'Party')
region = fields.Many2One('crm.region_fiduprevisora', 'Region')
receiver_service = fields.Many2One('crm.receiver_service', 'Receiver')
department_region = fields.Many2One('party.department_code', 'Department', domain=[
('region', '=', Eval('region'))
])
city_region = fields.Many2One('party.city_code', 'City', domain=[
('department', '=', Eval('department_region'))
])
@staticmethod
def default_company():
return Transaction().context.get('company')
@staticmethod
def default_region():
Configuration = Pool().get('crm.configuration')
config = Configuration(1)
if config and config.region_defect:
return config.region_defect.id
@staticmethod
def default_end():
Date = Pool().get('ir.date')
return Date.today()
class FiduprevisoraReportWizard(Wizard):
'Fiduprevisora Report Wizard'
__name__ = 'crm_fiduprevisora.fiduprevisora_report.wizard'
start = StateView('crm_fiduprevisora.fiduprevisora_report.start',
'crm_fiduprevisora.fiduprevisora_report_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-ok', default=True),
])
print_ = StateReport('crm_fiduprevisora.fiduprevisora_report')
def do_print_(self, action):
party_id = self.start.party.id if self.start.party else None
region_id = self.start.region.id if self.start.region else None
department_id = self.start.department_region.id if self.start.department_region else None
city_id = self.start.city_region.id if self.start.city_region else None
receiver_service_id = self.start.receiver_service.id if self.start.receiver_service else None
data = {
'company': self.start.company.id,
'start_date': self.start.start_date,
'end_date': self.start.end_date,
'party': party_id,
'region': region_id,
'department': department_id,
'city': city_id,
'receiver_service': receiver_service_id,
}
return action, data
def transition_print_(self):
return 'end'
class FiduprevisoraReport(Report):
'Fiduprevisora Report'
__name__ = 'crm_fiduprevisora.fiduprevisora_report'
@classmethod
def get_context(cls, records, header, data):
report_context = super(FiduprevisoraReport, cls).get_context(records, header, data)
pool = Pool()
Company = pool.get('company.company')
Service = pool.get('crm.customer_service')
company = Company(data['company'])
start_date = data['start_date']
end_date = data['end_date']
party = data['party']
region = data['region']
receiver_service = data['receiver_service']
department_region = data['department']
city_region = data['city']
records = {}
dom_service = [
('company', '=', data['company']),
('state', '!=', 'cancelled'),
]
if start_date:
start_date = datetime.combine(start_date, time(0,0))
dom_service.append(
('cs_date', '>=', start_date),
)
if end_date:
end_date = datetime.combine(end_date, time(23,59))
dom_service.append(
('cs_date', '<=', end_date),
)
if party:
dom_service.append(
('party', '=', party),
)
if region:
dom_service.append(
('region', '=', region),
)
if receiver_service:
dom_service.append(
('receiver', '=', receiver_service),
)
if department_region:
dom_service.append(
('department_region', '=', department_region),
)
if city_region:
dom_service.append(
('city_region', '=', city_region),
)
services = Service.search(dom_service)
report_context['records'] = services
report_context['start_date'] = start_date
report_context['end_date'] = end_date
report_context['company'] = company.party.name
return report_context
class CustomerReceiver(ModelSQL, ModelView):
'Customer Receiver'
__name__ = 'crm.customer_receiver'
customer_service = fields.Many2One('crm.customer_service', 'Customer Service', required=True)
receiver = fields.Many2One('crm.receiver_service', 'Receiver', required=True)
media = fields.Selection(NEW_MEDIA, 'Media', required=True)