diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/base_address_city/models | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/base_address_city/models')
| -rw-r--r-- | addons/base_address_city/models/__init__.py | 6 | ||||
| -rw-r--r-- | addons/base_address_city/models/res_city.py | 16 | ||||
| -rw-r--r-- | addons/base_address_city/models/res_country.py | 13 | ||||
| -rw-r--r-- | addons/base_address_city/models/res_partner.py | 91 |
4 files changed, 126 insertions, 0 deletions
diff --git a/addons/base_address_city/models/__init__.py b/addons/base_address_city/models/__init__.py new file mode 100644 index 00000000..7d7f5d58 --- /dev/null +++ b/addons/base_address_city/models/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import res_city +from . import res_country +from . import res_partner diff --git a/addons/base_address_city/models/res_city.py b/addons/base_address_city/models/res_city.py new file mode 100644 index 00000000..c542a1a3 --- /dev/null +++ b/addons/base_address_city/models/res_city.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class City(models.Model): + _name = 'res.city' + _description = 'City' + _order = 'name' + + name = fields.Char("Name", required=True, translate=True) + zipcode = fields.Char("Zip") + country_id = fields.Many2one('res.country', string='Country', required=True) + state_id = fields.Many2one( + 'res.country.state', 'State', domain="[('country_id', '=', country_id)]") diff --git a/addons/base_address_city/models/res_country.py b/addons/base_address_city/models/res_country.py new file mode 100644 index 00000000..a3de7de6 --- /dev/null +++ b/addons/base_address_city/models/res_country.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class Country(models.Model): + _inherit = 'res.country' + + enforce_cities = fields.Boolean( + string='Enforce Cities', + help="Check this box to ensure every address created in that country has a 'City' chosen " + "in the list of the country's cities.") diff --git a/addons/base_address_city/models/res_partner.py b/addons/base_address_city/models/res_partner.py new file mode 100644 index 00000000..f49d3e43 --- /dev/null +++ b/addons/base_address_city/models/res_partner.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from lxml import etree + +from odoo import api, models, fields +from odoo.tools.translate import _ + + +class Partner(models.Model): + _inherit = 'res.partner' + + country_enforce_cities = fields.Boolean(related='country_id.enforce_cities', readonly=True) + city_id = fields.Many2one('res.city', string='City of Address') + + @api.onchange('city_id') + def _onchange_city_id(self): + if self.city_id: + self.city = self.city_id.name + self.zip = self.city_id.zipcode + self.state_id = self.city_id.state_id + elif self._origin: + self.city = False + self.zip = False + self.state_id = False + + @api.model + def _fields_view_get_address(self, arch): + arch = super(Partner, self)._fields_view_get_address(arch) + # render the partner address accordingly to address_view_id + doc = etree.fromstring(arch) + if doc.xpath("//field[@name='city_id']"): + return arch + + replacement_xml = """ + <div> + <field name="country_enforce_cities" invisible="1"/> + <field name="parent_id" invisible="1"/> + <field name='city' placeholder="%(placeholder)s" class="o_address_city" + attrs="{ + 'invisible': [('country_enforce_cities', '=', True), '|', ('city_id', '!=', False), ('city', 'in', ['', False ])], + 'readonly': [('type', '=', 'contact')%(parent_condition)s] + }" + /> + <field name='city_id' placeholder="%(placeholder)s" string="%(placeholder)s" class="o_address_city" + context="{'default_country_id': country_id, + 'default_name': city, + 'default_zipcode': zip, + 'default_state_id': state_id}" + domain="[('country_id', '=', country_id)]" + attrs="{ + 'invisible': [('country_enforce_cities', '=', False)], + 'readonly': [('type', '=', 'contact')%(parent_condition)s] + }" + /> + </div> + """ + + replacement_data = { + 'placeholder': _('City'), + } + + def _arch_location(node): + in_subview = False + view_type = False + parent = node.getparent() + while parent is not None and (not view_type or not in_subview): + if parent.tag == 'field': + in_subview = True + elif parent.tag in ['list', 'tree', 'kanban', 'form']: + view_type = parent.tag + parent = parent.getparent() + return { + 'view_type': view_type, + 'in_subview': in_subview, + } + + for city_node in doc.xpath("//field[@name='city']"): + location = _arch_location(city_node) + replacement_data['parent_condition'] = '' + if location['view_type'] == 'form' or not location['in_subview']: + replacement_data['parent_condition'] = ", ('parent_id', '!=', False)" + + replacement_formatted = replacement_xml % replacement_data + for replace_node in etree.fromstring(replacement_formatted).getchildren(): + city_node.addprevious(replace_node) + parent = city_node.getparent() + parent.remove(city_node) + + arch = etree.tostring(doc, encoding='unicode') + return arch |
