Browse Source

pre-commit, black, isort

14.0
OCA-git-bot 5 years ago
committed by Pedro M. Baeza
parent
commit
e07efcdb8c
  1. 51
      base_location/__manifest__.py
  2. 12
      base_location/demo/res_city_zip.xml
  3. 17
      base_location/models/res_city.py
  4. 22
      base_location/models/res_city_zip.py
  5. 64
      base_location/models/res_company.py
  6. 74
      base_location/models/res_partner.py
  7. 254
      base_location/tests/test_base_location.py
  8. 39
      base_location/views/res_city_view.xml
  9. 26
      base_location/views/res_city_zip_view.xml
  10. 22
      base_location/views/res_company_view.xml
  11. 17
      base_location/views/res_country_view.xml
  12. 33
      base_location/views/res_partner_view.xml

51
base_location/__manifest__.py

@ -3,32 +3,29 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{ {
'name': 'Location management (aka Better ZIP)',
'version': '13.0.1.0.0',
'depends': [
'base_address_city',
'contacts',
"name": "Location management (aka Better ZIP)",
"version": "13.0.1.0.0",
"depends": ["base_address_city", "contacts"],
"author": (
"Camptocamp,"
"ACYSOS S.L.,"
"Alejandro Santana,"
"Tecnativa,"
"AdaptiveCity,"
"Odoo Community Association (OCA)"
),
"license": "AGPL-3",
"summary": """Enhanced zip/npa management system""",
"website": "https://github.com/OCA/partner-contact",
"data": [
"security/ir.model.access.csv",
"views/res_city_zip_view.xml",
"views/res_city_view.xml",
"views/res_country_view.xml",
"views/res_company_view.xml",
"views/res_partner_view.xml",
], ],
'author': "Camptocamp,"
"ACYSOS S.L.,"
"Alejandro Santana,"
"Tecnativa,"
"AdaptiveCity,"
"Odoo Community Association (OCA)",
'license': "AGPL-3",
'summary': '''Enhanced zip/npa management system''',
'website': 'https://github.com/OCA/partner-contact',
'data': [
'security/ir.model.access.csv',
'views/res_city_zip_view.xml',
'views/res_city_view.xml',
'views/res_country_view.xml',
'views/res_company_view.xml',
'views/res_partner_view.xml',
],
'demo': [
'demo/res_city_zip.xml',
],
'installable': True,
'auto_install': False,
"demo": ["demo/res_city_zip.xml"],
"installable": True,
"auto_install": False,
} }

12
base_location/demo/res_city_zip.xml

@ -1,13 +1,11 @@
<?xml version = "1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="demo_brussels_city" model="res.city"> <record id="demo_brussels_city" model="res.city">
<field name="name">Brussels</field>
<field name="country_id" ref="base.be"/>
<field name="name">Brussels</field>
<field name="country_id" ref="base.be" />
</record> </record>
<record id="demo_brussels_zip" model="res.city.zip"> <record id="demo_brussels_zip" model="res.city.zip">
<field name="name">1000</field>
<field name="city_id" ref="demo_brussels_city"/>
<field name="name">1000</field>
<field name="city_id" ref="demo_brussels_city" />
</record> </record>
</odoo> </odoo>

17
base_location/models/res_city.py

@ -5,15 +5,16 @@ from odoo import fields, models
class City(models.Model): class City(models.Model):
_inherit = 'res.city'
_inherit = "res.city"
zip_ids = fields.One2many('res.city.zip', 'city_id',
string="Zips in this city")
zip_ids = fields.One2many("res.city.zip", "city_id", string="Zips in this city")
_sql_constraints = [ _sql_constraints = [
('name_state_country_uniq',
'UNIQUE(name, state_id, country_id)',
'You already have a city with that name in the same state.'
'The city must have a unique name within '
'it\'s state and it\'s country'),
(
"name_state_country_uniq",
"UNIQUE(name, state_id, country_id)",
"You already have a city with that name in the same state."
"The city must have a unique name within "
"it's state and it's country",
)
] ]

22
base_location/models/res_city_zip.py

@ -13,22 +13,22 @@ class ResCityZip(models.Model):
_order = "name asc" _order = "name asc"
_rec_name = "display_name" _rec_name = "display_name"
name = fields.Char('ZIP', required=True)
city_id = fields.Many2one(
'res.city',
'City',
required=True,
name = fields.Char("ZIP", required=True)
city_id = fields.Many2one("res.city", "City", required=True)
display_name = fields.Char(
compute="_compute_new_display_name", store=True, index=True
) )
display_name = fields.Char(compute='_compute_new_display_name',
store=True, index=True)
_sql_constraints = [ _sql_constraints = [
('name_city_uniq', 'UNIQUE(name, city_id)',
'You already have a zip with that code in the same city. '
'The zip code must be unique within it\'s city'),
(
"name_city_uniq",
"UNIQUE(name, city_id)",
"You already have a zip with that code in the same city. "
"The zip code must be unique within it's city",
)
] ]
@api.depends('name', 'city_id')
@api.depends("name", "city_id")
def _compute_new_display_name(self): def _compute_new_display_name(self):
for rec in self: for rec in self:
name = [rec.name, rec.city_id.name] name = [rec.name, rec.city_id.name]

