trytond-stock_party_warehouse/party.py

283 lines
9.5 KiB
Python

# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.pool import PoolMeta, Pool
from trytond.model import fields, ModelView, ModelSQL, ValueMixin
from trytond.wizard import Wizard, StateView, Button, StateTransition
from trytond.pyson import Not, Bool, Eval
from trytond.transaction import Transaction
from trytond import backend
from sql import Null
class Party(metaclass=PoolMeta):
__name__ = 'party.party'
warehouse = fields.MultiValue(fields.Many2One('stock.location',
"Party Warehouse", domain=[('type', '=', 'warehouse')]))
warehouses = fields.One2Many('party.party.warehouse', 'party',
"Party Warehouses")
create_warehouse = fields.Function(
fields.Boolean('Create Warehouse',
states={
'readonly': Bool(Eval('warehouse')) | ~Eval('active'),
'invisible': Bool(Eval('warehouse'))
},
depends=['warehouse', 'active']),
'get_create_warehouse', setter='set_create_warehouse')
def get_create_warehouse(self, name=None):
return bool(self.warehouse)
@classmethod
def set_create_warehouse(cls, records, name, value):
pool = Pool()
CreateWarehouse = pool.get('party.party.create_warehouse',
type='wizard')
PartyWarehouse = pool.get('party.party.warehouse')
Configuration = pool.get('stock.configuration')
Location = pool.get('stock.location')
if not value:
return
to_save = []
conf = Configuration(1)
for record in records:
if record.warehouse:
continue
if Transaction().context.get('create_party', False):
warehouse = PartyWarehouse(party=record)
warehouse.save()
PartyWarehouse.create_warehouse([warehouse])
else:
warehouse = CreateWarehouse._get_warehouse(Location,
record.name, conf.party_warehouse_parent)
warehouse.save()
record.warehouse = warehouse
to_save.append(record)
if to_save:
cls.save(to_save)
@classmethod
def create(cls, vlist):
with Transaction().set_context(create_party=True):
return super().create(vlist)
@classmethod
def _multivalue_setter(cls, records, name, val):
if (name == 'warehouse'
and Transaction().context.get('create_party', False)
and not val):
return
super()._multivalue_setter(records, name, val)
class PartyWarehouse(ModelSQL, ModelView, ValueMixin):
"Party Warehouse"
__name__ = 'party.party.warehouse'
party = fields.Many2One('party.party', "Party", select=True,
required=True, ondelete='CASCADE')
warehouse = fields.Many2One('stock.location', "Warehouse",
domain=[('type', '=', 'warehouse')], ondelete='RESTRICT')
@classmethod
def __setup__(cls):
super().__setup__()
cls._order.insert(0, ('party', 'ASC'))
cls._buttons.update({
'create_warehouse':
{
'readonly': Bool(Eval('warehouse')),
'invisible': Bool(Eval('warehouse')),
'depends': ['warehouse']
}
})
@property
def warehouse_name(self):
return self.party.name
@classmethod
def __register__(cls, module_name):
pool = Pool()
Party = pool.get('party.party')
cursor = Transaction().connection.cursor()
table = cls.__table__()
party = Party.__table__()
exist = backend.TableHandler.table_exist(cls._table)
super().__register__(module_name)
if not exist:
party_h = Party.__table_handler__(module_name)
if party_h.column_exist('warehouse'):
cursor.execute(*table.insert([
table.create_uid,
table.create_date,
table.party,
table.warehouse,
],
party.select(
party.create_uid,
party.create_date,
party.id,
party.warehouse,
where=party.warehouse != Null))
)
party_h.drop_column('warehouse')
@classmethod
def create_warehouse(cls, records):
pool = Pool()
CreateWarehouse = pool.get('party.party.create_warehouse',
type='wizard')
Configuration = pool.get('stock.configuration')
Location = pool.get('stock.location')
to_save = []
conf = Configuration(1)
for record in records:
if not record.warehouse:
warehouse = CreateWarehouse._get_warehouse(Location,
record.warehouse_name, conf.party_warehouse_parent)
warehouse.save()
record.warehouse = warehouse
to_save.append(record)
if to_save:
cls.save(to_save)
class CreateWarehouseStart(ModelView):
"""Create Party Warehouse Start"""
__name__ = 'party.party.create_warehouse.start'
warehouse_per_party = fields.Boolean('Warehouse per party')
warehouse = fields.Many2One('stock.location', 'Warehouse',
domain=[
('type', '=', 'warehouse'),
],
states={
'required': (
Not(Bool(Eval('warehouse_per_party')))
& Not(Eval('warehouse_name'))),
'invisible': (
Bool(Eval('warehouse_per_party'))
| Eval('warehouse_name'))
},
depends=['warehouse_per_party', 'warehouse_name'])
warehouse_name = fields.Char('Name',
states={
'invisible': (Eval('warehouse_per_party') | Eval('warehouse')),
'required': (
Not(Eval('warehouse_per_party'))
& Not(Eval('warehouse')))
},
depends=['warehouse_per_party', 'warehouse'],
help='Determines the name for a new Warehouse.')
parent = fields.Many2One('stock.location', 'Parent',
domain=[
('type', '=', 'view'),
],
states={
'required': (
Bool(Eval('warehouse_per_party'))
| Eval('warehouse_name')),
'invisible': (
Not(Bool(Eval('warehouse_per_party')))
& Not(Eval('warehouse_name'))),
},
depends=['warehouse_per_party', 'warehouse_name'])
@fields.depends('warehouse')
def on_change_warehouse(self):
if self.warehouse:
self.warehouse_per_party = False
self.warehouse_name = None
@fields.depends('warehouse_per_party')
def on_change_warehouse_per_party(self):
if self.warehouse_per_party:
self.warehouse = None
self.warehouse_name = None
@classmethod
def view_attributes(cls):
attributes = super().view_attributes()
attributes.append(
('//group[@id="new_warehouse"]', 'states',
{'invisible': Eval('warehouse')})
)
return attributes
class CreateWarehouse(Wizard):
"""Create Party Warehouse"""
__name__ = 'party.party.create_warehouse'
start = StateView('party.party.create_warehouse.start',
'stock_party_warehouse.party_create_warehouse_start_view_form',
[Button('Cancel', 'end', 'tryton-cancel'),
Button('OK', 'add_', 'tryton-ok', default=True)])
add_ = StateTransition()
def default_start(self, fields):
pool = Pool()
Configuration = pool.get('stock.configuration')
conf = Configuration(1)
res = {'warehouse_per_party': True}
if conf.party_warehouse_parent:
res['parent'] = conf.party_warehouse_parent.id
return res
def transition_add_(self):
pool = Pool()
Party = pool.get('party.party')
Location = pool.get('stock.location')
parties = Party.browse(Transaction().context['active_ids'])
if self.start.warehouse_per_party:
to_save = []
for party in parties:
if party.warehouse:
continue
warehouse = self._get_warehouse(Location, party.name,
self.start.parent)
to_save.append(warehouse)
party.warehouse = warehouse
Location.save(to_save)
Party.save(parties)
else:
if self.start.warehouse_name:
warehouse = self._get_warehouse(Location,
self.start.warehouse_name, self.start.parent)
warehouse.save()
else:
warehouse = self.start.warehouse
Party.write(parties, {'warehouse': warehouse})
return 'end'
@classmethod
def _get_warehouse(cls, Location, name, parent):
ModelData = Pool().get('ir.model.data')
prod_location = Location(ModelData.get_id(
'production', 'location_production'))
storage_location = Location(
name=name,
type='storage')
storage_location.save()
return Location(
name=name,
type='warehouse',
parent=parent,
input_location=storage_location,
output_location=storage_location,
storage_location=storage_location,
production_location=prod_location,
)