district.py 10.8 KB
import logging

from odoo import api, fields, models
from odoo.exceptions import ValidationError
from odoo.osv import expression

_logger = logging.getLogger(__name__)


def get_selection_label(self, obj, field_name, field_value):
    return dict(self.env[obj].fields_get(allfields=[field_name])[field_name][
                    'selection'])[field_value]


class CountryState(models.Model):
    _inherit = 'res.country.state'
    district_ids = fields.One2many('res.district', 'state_id',
                                   string='Kota/Kabupaten')

    def name_get(self):
        result = []
        for record in self:
            result.append(
                (record.id, "{} ({})".format(record.name, record.code)))
        return result


class District(models.Model):
    _name = 'res.district'
    _description = 'Kota/Kabupaten'
    state_id = fields.Many2one('res.country.state', string='Provinsi',
                               required=True)
    typ = fields.Selection([
        ('kab', 'Kabupaten'),
        ('kabtif', 'Kabupaten Administratif'),
        ('kota', 'Kota'),
        ('kotif', 'Kota Administratif')],
        string='Jenis', required=True)
    code = fields.Char(string="Kode Kota/Kabupaten", required=True)
    name = fields.Char(string="Nama Kota/Kabupaten", index=True, required=True)
    # display_code = fields.Char(compute='_compute_display_code', store=True, index=True)
    # display_name = fields.Char(compute='_compute_display_name', store=True, index=True)
    sub_district_ids = fields.One2many('res.district.sub', 'district_id',
                                       string='Kecamatan')
    # address_view_id = fields.Many2one(
    #     comodel_name='ir.ui.view', string="Input View",
    #     domain=[('model', '=', 'res.partner'), ('type', '=', 'form')],
    #     help="Use this field if you want to replace the usual way to encode a complete address. "
    #          "Note that the address_format field is used to modify the way to display addresses "
    #          "(in reports for example), while this field is used to modify the input form for "
    #          "addresses.")
    #
    # image_url = fields.Char(
    #     compute="_compute_image_url", string="Flag",
    #     help="Url of static flag image",
    # )
    _sql_constraints = [
        ('code_uniq', 'unique (state_id,code)',
         'Kode Kabupaten/Kota Harus Unik !'),
        ('name_uniq', 'unique (state_id,typ,name)',
         'Nama Kabupaten/Kota Harus Unik !'),
    ]

    @api.model
    def _name_search(self, name, args=None, operator='ilike', limit=100,
                     name_get_uid=None):
        args = args or []
        if self.env.context.get('state_id'):
            args = expression.AND(
                [args, [('state_id', '=', self.env.context.get('state_id'))]])

        if operator == 'ilike' and not (name or '').strip():
            first_domain = []
            domain = []
        else:
            first_domain = [('code', '=ilike', name)]
            domain = [('name', operator, name)]

        first_district_ids = self._search(expression.AND([first_domain, args]),
                                          limit=limit,
                                          access_rights_uid=name_get_uid) if first_domain else []
        first_ids = list(first_district_ids) + [
            district_id
            for district_id in self._search(expression.AND([domain, args]),
                                            limit=limit,
                                            access_rights_uid=name_get_uid)
            if district_id not in first_district_ids
        ]
        # _logger.info(self.env.context.get('country_id'))
        # _logger.info(first_ids)
        return first_ids

    # @api.depends('code')
    # def _compute_display_code(self):
    #     self.display_code = "{}.{}".format(self.state_id.code, self.code)

    # @api.depends('name')
    # def _compute_display_name(self):
    #     pass
    # self.display_name = "{} {}".format(self.typ, self.name)

    def name_get(self):
        result = []
        for record in self:
            result.append((record.id, "{} {} ({}.{})".format(
                get_selection_label(self, self._name, 'typ', record.typ),
                record.name, record.state_id.code, record.code)))
        return result

    def code_get(self):
        result = []
        for record in self:
            result.append(
                (record.id, "{}.{}".format(record.state_id.code, record.code)))
        return result

    # @api.model_create_multi
    # def create(self, vals_list):
    #     for vals in vals_list:
    #         if vals.get('code'):
    #             vals['code'] = vals['code'].upper()
    #     return super(District, self).create(vals_list)
    #
    # def write(self, vals):
    #     if vals.get('code'):
    #         vals['code'] = vals['code'].upper()
    #     return super(District, self).write(vals)
    #
    # def get_address_fields(self):
    #     self.ensure_one()
    #     return re.findall(r'\((.+?)\)', self.address_format)
    #
    # @api.depends('code')
    # def _compute_image_url(self):
    #     for district in self:
    #         if not district.code:
    #             district.image_url = False
    #         else:
    #             code = self.display_code
    #             district.image_url = "/base/static/img/district_flags/%s.png" % code


