Index: __init__.py =================================================================== --- ./modules/stock_lot/__init__.py +++ ./modules/stock_lot/__init__.py @@ -21,4 +21,9 @@ Template, Product, TemplateLotType, + Location, + LotByLocationStart, module='stock_lot', type_='model') + Pool.register( + LotByLocation, + module='stock_lot', type_='wizard') Index: stock.py =================================================================== --- ./modules/stock_lot/stock.py +++ ./modules/stock_lot/stock.py @@ -1,17 +1,20 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of #this repository contains the full copyright notices and license terms. +import datetime from collections import defaultdict from trytond.model import ModelView, ModelSQL, Workflow, fields -from trytond.pyson import Eval +from trytond.pyson import PYSONEncoder, Eval from trytond.pool import Pool, PoolMeta from trytond.transaction import Transaction +from trytond.wizard import Wizard, StateView, StateAction, Button from trytond.modules.stock import StockMixin __all__ = ['Lot', 'LotType', 'Move', 'ShipmentIn', 'ShipmentOut', 'ShipmentOutReturn', 'Period', 'PeriodCacheLot', - 'Inventory', 'InventoryLine'] + 'Inventory', 'InventoryLine', + 'Location', 'LotByLocation', 'LotByLocationStart'] __metaclass__ = PoolMeta @@ -294,3 +297,73 @@ if move: move.lot = self.lot return move + + +class Location: + __name__ = 'stock.location' + + @classmethod + def _quantity_grouping_and_key(cls): + if Transaction().context.get('lot'): + lot_id = Transaction().context['lot'] + product_id = Transaction().context['product'] + return ('product', 'lot'), (product_id, lot_id) + return super(Location, cls)._quantity_grouping_and_key() + + +class LotByLocationStart(ModelView): + 'Lot by Location' + __name__ = 'stock.lot.by_location.start' + forecast_date = fields.Date( + 'At Date', help=('Allow to compute expected ' + 'stock quantities for this date.\n' + '* An empty value is an infinite date in the future.\n' + '* A date in the past will provide historical values.')) + + @staticmethod + def default_forecast_date(): + Date = Pool().get('ir.date') + return Date.today() + + +class LotByLocation(Wizard): + 'Lot by Location' + __name__ = 'stock.lot.by_location' + start = StateView('stock.lot.by_location.start', + 'stock_lot.lot_by_location_start_view_form', [ + Button('Cancel', 'end', 'tryton-cancel'), + Button('Open', 'open', 'tryton-ok', default=True), + ]) + open = StateAction('stock.act_location_quantity_tree') + + def do_open(self, action): + pool = Pool() + Lot = pool.get('stock.lot') + Lang = pool.get('ir.lang') + + context = {} + lot_id = Transaction().context['active_id'] + context['lot'] = lot_id + + lot = Lot(lot_id) + context['product'] = lot.product.id + + if self.start.forecast_date: + context['stock_date_end'] = self.start.forecast_date + else: + context['stock_date_end'] = datetime.date.max + action['pyson_context'] = PYSONEncoder().encode(context) + + for code in [Transaction().language, 'en_US']: + langs = Lang.search([ + ('code', '=', code), + ]) + if langs: + break + lang, = langs + date = Lang.strftime(context['stock_date_end'], + lang.code, lang.date) + + action['name'] += ' - %s (%s) @ %s' % (lot.rec_name, + lot.product.default_uom.rec_name, date) + return action, {} Index: stock.xml =================================================================== --- ./modules/stock_lot/stock.xml +++ ./modules/stock_lot/stock.xml @@ -48,6 +48,28 @@ + + Lot by Locations + stock.lot.by_location + stock.lot + + + form_relate + stock.lot,-1 + + + + + + + + + stock.lot.by_location.start + form + lot_by_location_start_form + + supplier Supplier Index: view/lot_by_location_start_form.xml =================================================================== new file mode 100644 --- /dev/null +++ ./modules/stock_lot/view/lot_by_location_start_form.xml @@ -0,0 +1,7 @@ + + +
+