Browse Source

[MIG] base_location

pull/638/head
etobella 7 years ago
committed by Pedro M. Baeza
parent
commit
e5d0e3d40a
  1. 53
      base_location/README.rst
  2. 1
      base_location/__init__.py
  3. 5
      base_location/__openerp__.py
  4. 8
      base_location/demo/better_zip.xml
  5. 1
      base_location/models/__init__.py
  6. 101
      base_location/models/better_zip.py
  7. 64
      base_location/models/company.py
  8. 60
      base_location/models/partner.py
  9. 1
      base_location/models/state.py
  10. 3
      base_location/tests/__init__.py
  11. 270
      base_location/tests/test_base_location.py
  12. 49
      base_location/tests/test_completion.py
  13. 35
      base_location/views/better_zip_view.xml
  14. 10
      base_location/views/company_view.xml
  15. 20
      base_location/views/partner_view.xml
  16. 16
      base_location/views/res_country_view.xml

53
base_location/README.rst

@ -1,5 +1,5 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
=======================
@ -12,27 +12,52 @@ It enables zip, city, state and country auto-completion on partners and companie
Also allows different search filters.
Configuration
=============
#. Activate the developer mode in *Settings*.
#. Go to *Settings / Technical / Locations Management / Locations*.
#. Create a new Location.
or, with module 'Contacts Directory' installed:
#. Go to *Contacts / Configuration / Localization / Countries*.
#. Locate the desired country.
#. Press on the button 'Locations'.
or,
#. Go to *Contacts / Configuration / Localization / Fed. States*
#. Locate the desired state.
#. Enter the desired Locations.
Usage
=====
#. Access a partner record
#. Fill the field *Location completion*
#. Information about country, state, city and zip will be filled automatically
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/134/10.0
:target: https://runbot.odoo-community.org/runbot/134/11.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/
partner_contact/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback `here <https://github.com/OCA/
partner_contact/issues/new?body=module:%20
base_location%0Aversion:%20
10.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/partner_contact/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
------
* Icon park: `Icon http://icon-park.com/icon/location-map-pin-orange3/`
Contributors
------------
@ -45,17 +70,13 @@ Contributors
* Francesco Apruzzese <f.apruzzese@apuliasoftware.it>
* Dave Lasley <dave@laslabs.com>
Icon
----
* http://icon-park.com/icon/location-map-pin-orange3/
Maintainer
----------
.. image:: http://odoo-community.org/logo.png
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://odoo-community.org
:target: https://odoo-community.org
This module is maintained by the OCA.
@ -63,4 +84,4 @@ 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 http://odoo-community.org.
To contribute to this module, please visit https://odoo-community.org.

1
base_location/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Nicolas Bessi, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

5
base_location/__openerp__.py

@ -1,12 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Nicolas Bessi, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Location management (aka Better ZIP)',
'version': '10.0.1.0.1',
'version': '11.0.1.0.0',
'depends': [
'base',
'base_address_city'
],
'author': "Camptocamp,"
"ACYSOS S.L.,"

8
base_location/demo/better_zip.xml

@ -1,12 +1,8 @@
<?xml version = "1.0" encoding="utf-8"?>
<openerp>
<data>
<odoo>
<record id="demo_brussels" model="res.better.zip">
<field name="name">1000</field>
<field name="city">Brussels</field>
<field name="country_id" ref="base.be"/>
</record>
</data>
</openerp>
</odoo>

1
base_location/models/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Nicolas Bessi, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

