123 lines
3.9 KiB
Python
123 lines
3.9 KiB
Python
# 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 sql import Literal
|
|
from sql.conditionals import Coalesce
|
|
|
|
from trytond.model import ModelSQL, ModelView, fields, sequence_ordered
|
|
from trytond.pool import Pool, PoolMeta
|
|
from trytond.pyson import Eval
|
|
from trytond.transaction import Transaction
|
|
|
|
|
|
class Party(metaclass=PoolMeta):
|
|
__name__ = 'party.party'
|
|
|
|
purchase_incoterms = fields.One2Many(
|
|
'party.incoterm', 'party', "Purchase Incoterms",
|
|
filter=[
|
|
('type', '=', 'purchase'),
|
|
],
|
|
help="Incoterms available for use with the supplier.\n"
|
|
"Leave empty for all.")
|
|
sale_incoterms = fields.One2Many(
|
|
'party.incoterm', 'party', "Sale Incoterms",
|
|
filter=[
|
|
('type', '=', 'sale'),
|
|
],
|
|
help="Incoterms available for use with the customer.\n"
|
|
"Leave empty for all.")
|
|
|
|
|
|
class Address(metaclass=PoolMeta):
|
|
__name__ = 'party.address'
|
|
|
|
is_incoterm_related = fields.Function(
|
|
fields.Boolean("Is Incoterm Related"),
|
|
'get_is_incoterm_related')
|
|
|
|
@classmethod
|
|
def _is_incoterm_related_query(cls, type=None, party=None):
|
|
pool = Pool()
|
|
Incoterm = pool.get('party.incoterm')
|
|
context = Transaction().context
|
|
if party is None:
|
|
party = context.get('related_party')
|
|
if type is None:
|
|
type = context.get('incoterm_type')
|
|
if not party:
|
|
return
|
|
table = Incoterm.__table__()
|
|
where = table.party == party
|
|
if type:
|
|
where &= table.type == type
|
|
return table.select(
|
|
table.incoterm_location.as_('address'),
|
|
Literal(True).as_('is_related'),
|
|
where=where,
|
|
group_by=[table.incoterm_location])
|
|
|
|
@classmethod
|
|
def get_is_incoterm_related(cls, addresses, name):
|
|
is_related = {a.id: False for a in addresses}
|
|
query = cls._is_incoterm_related_query()
|
|
if query:
|
|
cursor = Transaction().connection.cursor()
|
|
cursor.execute(*query)
|
|
is_related.update(cursor)
|
|
return is_related
|
|
|
|
@classmethod
|
|
def order_is_incoterm_related(cls, tables):
|
|
address, _ = tables[None]
|
|
key = 'is_incoterm_related'
|
|
if key not in tables:
|
|
query = cls._is_incoterm_related_query()
|
|
if not query:
|
|
return []
|
|
join = address.join(query, type_='LEFT',
|
|
condition=query.address == address.id)
|
|
tables[key] = {
|
|
None: (join.right, join.condition),
|
|
}
|
|
else:
|
|
query, _ = tables[key][None]
|
|
return [Coalesce(query.is_related, False)]
|
|
|
|
|
|
class Incoterm(sequence_ordered(), ModelView, ModelSQL):
|
|
__name__ = 'party.incoterm'
|
|
|
|
party = fields.Many2One(
|
|
'party.party', "Party", required=True, ondelete='CASCADE',
|
|
context={
|
|
'company': Eval('company', -1),
|
|
},
|
|
depends={'company'})
|
|
company = fields.Many2One('company.company', "Company")
|
|
type = fields.Selection([
|
|
('purchase', "Purchase"),
|
|
('sale', "Sale"),
|
|
], "Type", required=True)
|
|
incoterm = fields.Many2One(
|
|
'incoterm.incoterm', "Incoterm", required=True, ondelete='CASCADE')
|
|
incoterm_location = fields.Many2One(
|
|
'party.address', "Incoterm Location", ondelete='CASCADE',
|
|
search_context={
|
|
'related_party': Eval('party'),
|
|
},
|
|
search_order=[
|
|
('party.distance', 'ASC NULLS LAST'),
|
|
('id', None),
|
|
],
|
|
depends={'party'})
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls.__access__.add('party')
|
|
|
|
@classmethod
|
|
def default_company(cls):
|
|
return Transaction().context.get('company')
|