64
base_location/models/res_company.py

@ -2,11 +2,11 @@
# Copyright 2018 Tecnativa - Pedro M. Baeza # Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api
from odoo import api, fields, models
class ResCompany(models.Model): class ResCompany(models.Model):
_inherit = 'res.company'
_inherit = "res.company"
# In order to keep the same logic used in Odoo, fields must be computed # 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 # and inversed, not related. This way we can ensure that it works
@ -21,59 +21,63 @@ class ResCompany(models.Model):
# don't for all of them. Mixing both approaches produces inconsistencies. # don't for all of them. Mixing both approaches produces inconsistencies.
city_id = fields.Many2one( city_id = fields.Many2one(
'res.city',
compute='_compute_address',
inverse='_inverse_city_id',
string="City ID"
"res.city",
compute="_compute_address",
inverse="_inverse_city_id",
string="City ID",
) )
zip_id = fields.Many2one( zip_id = fields.Many2one(
'res.city.zip',
string='ZIP Location',
compute='_compute_address',
inverse='_inverse_zip_id',
help='Use the city name or the zip code to search the location',
"res.city.zip",
string="ZIP Location",
compute="_compute_address",
inverse="_inverse_zip_id",
help="Use the city name or the zip code to search the location",
) )
country_enforce_cities = fields.Boolean( country_enforce_cities = fields.Boolean(
related='partner_id.country_id.enforce_cities',
related="partner_id.country_id.enforce_cities"
) )
def _get_company_address_fields(self, partner): def _get_company_address_fields(self, partner):
res = super()._get_company_address_fields(partner) res = super()._get_company_address_fields(partner)
res['city_id'] = partner.city_id
res['zip_id'] = partner.zip_id
res["city_id"] = partner.city_id
res["zip_id"] = partner.zip_id
return res return res
def _inverse_city_id(self): def _inverse_city_id(self):
for company in self: for company in self:
company.with_context( company.with_context(
skip_check_zip=True).partner_id.city_id = company.city_id
skip_check_zip=True
).partner_id.city_id = company.city_id
def _inverse_zip_id(self): def _inverse_zip_id(self):
for company in self: for company in self:
company.with_context(
skip_check_zip=True).partner_id.zip_id = company.zip_id
company.with_context(skip_check_zip=True).partner_id.zip_id = company.zip_id
def _inverse_state(self): def _inverse_state(self):
return super(ResCompany, self.with_context(
skip_check_zip=True))._inverse_state()
return super(
ResCompany, self.with_context(skip_check_zip=True)
)._inverse_state()
def _inverse_country(self): def _inverse_country(self):
return super(ResCompany, self.with_context(
skip_check_zip=True))._inverse_country()
return super(
ResCompany, self.with_context(skip_check_zip=True)
)._inverse_country()
@api.onchange('zip_id')
@api.onchange("zip_id")
def _onchange_zip_id(self): def _onchange_zip_id(self):
if self.zip_id: if self.zip_id:
self.update({
'zip': self.zip_id.name,
'city_id': self.zip_id.city_id,
'city': self.zip_id.city_id.name,
'country_id': self.zip_id.city_id.country_id,
'state_id': self.zip_id.city_id.state_id,
})
self.update(
{
"zip": self.zip_id.name,
"city_id": self.zip_id.city_id,
"city": self.zip_id.city_id.name,
"country_id": self.zip_id.city_id.country_id,
"state_id": self.zip_id.city_id.state_id,
}
)
@api.onchange('state_id')
@api.onchange("state_id")
def _onchange_state_id(self): def _onchange_state_id(self):
if self.state_id.country_id: if self.state_id.country_id:
self.country_id = self.state_id.country_id.id self.country_id = self.state_id.country_id.id

74
base_location/models/res_partner.py

