trytond-stock_product_categ.../location.py
2021-09-24 10:02:16 +02:00

125 lines
4.2 KiB
Python

# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields
from trytond.pyson import Eval, Bool, Not, Equal
from trytond.pool import PoolMeta, Pool
from trytond.transaction import Transaction
from trytond.exceptions import UserError
from trytond.i18n import gettext
from sql.aggregate import Max
__all__ = ['ProductCategoryLocation', 'Location']
class ProductCategoryLocation(ModelSQL, ModelView):
"""Product Category Location"""
__name__ = 'stock.product.category.location'
category = fields.Many2One(
'product.category', 'Category', required=True,
select=True, ondelete='CASCADE')
warehouse = fields.Many2One('stock.location', 'Warehouse', required=True,
domain=[('type', '=', 'warehouse')],
states={
'invisible': Bool(
Eval('context', {}).get('current_location', None)),
'readonly': Bool(
Eval('context', {}).get('current_location', None)),
},
ondelete='CASCADE')
location = fields.Many2One('stock.location', 'Storage Location',
required=True, ondelete='CASCADE',
domain=[
('type', '=', 'storage'),
('parent', 'child_of', Eval('warehouse'))
], depends=['warehouse'])
sequence = fields.Integer('Sequence')
@staticmethod
def _compute_sequence_where(table, record):
return (
(table.category == record['category'])
& (table.warehouse == record['warehouse']))
@staticmethod
def _compute_sequence(table, record):
cursor = Transaction().connection.cursor()
seq_sel = table.select(
Max(table.sequence).as_('max_sequence'))
seq_sel.where = ProductCategoryLocation._compute_sequence_where(
table, record)
cursor.execute(*seq_sel)
rec = cursor.fetchall()[0]
return rec[0] + 1 if rec[0] else 1
@classmethod
def create(cls, vlist):
vlist = [x.copy() for x in vlist]
for values in vlist:
if not values.get('sequence', None):
values['sequence'] = cls._compute_sequence(
cls.__table__(), values)
return super().create(vlist)
@classmethod
def default_warehouse(cls):
Location = Pool().get('stock.location')
loc_id = Transaction().context.get('current_location', None)
if loc_id:
loc = Location(loc_id)
if loc and loc.type == 'storage':
while not loc.parent.type == 'warehouse':
loc = loc.parent
return loc.parent.id
return None
def _get_unique_key(self):
return (self.category.id, self.location.id)
@classmethod
def validate(cls, records):
values = {}
for record in records:
_uq = record._get_unique_key()
if values.get(_uq):
raise UserError(gettext(
'stock_product_category_location.'
'msg_category_location_unique_key'))
values.setdefault(_uq, 1)
others = cls.search([('id', 'not in', list(map(int, records)))])
for other in others:
_uq = other._get_unique_key()
if values.get(_uq):
raise UserError(gettext(
'stock_product_category_location.'
'msg_category_location_unique_key'))
super().validate(records)
class Location(metaclass=PoolMeta):
__name__ = 'stock.location'
categories = fields.One2Many('stock.product.category.location',
'location', 'Categories',
states={
'invisible': Not(Equal(Eval('type'), 'storage'))
},
context={'current_location': Eval('id')})
wh_categories = fields.One2Many('stock.product.category.location',
'warehouse', 'Categories',
states={
'invisible': Not(Equal(Eval('type'), 'warehouse'))
},
context={'current_location': Eval('id')})
@classmethod
def view_attributes(cls):
return super().view_attributes() + [
('//page[@id="categories"]', 'states', {
'invisible': ~Eval('type').in_(['warehouse', 'storage'])})]