101
base_location/models/better_zip.py

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Nicolas Bessi, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class BetterZip(models.Model):
@ -11,37 +11,90 @@ class BetterZip(models.Model):
_name = "res.better.zip"
_description = __doc__
_order = "name asc"
_rec_name = "display_name"
display_name = fields.Char('Name', compute='_get_display_name', store=True)
name = fields.Char('ZIP')
code = fields.Char('City Code', size=64,
help="The official code for the city")
code = fields.Char(
'City Code',
size=64,
help="The official code for the city"
)
city = fields.Char('City', required=True)
state_id = fields.Many2one('res.country.state', 'State')
city_id = fields.Many2one(
'res.city',
'City',
)
state_id = fields.Many2one(
'res.country.state',
'State',
)
country_id = fields.Many2one('res.country', 'Country')
enforce_cities = fields.Boolean(
related='country_id.enforce_cities',
readonly=True,
)
latitude = fields.Float()
longitude = fields.Float()
@api.one
@api.depends(
'name',
'city',
'state_id',
'country_id',
)
def _get_display_name(self):
if self.name:
name = [self.name, self.city]
else:
name = [self.city]
if self.state_id:
name.append(self.state_id.name)
@api.multi
@api.depends('name', 'city', 'state_id', 'country_id')
def name_get(self):
result = []
for rec in self:
name = []
if rec.name:
name.append('%(name)s' % {'name': rec.name})
name.append('%(name)s' % {'name': rec.city})
if rec.state_id:
name.append('%(name)s' % {'name': rec.state_id.name})
if rec.country_id:
name.append('%(name)s' % {'name': rec.country_id.name})
result.append((rec.id, ", ".join(name)))
return result
@api.onchange('country_id')
def _onchange_country_id(self):
if self.state_id.country_id != self.country_id:
self.state_id = False
if self.city_id.country_id != self.country_id:
self.city_id = False
if self.country_id:
name.append(self.country_id.name)
self.display_name = ", ".join(name)
domain = [('country_id', '=', self.country_id.id)]
else:
domain = []
return {
'domain': {
'state_id': domain,
'city_id': domain,
}
}
@api.onchange('city_id')
def _onchange_city_id(self):
if self.city_id:
self.city = self.city_id.name
self.country_id = self.city_id.country_id
self.state_id = self.city_id.state_id
@api.onchange('state_id')
def onchange_state_id(self):
def _onchange_state_id(self):
if self.state_id:
self.country_id = self.state_id.country_id
@api.constrains('state_id', 'country_id', 'city_id')
def constrains_country(self):
for rec in self:
if rec.state_id and rec.state_id.country_id != \
rec.country_id:
raise ValidationError(_(
"The country of the state differs from the country in "
"location %s") % rec.name)
if rec.city_id and rec.city_id.country_id \
!= rec.country_id:
raise ValidationError(_(
"The country of the city differs from the country in "
"location %s") % rec.name)
if rec.city_id and rec.city_id.state_id \
!= rec.state_id:
raise ValidationError(_(
"The state of the city differs from the state in "
"location %s") % rec.name)