@ -2,83 +2,77 @@
# Copyright 2018 Tecnativa - Pedro M. Baeza # Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
class ResPartner(models.Model): class ResPartner(models.Model):
_inherit = 'res.partner'
_inherit = "res.partner"
zip_id = fields.Many2one('res.city.zip', 'ZIP Location')
zip_id = fields.Many2one("res.city.zip", "ZIP Location")
@api.onchange('city_id')
@api.onchange("city_id")
def _onchange_city_id(self): def _onchange_city_id(self):
if not self.zip_id: if not self.zip_id:
super()._onchange_city_id() super()._onchange_city_id()
if self.zip_id and self.city_id != self.zip_id.city_id: if self.zip_id and self.city_id != self.zip_id.city_id:
self.update({
'zip_id': False,
'zip': False,
'city': False,
})
self.update({"zip_id": False, "zip": False, "city": False})
if self.city_id: if self.city_id:
return {
'domain': {
'zip_id': [('city_id', '=', self.city_id.id)]
},
}
return {'domain': {'zip_id': []}}
return {"domain": {"zip_id": [("city_id", "=", self.city_id.id)]}}
return {"domain": {"zip_id": []}}
@api.onchange('country_id')
@api.onchange("country_id")
def _onchange_country_id(self): def _onchange_country_id(self):
res = super()._onchange_country_id() res = super()._onchange_country_id()
if self.zip_id and self.zip_id.city_id.country_id != self.country_id: if self.zip_id and self.zip_id.city_id.country_id != self.country_id:
self.zip_id = False self.zip_id = False
return res return res
@api.onchange('zip_id')
@api.onchange("zip_id")
def _onchange_zip_id(self): def _onchange_zip_id(self):
if self.zip_id: if self.zip_id:
vals = { vals = {
'city_id': self.zip_id.city_id,
'zip': self.zip_id.name,
'city': self.zip_id.city_id.name,
"city_id": self.zip_id.city_id,
"zip": self.zip_id.name,
"city": self.zip_id.city_id.name,
} }
if self.zip_id.city_id.country_id: if self.zip_id.city_id.country_id:
vals.update({'country_id': self.zip_id.city_id.country_id})
vals.update({"country_id": self.zip_id.city_id.country_id})
if self.zip_id.city_id.state_id: if self.zip_id.city_id.state_id:
vals.update({'state_id': self.zip_id.city_id.state_id})
vals.update({"state_id": self.zip_id.city_id.state_id})
self.update(vals) self.update(vals)
@api.constrains('zip_id', 'country_id', 'city_id', 'state_id')
@api.constrains("zip_id", "country_id", "city_id", "state_id")
def _check_zip(self): def _check_zip(self):
if self.env.context.get('skip_check_zip'):
if self.env.context.get("skip_check_zip"):
return return
for rec in self: for rec in self:
if not rec.zip_id: if not rec.zip_id:
continue continue
if rec.zip_id.city_id.state_id != rec.state_id: if rec.zip_id.city_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))
raise ValidationError(
_("The state of the partner %s differs from that in " "location %s")
% (rec.name, rec.zip_id.name)
)
if rec.zip_id.city_id.country_id != rec.country_id: if rec.zip_id.city_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))
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: 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))
raise ValidationError(
_("The city of partner %s differs from that in " "location %s")
% (rec.name, rec.zip_id.name)
)
@api.onchange('state_id')
@api.onchange("state_id")
def _onchange_state_id(self): def _onchange_state_id(self):
vals = {} vals = {}
if self.state_id.country_id: if self.state_id.country_id:
vals.update({'country_id': self.state_id.country_id})
vals.update({"country_id": self.state_id.country_id})
if self.zip_id and self.state_id != self.zip_id.city_id.state_id: if self.zip_id and self.state_id != self.zip_id.city_id.state_id:
vals.update({
'zip_id': False,
'zip': False,
'city': False,
})
vals.update({"zip_id": False, "zip": False, "city": False})
self.update(vals) self.update(vals)

254
base_location/tests/test_base_location.py

