adapt to 4.7

This commit is contained in:
?ngel ?lvarez 2018-10-09 09:56:40 +02:00
parent d1d29fa4ec
commit 2a6325c193
20 changed files with 120 additions and 115 deletions

View file

@ -1,31 +1,36 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.pool import Pool
from .package import *
from .product import *
from .move import *
from .period import *
from .lot import *
from .shipment import *
from .inventory import *
from .location import *
from . import package
from . import product
from . import move
from . import period
from . import lot
from . import shipment
from . import inventory
from . import location
def register():
Pool.register(
Template,
Product,
ProductPack,
Move,
Period,
PeriodCache,
PeriodCacheLot,
PeriodCachePackage,
Lot,
ShipmentIn,
ShipmentOut,
ShipmentOutReturn,
Inventory,
InventoryLine,
Location,
move.Move,
package.ProductPack,
product.Template,
product.Product,
period.Period,
period.PeriodCache,
period.PeriodCachePackage,
shipment.ShipmentIn,
shipment.ShipmentOut,
shipment.ShipmentOutReturn,
inventory.Inventory,
inventory.InventoryLine,
location.Location,
module='stock_number_of_packages', type_='model')
Pool.register(
lot.Lot,
move.MoveLot,
inventory.LotInventoryLine,
period.PeriodCacheLot,
depends=['stock_lot'],
module='stock_number_of_packages', type_='model')

View file

@ -4,14 +4,14 @@ from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
from .move import StockPackagedMixin
from .move import StockPackagedMixin, LotPackagedMixin
__all__ = ['Inventory', 'InventoryLine']
__metaclass__ = PoolMeta
class Inventory:
__name__ = 'stock.inventory'
__metaclass__ = PoolMeta
@classmethod
def grouping(cls):
@ -49,8 +49,8 @@ class Inventory:
stock_date_end=inventory.date,
number_of_packages=True):
pbl = Product.products_by_location(
[inventory.location.id], product_ids=product_ids,
grouping=grouping)
[inventory.location.id],
grouping=grouping, grouping_filter=(product_ids,))
# Index some data
product2type = {}
@ -66,7 +66,7 @@ class Inventory:
continue
key = (inventory.location.id,) + line.unique_key
if key in pbl:
number_of_packages = pbl.pop(key)
number_of_packages = int(pbl.pop(key))
else:
number_of_packages = 0
if (line.number_of_packages == line.expected_number_of_packages
@ -98,7 +98,7 @@ class Inventory:
values = Line.create_values4complete(inventory, 0.)
for i, fname in enumerate(grouping, 1):
values[fname] = key[i]
values['expected_number_of_packages'] = number_of_packages
values['expected_number_of_packages'] = int(number_of_packages)
if getattr(inventory, 'init_quantity_zero', False):
values['number_of_packages'] = 0
else:
@ -108,8 +108,14 @@ class Inventory:
Line.create(to_create)
class LotInventoryLine(LotPackagedMixin):
__name__ = 'stock.inventory.line'
__metaclass__ = PoolMeta
class InventoryLine(StockPackagedMixin):
__name__ = 'stock.inventory.line'
__metaclass__ = PoolMeta
expected_number_of_packages = fields.Integer('Expected Number of packages',
readonly=True)
@ -139,14 +145,16 @@ class InventoryLine(StockPackagedMixin):
return 0
@fields.depends('inventory', '_parent_inventory.date',
'_parent_inventory.location', 'product', 'lot', 'package')
'_parent_inventory.location', 'product', 'package',
methods=['expected_number_of_packages'])
def on_change_with_expected_number_of_packages(self):
if not self.inventory or not self.product:
return
return self._compute_expected_number_of_packages(
self.inventory,
self.product.id,
self.lot.id if getattr(self, 'lot', None) else None,
(self.lot.id if hasattr(self, 'lot') and
getattr(self, 'lot', None) else None),
self.package.id if self.package else None)
def get_move(self):
@ -227,7 +235,7 @@ class InventoryLine(StockPackagedMixin):
stock_date_end=inventory.date,
number_of_packages=True):
pbl = Product.products_by_location(
[inventory.location.id], product_ids=[product_id],
[inventory.location.id], grouping_filter=([product_id],),
grouping=grouping)
if key in pbl:

View file