64
base_location/models/company.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Nicolas Bessi, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -6,19 +5,60 @@ from odoo import models, fields, api
class ResCompany(models.Model):
_inherit = 'res.company'
@api.onchange('better_zip_id')
def on_change_city(self):
if self.better_zip_id:
self.zip = self.better_zip_id.name
self.city = self.better_zip_id.city
self.state_id = self.better_zip_id.state_id
self.country_id = self.better_zip_id.country_id
better_zip_id = fields.Many2one(
city_id = fields.Many2one(
'res.city',
compute='_compute_address',
inverse='_inverse_city_id',
string="City"
)
zip_id = fields.Many2one(
'res.better.zip',
string='Location',
string='ZIP Location',
compute='_compute_address',
inverse='_inverse_zip_id',
oldname="better_zip_id",
help='Use the city name or the zip code to search the location',
)
# In order to keep the same logic used in odoo, fields must be computed
# and inversed, not related. This way, we can ensure that it works
# correctly on changes and inconsistencies cannot happen.
# When you make the fields related, the constrains added in res.partner
# will fail. because when you change the city_id in the company, you are
# effectively changing it in the partner. The constrains on the partner
# are evaluated before the inverse methods update the other fields (city,
# etc..). And we need constrains in the partner to ensure consistency.
# So, as a conclusion, address fields are very related to each other.
# Either you make them all related to the partner in company, or you
# don't for all of them. But mixing methods produces inconsistencies.
country_enforce_cities = fields.Boolean(
related='country_id.enforce_cities'
)
def _get_company_address_fields(self, partner):
res = super(ResCompany, self)._get_company_address_fields(partner)
res['city_id'] = partner.city_id
res['zip_id'] = partner.zip_id
return res
def _inverse_city_id(self):
for company in self:
company.partner_id.city_id = company.city_id
def _inverse_zip_id(self):
for company in self:
company.partner_id.zip_id = company.zip_id
@api.onchange('zip_id')
def _onchange_zip_id(self):
if self.zip_id:
self.zip = self.zip_id.name
self.city_id = self.zip_id.city_id
self.city = self.zip_id.city
self.country_id = self.zip_id.country_id
if self.country_id.enforce_cities:
self.state_id = self.city_id.state_id
else:
self.state_id = self.zip_id.state_id

60
base_location/models/partner.py

@ -1,18 +1,66 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Nicolas Bessi, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class ResPartner(models.Model):
_inherit = 'res.partner'
zip_id = fields.Many2one('res.better.zip', 'City/Location')
zip_id = fields.Many2one('res.better.zip', 'ZIP Location')
@api.onchange('city_id')
def _onchange_city_id(self):
if not self.zip_id:
super(ResPartner, self)._onchange_city_id()
if self.zip_id and self.city_id != self.zip_id.city_id:
self.zip_id = False
self.zip = False
self.city = False
if self.city_id:
return {
'domain': {
'zip_id': [('city_id', '=', self.city_id.id)]
},
}
return {'domain': {'zip_id': []}}
@api.onchange('state_id')
def _onchange_state_id(self):
if self.zip_id and self.state_id != self.zip_id.state_id:
self.zip_id = False
self.zip = False
self.city = False
@api.onchange('country_id')
def _onchange_country_id(self):
res = super(ResPartner, self)._onchange_country_id()
if self.zip_id and self.zip_id.country_id != self.country_id:
self.zip_id = False
return res
@api.onchange('zip_id')
def onchange_zip_id(self):
def _onchange_zip_id(self):
if self.zip_id:
self.country_id = self.zip_id.country_id
if self.country_id.enforce_cities:
self.city_id = self.zip_id.city_id
self.zip = self.zip_id.name
self.city = self.zip_id.city
self.state_id = self.zip_id.state_id
self.country_id = self.zip_id.country_id
self.city = self.zip_id.city
@api.constrains('zip_id', 'country_id', 'city_id', 'state_id')
def _check_zip(self):
for rec in self.filtered('zip_id'):
if rec.zip_id.state_id != rec.state_id:
raise ValidationError(_(
"The state of the partner %s differs from that in "
"location %s") % (rec.name, rec.zip_id.name))
if rec.zip_id.country_id != rec.country_id:
raise ValidationError(_(
"The country of the partner %s differs from that in "
"location %s") % (rec.name, rec.zip_id.name))
if rec.zip_id.city_id != rec.city_id:
raise ValidationError(_(
"The city of partner %s differs from that in "
"location %s") % (rec.name, rec.zip_id.name))

1
base_location/models/state.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Nicolas Bessi, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

3
base_location/tests/__init__.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright 2015 Yannick Vaucher, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_completion
from . import test_base_location

270
base_location/tests/test_base_location.py

@ -0,0 +1,270 @@
# Copyright 2015 Yannick Vaucher, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import TransactionCase
from odoo.exceptions import ValidationError
class TestBaseLocation(TransactionCase):
def test_onchange_better_zip_state_id(self):
""" Test onchange on res.better.zip """
usa_MA = self.env.ref('base.state_us_34')
better_zip1 = self.env['res.better.zip'].new(self.values_better_zip1())
better_zip1.state_id = usa_MA
better_zip1._onchange_state_id()
self.assertEqual(better_zip1.country_id, usa_MA.country_id)
def test_onchange_better_zip_city_id(self):
better_zip2 = self.env['res.better.zip'].new(self.values_better_zip2())
better_zip2.city_id = self.city_madrid
better_zip2._onchange_city_id()
self.assertEqual(better_zip2.city, self.city_madrid.name)
def test_onchange_better_zip_country_id(self):
better_zip1 = self.env['res.better.zip'].new(self.values_better_zip1())
better_zip1.country_id = self.env.ref('base.es')
better_zip1._onchange_country_id()
self.assertFalse(better_zip1.state_id)
def test_onchange_better_zip_none(self):
better_zip1 = self.env['res.better.zip'].new(self.values_better_zip1())
better_zip1.country_id = False
better_zip1._onchange_country_id()
self.assertFalse(better_zip1.state_id)
def test_onchange_partner_city_completion(self):
partner1 = self.env['res.partner'].new({
'name': 'Camptocamp',
})
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2())
better_zip2.country_id.enforce_cities = True
partner1.zip_id = better_zip2
partner1._onchange_zip_id()
self.assertEqual(partner1.zip, better_zip2.name)
self.assertEqual(partner1.city, better_zip2.city)
self.assertEqual(partner1.state_id, better_zip2.state_id)
self.assertEqual(partner1.country_id, better_zip2.country_id)
def test_onchange_company_city_completion(self):
company = self.env['res.company'].new({'name': 'Test'})
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1())
company.zip_id = better_zip1
company._onchange_zip_id()
self.assertEqual(company.zip, better_zip1.name)
self.assertEqual(company.city, better_zip1.city)
self.assertEqual(company.state_id, better_zip1.state_id)
self.assertEqual(company.country_id, better_zip1.country_id)
def test_company_address_fields(self):
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1()
)
company = self.env['res.company'].create({
'name': 'Test',
})
self.assertTrue(company.partner_id)
company.partner_id.write({
'zip_id': better_zip1.id,
'state_id': better_zip1.state_id.id,
'country_id': better_zip1.country_id.id,
'city_id': better_zip1.city_id.id,
'city': better_zip1.city,
'zip': better_zip1.name,
})
company._compute_address()
self.assertEqual(company.zip_id, company.partner_id.zip_id)
self.assertEqual(company.city_id, company.partner_id.city_id)
def test_company_address_fields_inverse(self):
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2()
)
company = self.env['res.company'].new({
'name': 'Test',
'partner_id': self.env['res.partner'].new({}).id
# Partner must be initiated in order to be filled
})
company.update({
'zip_id': better_zip2.id,
})
company._inverse_city_id()
company._inverse_zip_id()
self.assertEqual(company.zip_id, company.partner_id.zip_id)
self.assertEqual(company.city_id, company.partner_id.city_id)
def test_onchange_company_city_id_completion(self):
company = self.env['res.company'].new({'name': 'Test'})
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2())
company.zip_id = better_zip2
company._onchange_zip_id()
self.assertEqual(company.city_id, better_zip2.city_id)
def test_constrains_better_zip_01(self):
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1())
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2())
better_zip1.city_id = self.city_lausanne
with self.assertRaises(ValidationError):
better_zip2.city_id = better_zip1.city_id
def test_constrains_better_zip_02(self):
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1())
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2())
with self.assertRaises(ValidationError):
better_zip2.country_id = better_zip1.country_id
def test_constrains_better_zip_03(self):
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1())
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2())
with self.assertRaises(ValidationError):
better_zip2.state_id = better_zip1.state_id
def test_constrains_better_zip_04(self):
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2())
with self.assertRaises(ValidationError):
better_zip2.city_id = self.city_madrid
def test_constrains_partner_01(self):
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2())
with self.assertRaises(ValidationError):
self.env['res.partner'].create({
'name': 'P1',
'zip_id': better_zip2.id,
})
def test_constrains_partner_02(self):
better_zip2 = self.env['res.better.zip'].create(
self.values_better_zip2())
partner = self.env['res.partner'].create({
'name': 'P1',
'zip_id': better_zip2.id,
'country_id': better_zip2.country_id.id,
'state_id': better_zip2.state_id.id,
'city_id': better_zip2.city_id.id,
})
with self.assertRaises(ValidationError):
partner.country_id = self.ref('base.ch')
with self.assertRaises(ValidationError):
partner.state_id = self.state_vd.id,
with self.assertRaises(ValidationError):
partner.city_id = self.city_lausanne
def values_better_zip1(self):
return {
'name': 1000,
'city': 'Lausanne',
'state_id': self.state_vd.id,
'country_id': self.ref('base.ch'),
}
def values_better_zip2(self):
return {
'city_id': self.city_bcn.id,
'city': self.city_bcn.name,
'state_id': self.state_bcn.id,
'country_id': self.ref('base.es'),
}
def test_partner_onchange_country(self):
country_es = self.browse_ref('base.es')
country_es.enforce_cities = True
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1())
partner = self.env['res.partner'].new({
'name': 'TEST',
'zip_id': better_zip1.id
})
partner.country_id = country_es
partner._onchange_country_id()
self.assertFalse(partner.zip_id)
def test_partner_onchange_city(self):
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1())
partner = self.env['res.partner'].new({
'name': 'TEST',
'zip_id': better_zip1.id
})
self.city_bcn.country_id.enforce_cities = False
partner.city_id = self.city_bcn
partner._onchange_city_id()
self.assertFalse(partner.zip_id)
partner.city_id = False
res = partner._onchange_city_id()
self.assertFalse(res['domain']['zip_id'])
def test_partner_onchange_state(self):
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1())
partner = self.env['res.partner'].new({
'name': 'TEST',
'zip_id': better_zip1.id
})
partner.state_id = self.state_bcn
partner._onchange_state_id()
self.assertFalse(partner.zip_id)
def test_display_name(self):
better_zip1 = self.env['res.better.zip'].create(
self.values_better_zip1())
self.assertEqual(
better_zip1.display_name, '1000, Lausanne, Vaud, '+self.browse_ref(
'base.ch'
).name
)
def setUp(self):
super(TestBaseLocation, self).setUp()
self.state_vd = self.env['res.country.state'].create({
'name': 'Vaud',
'code': 'VD',
'country_id': self.ref('base.ch'),
})
self.env['res.country'].browse(self.ref('base.es')).write({
'enforce_cities': True
})
self.company = self.env.ref('base.main_company')
self.state_bcn = self.env['res.country.state'].create({
'name': 'Barcelona',
'code': '08',
'country_id': self.ref('base.es'),
})
self.state_madrid = self.env['res.country.state'].create({
'name': 'Madrid',
'code': '28',
'country_id': self.ref('base.es'),
})
self.city_bcn = self.env['res.city'].create({
'name': 'Barcelona',
'state_id': self.state_bcn.id,
'country_id': self.ref('base.es'),
})
self.city_madrid = self.env['res.city'].create({
'name': 'Madrid',
'state_id': self.state_madrid.id,
'country_id': self.ref('base.es'),
})
self.city_lausanne = self.env['res.city'].create({
'name': 'Lausanne',
'state_id': self.state_vd.id,
'country_id': self.ref('base.ch'),
})