@ -1,83 +1,72 @@
# Copyright 2015 Yannick Vaucher, Camptocamp SA # Copyright 2015 Yannick Vaucher, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import psycopg2
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo.tests import tagged, common
from odoo.tests import common, tagged
from odoo.tools.misc import mute_logger from odoo.tools.misc import mute_logger
import psycopg2
@tagged('post_install', '-at_install')
@tagged("post_install", "-at_install")
class TestBaseLocation(common.SavepointCase): class TestBaseLocation(common.SavepointCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super().setUpClass() super().setUpClass()
state_obj = cls.env['res.country.state']
city_obj = cls.env['res.city']
zip_obj = cls.env['res.city.zip']
cls.partner_obj = cls.env['res.partner']
state_obj = cls.env["res.country.state"]
city_obj = cls.env["res.city"]
zip_obj = cls.env["res.city.zip"]
cls.partner_obj = cls.env["res.partner"]
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.state_vd = state_obj.create({
'name': 'Vaud',
'code': 'VD',
'country_id': cls.env.ref('base.ch').id,
})
cls.env.ref('base.es').write({
'enforce_cities': True
})
cls.company = cls.env.ref('base.main_company')
cls.state_vd = state_obj.create(
{"name": "Vaud", "code": "VD", "country_id": cls.env.ref("base.ch").id}
)
cls.env.ref("base.es").write({"enforce_cities": True})
cls.company = cls.env.ref("base.main_company")
cls.state_bcn = state_obj.create({
'name': 'Barcelona',
'code': '08',
'country_id': cls.env.ref('base.es').id,
})
cls.state_madrid = state_obj.create({
'name': 'Madrid',
'code': '28',
'country_id': cls.env.ref('base.es').id,
})
cls.city_bcn = city_obj.create({
'name': 'Barcelona',
'state_id': cls.state_bcn.id,
'country_id': cls.env.ref('base.es').id,
})
cls.city_madrid = city_obj.create({
'name': 'Madrid',
'state_id': cls.state_madrid.id,
'country_id': cls.env.ref('base.es').id,
})
cls.city_lausanne = city_obj.create({
'name': 'Lausanne',
'state_id': cls.state_vd.id,
'country_id': cls.env.ref('base.ch').id,
})
cls.lausanne = zip_obj.create({
'name': '666',
'city_id': cls.city_lausanne.id,
})
cls.barcelona = zip_obj.create({
'name': '444',
'city_id': cls.city_bcn.id,
})
cls.state_bcn = state_obj.create(
{"name": "Barcelona", "code": "08", "country_id": cls.env.ref("base.es").id}
)
cls.state_madrid = state_obj.create(
{"name": "Madrid", "code": "28", "country_id": cls.env.ref("base.es").id}
)
cls.city_bcn = city_obj.create(
{
"name": "Barcelona",
"state_id": cls.state_bcn.id,
"country_id": cls.env.ref("base.es").id,
}
)
cls.city_madrid = city_obj.create(
{
"name": "Madrid",
"state_id": cls.state_madrid.id,
"country_id": cls.env.ref("base.es").id,
}
)
cls.city_lausanne = city_obj.create(
{
"name": "Lausanne",
"state_id": cls.state_vd.id,
"country_id": cls.env.ref("base.ch").id,
}
)
cls.lausanne = zip_obj.create({"name": "666", "city_id": cls.city_lausanne.id})
cls.barcelona = zip_obj.create({"name": "444", "city_id": cls.city_bcn.id})
def test_onchange_partner_city_completion(self): def test_onchange_partner_city_completion(self):
"""Test that partner data is filled accodingly""" """Test that partner data is filled accodingly"""
partner1 = self.partner_obj.new({
'name': 'Camptocamp',
})
partner1 = self.partner_obj.new({"name": "Camptocamp"})
partner1.zip_id = self.barcelona partner1.zip_id = self.barcelona
partner1._onchange_zip_id() partner1._onchange_zip_id()
self.assertEqual(partner1.zip, self.barcelona.name) self.assertEqual(partner1.zip, self.barcelona.name)
self.assertEqual(partner1.city, self.barcelona.city_id.name) self.assertEqual(partner1.city, self.barcelona.city_id.name)
self.assertEqual(partner1.state_id, self.barcelona.city_id.state_id) self.assertEqual(partner1.state_id, self.barcelona.city_id.state_id)
self.assertEqual(partner1.country_id,
self.barcelona.city_id.country_id)
self.assertEqual(partner1.country_id, self.barcelona.city_id.country_id)
def test_onchange_company_city_completion(self): def test_onchange_company_city_completion(self):
"""Test that company data is filled accodingly""" """Test that company data is filled accodingly"""
company = self.env['res.company'].new({'name': 'Test'})
company = self.env["res.company"].new({"name": "Test"})
company.zip_id = self.lausanne company.zip_id = self.lausanne
company._onchange_zip_id() company._onchange_zip_id()
self.assertEqual(company.zip, self.lausanne.name) self.assertEqual(company.zip, self.lausanne.name)
@ -88,27 +77,25 @@ class TestBaseLocation(common.SavepointCase):
def test_company_address_fields(self): def test_company_address_fields(self):
"""Test if the partner address fields changes when """Test if the partner address fields changes when
changing the ones from the company""" changing the ones from the company"""
company = self.env['res.company'].create({
'name': 'Test',
})
company = self.env["res.company"].create({"name": "Test"})
self.assertTrue(company.partner_id) self.assertTrue(company.partner_id)
company.partner_id.write({
'zip_id': self.lausanne.id,
'state_id': self.lausanne.city_id.state_id.id,
'country_id': self.lausanne.city_id.country_id.id,
'city_id': self.lausanne.city_id.id,
'city': self.lausanne.city_id.name,
'zip': self.lausanne.name,
})
company.partner_id.write(
{
"zip_id": self.lausanne.id,
"state_id": self.lausanne.city_id.state_id.id,
"country_id": self.lausanne.city_id.country_id.id,
"city_id": self.lausanne.city_id.id,
"city": self.lausanne.city_id.name,
"zip": self.lausanne.name,
}
)
company._compute_address() company._compute_address()
self.assertEqual(company.zip_id, company.partner_id.zip_id) self.assertEqual(company.zip_id, company.partner_id.zip_id)
self.assertEqual(company.city_id, company.partner_id.city_id) self.assertEqual(company.city_id, company.partner_id.city_id)
def test_company_address_fields_inverse(self): def test_company_address_fields_inverse(self):
"""Test inverse fields from res.company""" """Test inverse fields from res.company"""
company = self.env['res.company'].create({
'name': 'Test',
})
company = self.env["res.company"].create({"name": "Test"})
company.zip_id = self.barcelona.id company.zip_id = self.barcelona.id
company._inverse_city_id() company._inverse_city_id()
company._inverse_zip_id() company._inverse_zip_id()
@ -117,7 +104,7 @@ class TestBaseLocation(common.SavepointCase):
def test_onchange_company_city_id_completion(self): def test_onchange_company_city_id_completion(self):
"""Test city auto-completion when changing zip in a company""" """Test city auto-completion when changing zip in a company"""
company = self.env['res.company'].new({'name': 'Test'})
company = self.env["res.company"].new({"name": "Test"})
company.zip_id = self.barcelona company.zip_id = self.barcelona
company._onchange_zip_id() company._onchange_zip_id()
self.assertEqual(company.city_id, self.barcelona.city_id) self.assertEqual(company.city_id, self.barcelona.city_id)
@ -125,83 +112,77 @@ class TestBaseLocation(common.SavepointCase):
def test_constrains_partner_01(self): def test_constrains_partner_01(self):
"""Test partner 1 constraints""" """Test partner 1 constraints"""
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
self.partner_obj.create({
'name': 'P1',
'zip_id': self.barcelona.id,
})
self.partner_obj.create({"name": "P1", "zip_id": self.barcelona.id})
def test_writing_company(self): def test_writing_company(self):
self.company.zip_id = self.barcelona self.company.zip_id = self.barcelona
def test_constrains_partner_country(self): def test_constrains_partner_country(self):
"""Test partner country constraints""" """Test partner country constraints"""
partner = self.partner_obj.create({
'name': 'P1',
'zip_id': self.barcelona.id,
'country_id': self.barcelona.city_id.country_id.id,
'state_id': self.barcelona.city_id.state_id.id,
'city_id': self.barcelona.city_id.id,
})
partner = self.partner_obj.create(
{
"name": "P1",
"zip_id": self.barcelona.id,
"country_id": self.barcelona.city_id.country_id.id,
"state_id": self.barcelona.city_id.state_id.id,
"city_id": self.barcelona.city_id.id,
}
)
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
partner.country_id = self.ref('base.ch')
partner.country_id = self.ref("base.ch")
def test_constrains_partner_state(self): def test_constrains_partner_state(self):
"""Test partner state constraints""" """Test partner state constraints"""
partner = self.partner_obj.create({
'name': 'P1',
'zip_id': self.barcelona.id,
'country_id': self.barcelona.city_id.country_id.id,
'state_id': self.barcelona.city_id.state_id.id,
'city_id': self.barcelona.city_id.id,
})
partner = self.partner_obj.create(
{
"name": "P1",
"zip_id": self.barcelona.id,
"country_id": self.barcelona.city_id.country_id.id,
"state_id": self.barcelona.city_id.state_id.id,
"city_id": self.barcelona.city_id.id,
}
)
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
partner.state_id = self.state_vd.id partner.state_id = self.state_vd.id
def test_constrains_partner_city(self): def test_constrains_partner_city(self):
"""Test partner city constraints""" """Test partner city constraints"""
partner = self.partner_obj.create({
'name': 'P1',
'zip_id': self.barcelona.id,
'country_id': self.barcelona.city_id.country_id.id,
'state_id': self.barcelona.city_id.state_id.id,
'city_id': self.barcelona.city_id.id,
})
partner = self.partner_obj.create(
{
"name": "P1",
"zip_id": self.barcelona.id,
"country_id": self.barcelona.city_id.country_id.id,
"state_id": self.barcelona.city_id.state_id.id,
"city_id": self.barcelona.city_id.id,
}
)
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
partner.city_id = self.city_lausanne partner.city_id = self.city_lausanne
def test_partner_onchange_country(self): def test_partner_onchange_country(self):
"""Test partner onchange country_id""" """Test partner onchange country_id"""
partner = self.partner_obj.new({
'name': 'TEST',
'zip_id': self.lausanne.id
})
partner.country_id = self.env.ref('base.es')
partner = self.partner_obj.new({"name": "TEST", "zip_id": self.lausanne.id})
partner.country_id = self.env.ref("base.es")
partner._onchange_country_id() partner._onchange_country_id()
self.assertFalse(partner.zip_id) self.assertFalse(partner.zip_id)
def test_partner_onchange_city(self): def test_partner_onchange_city(self):
"""Test partner onchange city_id""" """Test partner onchange city_id"""
partner = self.partner_obj.new({
'name': 'TEST',
'zip_id': self.lausanne.id
})
partner = self.partner_obj.new({"name": "TEST", "zip_id": self.lausanne.id})
self.city_bcn.country_id.enforce_cities = False self.city_bcn.country_id.enforce_cities = False
partner.city_id = self.city_bcn partner.city_id = self.city_bcn
partner._onchange_city_id() partner._onchange_city_id()
self.assertFalse(partner.zip_id) self.assertFalse(partner.zip_id)
partner.city_id = False partner.city_id = False
res = partner._onchange_city_id() res = partner._onchange_city_id()
self.assertFalse(res['domain']['zip_id'])
self.assertFalse(res["domain"]["zip_id"])
def test_partner_onchange_state(self): def test_partner_onchange_state(self):
"""Test partner onchange state_id""" """Test partner onchange state_id"""
partner = self.partner_obj.new({
'name': 'TEST',
'zip_id': self.lausanne.id
})
partner = self.partner_obj.new({"name": "TEST", "zip_id": self.lausanne.id})
partner.state_id = self.state_bcn partner.state_id = self.state_bcn
partner._onchange_state_id() partner._onchange_state_id()
self.assertFalse(partner.zip_id) self.assertFalse(partner.zip_id)
@ -211,64 +192,57 @@ class TestBaseLocation(common.SavepointCase):
"""Test company onchange state_id""" """Test company onchange state_id"""
self.company.state_id = self.state_bcn self.company.state_id = self.state_bcn
self.company._onchange_state_id() self.company._onchange_state_id()
self.assertEqual(self.company.country_id,
self.company.state_id.country_id)
self.assertEqual(self.company.country_id, self.company.state_id.country_id)
def test_display_name(self): def test_display_name(self):
"""Test if the display_name is stored and computed properly""" """Test if the display_name is stored and computed properly"""
self.assertEqual( self.assertEqual(
self.lausanne.display_name, self.lausanne.display_name,
'666, Lausanne, Vaud, ' + self.browse_ref(
'base.ch'
).name
"666, Lausanne, Vaud, " + self.browse_ref("base.ch").name,
) )
def test_name_search(self): def test_name_search(self):
"""Test that zips can be searched through both the name of the """Test that zips can be searched through both the name of the
city or the zip code""" city or the zip code"""
madrid_data = {
'city_id': self.city_madrid.id,
'name': '555',
}
madrid_data = {"city_id": self.city_madrid.id, "name": "555"}
madrid = self.env['res.city.zip'].create(madrid_data)
madrid = self.env["res.city.zip"].create(madrid_data)
found_recs = self.env['res.city.zip'].name_search(name='444')
found_recs = self.env["res.city.zip"].name_search(name="444")
self.assertEqual(len(found_recs), 1) self.assertEqual(len(found_recs), 1)
self.assertEqual(found_recs[0][0], self.barcelona.id) self.assertEqual(found_recs[0][0], self.barcelona.id)
found_recs = self.env['res.city.zip'].name_search(name='Barcelona')
found_recs = self.env["res.city.zip"].name_search(name="Barcelona")
self.assertEqual(len(found_recs), 1) self.assertEqual(len(found_recs), 1)
self.assertEqual(found_recs[0][0], self.barcelona.id) self.assertEqual(found_recs[0][0], self.barcelona.id)
found_recs = self.env['res.city.zip'].name_search(name='555')
found_recs = self.env["res.city.zip"].name_search(name="555")
self.assertEqual(len(found_recs), 1) self.assertEqual(len(found_recs), 1)
self.assertEqual(found_recs[0][0], madrid.id) self.assertEqual(found_recs[0][0], madrid.id)
found_recs = self.env['res.city.zip'].name_search(name='Madrid')
found_recs = self.env["res.city.zip"].name_search(name="Madrid")
self.assertEqual(len(found_recs), 1) self.assertEqual(len(found_recs), 1)
self.assertEqual(found_recs[0][0], madrid.id) self.assertEqual(found_recs[0][0], madrid.id)
found_recs = self.env['res.city.zip'].name_search(name='666')
found_recs = self.env["res.city.zip"].name_search(name="666")
self.assertEqual(len(found_recs), 1) self.assertEqual(len(found_recs), 1)
self.assertEqual(found_recs[0][0], self.lausanne.id) self.assertEqual(found_recs[0][0], self.lausanne.id)
found_recs = self.env['res.city.zip'].name_search(name='Lausanne')
found_recs = self.env["res.city.zip"].name_search(name="Lausanne")
self.assertEqual(len(found_recs), 1) self.assertEqual(len(found_recs), 1)
self.assertEqual(found_recs[0][0], self.lausanne.id) self.assertEqual(found_recs[0][0], self.lausanne.id)
def test_zip_ql_constraints(self): def test_zip_ql_constraints(self):
"""Test UNIQUE name within it's area for zips""" """Test UNIQUE name within it's area for zips"""
with self.assertRaises(
psycopg2.IntegrityError), mute_logger('odoo.sql_db'):
self.env['res.city.zip'].create({
'name': '666',
'city_id': self.city_lausanne.id,
})
with self.assertRaises(psycopg2.IntegrityError), mute_logger("odoo.sql_db"):
self.env["res.city.zip"].create(
{"name": "666", "city_id": self.city_lausanne.id}
)
def test_city_sql_contraint(self): def test_city_sql_contraint(self):
"""Test UNIQUE name within it's area for cities""" """Test UNIQUE name within it's area for cities"""
with self.assertRaises(
psycopg2.IntegrityError), mute_logger('odoo.sql_db'):
self.env['res.city'].create({
'name': 'Barcelona',
'state_id': self.state_bcn.id,
'country_id': self.ref('base.es'),
})
with self.assertRaises(psycopg2.IntegrityError), mute_logger("odoo.sql_db"):
self.env["res.city"].create(
{
"name": "Barcelona",
"state_id": self.state_bcn.id,
"country_id": self.ref("base.es"),
}
)

39
base_location/views/res_city_view.xml

@ -1,62 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<record id="view_city_tree_inherit" model="ir.ui.view"> <record id="view_city_tree_inherit" model="ir.ui.view">
<field name="model">res.city</field> <field name="model">res.city</field>
<field name="inherit_id" ref="base_address_city.view_city_tree"/>
<field name="inherit_id" ref="base_address_city.view_city_tree" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree position="attributes"> <tree position="attributes">
<attribute name="editable"/>
<attribute name="editable" />
</tree> </tree>
<field name="zipcode" position="attributes"> <field name="zipcode" position="attributes">
<attribute name="invisible">1</attribute> <attribute name="invisible">1</attribute>
</field> </field>
<field name="zipcode" position="after"> <field name="zipcode" position="after">
<field name="zip_ids" widget="many2many_tags"/>
<field name="zip_ids" widget="many2many_tags" />
</field> </field>
</field> </field>
</record> </record>
<record id="view_city_form" model="ir.ui.view"> <record id="view_city_form" model="ir.ui.view">
<field name="model">res.city</field> <field name="model">res.city</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form> <form>
<group> <group>
<field name="name"/>
<field name="country_id"/>
<field name="state_id"/>
<field name="name" />
<field name="country_id" />
<field name="state_id" />
</group> </group>
<notebook> <notebook>
<page name="zips" string="Zips"> <page name="zips" string="Zips">
<field name="zip_ids"/>
<field name="zip_ids" />
</page> </page>
</notebook> </notebook>
</form> </form>
</field> </field>
</record> </record>
<record id="action_res_city_full" model="ir.actions.act_window"> <record id="action_res_city_full" model="ir.actions.act_window">
<field name="name">Cities</field> <field name="name">Cities</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">res.city</field> <field name="res_model">res.city</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="view_ids"
eval="[(5,0,0),
<field
name="view_ids"
eval="[(5,0,0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('base_address_city.view_city_tree')}), (0, 0, {'view_mode': 'tree', 'view_id': ref('base_address_city.view_city_tree')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('view_city_form')})]"/>
(0, 0, {'view_mode': 'form', 'view_id': ref('view_city_form')})]"
/>
<field name="help"> <field name="help">
Display and manage the list of all cities that can be assigned to Display and manage the list of all cities that can be assigned to
your partner records. Note that an option can be set on each country separately your partner records. Note that an option can be set on each country separately
to enforce any address of it to have a city in this list. to enforce any address of it to have a city in this list.
</field> </field>
</record> </record>
<menuitem <menuitem
name="Cities"
id="locations_menu_cities"
parent="contacts.menu_localisation"
action="action_res_city_full"
sequence="4"
name="Cities"
id="locations_menu_cities"
parent="contacts.menu_localisation"
action="action_res_city_full"
sequence="4"
/> />
</odoo> </odoo>

