Skip to content

Commit

Permalink
[ADD] pos_partner_location_google_map: Module added.
Browse files Browse the repository at this point in the history
  • Loading branch information
geomer198 committed Dec 28, 2023
1 parent 239d49e commit 37c54c5
Show file tree
Hide file tree
Showing 22 changed files with 1,189 additions and 0 deletions.
87 changes: 87 additions & 0 deletions pos_partner_location_google_map/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
===============================
POS Partner Location Google Map
===============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:90461c6096bed16c091f202daefa26f0832cb9a0bab1d6608f1fd457aa3d3d25
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github
:target: https://github.com/OCA/pos/tree/16.0/pos_partner_location_google_map
:alt: OCA/pos
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/pos-16-0/pos-16-0-pos_partner_location_google_map
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/pos&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows to select partner address directly on map.

**Table of contents**

.. contents::
:local:

Usage
=====

In POS open customer list, select a customer and click "Details".
On the customer form click on the "globe" icon and select a location on map.
Click "Save" to save the location.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/pos/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/pos/issues/new?body=module:%20pos_partner_location_google_map%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Cetmix

Contributors
~~~~~~~~~~~~

* Cetmix <https://cetmix.com/>

* Ivan Sokolov
* Maksim Shurupov


Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

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.

This module is part of the `OCA/pos <https://github.com/OCA/pos/tree/16.0/pos_partner_location_google_map>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions pos_partner_location_google_map/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
20 changes: 20 additions & 0 deletions pos_partner_location_google_map/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (C) 2023 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "POS Partner Location Google Map",
"version": "16.0.1.0.0",
"category": "Point Of Sale",
"summary": "POS Partner Location Google Map",
"author": "Cetmix, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/pos",
"license": "AGPL-3",
"depends": ["pos_partner_location_abstract"],
"data": [],
"assets": {
"point_of_sale.assets": [
"pos_partner_location_google_map/static/src/js/*.js",
],
},
"installable": True,
}
4 changes: 4 additions & 0 deletions pos_partner_location_google_map/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import address_google_struct
from . import base_geocoder
from . import pos_config
from . import res_partner
140 changes: 140 additions & 0 deletions pos_partner_location_google_map/models/address_google_struct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Copyright (C) 2023 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo.osv.expression import AND, OR

from odoo.addons.pos_partner_location_abstract.models.address_struct import (
AddressStruct,
)


class AddressGoogleStruct(AddressStruct):
ADDR_FIELDS = {
"number": ["street_number"],
"street": ["street_address", "route", "plus_code"],
"city": [
"locality",
"sublocality",
"sublocality_level_1",
"sublocality_level_2",
"sublocality_level_3",
"sublocality_level_4",
],
"state_id": [
"administrative_area_level_1",
"administrative_area_level_2",
"administrative_area_level_3",
"administrative_area_level_4",
"administrative_area_level_5",
],
"country_id": ["country"],
"zip": ["postal_code"],
}
SERVICE_URL = "https://maps.googleapis.com/maps/api/place/details/json"

def __init__(self, odoo_env):
super(AddressGoogleStruct, self).__init__(odoo_env)
self.api_key = (
self.env["ir.config_parameter"]
.sudo()
.get_param("base_geolocalize.google_map_api_key", False)
)

def has_token(self):
"""Checking exists Google API key in settings"""
return bool(self.api_key)

def _get_fields_value(self, addr_key):
"""
Get fields value for preparing values address
:param str addr_key: field name
:return list: list of fields values
"""
return [self._result.get(key, False) for key in self.ADDR_FIELDS[addr_key]]

@property
def street(self):
street_number = self._result.get("street_number")
result = []
if street_number:
result.append(street_number)
for address in self._get_fields_value("street"):
if address:
result.append(address)
return " ".join(result)
return ""

@property
def city(self):
for city in self._get_fields_value("city"):
if city:
return city
return False

@property
def state_id(self):
domain = []
codes = []
for state in self._get_fields_value("state_id"):
if state:
domain = OR([domain, [("name", "like", state.get("name"))]])
codes.append(state.get("code"))
if codes:
domain = OR([domain, [("code", "in", codes)]])
if len(domain) == 0:
return False
country_id = self.country_id
if country_id:
domain = AND([domain, [("country_id", "=", country_id[0])]])
state = self.env["res.country.state"].search(domain, limit=1)
return state.name_get()[0] if state else False

@property
def country_id(self):
country_item = self._result.get("country")
if not country_item:
return False
country = self.env["res.country"].search(
[
"|",
("name", "like", country_item.get("name")),
("code", "=", country_item.get("code")),
]
)
return country.name_get()[0] if country else False

@property
def zip(self):
return self._result.get("postal_code")

def query_addr(self, params, timeout=5):
params.update(key=self.api_key)
response = super(AddressGoogleStruct, self).query_addr(params, timeout=timeout)
if response:
if response.get("status") == "OK":
self._prepare_components_data(response["result"]["address_components"])
return True
return False

def _prepare_components_data(self, components):
"""
Preparing component values for class result
:param dict components: list of components
:return: None
:rtype: NoneType
"""
state_country_fields = [
*self.ADDR_FIELDS.get("state_id", []),
*self.ADDR_FIELDS.get("country_id", []),
]
for component in components:
for type_ in component["types"]:
if type_ in state_country_fields:
self._result[type_] = {
"code": component["short_name"],
"name": component["long_name"],
}
elif type_ in self.ADDR_FIELDS.get("street", []):
self._result[type_] = component["short_name"]
else:
self._result[type_] = component["long_name"]
36 changes: 36 additions & 0 deletions pos_partner_location_google_map/models/base_geocoder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (C) 2023 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import logging

from odoo import _, api, models

from .address_google_struct import AddressGoogleStruct

_logger = logging.getLogger(__name__)


class GeoProvider(models.AbstractModel):
_inherit = "base.geocoder"

@api.model
def prepare_geo_address_googlemap(self, place_id):
"""
Prepare Address values by place id
:param str place_id: Google map place id
:return dict: address fields values
"""
google = AddressGoogleStruct(self.env)
if not google.has_token():
raise models.UserError(
_(
"API key for GeoCoding (Places) required.\n"
"Visit https://developers.google.com/maps/documentation/geocoding/get-api-key " # noqa
"for more information."
)
)
status = google.query_addr({"place_id": place_id})
if status:
return google.get_result()
_logger.warning("Google map place id is not found!")
return {}

Check warning on line 36 in pos_partner_location_google_map/models/base_geocoder.py

View check run for this annotation

Codecov / codecov/patch

pos_partner_location_google_map/models/base_geocoder.py#L35-L36

Added lines #L35 - L36 were not covered by tests
26 changes: 26 additions & 0 deletions pos_partner_location_google_map/models/pos_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (C) 2023 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, fields, models


class PosConfig(models.Model):
_inherit = "pos.config"

googlemap_api_key = fields.Char(compute="_compute_geolocalize")

@api.model
def _set_extended_data(self):
data = super(PosConfig, self)._set_extended_data()
ICPSudo = self.env["ir.config_parameter"].sudo()
data.update(
api_key=ICPSudo.get_param("base_geolocalize.google_map_api_key", False)
)
return data

def _set_pos_config_parameter(self, tech_name, ext_vals=None):
super(PosConfig, self)._set_pos_config_parameter(tech_name, ext_vals)
key = ext_vals.get("api_key", "") if tech_name == "googlemap" else ""
for config in self:
config.googlemap_api_key = key
return
28 changes: 28 additions & 0 deletions pos_partner_location_google_map/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (C) 2023 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, models


class ResPartner(models.Model):
_inherit = "res.partner"

@api.model
def _get_map_provider_tech_name(self):
"""Get map provider technical name"""
ICPSudo = self.env["ir.config_parameter"].sudo()
geo_provider_obj = self.env["base.geo_provider"]
geo_provider_id = ICPSudo.get_param("base_geolocalize.geo_provider")
provider = geo_provider_obj.browse(int(geo_provider_id))
return provider.tech_name

def _compute_qr_code_url(self):
if self._get_map_provider_tech_name() != "googlemap":
return super()._compute_qr_code_url()
map_url = "https://maps.google.com/maps?q={},{}"
for rec in self:
rec.qr_code_url = (
map_url.format(rec.partner_latitude, rec.partner_longitude)
if rec.partner_latitude and rec.partner_longitude
else ""
)
2 changes: 2 additions & 0 deletions pos_partner_location_google_map/readme/CONFIGURATION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
In General Settings -> Integrations enable the Geo Localisation checkbox.
Select provided and add API key. NB: only google maps are currently supported.
5 changes: 5 additions & 0 deletions pos_partner_location_google_map/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* Cetmix <https://cetmix.com/>

* Ivan Sokolov
* Maksim Shurupov

1 change: 1 addition & 0 deletions pos_partner_location_google_map/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module allows to select partner address directly on map.
3 changes: 3 additions & 0 deletions pos_partner_location_google_map/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
In POS open customer list, select a customer and click "Details".
On the customer form click on the "globe" icon and select a location on map.
Click "Save" to save the location.
Loading

0 comments on commit 37c54c5

Please sign in to comment.