49
base_location/tests/test_completion.py

@ -1,49 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2015 Yannick Vaucher, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import TransactionCase
class TestCompletion(TransactionCase):
def test_onchange_better_zip_state_id(self):
""" Test onchange on res.better.zip """
usa_MA = self.env.ref('base.state_us_34')
self.better_zip1.state_id = usa_MA
self.better_zip1.onchange_state_id()
self.assertEqual(self.better_zip1.country_id, usa_MA.country_id)
def test_onchange_partner_city_completion(self):
self.partner1.zip_id = self.better_zip1
self.partner1.onchange_zip_id()
self.assertEqual(self.partner1.zip, self.better_zip1.name)
self.assertEqual(self.partner1.city, self.better_zip1.city)
self.assertEqual(self.partner1.state_id, self.better_zip1.state_id)
self.assertEqual(self.partner1.country_id, self.better_zip1.country_id)
def test_onchange_company_city_completion(self):
self.company.better_zip_id = self.better_zip1
self.company.on_change_city()
self.assertEqual(self.company.zip, self.better_zip1.name)
self.assertEqual(self.company.city, self.better_zip1.city)
self.assertEqual(self.company.state_id, self.better_zip1.state_id)
self.assertEqual(self.company.country_id, self.better_zip1.country_id)
def setUp(self):
super(TestCompletion, self).setUp()
state_vd = self.env['res.country.state'].create({
'name': 'Vaud',
'code': 'VD',
'country_id': self.ref('base.ch'),
})
self.company = self.env.ref('base.main_company')
self.better_zip1 = self.env['res.better.zip'].create({
'name': 1000,
'city': 'Lausanne',
'state_id': state_vd.id,
'country_id': self.ref('base.ch'),
})
self.partner1 = self.env['res.partner'].create({
'name': 'Camptocamp',
})

