diff --git a/addons/product_expiry/__openerp__.py b/addons/product_expiry/__openerp__.py
index 830524769e4..7b62ad60f1a 100644
--- a/addons/product_expiry/__openerp__.py
+++ b/addons/product_expiry/__openerp__.py
@@ -19,6 +19,8 @@ Following dates can be tracked:
Also implements the removal strategy First Expiry First Out (FEFO) widely used, for example, in food industries.
""",
'data': ['views/product_expiry_view.xml',
+ 'views/product_template_views.xml',
+ 'views/stock_quant_views.xml',
'data/product_expiry_data.xml'],
'auto_install': False,
'installable': True,
diff --git a/addons/product_expiry/models/__init__.py b/addons/product_expiry/models/__init__.py
index 2606c927a1c..751af480a33 100644
--- a/addons/product_expiry/models/__init__.py
+++ b/addons/product_expiry/models/__init__.py
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-import product_expiry
\ No newline at end of file
+import production_lot
+import stock_quant
+import product_product
\ No newline at end of file
diff --git a/addons/product_expiry/models/product_expiry.py b/addons/product_expiry/models/product_expiry.py
deleted file mode 100644
index 25390891aa5..00000000000
--- a/addons/product_expiry/models/product_expiry.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import datetime
-
-import openerp
-from openerp import api, models
-from openerp.osv import fields, osv
-
-class stock_production_lot(osv.osv):
- _inherit = 'stock.production.lot'
-
- def _get_date(dtype):
- """Return a function to compute the limit date for this type"""
- def calc_date(self, cr, uid, context=None):
- """Compute the limit date for a given date"""
- if context is None:
- context = {}
- if not context.get('product_id', False):
- date = False
- else:
- product = openerp.registry(cr.dbname)['product.product'].browse(
- cr, uid, context['product_id'])
- duration = getattr(product, dtype)
- # set date to False when no expiry time specified on the product
- date = duration and (datetime.datetime.today()
- + datetime.timedelta(days=duration))
- return date and date.strftime('%Y-%m-%d %H:%M:%S') or False
- return calc_date
-
- _columns = {
- 'life_date': fields.datetime('End of Life Date',
- help='This is the date on which the goods with this Serial Number may become dangerous and must not be consumed.'),
- 'use_date': fields.datetime('Best before Date',
- help='This is the date on which the goods with this Serial Number start deteriorating, without being dangerous yet.'),
- 'removal_date': fields.datetime('Removal Date',
- help='This is the date on which the goods with this Serial Number should be removed from the stock.'),
- 'alert_date': fields.datetime('Alert Date',
- help="This is the date on which an alert should be notified about the goods with this Serial Number."),
- }
- # Assign dates according to products data
- def create(self, cr, uid, vals, context=None):
- context = dict(context or {})
- context['product_id'] = vals.get('product_id', context.get('default_product_id'))
- return super(stock_production_lot, self).create(cr, uid, vals, context=context)
-
- _defaults = {
- 'life_date': _get_date('life_time'),
- 'use_date': _get_date('use_time'),
- 'removal_date': _get_date('removal_time'),
- 'alert_date': _get_date('alert_time'),
- }
-
-
-# Onchange added in new api to avoid having to change views
-class StockProductionLot(models.Model):
- _inherit = 'stock.production.lot'
-
- @api.onchange('product_id')
- def _onchange_product(self):
- defaults = self.with_context(
- product_id=self.product_id.id).default_get(
- ['life_date', 'use_date', 'removal_date', 'alert_date'])
- for field, value in defaults.items():
- setattr(self, field, value)
-
-
-class stock_quant(osv.osv):
- _inherit = 'stock.quant'
-
- def _get_quants(self, cr, uid, ids, context=None):
- return self.pool.get('stock.quant').search(cr, uid, [('lot_id', 'in', ids)], context=context)
-
- _columns = {
- 'removal_date': fields.related('lot_id', 'removal_date', type='datetime', string='Removal Date',
- store={
- 'stock.quant': (lambda self, cr, uid, ids, ctx: ids, ['lot_id'], 20),
- 'stock.production.lot': (_get_quants, ['removal_date'], 20),
- }),
- }
-
- def apply_removal_strategy(self, cr, uid, qty, move, ops=False, domain=None, removal_strategy='fifo', context=None):
- if removal_strategy == 'fefo':
- order = 'removal_date, in_date, id'
- return self._quants_get_order(cr, uid, qty, move, ops=ops, domain=domain, orderby=order, context=context)
- return super(stock_quant, self).apply_removal_strategy(cr, uid, qty, move, ops=ops, domain=domain,
- removal_strategy=removal_strategy, context=context)
-
-
-class product_product(osv.osv):
- _inherit = 'product.template'
- _columns = {
- 'life_time': fields.integer('Product Life Time',
- help='When a new a Serial Number is issued, this is the number of days before the goods may become dangerous and must not be consumed.'),
- 'use_time': fields.integer('Product Use Time',
- help='When a new a Serial Number is issued, this is the number of days before the goods starts deteriorating, without being dangerous yet.'),
- 'removal_time': fields.integer('Product Removal Time',
- help='When a new a Serial Number is issued, this is the number of days before the goods should be removed from the stock.'),
- 'alert_time': fields.integer('Product Alert Time',
- help='When a new a Serial Number is issued, this is the number of days before an alert should be notified.'),
- }
diff --git a/addons/product_expiry/models/product_product.py b/addons/product_expiry/models/product_product.py
new file mode 100644
index 00000000000..1d660f2cf34
--- /dev/null
+++ b/addons/product_expiry/models/product_product.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import datetime
+
+import openerp
+from openerp.osv import fields, osv
+
+
+class product_product(osv.osv):
+ _inherit = 'product.template'
+ _columns = {
+ 'life_time': fields.integer('Product Life Time',
+ help='When a new a Serial Number is issued, this is the number of days before the goods may become dangerous and must not be consumed.'),
+ 'use_time': fields.integer('Product Use Time',
+ help='When a new a Serial Number is issued, this is the number of days before the goods starts deteriorating, without being dangerous yet.'),
+ 'removal_time': fields.integer('Product Removal Time',
+ help='When a new a Serial Number is issued, this is the number of days before the goods should be removed from the stock.'),
+ 'alert_time': fields.integer('Product Alert Time',
+ help='When a new a Serial Number is issued, this is the number of days before an alert should be notified.'),
+ }
diff --git a/addons/product_expiry/models/production_lot.py b/addons/product_expiry/models/production_lot.py
new file mode 100644
index 00000000000..9bfc169442e
--- /dev/null
+++ b/addons/product_expiry/models/production_lot.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import datetime
+
+import openerp
+from openerp.osv import fields, osv
+
+
+class stock_production_lot(osv.osv):
+ _inherit = 'stock.production.lot'
+
+ def _get_date(dtype):
+ """Return a function to compute the limit date for this type"""
+ def calc_date(self, cr, uid, context=None):
+ """Compute the limit date for a given date"""
+ if context is None:
+ context = {}
+ if not context.get('product_id', False):
+ date = False
+ else:
+ product = openerp.registry(cr.dbname)['product.product'].browse(
+ cr, uid, context['product_id'])
+ duration = getattr(product, dtype)
+ # set date to False when no expiry time specified on the product
+ date = duration and (datetime.datetime.today()
+ + datetime.timedelta(days=duration))
+ return date and date.strftime('%Y-%m-%d %H:%M:%S') or False
+ return calc_date
+
+ _columns = {
+ 'life_date': fields.datetime('End of Life Date',
+ help='This is the date on which the goods with this Serial Number may become dangerous and must not be consumed.'),
+ 'use_date': fields.datetime('Best before Date',
+ help='This is the date on which the goods with this Serial Number start deteriorating, without being dangerous yet.'),
+ 'removal_date': fields.datetime('Removal Date',
+ help='This is the date on which the goods with this Serial Number should be removed from the stock.'),
+ 'alert_date': fields.datetime('Alert Date',
+ help="This is the date on which an alert should be notified about the goods with this Serial Number."),
+ }
+ # Assign dates according to products data
+ def create(self, cr, uid, vals, context=None):
+ context = dict(context or {})
+ context['product_id'] = vals.get('product_id', context.get('default_product_id'))
+ return super(stock_production_lot, self).create(cr, uid, vals, context=context)
+
+ _defaults = {
+ 'life_date': _get_date('life_time'),
+ 'use_date': _get_date('use_time'),
+ 'removal_date': _get_date('removal_time'),
+ 'alert_date': _get_date('alert_time'),
+ }
diff --git a/addons/product_expiry/models/stock_quant.py b/addons/product_expiry/models/stock_quant.py
new file mode 100644
index 00000000000..71826a61611
--- /dev/null
+++ b/addons/product_expiry/models/stock_quant.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import datetime
+
+import openerp
+from openerp.osv import fields, osv
+
+
+class stock_quant(osv.osv):
+ _inherit = 'stock.quant'
+
+ def _get_quants(self, cr, uid, ids, context=None):
+ return self.pool.get('stock.quant').search(cr, uid, [('lot_id', 'in', ids)], context=context)
+
+ _columns = {
+ 'removal_date': fields.related('lot_id', 'removal_date', type='datetime', string='Removal Date',
+ store={
+ 'stock.quant': (lambda self, cr, uid, ids, ctx: ids, ['lot_id'], 20),
+ 'stock.production.lot': (_get_quants, ['removal_date'], 20),
+ }),
+ }
+
+ def apply_removal_strategy(self, cr, uid, qty, move, ops=False, domain=None, removal_strategy='fifo', context=None):
+ if removal_strategy == 'fefo':
+ order = 'removal_date, in_date, id'
+ return self._quants_get_order(cr, uid, qty, move, ops=ops, domain=domain, orderby=order, context=context)
+ return super(stock_quant, self).apply_removal_strategy(cr, uid, qty, move, ops=ops, domain=domain,
+ removal_strategy=removal_strategy, context=context)
diff --git a/addons/product_expiry/views/product_expiry_view.xml b/addons/product_expiry/views/product_expiry_view.xml
index ea33337a879..ac5a8bfdf4c 100644
--- a/addons/product_expiry/views/product_expiry_view.xml
+++ b/addons/product_expiry/views/product_expiry_view.xml
@@ -20,34 +20,6 @@
-
-
- product.normal.form
- product.template
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- stock.quant.form
- stock.quant
-
-
-
-
-
-
-
-
diff --git a/addons/product_expiry/views/product_template_views.xml b/addons/product_expiry/views/product_template_views.xml
new file mode 100644
index 00000000000..c47c385be7c
--- /dev/null
+++ b/addons/product_expiry/views/product_template_views.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ product.normal.form
+ product.template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/product_expiry/views/stock_quant_views.xml b/addons/product_expiry/views/stock_quant_views.xml
new file mode 100644
index 00000000000..33a8b42a60f
--- /dev/null
+++ b/addons/product_expiry/views/stock_quant_views.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ stock.quant.form
+ stock.quant
+
+
+
+
+
+
+
+
+
\ No newline at end of file