26
base_location/views/res_city_zip_view.xml

@ -1,55 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<record model="ir.ui.view" id="city_zip_form"> <record model="ir.ui.view" id="city_zip_form">
<field name="name">res.city.zip.form</field> <field name="name">res.city.zip.form</field>
<field name="model">res.city.zip</field> <field name="model">res.city.zip</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Zip"> <form string="Zip">
<group> <group>
<field name="name"/>
<field name="city_id"/>
<field name="name" />
<field name="city_id" />
</group> </group>
</form> </form>
</field> </field>
</record> </record>
<record model="ir.ui.view" id="city_zip_tree"> <record model="ir.ui.view" id="city_zip_tree">
<field name="name">res.city.zip.tree</field> <field name="name">res.city.zip.tree</field>
<field name="model">res.city.zip</field> <field name="model">res.city.zip</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Zips" editable="top"> <tree string="Zips" editable="top">
<field name="name"/>
<field name="city_id"/>
<field name="name" />
<field name="city_id" />
</tree> </tree>
</field> </field>
</record> </record>
<record id="view_city_zip_filter" model="ir.ui.view"> <record id="view_city_zip_filter" model="ir.ui.view">
<field name="name">res.city.zip.select</field> <field name="name">res.city.zip.select</field>
<field name="model">res.city.zip</field> <field name="model">res.city.zip</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Search zip"> <search string="Search zip">
<field name="name"/>
<field name="city_id"/>
<field name="name" />
<field name="city_id" />
</search> </search>
</field> </field>
</record> </record>
<record id="action_zip_tree" model="ir.actions.act_window"> <record id="action_zip_tree" model="ir.actions.act_window">
<field name="name">Locations</field> <field name="name">Locations</field>
<field name="res_model">res.city.zip</field> <field name="res_model">res.city.zip</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field ref="city_zip_tree" name="view_id"/>
<field name="search_view_id" ref="view_city_zip_filter"/>
<field ref="city_zip_tree" name="view_id" />
<field name="search_view_id" ref="view_city_zip_filter" />
</record> </record>
<menuitem <menuitem
name="Zips" name="Zips"
id="locations_menu_zips" id="locations_menu_zips"
parent="contacts.menu_localisation" parent="contacts.menu_localisation"
action="action_zip_tree" action="action_zip_tree"
sequence="5" sequence="5"
/>
/>
</odoo> </odoo>

