# This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. from trytond.i18n import lazy_gettext from trytond.model import Model, fields from trytond.pool import Pool from trytond.pyson import Eval, If __all__ = ['IncotermMixin', 'IncotermAvailableMixin'] class IncotermMixin(Model): incoterm = fields.Many2One( 'incoterm.incoterm', lazy_gettext('incoterm.msg_incoterm'), ondelete='RESTRICT') incoterm_location = fields.Many2One( 'party.address', lazy_gettext('incoterm.msg_incoterm_location'), ondelete='RESTRICT', search_order=[ ('is_incoterm_related', 'DESC NULLS LAST'), ('party.distance', 'ASC NULLS LAST'), ('id', None), ]) @classmethod def __setup__(cls): super().__setup__() readonly = cls._incoterm_readonly_state() cls.incoterm.states = { 'readonly': readonly, } cls.incoterm_location.states = { 'readonly': readonly, 'invisible': ~Eval('incoterm', False), } related_party, related_party_depends = cls._incoterm_related_party() cls.incoterm_location.search_context = { 'related_party': related_party, } cls.incoterm_location.depends = {'incoterm'} | related_party_depends @classmethod def _incoterm_readonly_state(cls): return ~Eval('state').in_(['draft']) @classmethod def _incoterm_related_party(cls): return Eval('party'), {'party'} @property def incoterm_name(self): name = '' if self.incoterm: name = self.incoterm.rec_name if self.incoterm_location: name += ' %s' % self.incoterm_location.rec_name return name class IncotermAvailableMixin(IncotermMixin): available_incoterms = fields.Function(fields.Many2Many( 'incoterm.incoterm', None, None, "Available Incoterms"), 'on_change_with_available_incoterms') incoterm_location_required = fields.Function(fields.Boolean( lazy_gettext('incoterm.msg_incoterm_location_required')), 'on_change_with_incoterm_location_required') @classmethod def __setup__(cls): super().__setup__() readonly = cls._incoterm_readonly_state() cls.incoterm.domain = [ If(~readonly, ('id', 'in', Eval('available_incoterms', [])), ()), ] cls.incoterm_location.states['required'] = ( Eval('incoterm_location_required', False)) @fields.depends('company', 'party', methods=['_get_incoterm_pattern']) def on_change_with_available_incoterms(self, name=None): pool = Pool() Incoterm = pool.get('incoterm.incoterm') pattern = self._get_incoterm_pattern() incoterms = Incoterm.get_incoterms(self.company, pattern) if self.party: party_incoterms = {r.incoterm for r in self._party_incoterms} else: party_incoterms = set() return [ i for i in incoterms if not party_incoterms or i in party_incoterms] @fields.depends() def _get_incoterm_pattern(self): return {} @fields.depends('incoterm') def on_change_with_incoterm_location_required(self, name=None): if self.incoterm: return self.incoterm.location @fields.depends(methods=['_set_default_incoterm']) def on_change_company(self): try: super_on_change = super().on_change_company except AttributeError: pass else: super_on_change() self._set_default_incoterm() @fields.depends(methods=['_set_default_incoterm']) def on_change_party(self): try: super_on_change = super().on_change_party except AttributeError: pass else: super_on_change() self._set_default_incoterm() @fields.depends('incoterm', 'party', 'company', methods=['_party_incoterms']) def on_change_incoterm(self): if self.incoterm: if self._party_incoterms: for record in self._party_incoterms: if record.company and record.company != self.company: continue if record.incoterm == self.incoterm: self.incoterm_location = record.incoterm_location break else: self.incoterm_location = None else: self.incoterm_location = None @fields.depends('incoterm', 'party', 'company', methods=['on_change_with_available_incoterms', '_incoterm_required', '_party_incoterms']) def _set_default_incoterm(self): self.available_incoterms = self.on_change_with_available_incoterms() if not self.available_incoterms: self.incoterm = None self.incoterm_location = None elif self._incoterm_required: if self.incoterm not in self.available_incoterms: if len(self.available_incoterms) == 1: self.incoterm, = self.available_incoterms else: self.incoterm = None self.incoterm_location = None if self.party and self._party_incoterms: for record in self._party_incoterms: if record.company and record.company != self.company: continue if record.incoterm in self.available_incoterms: self.incoterm = record.incoterm self.incoterm_location = record.incoterm_location break else: self.incoterm = None self.incoterm_location = None elif self.incoterm not in self.available_incoterms: self.incoterm = None self.incoterm_location = None @property def _party_incoterms(self): raise NotImplementedError @property def _incoterm_required(self): raise NotImplementedError