class SubDistrict(models.Model):
    _name = 'res.district.sub'
    _description = 'Kecamatan'
    district_id = fields.Many2one('res.district', string='Kabupaten/Kota',
                                  required=True)
    code = fields.Char(string="Kode Kecamatan")
    name = fields.Char(string="Nama Kecamatan", index=True)
    _sql_constraints = [
        ('code_uniq', 'unique (district_id,code)',
         'Kode Kecamatan Harus Unik !'),
        ('name_uniq', 'unique (district_id,name)',
         'Nama Kecamatan Harus Unik !'),
    ]

    @api.model
    def _name_search(self, name, args=None, operator='ilike', limit=100,
                     name_get_uid=None):
        args = args or []
        if self.env.context.get('district_id'):
            args = expression.AND([args, [
                ('district_id', '=', self.env.context.get('district_id'))]])

        if operator == 'ilike' and not (name or '').strip():
            first_domain = []
            domain = []
        else:
            first_domain = [('code', '=ilike', name)]
            domain = [('name', operator, name)]

        first_sub_district_ids = self._search(
            expression.AND([first_domain, args]), limit=limit,
            access_rights_uid=name_get_uid) if first_domain else []
        return list(first_sub_district_ids) + [
            district_id
            for district_id in self._search(expression.AND([domain, args]),
                                            limit=limit,
                                            access_rights_uid=name_get_uid)
            if district_id not in first_sub_district_ids
        ]

    def code_get(self):
        result = []
        for record in self:
            result.append((record.id, "{}.{}.{}".format(
                record.district_id.state_id.code, record.district_id.code,
                record.code)))
        return result

    def name_get(self):
        result = []
        for record in self:
            result.append((record.id, "{} ({}.{}.{})".format(
                record.name, record.district_id.state_id.code,
                record.district_id.code, record.code)))
        return result


class Village(models.Model):
    _name = 'res.district.village'
    _description = "Desa/Keurahan"
    sub_district_id = fields.Many2one('res.district.sub', string='Kecamatan',
                                      required=True)
    typ = fields.Selection([
        ('desa', 'Desa'),
        ('kelurahan', 'Kelurahan')],
        string='Jenis')
    code = fields.Char(string="Kode Desa/Kelurahan")
    name = fields.Char(string="Nama Desa/Kelurahan", index=True)
    zip = fields.Char(string="Kode Pos Desa/Kelurahan", size=5, )
    _sql_constraints = [
        ('village_code_uniq', 'unique (sub_district_id,code)',
         'Kode Kelurahan/Desa Harus Unik !'),
        ('village_name_uniq', 'unique (sub_district_id,typ,name)',
         'Nama Kelurahan/Desa  Harus Unik !'),
    ]

    @api.model
    def _name_search(self, name, args=None, operator='ilike', limit=100,
                     name_get_uid=None):
        args = args or []
        if self.env.context.get('sub_district_id'):
            args = expression.AND([args, [('sub_district_id', '=',
                                           self.env.context.get(
                                               'sub_district_id'))]])
        # _logger.info(self.env.context.get('sub_district_id'))
        # _logger.info(args)

        if operator == 'ilike' and not (name or '').strip():
            first_domain = []
            domain = []
        else:
            first_domain = [('code', '=ilike', name)]
            domain = [('name', operator, name)]

        first_village_ids = self._search(expression.AND([first_domain, args]),
                                         limit=limit,
                                         access_rights_uid=name_get_uid) if first_domain else []
        first_ids = list(first_village_ids) + [
            sub_district_id
            for sub_district_id in self._search(expression.AND([domain, args]),
                                                limit=limit,
                                                access_rights_uid=name_get_uid)
            if sub_district_id not in first_village_ids
        ]
        # _logger.info(first_ids)
        # _logger.info(first_village_ids)
        return first_ids

    def code_get(self):
        result = []
        for record in self:
            result.append((record.id, "{}.{}.{}".format(
                record.sub_district_id.district_id.state_id.code,
                record.sub_district_id.district_id.code,
                record.sub_district_id.code, record.code)))
        return result

    def name_get(self):
        result = []
        for record in self:
            result.append((record.id, "{} {} ({}.{}.{}.{})".format(
                get_selection_label(self, self._name, 'typ', record.typ),
                record.name,
                record.sub_district_id.district_id.state_id.code,
                record.sub_district_id.district_id.code,
                record.sub_district_id.code, record.code)))
        return result

    @api.constrains('zip')
    def _check_zip(self):
        if self.zip:
            if len(self.zip) < 5:
                raise ValidationError('Kode Pos harus 5 digit')