35
base_location/views/better_zip_view.xml

@ -7,11 +7,20 @@
<field name="arch" type="xml">
<form string="City">
<group col="4">
<field name="name"/>
<field name="code"/>
<field name="city"/>
<field name="state_id"/>
<field name="country_id"/>
<group>
<field name="name"/>
<field name="city_id"
attrs="{'invisible': [('enforce_cities', '=', False)],'required': [('enforce_cities', '=', True)]}"/>
<field name="city"
attrs="{'invisible': [('enforce_cities', '=', True)]}"/>
<field name="country_id"/>
<field name="enforce_cities" invisible="1"/>
</group>
<group>
<field name="code"/>
<field name="state_id"
attrs="{'invisible': [('enforce_cities', '=', True)]}"/>
</group>
</group>
</form>
</field>
@ -41,16 +50,18 @@
<field name="city"/>
<field name="state_id"/>
<field name="country_id"/>
<group expand="0" string="Group By">
<filter string="State" domain="[]" context="{'group_by':'state_id'}"/>
<filter string="Country" domain="[]" context="{'group_by':'country_id'}"/>
</group>
<group expand="0" string="Group By">
<filter string="State" domain="[]"
context="{'group_by':'state_id'}"/>
<filter string="Country" domain="[]"
context="{'group_by':'country_id'}"/>
</group>
</search>
</field>
</record>
<record id="action_zip_tree" model="ir.actions.act_window">
<field name="name">Cites/locations</field>
<field name="name">Locations</field>
<field name="res_model">res.better.zip</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
@ -59,13 +70,13 @@
</record>
<menuitem
name="Cities/Locations Management"
name="Locations Management"
id="locations_root_menu"
parent="base.menu_custom"
/>
<menuitem
name="Cities/Locations"
name="Locations"
id="locations_menu"
parent="locations_root_menu"
action="action_zip_tree"