22
base_location/views/res_company_view.xml

@ -1,6 +1,5 @@
<?xml version="1.0"?>
<?xml version="1.0" ?>
<odoo> <odoo>
<!-- Add cities to the company form --> <!-- Add cities to the company form -->
<record id="view_company_form_city" model="ir.ui.view"> <record id="view_company_form_city" model="ir.ui.view">
<field name="name">res.company.form.city</field> <field name="name">res.company.form.city</field>
@ -8,20 +7,25 @@
<field name="inherit_id" ref="base.view_company_form" /> <field name="inherit_id" ref="base.view_company_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="street2" position="after"> <field name="street2" position="after">
<field name="zip_id"
<field
name="zip_id"
options="{'create_name_field': 'city'}" options="{'create_name_field': 'city'}"
colspan="4" colspan="4"
placeholder="City completion" />
placeholder="City completion"
/>
</field> </field>
<field name="city" position="after"> <field name="city" position="after">
<field name="country_enforce_cities" invisible="1"/>
<field name='city_id'
attrs="{'invisible': [('country_enforce_cities', '=', False)]}"/>
<field name="country_enforce_cities" invisible="1" />
<field
name='city_id'
attrs="{'invisible': [('country_enforce_cities', '=', False)]}"
/>
</field> </field>
<field name="city" position="attributes"> <field name="city" position="attributes">
<attribute name="invisible">[('country_enforce_cities', '=', True)]</attribute>
<attribute
name="invisible"
>[('country_enforce_cities', '=', True)]</attribute>
</field> </field>
</field> </field>
</record> </record>
</odoo> </odoo>

