# 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 __all__ = ['CustomerService', 'RegionDepartment', 'ReceiverService', 'DepartmentEmail', 'HealthProvider'] STATES = { 'readonly': (Eval('state') != 'draft'), } NEW_MEDIA = new_sel = [ ('', ''), ('sede', 'Sede'), ('web', 'Web'), ('supersalud', 'Supersalud'), ] 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') 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')) ]) 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') @classmethod def __setup__(cls): super(CustomerService, cls).__setup__() cls.party.required = True cls.media.readonly = False 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 != 'supersalud': 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: 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): self.raise_user_error('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, data): report_context = super(FiduprevisoraReport, cls).get_context(records, 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') media = fields.Selection(NEW_MEDIA, 'Media')