10
base_location/views/company_view.xml

@ -8,11 +8,19 @@
<field name="inherit_id" ref="base.view_company_form" />
<field name="arch" type="xml">
<field name="street2" position="after">
<field name="better_zip_id"
<field name="zip_id"
options="{'create_name_field': 'city'}"
colspan="4"
placeholder="City completion" />
</field>
<field name="city" position="after">
<field name="country_enforce_cities" invisible="1"/>
<field name='city_id'
attrs="{'invisible': [('country_enforce_cities', '=', False)]}"/>
</field>
<field name="city" position="attributes">
<attribute name="invisible">[('country_enforce_cities', '=', True)]</attribute>
</field>
</field>
</record>

20
base_location/views/partner_view.xml

@ -1,24 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="view_partner_form" model="ir.ui.view">
<field name="name">res.partner.zip_id.2</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="city" position="before">
<field name="zip_id"
options="{'create_name_field': 'city', 'no_open': True, 'no_create': True}"
placeholder="City completion"
class="oe_edit_only" />
options="{'create_name_field': 'city', 'no_open': True, 'no_create': True}"
placeholder="Location completion"
class="oe_edit_only"
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}"/>
</field>
<xpath expr="//field[@name='child_ids']/form//field[@name='city']" position="before">
<xpath expr="//field[@name='child_ids']/form//field[@name='city']"
position="before">
<field name="zip_id"
options="{'create_name_field': 'city', 'no_open': True, 'no_create': True}"
placeholder="City completion"
class="oe_edit_only" />
options="{'create_name_field': 'city', 'no_open': True, 'no_create': True}"
placeholder="City completion"
class="oe_edit_only"/>
</xpath>
</field>
</record>
</odoo>

16
base_location/views/res_country_view.xml

@ -12,4 +12,20 @@
</field>
</record>
<record id="view_res_country_city_better_zip_form" model="ir.ui.view">
<field name="model">res.country</field>
<field name="inherit_id" ref="base.view_country_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('oe_button_box')]" position="inside">
<button name="%(action_zip_tree)d"
class="oe_stat_button"
icon="fa-globe"
type="action"
context="{'default_country_id': active_id, 'search_default_country_id': active_id}"
string="Locations">
</button>
</xpath>
</field>
</record>
</odoo>
Loading…
Cancel
Save