17
base_location/views/res_country_view.xml

@ -1,31 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="view_country_search" model="ir.ui.view"> <record id="view_country_search" model="ir.ui.view">
<field name="name">res.country.search</field> <field name="name">res.country.search</field>
<field name="model">res.country</field> <field name="model">res.country</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Country"> <search string="Country">
<field name="name"/>
<field name="code"/>
<field name="name" />
<field name="code" />
</search> </search>
</field> </field>
</record> </record>
<record id="view_res_country_city_better_zip_form" model="ir.ui.view"> <record id="view_res_country_city_better_zip_form" model="ir.ui.view">
<field name="model">res.country</field> <field name="model">res.country</field>
<field name="inherit_id" ref="base.view_country_form"/>
<field name="inherit_id" ref="base.view_country_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//div[hasclass('oe_button_box')]" position="inside"> <xpath expr="//div[hasclass('oe_button_box')]" position="inside">
<button name="%(action_zip_tree)d"
<button
name="%(action_zip_tree)d"
class="oe_stat_button" class="oe_stat_button"
icon="fa-globe" icon="fa-globe"
type="action" type="action"
context="{'default_country_id': active_id, 'search_default_country_id': active_id}" context="{'default_country_id': active_id, 'search_default_country_id': active_id}"
string="Zips">
string="Zips"
>
</button> </button>
</xpath> </xpath>
</field> </field>
</record> </record>
</odoo> </odoo>

33
base_location/views/res_partner_view.xml

@ -1,25 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<record id="view_partner_form" model="ir.ui.view"> <record id="view_partner_form" model="ir.ui.view">
<field name="name">res.partner.zip_id.2</field> <field name="name">res.partner.zip_id.2</field>
<field name="model">res.partner</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="arch" type="xml">
<field name="city" position="before"> <field name="city" position="before">
<field name="zip_id"
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
name="zip_id"
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> </field>
<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"/>
<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"
/>
</xpath> </xpath>
</field> </field>
</record> </record>
</odoo> </odoo>
Loading…
Cancel
Save