partner.py 4.18 KB
from sqlite3 import DatabaseError

from odoo import api, fields, models, _
from psycopg2 import sql, DatabaseError
import logging

_logger = logging.getLogger(__name__)


class ResPartner(models.Model):
    _inherit = 'res.partner'
    supplier_rank = fields.Integer(default=0)
    customer_rank = fields.Integer(default=0)
    company_id = fields.Many2one('res.company', string="Company",
                                 default=lambda self: self.env.company.id
                                 if not self.company_id else False
                                 )
    country_id = fields.Many2one('res.country', string="Country",
                                 default=lambda self: self.env.company.country_id
                                 if not self.country_id else False
                                 )
    state_id = fields.Many2one('res.country.state', string="State",
                               domain="[('country_id', '=?', country_id)]",
                               default=lambda self: self.env.company.state_id
                               if not self.state_id else False
                               )
    district_id = fields.Many2one('res.district', string="Kabupaten/Kota",
                                  ondelete='restrict',
                                  domain="[('state_id', '=?', state_id)]",
                                  default=lambda self: self.env.company.district_id
                                  if not self.district_id else False
                                  )
    sub_district_id = fields.Many2one('res.district.sub', string="Kecamatan",
                                      ondelete='restrict',
                                      domain="[('district_id', '=?', district_id)]"
                                      )
    village_id = fields.Many2one('res.district.village', string="Desa/Kelurahan",
                                 ondelete='restrict',
                                 domain="[('sub_district_id', '=?', sub_district_id)]"
                                 )

    def _get_name_search_order_by_fields(self):
        res = super()._get_name_search_order_by_fields()
        partner_search_mode = self.env.context.get('res_partner_search_mode')
        if not partner_search_mode in ('customer', 'supplier'):
            return res
        order_by_field = 'COALESCE(res_partner.%s, 0) DESC,'
        if partner_search_mode == 'customer':
            field = 'customer_rank'
        else:
            field = 'supplier_rank'

        order_by_field = order_by_field % field
        return '%s, %s' % (res, order_by_field % field) if res else order_by_field

    @api.model_create_multi
    def create(self, vals_list):
        search_partner_mode = self.env.context.get('res_partner_search_mode')
        is_customer = search_partner_mode == 'customer'
        is_supplier = search_partner_mode == 'supplier'
        if search_partner_mode:
            for vals in vals_list:
                if is_customer and 'customer_rank' not in vals:
                    vals['customer_rank'] = 1
                elif is_supplier and 'supplier_rank' not in vals:
                    vals['supplier_rank'] = 1
        return super().create(vals_list)

    def _increase_rank(self, field, n=1):
        if self.ids and field in ['customer_rank', 'supplier_rank']:
            try:
                with self.env.cr.savepoint(flush=False):
                    query = sql.SQL("""
                        SELECT {field} FROM res_partner WHERE ID IN %(partner_ids)s FOR UPDATE NOWAIT;
                        UPDATE res_partner SET {field} = {field} + %(n)s
                        WHERE id IN %(partner_ids)s
                    """).format(field=sql.Identifier(field))
                    self.env.cr.execute(query, {'partner_ids': tuple(self.ids), 'n': n})
                    for partner in self:
                        self.env.cache.remove(partner, partner._fields[field])
            except DatabaseError as e:
                if e.pgcode == '55P03':
                    _logger.debug('Another transaction already locked partner rows. Cannot update partner ranks.')
                else:
                    raise e