@ -5,11 +5,11 @@ from trytond.pool import PoolMeta
from trytond.transaction import Transaction
__all__ = ['Location']
__metaclass__ = PoolMeta
class Location:
__name__ = 'stock.location'
__metaclass__ = PoolMeta
number_of_packages = fields.Function(fields.Integer('Number of packages'),
'get_number_of_packages')
forecast_number_of_packages = fields.Function(

20
lot.py
View file

@ -10,7 +10,6 @@ from trytond.pyson import Bool, Eval
from .move import StockMixin
__all__ = ['Lot']
__metaclass__ = PoolMeta
STATES_ON_CREATE = {
@ -26,6 +25,8 @@ DEPENDS_REQUIRED = DEPENDS_ON_CREATE + ['package_required']
class Lot(StockMixin):
__name__ = 'stock.lot'
__metaclass__ = PoolMeta
package = fields.Many2One('product.pack', 'Packaging', domain=[
('product.products', 'in', [Eval('product')]),
],
@ -152,7 +153,6 @@ class Lot(StockMixin):
return self.product_uom.digits
return self.default_product_unit_digits()
@property
def is_weight_uom(self):
pool = Pool()
ModelData = pool.get('ir.model.data')
@ -161,21 +161,21 @@ class Lot(StockMixin):
weight_uom_category = ModelData.get_id('product', 'uom_cat_weight')
return self.product.default_uom.category.id == weight_uom_category
@fields.depends('package_qty', methods=['weight_by_package'])
@fields.depends('package_qty','product',
'product_uom', methods=['weight_by_package'])
def on_change_with_package_qty(self, name=None):
pool = Pool()
ModelData = pool.get('ir.model.data')
Uom = pool.get('product.uom')
self.weight_by_package = self.on_change_with_weight_by_package()
if self.is_weight_uom and self.weight_by_package:
if self.is_weight_uom() and self.weight_by_package:
kg = Uom(ModelData.get_id('product', 'uom_kilogram'))
return Uom.compute_qty(kg, self.weight_by_package,
self.product_uom)
return self.package_qty
@fields.depends('initial_number_of_packages', 'package_qty',
methods=['package_qty', 'product_unit_digits'])
@fields.depends('initial_number_of_packages', 'package_qty')
def on_change_with_total_qty(self, name=None):
pool = Pool()
Uom = pool.get('product.uom')
@ -232,9 +232,9 @@ class Lot(StockMixin):
return
return self._round_weight(self.gross_weight - self.pallet_weight)
@fields.depends(methods=['total_qty', 'gross_weight_packages'])
@fields.depends('product', methods=['total_qty', 'gross_weight_packages'])
def on_change_with_unit_gross_weight(self, name=None):
if self.is_weight_uom:
if self.is_weight_uom():
return
self.gross_weight_packages = (
@ -244,9 +244,9 @@ class Lot(StockMixin):
return 0.0
return self._round_weight(self.gross_weight_packages / self.total_qty)
@fields.depends(methods=['total_qty', 'weight'])
@fields.depends('product', methods=['total_qty', 'weight'])
def on_change_with_unit_weight(self, name=None):
if self.is_weight_uom:
if self.is_weight_uom():
return
self.weight = self.on_change_with_weight()

40
move.py
View file

@ -11,45 +11,45 @@ from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, In
from trytond.transaction import Transaction
from .package import PackagedMixin
from trytond.modules.stock_number_of_packages.package import PackagedMixin
__all__ = ['StockPackagedMixin', 'StockMixin', 'Move']
__metaclass__ = PoolMeta
__all__ = ['StockPackagedMixin', 'StockMixin', 'Move', 'MoveLot']
class StockPackagedMixin(PackagedMixin):
class LotPackagedMixin(object):
@classmethod
def __setup__(cls):
super(StockPackagedMixin, cls).__setup__()
super(LotPackagedMixin, cls).__setup__()
if hasattr(cls, 'lot'):
cls.package.states['readonly'] = Bool(Eval('lot'))
cls.package.depends.append('lot')
cls.package.on_change.add('lot')
if cls.quantity.on_change:
cls.quantity.on_change.add('lot')
cls.quantity.on_change.add('lot')
cls.number_of_packages.on_change.add('lot')
@fields.depends('lot', 'package', methods=['package'])
@fields.depends('package', methods=['package'])
def on_change_lot(self):
try:
super(StockPackagedMixin, self).on_change_lot()
super(LotPackagedMixin, self).on_change_lot()
except AttributeError:
pass
if self.lot:
if hasattr(self, 'lot') and getattr(self, 'lot', None):
if self.lot.package and self.package != self.lot.package:
self.package = self.lot.package
elif not self.lot.package and self.package:
self.package = None
self.on_change_package()
class StockPackagedMixin(PackagedMixin):
def check_package(self, quantity):
if self.number_of_packages and self.number_of_packages < 0:
self.raise_user_error('number_of_packages_positive', self.rec_name)
super(StockPackagedMixin, self).check_package(quantity)
class StockMixin:
class StockMixin(object):
package_required = fields.Function(fields.Boolean('Packaging Required'),
'get_package_required', searcher='search_package_required')
number_of_packages = fields.Function(fields.Integer('Number of packages',
@ -80,11 +80,13 @@ class StockMixin:
return super(StockMixin, cls)._quantity_context(name)
@classmethod
def _get_quantity(cls, records, name, location_ids, products=None,
grouping=('product',), position=-1):
def _get_quantity(cls, records, name, location_ids,
grouping=('product',), grouping_filter=None, position=-1):
quantities = super(StockMixin, cls)._get_quantity(records, name,
location_ids, products=products, grouping=grouping,
position=position)
location_ids, grouping=grouping,
grouping_filter=grouping_filter, position=position)
if name.endswith('number_of_packages'):
for key, quantity in quantities.iteritems():
if quantity != None:
@ -92,8 +94,14 @@ class StockMixin:
return quantities
class MoveLot(LotPackagedMixin):
__name__ = 'stock.move'
__metaclass__ = PoolMeta
class Move(StockPackagedMixin):
__name__ = 'stock.move'
__metaclass__ = PoolMeta
@classmethod
def __setup__(cls):

View file

@ -7,10 +7,9 @@ from trytond.tools import grouped_slice
from trytond.transaction import Transaction
__all__ = ['PackagedMixin', 'ProductPack']
__metaclass__ = PoolMeta
class PackagedMixin:
class PackagedMixin(object):
package = fields.Many2One('product.pack', 'Packaging', domain=[
('product.products', 'in', [Eval('product')]),
],
@ -34,7 +33,7 @@ class PackagedMixin:
else:
self.package = None
@fields.depends('package', 'number_of_packages', 'lot')
@fields.depends('package', 'quantity', 'number_of_packages')
def on_change_package(self):
if hasattr(self, 'lot') and getattr(self, 'lot', None):
package_qty = self.lot.package_qty
@ -108,6 +107,7 @@ class PackagedMixin:
class ProductPack:
__name__ = 'product.pack'
__metaclass__ = PoolMeta
@classmethod
def __setup__(cls):

View file

@ -5,10 +5,9 @@ from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
__all__ = ['Period', 'PeriodCache', 'PeriodCacheLot', 'PeriodCachePackage']
__metaclass__ = PoolMeta
class NumberOfPackagesCacheMixin:
class NumberOfPackagesCacheMixin(object):
number_of_packages = fields.Integer('Number of packages', readonly=True)
@classmethod
@ -46,6 +45,7 @@ class NumberOfPackagesCacheMixin:
class Period:
__name__ = 'stock.period'
__metaclass__ = PoolMeta
package_caches = fields.One2Many('stock.period.cache.package', 'period',
'Package Caches', readonly=True)
@ -64,6 +64,7 @@ class Period:
class PeriodCache(NumberOfPackagesCacheMixin):
__name__ = 'stock.period.cache'
__metaclass__ = PoolMeta
@classmethod
def create(cls, vlist):
@ -73,6 +74,7 @@ class PeriodCache(NumberOfPackagesCacheMixin):
class PeriodCacheLot(NumberOfPackagesCacheMixin):
__name__ = 'stock.period.cache.lot'
__metaclass__ = PoolMeta
@classmethod
def create(cls, vlist):

View file

@ -7,11 +7,11 @@ from trytond.pyson import Eval
from .move import StockMixin
__all__ = ['Template', 'Product']
__metaclass__ = PoolMeta
class Template:
__name__ = 'product.template'
__metaclass__ = PoolMeta
package_required = fields.Boolean('Packaging Requried')
default_package = fields.Many2One('product.pack', 'Default Packaging',
domain=[
@ -56,6 +56,7 @@ class Template:
class Product(StockMixin):
__name__ = 'product.product'
__metaclass__ = PoolMeta
def get_package_required(self, name):
return self.template.package_required

View file

@ -4,11 +4,11 @@ from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
__all__ = ['ShipmentIn', 'ShipmentOut', 'ShipmentOutReturn']
__metaclass__ = PoolMeta
class ShipmentIn:
__name__ = 'stock.shipment.in'
__metaclass__ = PoolMeta
@classmethod
def _get_inventory_moves(cls, incoming_move):
@ -22,6 +22,7 @@ class ShipmentIn:
class ShipmentOut:
__name__ = 'stock.shipment.out'
__metaclass__ = PoolMeta
def _get_inventory_move(self, move):
inventory_move = super(ShipmentOut, self)._get_inventory_move(move)
@ -57,6 +58,7 @@ class ShipmentOut:
class ShipmentOutReturn:
__name__ = 'stock.shipment.out.return'
__metaclass__ = PoolMeta
@classmethod
def _get_inventory_moves(cls, incoming_move):

View file

@ -1,3 +1,6 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from .test_stock_number_of_packages import suite
__all__ = ['suite']

View file

@ -12,22 +12,15 @@ Imports::
>>> from dateutil.relativedelta import relativedelta
>>> from decimal import Decimal
>>> from proteus import config, Model, Wizard
>>> from trytond.tests.tools import activate_modules
>>> from trytond.modules.company.tests.tools import create_company, \
... get_company
>>> today = datetime.date.today()
>>> last_month = today - relativedelta(months=1)
Create database::
>>> config = config.set_trytond()
>>> config.pool.test = True
Install stock_number_of_packages Module::
>>> Module = Model.get('ir.module')
>>> stock_module, = Module.find([('name', '=', 'stock_number_of_packages')])
>>> stock_module.click('install')
>>> Wizard('ir.module.install_upgrade').execute('upgrade')
>>> config = activate_modules('stock_number_of_packages')
Create company::
@ -137,22 +130,25 @@ Receive products one month ago::
>>> incoming_move.from_location = supplier_loc
>>> incoming_move.to_location = shipment_in.warehouse_input
>>> shipment_in.save()
>>> shipment_in.click('receive')
>>> shipment_in.click('done')
>>> ShipmentIn.receive([shipment_in], config.context)
>>> ShipmentIn.done([shipment_in], config.context)
>>> shipment_in.reload()
>>> shipment_in.state
u'done'
Check available quantities::
>>> with config.set_context({'locations': [storage_loc.id], 'stock_date_end': today}):
... product_wo_package.reload()
... product_wo_package.quantity
... product_wo_package.number_of_packages
... product_w_package.reload()
... product_w_package.quantity
... product_w_package.number_of_packages
100.0
0
>>> config._context['locations'] = [storage_loc.id]
>>> product_w_package = Product(product_w_package.id, config._context)
>>> product_w_package.quantity
76.0
>>> product_w_package.number_of_packages
16
>>> product_wo_package = Product(product_wo_package.id, config._context)
>>> product_wo_package.quantity
100.0
>>> product_wo_package.number_of_packages
0
Create an inventory::

View file

@ -21,27 +21,12 @@ Imports::
>>> today = datetime.date.today()
>>> last_month = today - relativedelta(months=1)
Create database::
>>> config = config.set_trytond()
>>> config.pool.test = True
Install stock_number_of_packages Module::
>>> Module = Model.get('ir.module')
>>> stock_module, = Module.find([('name', '=', 'stock_number_of_packages')])
>>> stock_module.click('install')
>>> stock_module, = Module.find([('name', '=', 'stock_lot')])
>>> stock_module.click('install')
>>> stock_module, = Module.find([('name', '=', 'stock_inventory_product_category')])
>>> stock_module.click('install')
>>> stock_module, = Module.find([('name', '=', 'stock_lot_quantity')])
>>> stock_module.click('install')
>>> stock_module, = Module.find([('name', '=', 'sale')])
>>> stock_module.click('install')
>>> stock_module, = Module.find([('name', '=', 'purchase')])
>>> stock_module.click('install')
>>> Wizard('ir.module.install_upgrade').execute('upgrade')
>>> config = activate_modules('stock_number_of_packages', 'stock_lot',
... 'stock_inventory_product_category', 'stock_lot_quantit', 'sale',
... 'purchase'])
Create company::

View file

@ -6,19 +6,12 @@ import trytond.tests.test_tryton
from trytond.tests.test_tryton import ModuleTestCase
from trytond.tests.test_tryton import doctest_setup, doctest_teardown
from trytond.tests.test_tryton import doctest_checker
from trytond.tests.test_tryton import install_module, drop_create
class StockNumberOfPackagesTestCase(ModuleTestCase):
'Test Stock Number of Packages module'
module = 'stock_number_of_packages'
@classmethod
def setUpClass(cls):
drop_create()
super(ModuleTestCase, cls).setUpClass()
install_module('stock_lot')
def suite():
suite = trytond.tests.test_tryton.suite()

View file

@ -1,5 +1,5 @@
[tryton]
version=4.1.0
version=4.7.0
depends:
product_pack
stock

View file

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form string="Period Cache" col="6">
<form col="6">
<label name="period"/>
<field name="period" colspan="5"/>
<label name="location"/>

View file

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree string="Period Package Caches">
<tree>
<field name="period"/>
<field name="location"/>
<field name="product"/>

View file

@ -4,5 +4,7 @@
<data>
<xpath expr="/tree/field[@name='default_uom']" position="after">
<field name="default_package"/>
<field name="number_of_packages"/>
<field name="forecast_number_of_packages"/>
</xpath>
</data>
</data>