Skip to content

Commit

Permalink
[ADD] connector_carepoint: Patient & Address export logic
Browse files Browse the repository at this point in the history
* Improve existing patient export
* Add tests for patient importer/exporter
* Add abstract address export logic
* Add patient address export logic
  • Loading branch information
lasley committed Sep 13, 2016
1 parent 4aa77e6 commit 517ba1a
Show file tree
Hide file tree
Showing 9 changed files with 391 additions and 32 deletions.
8 changes: 6 additions & 2 deletions connector_carepoint/consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ def delay_export(session, model_name, record_id, vals):
export_record.delay(session, model_name, record_id, fields=fields)


@on_record_write(model_names=['carepoint.address',
@on_record_write(model_names=['medical.patient',
'carepoint.address',
'carepoint.address.patient',
])
def delay_export_all_bindings(session, model_name, record_id, vals):
""" Delay a job which export all the bindings of a record.
Expand All @@ -47,7 +49,9 @@ def delay_export_all_bindings(session, model_name, record_id, vals):
fields=fields)


@on_record_create(model_names=['carepoint.address',
@on_record_create(model_names=['medical.patient',
'carepoint.address',
'carepoint.address.patient',
])
def delay_create(session, model_name, record_id, vals):
""" Create a new binding record, then trigger delayed export
Expand Down
40 changes: 30 additions & 10 deletions connector_carepoint/models/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from openerp.addons.connector.connector import ConnectorUnit
from openerp.addons.connector.unit.mapper import (mapping,
changed_by,
ExportMapper
)
from ..unit.backend_adapter import CarepointCRUDAdapter
Expand All @@ -16,8 +17,7 @@
from ..unit.import_synchronizer import (DelayedBatchImporter,
CarepointImporter,
)
from ..unit.export_synchronizer import (CarepointExporter)
from ..unit.delete_synchronizer import (CarepointDeleter)
from ..unit.export_synchronizer import CarepointExporter


_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -99,9 +99,11 @@ def _get_partner_sync_vals(self, partner):
"""
vals = {}
for attr in self.PARTNER_ATTRS:
val = getattr(partner, attr, None)
if getattr(val, 'id', None):
val = getattr(partner, attr, False)
if getattr(val, 'id', False):
val = val.id
if not val:
val = False
vals[attr] = val
return vals

Expand Down Expand Up @@ -179,10 +181,33 @@ class CarepointAddressExportMapper(ExportMapper):

direct = [
('street', 'addr1'),
('email', 'addr2'),
('street2', 'addr2'),
('city', 'city'),
]

@mapping
@changed_by('state_id')
def state_cd(self, record):
return {'state_cd': record.state_id.code}

@mapping
@changed_by('zip')
def zip_and_plus_four(self, record):
if not record.zip:
return
_zip = record.zip.replace('-', '')
if len(_zip) > 5:
return {
'zip': _zip[0:5],
'zip_plus4': _zip[5:],
}
return {'zip': _zip}

@mapping
@changed_by('country_id')
def country_cd(self, record):
return {'country_cd': record.country_id.code}

@mapping
def addr_id(self, record):
return {'addr_id': record.carepoint_id}
Expand All @@ -192,8 +217,3 @@ def addr_id(self, record):
class CarepointAddressExporter(CarepointExporter):
_model_name = ['carepoint.carepoint.address']
_base_mapper = CarepointAddressExportMapper


@carepoint
class CarepointAddressDeleteSynchronizer(CarepointDeleter):
_model_name = ['carepoint.carepoint.address']
75 changes: 75 additions & 0 deletions connector_carepoint/models/address_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,35 @@ class CarepointAddressAbstract(models.AbstractModel):
string='Partner',
comodel_name='res.partner',
required=True,
store=True,
compute='_compute_partner_id',
inverse='_set_partner_id',
)
res_model = fields.Char(
string='Resource Model',
default=lambda s: s._default_res_model(),
)
res_id = fields.Integer(
string='Resource PK',
compute='_compute_res_id',
store=True,
)

@property
@api.multi
def medical_entity_id(self):
self.ensure_one()
return self.env[self.res_model].browse(self.res_id)

@api.model
def _default_res_model(self):
""" It returns the res model. Should be overloaded in children """
raise NotImplementedError(
_('_default_res_model should be implemented in child classes')
)

@api.multi
@api.depends('partner_id')
def _compute_partner_id(self):
""" It sets the partner_id from the address_id """
for rec_id in self:
Expand Down Expand Up @@ -73,6 +97,44 @@ def _set_partner_id(self):
else:
rec_id.address_id.write(vals)

@api.multi
@api.depends('partner_id', 'res_model')
def _compute_res_id(self):
""" It computes the resource ID from model """
for rec_id in self:
if not all([rec_id.res_model, rec_id.partner_id]):
continue
medical_entity = self.env[rec_id.res_model].search([
('partner_id', '=', rec_id.partner_id.id),
],
limit=1,
)
rec_id.res_id = medical_entity.id

@api.model
def _get_by_partner(self, partner, create=True, recurse=False):
""" It returns the address associated to the partner.
Params:
partner: Recordset singleton of partner to search for
create: Bool determining whether to create address if not exist
recurse: Bool determining whether to recurse into children (this
is only really useful when create=True)
Return:
Recordset of partner address
"""
address = self.search([('partner_id', '=', partner.id)], limit=1)
vals = self.address_id._get_partner_sync_vals(partner)
_logger.info('_get_by_partner %s, %s, %s' % (address, partner, vals))
if not address and create:
vals['partner_id'] = partner.id
address = self.create(vals)
else:
address.write(vals)
if recurse:
for child in partner.child_ids:
self._get_by_partner(child, create, recurse)
return address


@carepoint
class CarepointAddressAbstractImportMapper(CarepointImportMapper):
Expand Down Expand Up @@ -118,6 +180,19 @@ def partner_id(self, record, medical_entity):
partner = self.env['res.partner'].create(vals)
return {'partner_id': partner.id}

def res_model_and_id(self, record, medical_entity):
""" It returns the vals dict for res_model and res_id
Params:
record: ``dict`` of carepoint record
medical_entity: Recordset with a ``partner_id`` column
Return:
``dict`` of values for mapping
"""
return {
'res_id': medical_entity.id,
'res_model': medical_entity._name,
}

@mapping
@only_create
def address_id(self, record):
Expand Down
40 changes: 39 additions & 1 deletion connector_carepoint/models/address_patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import logging
from openerp import models, fields
from openerp import models, fields, api
from openerp.addons.connector.connector import ConnectorUnit
from openerp.addons.connector.unit.mapper import (mapping,
only_create,
Expand All @@ -14,6 +14,8 @@

from .address_abstract import (CarepointAddressAbstractImportMapper,
CarepointAddressAbstractImporter,
CarepointAddressAbstractExportMapper,
CarepointAddressAbstractExporter,
)

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -49,6 +51,11 @@ class CarepointAddressPatient(models.Model):
string='Carepoint Bindings',
)

@api.model
def _default_res_model(self):
""" It returns the res model. """
return 'medical.patient'


@carepoint
class CarepointAddressPatientAdapter(CarepointCRUDAdapter):
Expand Down Expand Up @@ -81,6 +88,16 @@ def partner_id(self, record):
record, patient_id,
)

@mapping
@only_create
def res_model_and_id(self, record):
binder = self.binder_for('carepoint.medical.patient')
patient_id = binder.to_odoo(record['pat_id'], browse=True)
_sup = super(CarepointAddressPatientImportMapper, self)
return _sup.res_model_and_id(
record, patient_id,
)

@mapping
def carepoint_id(self, record):
return {'carepoint_id': '%d,%d' % (record['pat_id'],
Expand Down Expand Up @@ -111,3 +128,24 @@ def _import_addresses(self, patient_id, partner_binding):
address_ids = adapter.search(pat_id=patient_id)
for address_id in address_ids:
importer.run(address_id)


@carepoint
class CarepointAddressPatientExportMapper(
CarepointAddressAbstractExportMapper
):
_model_name = 'carepoint.carepoint.address.patient'

@mapping
def pat_id(self, binding):
binder = self.binder_for('carepoint.medical.patient')
rec_id = binder.to_backend(binding.res_id)
return {'pat_id': rec_id}


@carepoint
class CarepointAddressPatientExporter(
CarepointAddressAbstractExporter
):
_model_name = 'carepoint.carepoint.address.patient'
_base_mapper = CarepointAddressPatientExportMapper
38 changes: 32 additions & 6 deletions connector_carepoint/models/medical_patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from ..unit.import_synchronizer import (DelayedBatchImporter,
CarepointImporter,
)
from ..unit.export_synchronizer import (CarepointExporter)
from ..unit.export_synchronizer import CarepointExporter

from .address_patient import CarepointAddressPatientUnit

Expand Down Expand Up @@ -76,8 +76,13 @@ class MedicalPatientImportMapper(PersonImportMapper):
(trim('email'), 'email'),
('birth_date', 'dob'),
('death_date', 'dod'),
('pat_status_cn', 'active'),
]

@mapping
def safety_cap_yn(self, record):
return {'safety_caps_yn': not record['no_safety_caps_yn']}

@mapping
def gender(self, record):
gender = record.get('gender_cd')
Expand Down Expand Up @@ -124,19 +129,40 @@ class MedicalPatientExportMapper(PersonExportMapper):
('email', 'email'),
('dob', 'birth_date'),
('dod', 'death_date'),
('active', 'pat_status_cn')
]

@mapping
def pat_id(self, record):
return {'pat_id': record.carepoint_id}

@mapping
@changed_by('gender')
def gender_cd(self, record):
return {'gender_cd': record.get('gender').upper()}
if record.gender:
return {'gender_cd': record.gender.upper()}

@mapping
def static_defaults(self, record):
""" It provides all static default mappings """
return {
'pat_type_cn': 1,
'bad_check_yn': 0,
'app_flags': 0,
'comp_cn': 0,
'status_cn': 0,
}

@mapping
@changed_by('safety_cap_yn')
def no_safety_caps_yn(self, record):
return {'no_safety_caps_yn': not record.safety_cap_yn}


@carepoint
class MedicalPatientExporter(CarepointExporter):
_model_name = ['carepoint.medical.patient']
_base_mapper = MedicalPatientExportMapper

def _after_export(self):
self.env['carepoint.address.patient']._get_by_partner(
self.binding_record.commercial_partner_id,
create=True,
recurse=True,
)
1 change: 1 addition & 0 deletions connector_carepoint/tests/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@
from . import test_address_patient
from . import test_address_store
from . import test_address_organization
from . import test_medical_patient
32 changes: 29 additions & 3 deletions connector_carepoint/tests/models/test_address_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ def new_address(self, partner=None):
return self.env['carepoint.address'].create(vals)

def new_patient_address(self):
patient = self.new_patient()
self.address = self.new_address(patient.partner_id)
self.patient = self.new_patient()
self.address = self.new_address(self.patient.partner_id)
return self.model.create({
'partner_id': patient.partner_id,
'partner_id': self.patient.partner_id.id,
'address_id': self.address.id,
'res_model': 'medical.patient',
})

def test_compute_partner_id(self):
Expand Down Expand Up @@ -94,6 +95,21 @@ def test_set_partner_id_with_address(self):
address.street,
)

def test_medical_entity_id(self):
""" It should return patient record """
address = self.new_patient_address()
self.assertEqual(
self.patient,
address.medical_entity_id,
)

def test_compute_res_id(self):
address = self.new_patient_address()
self.assertEqual(
self.patient.id,
address.res_id,
)


class TestAddressAbstractImportMapper(AddressAbstractTestBase):

Expand Down Expand Up @@ -172,6 +188,16 @@ def test_address_id_return(self):
expect = self.unit.binder_for().to_odoo()
self.assertDictEqual({'address_id': expect}, res)

def test_res_model_and_id(self):
""" It should return values dict for medical entity """
entity = mock.MagicMock()
expect = {
'res_id': entity.id,
'res_model': entity._name,
}
res = self.unit.res_model_and_id(None, entity)
self.assertDictEqual(expect, res)


class TestAddressAbstractImporter(AddressAbstractTestBase):

Expand Down
Loading

0 comments on commit 517ba1a

Please sign in to comment.