Add module product_expiry_simple
This commit is contained in:
3
product_expiry_simple/__init__.py
Normal file
3
product_expiry_simple/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import stock
|
||||||
34
product_expiry_simple/__openerp__.py
Normal file
34
product_expiry_simple/__openerp__.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
{
|
||||||
|
'name': 'Product Expiry Simple',
|
||||||
|
'version': '8.0.1.0.0',
|
||||||
|
'category': 'Product',
|
||||||
|
'license': 'AGPL-3',
|
||||||
|
'summary': 'Simpler and better alternative to the official product_expiry module',
|
||||||
|
'description': """
|
||||||
|
Product Expiry Simple
|
||||||
|
=====================
|
||||||
|
|
||||||
|
This module is similar to the official *product_expiry* modules, but much simpler and much better:
|
||||||
|
|
||||||
|
* Only one expiry date field instead of 4 !
|
||||||
|
* date field instead of datetime
|
||||||
|
* No automatic computing of expiry date based on a delay configured on product (not needed in most companies)
|
||||||
|
* colored production lot and stock quant tree views depending on expiry dates
|
||||||
|
* ability to show stats about expiry dates on quants pivot table (thanks to related stored field on stock.quant)
|
||||||
|
|
||||||
|
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
||||||
|
""",
|
||||||
|
'author': 'Akretion',
|
||||||
|
'website': 'http://www.akretion.com',
|
||||||
|
'depends': ['stock'],
|
||||||
|
'conflicts': ['product_expiry'],
|
||||||
|
'data': [
|
||||||
|
'stock_view.xml',
|
||||||
|
'product_removal_data.xml',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
}
|
||||||
11
product_expiry_simple/product_removal_data.xml
Normal file
11
product_expiry_simple/product_removal_data.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<record id="removal_fefo" model="product.removal">
|
||||||
|
<field name="name">First Expiry First Out (FEFO)</field>
|
||||||
|
<field name="method">fefo</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
43
product_expiry_simple/stock.py
Normal file
43
product_expiry_simple/stock.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from openerp import models, fields, api
|
||||||
|
|
||||||
|
|
||||||
|
class StockProductionLot(models.Model):
|
||||||
|
_inherit = 'stock.production.lot'
|
||||||
|
_rec_name = 'display_name'
|
||||||
|
|
||||||
|
expiry_date = fields.Date(string='Expiry Date')
|
||||||
|
display_name = fields.Char(
|
||||||
|
compute='compute_display_name_field',
|
||||||
|
string='Lot/Serial Number Display', store=True, readonly=True)
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
@api.depends('name', 'expiry_date')
|
||||||
|
def compute_display_name_field(self):
|
||||||
|
for lot in self:
|
||||||
|
dname = lot.name
|
||||||
|
if lot.expiry_date:
|
||||||
|
dname = '[%s] %s' % (lot.expiry_date, dname)
|
||||||
|
lot.display_name = dname
|
||||||
|
|
||||||
|
|
||||||
|
class StockQuant(models.Model):
|
||||||
|
_inherit = 'stock.quant'
|
||||||
|
|
||||||
|
expiry_date = fields.Date(
|
||||||
|
related='lot_id.expiry_date', store=True, readonly=True)
|
||||||
|
|
||||||
|
# method copy/pasted from the official product_expiry module
|
||||||
|
# © Odoo SA
|
||||||
|
@api.model
|
||||||
|
def apply_removal_strategy(
|
||||||
|
self, location, product, qty, domain, removal_strategy):
|
||||||
|
if removal_strategy == 'fefo':
|
||||||
|
order = 'expiry_date, location_id, package_id, lot_id, in_date, id'
|
||||||
|
return self._quants_get_order(
|
||||||
|
location, product, qty, domain, order)
|
||||||
|
return super(StockQuant, self).apply_removal_strategy(
|
||||||
|
location, product, qty, domain, removal_strategy)
|
||||||
94
product_expiry_simple/stock_view.xml
Normal file
94
product_expiry_simple/stock_view.xml
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<!-- LOTS -->
|
||||||
|
<record id="view_production_lot_form" model="ir.ui.view">
|
||||||
|
<field name="name">product_expiry_simple.stock.production.lot.form</field>
|
||||||
|
<field name="model">stock.production.lot</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_production_lot_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="ref" position="after">
|
||||||
|
<field name="expiry_date"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_production_lot_tree" model="ir.ui.view">
|
||||||
|
<field name="name">product_expiry_simple.stock.production.lot.tree</field>
|
||||||
|
<field name="model">stock.production.lot</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_production_lot_tree"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="product_id" position="after">
|
||||||
|
<field name="expiry_date"/>
|
||||||
|
</field>
|
||||||
|
<xpath expr="/tree" position="attributes">
|
||||||
|
<attribute name="colors">red:expiry_date and expiry_date < current_date;green:expiry_date >= current_date</attribute>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="search_product_lot_filter" model="ir.ui.view">
|
||||||
|
<field name="name">product_expiry_simple.stock.production.lot.search</field>
|
||||||
|
<field name="model">stock.production.lot</field>
|
||||||
|
<field name="inherit_id" ref="stock.search_product_lot_filter"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="product_id" position="after">
|
||||||
|
<filter string="Expired" name="expired"
|
||||||
|
domain="[('expiry_date', '<', context_today().strftime('%Y-%m-%d'))]"/>
|
||||||
|
<filter string="Not Expired" name="no-expired"
|
||||||
|
domain="[('expiry_date', '>=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||||
|
</field>
|
||||||
|
<group expand="0" position="inside">
|
||||||
|
<filter name="expiry_date_groupby" string="Expiry Date"
|
||||||
|
context="{'group_by': 'expiry_date:month'}"/>
|
||||||
|
</group>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- QUANTS -->
|
||||||
|
|
||||||
|
<!-- No need to inherit the form view, because the expiry date is shown in the lot_id via display_name field -->
|
||||||
|
|
||||||
|
<record id="view_stock_quant_tree" model="ir.ui.view">
|
||||||
|
<field name="name">product_expiry_simple.stock.quant.tree</field>
|
||||||
|
<field name="model">stock.quant</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_stock_quant_tree"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="lot_id" position="after">
|
||||||
|
<field name="expiry_date"/>
|
||||||
|
</field>
|
||||||
|
<xpath expr="/tree" position="attributes">
|
||||||
|
<attribute name="colors">red:expiry_date and expiry_date < current_date;green:expiry_date >= current_date</attribute>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="quant_search_view" model="ir.ui.view">
|
||||||
|
<field name="name">product_expiry_simple.stock.quant.search</field>
|
||||||
|
<field name="model">stock.quant</field>
|
||||||
|
<field name="inherit_id" ref="stock.quant_search_view"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<filter name="internal_loc" position="after">
|
||||||
|
<separator/>
|
||||||
|
<filter string="Expired" name="expired"
|
||||||
|
domain="[('expiry_date', '<', context_today().strftime('%Y-%m-%d'))]"
|
||||||
|
groups="stock.group_production_lot"/>
|
||||||
|
<filter string="Not Expired" name="no-expired"
|
||||||
|
domain="[('expiry_date', '>=', context_today().strftime('%Y-%m-%d'))]"
|
||||||
|
groups="stock.group_production_lot"/>
|
||||||
|
</filter>
|
||||||
|
<filter context="{'group_by' : 'lot_id'}" position="after">
|
||||||
|
<filter name="expiry_date_groupby" string="Expiry Date"
|
||||||
|
context="{'group_by': 'expiry_date:month'}" groups="stock.group_production_lot"/>
|
||||||
|
</filter>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
Reference in New Issue
Block a user