No known key found for this signature in database
GPG Key ID: 7DDBA4BA81B934CF
13 changed files with 430 additions and 0 deletions
-
69base_partner_validate_address/README.rst
-
6base_partner_validate_address/__init__.py
-
23base_partner_validate_address/__manifest__.py
-
7base_partner_validate_address/models/__init__.py
-
84base_partner_validate_address/models/address_validate.py
-
15base_partner_validate_address/models/res_company.py
-
12base_partner_validate_address/models/res_partner.py
-
2base_partner_validate_address/security/ir.model.access.csv
-
BINbase_partner_validate_address/static/description/icon.png
-
5base_partner_validate_address/wizards/__init__.py
-
123base_partner_validate_address/wizards/wizard_address_validate.py
-
83base_partner_validate_address/wizards/wizard_address_validate_view.xml
-
1oca_dependencies.txt
@ -0,0 +1,69 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-LGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/lgpl.html |
||||
|
:alt: License: LGPL-3 |
||||
|
|
||||
|
============================= |
||||
|
Base Partner Validate Address |
||||
|
============================= |
||||
|
|
||||
|
Adds an abstract core for address verification via remote interfaces. |
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
||||
|
:alt: Try me on Runbot |
||||
|
:target: https://runbot.odoo-community.org/runbot/149/10.0 |
||||
|
|
||||
|
Known Issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
Known Issues |
||||
|
------------ |
||||
|
|
||||
|
|
||||
|
Roadmap |
||||
|
------- |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues |
||||
|
<https://github.com/OCA/server-tools/issues>`_. In case of trouble, please |
||||
|
check there if your issue has already been reported. If you spotted it first, |
||||
|
help us smash it by providing detailed and welcomed feedback. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Images |
||||
|
------ |
||||
|
|
||||
|
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Dave Lasley <dave@laslabs.com> |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,6 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2016-2017 LasLabs Inc. |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
from . import models |
||||
|
from . import wizards |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2016-2017 LasLabs Inc. |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
{ |
||||
|
'name': 'Base Partner Validate Address', |
||||
|
'summary': 'Provides an abstract interface/adapter mechanism allowing ' |
||||
|
'for the unification of address verification providers.', |
||||
|
'version': '10.0.1.0.0', |
||||
|
'category': 'Extra Tools', |
||||
|
'website': 'https://laslabs.com/', |
||||
|
'author': 'LasLabs, Odoo Community Association (OCA)', |
||||
|
'license': 'LGPL-3', |
||||
|
'application': False, |
||||
|
'installable': True, |
||||
|
'depends': [ |
||||
|
'base_external_system', |
||||
|
], |
||||
|
'data': [ |
||||
|
'security/ir.model.access.csv', |
||||
|
'wizards/wizard_address_validate_view.xml', |
||||
|
], |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2016-2017 LasLabs Inc. |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
from . import address_validate |
||||
|
from . import res_company |
||||
|
from . import res_partner |
@ -0,0 +1,84 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class AddressValidate(models.Model): |
||||
|
"""Child modules should inherit this model to create new validators. |
||||
|
|
||||
|
In the ``_get_interface_types`` method, new interfaces should add |
||||
|
themselves:: |
||||
|
|
||||
|
@api.model |
||||
|
def _get_interface_types(self): |
||||
|
res = super()._get_interface_types() |
||||
|
return res + [('easypost', 'EasyPost')] |
||||
|
|
||||
|
The following methods must be implemented for each adapter, where |
||||
|
``<name>`` is equal to the interface name (``easypost`` in above): |
||||
|
|
||||
|
* ``<name>_get_client``: Return a usable API client for the |
||||
|
validator. |
||||
|
* ``<name>_test_connector``: Test the connection to the API, and |
||||
|
escalate to super if success. |
||||
|
* ``<name>_get_address``: Return the suggested address for a |
||||
|
partner using the API. It should accept an authenticated API |
||||
|
client as the first parameter and a ``res.partner`` singleton |
||||
|
as the second. |
||||
|
|
||||
|
If the remote system does not disconnect automatically, destruction can |
||||
|
be implemented in: |
||||
|
|
||||
|
* ``<name>_destroy_client``: Destroy the connection. It should accept |
||||
|
an instance of the client as returned by ``<name>_get_client``. |
||||
|
""" |
||||
|
|
||||
|
_name = 'address.validate' |
||||
|
_description = 'Address Validator Interface' |
||||
|
_inherit = 'external.system.adapter' |
||||
|
|
||||
|
interface_type = fields.Selection( |
||||
|
selection='_get_interface_types', |
||||
|
required=True, |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def _get_interface_types(self): |
||||
|
"""Child modules should add themselves to these selection values.""" |
||||
|
return [] |
||||
|
|
||||
|
@api.multi |
||||
|
def get_address(self, partner): |
||||
|
"""Returns an address suggestion from the interface. |
||||
|
|
||||
|
Args: |
||||
|
partner (ResPartner): Partner record to get address for. |
||||
|
|
||||
|
Returns: |
||||
|
dict: The suggested address. Should contain keys: ``street``, |
||||
|
``street2``, ``city``, ``state_id``, ``zip``, ``country_id``, |
||||
|
``is_valid``, and ``validation_messages``. |
||||
|
""" |
||||
|
self.ensure_one() |
||||
|
with self.interface.client() as client: |
||||
|
return self.__interface_method('get_address')(client, partner) |
||||
|
|
||||
|
@api.multi |
||||
|
def external_get_client(self): |
||||
|
return self.__interface_method('get_client')() |
||||
|
|
||||
|
@api.multi |
||||
|
def external_destroy_client(self, client): |
||||
|
try: |
||||
|
return self.__interface_method('destroy_client')(client) |
||||
|
except AttributeError: |
||||
|
pass |
||||
|
|
||||
|
@api.multi |
||||
|
def external_test_connector(self): |
||||
|
return self.__interface_method('test_connector')() |
||||
|
|
||||
|
def __interface_method(self, method_name): |
||||
|
return getattr(self, '%s_%s' % (self.interface_type, method_name)) |
@ -0,0 +1,15 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResCompany(models.Model): |
||||
|
_inherit = 'res.company' |
||||
|
|
||||
|
default_address_validate_id = fields.Many2one( |
||||
|
string='Default Address Validator', |
||||
|
comodel_name='address.validate', |
||||
|
domain="[('company_ids', 'in', id)]", |
||||
|
) |
@ -0,0 +1,12 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
latitude = fields.Float() |
||||
|
longitude = fields.Float() |
@ -0,0 +1,2 @@ |
|||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
||||
|
access_address_validate_admin,access_address_validate_admin,model_address_validate,base.group_system,1,1,1,1 |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,5 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2016-2017 LasLabs Inc. |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
from . import wizard_address_validate |
@ -0,0 +1,123 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class WizardAddressValidate(models.TransientModel): |
||||
|
_name = 'wizard.address.validate' |
||||
|
_description = 'Validate Address Wizard' |
||||
|
|
||||
|
partner_id = fields.Many2one( |
||||
|
string='Partner', |
||||
|
comodel_name='res.partner', |
||||
|
required=True, |
||||
|
default=lambda s: s._default_partner_id(), |
||||
|
) |
||||
|
interface_id = fields.Many2one( |
||||
|
string='Validation Interface', |
||||
|
comodel_name='address.validate', |
||||
|
default=lambda s: s._default_interface_id(), |
||||
|
) |
||||
|
street = fields.Char() |
||||
|
street2 = fields.Char() |
||||
|
city = fields.Char() |
||||
|
zip = fields.Char() |
||||
|
state_id = fields.Many2one( |
||||
|
string='State', |
||||
|
comodel_name='res.country.state', |
||||
|
) |
||||
|
country_id = fields.Many2one( |
||||
|
string='Country', |
||||
|
comodel_name='res.country', |
||||
|
) |
||||
|
latitude = fields.Float() |
||||
|
longitude = fields.Float() |
||||
|
is_valid = fields.Boolean() |
||||
|
validation_messages = fields.Text() |
||||
|
street_original = fields.Char( |
||||
|
related='partner_id.street', |
||||
|
readonly=True, |
||||
|
) |
||||
|
street2_original = fields.Char( |
||||
|
related='partner_id.street2', |
||||
|
readonly=True, |
||||
|
) |
||||
|
city_original = fields.Char( |
||||
|
related='partner_id.city', |
||||
|
readonly=True, |
||||
|
) |
||||
|
zip_original = fields.Char( |
||||
|
related='partner_id.zip', |
||||
|
readonly=True, |
||||
|
) |
||||
|
state_id_original = fields.Many2one( |
||||
|
string='State', |
||||
|
comodel_name='res.country.state', |
||||
|
related='partner_id.state_id', |
||||
|
readonly=True, |
||||
|
) |
||||
|
country_id_original = fields.Many2one( |
||||
|
string='Country', |
||||
|
comodel_name='res.country', |
||||
|
related='partner_id.country_id', |
||||
|
readonly=True, |
||||
|
) |
||||
|
latitude_original = fields.Float( |
||||
|
string='Latitude', |
||||
|
related='partner_id.latitude', |
||||
|
) |
||||
|
longitude_original = fields.Float( |
||||
|
string='Longitude', |
||||
|
related='partner_id.longitude', |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def _default_partner_id(self): |
||||
|
active_model = self.env.context.get('active_model') |
||||
|
active_id = self.env.context.get('active_id') |
||||
|
if active_model == 'res.partner': |
||||
|
return active_id |
||||
|
if active_model == 'res.company': |
||||
|
company = self.env['res.company'].browse(active_id) |
||||
|
return company.partner_id.id |
||||
|
|
||||
|
@api.model |
||||
|
def _default_interface_id(self): |
||||
|
return self.env.user.company_id.default_address_validate_id.id |
||||
|
|
||||
|
@api.multi |
||||
|
def action_validate(self): |
||||
|
"""Get the suggested address from the provider.""" |
||||
|
self.ensure_one() |
||||
|
self.write( |
||||
|
self.interface_id.get_address(self.partner_id) |
||||
|
) |
||||
|
return { |
||||
|
'context': self.env.context, |
||||
|
'view_type': 'form', |
||||
|
'view_mode': 'form', |
||||
|
'res_model': self._name, |
||||
|
'src_model': 'res.partner', |
||||
|
'res_id': self.id, |
||||
|
'view_id': False, |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'target': 'new', |
||||
|
} |
||||
|
|
||||
|
@api.multi |
||||
|
def action_confirm(self): |
||||
|
"""Copy the validated information to the partner.""" |
||||
|
for record in self: |
||||
|
record.partner_id.write({ |
||||
|
'street': record.street, |
||||
|
'street2': record.street2, |
||||
|
'city': record.city, |
||||
|
'state_id': record.state_id.id, |
||||
|
'country_id': record.country_id.id, |
||||
|
'zip': record.zip, |
||||
|
}) |
||||
|
return { |
||||
|
'type': 'ir.actions.act_window_close', |
||||
|
} |
@ -0,0 +1,83 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright 2016-2017 LasLabs Inc. |
||||
|
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<record id="wizard_address_validate_view_form" model="ir.ui.view"> |
||||
|
<field name="name">Address Verification Form</field> |
||||
|
<field name="model">wizard.address.validate</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Address Verification"> |
||||
|
<header/> |
||||
|
<sheet> |
||||
|
<group name="group_interface" |
||||
|
attrs="{'invisible': [('is_valid', '!=', False)]}"> |
||||
|
<field name="interface_id" /> |
||||
|
<field name="partner_id" readonly="True" /> |
||||
|
<field name="is_valid" invisible="True"/> |
||||
|
<field name="validation_messages" readonly="True" /> |
||||
|
</group> |
||||
|
<group name="group_data" |
||||
|
attrs="{'invisible': [('is_valid', '=', False)]}"> |
||||
|
<group name="group_data_original" string="Original"> |
||||
|
<field name="street_original" /> |
||||
|
<field name="street2_original" /> |
||||
|
<field name="city_original" /> |
||||
|
<field name="state_id_original" /> |
||||
|
<field name="zip_original" /> |
||||
|
<field name="country_id_original" /> |
||||
|
<field name="latitude_original" /> |
||||
|
<field name="longitude_original" /> |
||||
|
</group> |
||||
|
<group name="group_data_suggested" string="Suggested"> |
||||
|
<field name="street" /> |
||||
|
<field name="street2" /> |
||||
|
<field name="city" /> |
||||
|
<field name="state_id" /> |
||||
|
<field name="zip" /> |
||||
|
<field name="country_id" /> |
||||
|
<field name="latitude" /> |
||||
|
<field name="longitude" /> |
||||
|
</group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
<footer> |
||||
|
<button special="cancel" |
||||
|
string="Cancel" |
||||
|
class="pull-left" /> |
||||
|
<button name="action_validate" |
||||
|
type="object" |
||||
|
string="Validate" |
||||
|
attrs="{'invisible': [('is_valid', '=', True)]}" |
||||
|
class="oe_highlight pull-right" /> |
||||
|
<button name="action_confirm" |
||||
|
type="object" |
||||
|
string="Confirm" |
||||
|
attrs="{'invisible': [('is_valid', '=', False)]}" |
||||
|
class="oe_highlight pull-right" /> |
||||
|
</footer> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<act_window id="wizard_company_address_validate_action" |
||||
|
name="Verify Address" |
||||
|
src_model="res.company" |
||||
|
res_model="wizard.address.validate" |
||||
|
view_mode="form" |
||||
|
target="new" |
||||
|
key2="client_action_multi" /> |
||||
|
|
||||
|
<act_window id="wizard_partner_address_validate_action" |
||||
|
name="Verify Address" |
||||
|
src_model="res.partner" |
||||
|
res_model="wizard.address.validate" |
||||
|
view_mode="form" |
||||
|
target="new" |
||||
|
key2="client_action_multi" /> |
||||
|
|
||||
|
</odoo> |
@ -1 +1,2 @@ |
|||||
product-attribute |
product-attribute |
||||
|
server-tools |
Write
Preview
Loading…
Cancel
Save
Reference in new issue