Extra modules Julius V1.0

This commit is contained in:
Mathieu Vatel
2012-03-07 13:56:37 +01:00
commit e2aa9b603f
63 changed files with 4882 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Invetory Extended",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This module adds a new field based on lines into the inventory
to know what are lines correctly in the system """,
"website" : "http://www.julius.fr",
"depends" : [
"stock",
],
"category" : "Customs/Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [
'stock_view.xml',
"security/ir.model.access.csv",
],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,100 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * stock_inventory_existing_lines
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-12-19 10:50+0000\n"
"PO-Revision-Date: 2011-12-19 10:50+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: stock_inventory_existing_lines
#: view:stock.inventory:0
msgid "General Informations"
msgstr "Informations générales"
#. module: stock_inventory_existing_lines
#: field:stock.inventory.line2,product_id:0
msgid "Product"
msgstr "Produit"
#. module: stock_inventory_existing_lines
#: model:ir.model,name:stock_inventory_existing_lines.model_stock_inventory_line2
msgid "stock.inventory.line2"
msgstr "stock.inventory.line2"
#. module: stock_inventory_existing_lines
#: field:stock.inventory.line2,state:0
msgid "State"
msgstr "Etat"
#. module: stock_inventory_existing_lines
#: field:stock.inventory.line2,company_id:0
msgid "Company"
msgstr "Société"
#. module: stock_inventory_existing_lines
#: view:stock.inventory:0
msgid "Lines"
msgstr "Lignes correspondantes"
#. module: stock_inventory_existing_lines
#: model:ir.module.module,description:stock_inventory_existing_lines.module_meta_information
msgid " This module adds a new field based on lines into the inventory\n"
" to know what are lines correctly in the system "
msgstr " Ce module ajoute un nouveau champ basé sur des lignes dans l'inventaire\n"
" pour savoir quelles sont les lignes qui existent déjà dans le système "
#. module: stock_inventory_existing_lines
#: view:stock.inventory.line2:0
msgid "Stock Inventory Lines"
msgstr "Lignes d'inventaires des stocks"
#. module: stock_inventory_existing_lines
#: model:ir.module.module,shortdesc:stock_inventory_existing_lines.module_meta_information
msgid "Invetory Extended"
msgstr "Inventaire étendu"
#. module: stock_inventory_existing_lines
#: field:stock.inventory.line2,product_qty:0
msgid "Quantity"
msgstr "Quantité"
#. module: stock_inventory_existing_lines
#: field:stock.inventory.line2,product_uom:0
msgid "Product UOM"
msgstr "Produit UdM"
#. module: stock_inventory_existing_lines
#: model:ir.model,name:stock_inventory_existing_lines.model_stock_inventory
#: field:stock.inventory.line2,inventory_id:0
msgid "Inventory"
msgstr "Inventaire"
#. module: stock_inventory_existing_lines
#: view:stock.inventory:0
msgid "Correct lines"
msgstr "Lignes correspondantes"
#. module: stock_inventory_existing_lines
#: field:stock.inventory,inventory_line_id2:0
msgid "Inventories"
msgstr "Inventaires"
#. module: stock_inventory_existing_lines
#: field:stock.inventory.line2,prod_lot_id:0
msgid "Production Lot"
msgstr "Numéro de série"
#. module: stock_inventory_existing_lines
#: field:stock.inventory.line2,location_id:0
msgid "Location"
msgstr "Emplacement"

View File

@@ -0,0 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_stock_inventory_line2_user","stock.inventory.line2 user","model_stock_inventory_line2","stock.group_stock_user",1,1,1,1
"access_stock_inventory_line2_manager","stock.inventory.line2 manager","model_stock_inventory_line2","stock.group_stock_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_stock_inventory_line2_user stock.inventory.line2 user model_stock_inventory_line2 stock.group_stock_user 1 1 1 1
3 access_stock_inventory_line2_manager stock.inventory.line2 manager model_stock_inventory_line2 stock.group_stock_manager 1 1 1 1

View File

@@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
import decimal_precision as dp
class stock_inventory(osv.osv):
_inherit = "stock.inventory"
_columns = {
'inventory_line_id2': fields.one2many('stock.inventory.line2', 'inventory_id', 'Inventories', states={'done': [('readonly', True)]}),
}
def action_confirm(self, cr, uid, ids, context=None):
if context is None:
context = {}
''' to perform the correct inventory corrections we need analyze stock location by
location, never recursively, so we use a special context '''
product_context = dict(context, compute_child=False)
location_obj = self.pool.get('stock.location')
line_obj = self.pool.get('stock.inventory.line')
line2_obj = self.pool.get('stock.inventory.line2')
for inv in self.browse(cr, uid, ids, context=context):
move_ids = []
for line in inv.inventory_line_id:
# ''' if the production lot is tracked but do not have a serial code then it is not taken into account '''
# if line.product_id.categ_id.tracked and not line.prod_lot_id:
# continue
if not line.product_qty:
continue
pid = line.product_id.id
date = line.date or inv.date
product_context.update(uom=line.product_uom.id, date=date, to_date=date, prodlot_id=line.prod_lot_id.id)
amount = location_obj._product_get(cr, uid, line.location_id.id, [pid], product_context)[pid]
if not amount:
continue
val_qty = min(line.product_qty,amount)
if val_qty and val_qty > 0:
vals = line_obj.copy_data(cr, uid, line.id)
line2_obj.create(cr, uid, vals)
# location_id = line.product_id.product_tmpl_id.property_stock_inventory.id
res = super(stock_inventory, self).action_confirm(cr, uid, ids, context)
return res
stock_inventory()
#class stock_move(osv.osv):
# _inherit = "stock.move"
#
# _columns = {
# 'inventory_type': fields.selection([('in','In'),('out','Out')], 'Inventory type')
# }
#stock_move()
class stock_inventory_line2(osv.osv):
_name = "stock.inventory.line2"
_columns = {
'inventory_id': fields.many2one('stock.inventory', 'Inventory', ondelete='cascade', select=True),
'location_id': fields.many2one('stock.location', 'Location', required=True),
'product_id': fields.many2one('product.product', 'Product', required=True, select=True),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product UoM')),
'company_id': fields.related('inventory_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, select=True, readonly=True),
'prod_lot_id': fields.many2one('stock.production.lot', 'Production Lot', domain="[('product_id','=',product_id)]"),
'state': fields.related('inventory_id', 'state', type='char', string='State',readonly=True),
}
stock_inventory_line2()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="stock_inventory_line2_tree" model="ir.ui.view">
<field name="name">stock.inventory.line2.tree</field>
<field name="model">stock.inventory.line2</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Stock Inventory Lines">
<field name="product_id"/>
<field name="product_qty"/>
<field name="product_uom"/>
<field name="prod_lot_id" groups="base.group_extended"/>
<field name="location_id"/>
</tree>
</field>
</record>
<record id="view_inventory_line2_form" model="ir.ui.view">
<field name="name">stock.inventory.line2.form</field>
<field name="model">stock.inventory.line2</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Stock Inventory Lines">
<field context="location=location_id,uom=product_uom,to_date=parent.date" name="product_id" on_change="on_change_product_id(location_id,product_id,product_uom,parent.date)" select="1" domain="[('type','&lt;&gt;','service')]"/>
<field name="product_qty"/>
<field name="product_uom"/>
<field name="prod_lot_id" groups="base.group_extended"/>
<field colspan="4" domain="[('usage','=','internal')]" name="location_id" select="1"/>
</form>
</field>
</record>
<record id="view_inventory_form" model="ir.ui.view">
<field name="name">stock.inventory.form</field>
<field name="model">stock.inventory</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_inventory_form"/>
<field name="arch" type="xml">
<page string="General Informations" position="after">
<page string="Lines">
<group colspan="4" col="4">
<separator string="Correct lines" colspan="4"/>
<field name="inventory_line_id2" colspan="4" nolabel="1"/>
</group>
</page>
</page>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Move Invetory Extended",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This module adds a new field based on lines into the inventory
to get all lines pre-filled and all lines scanned """,
"website" : "http://www.julius.fr",
"depends" : [
"stock",
],
"category" : "Customs/Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [
'stock_view.xml',
# 'wizard/stock_fill_inventory_view.xml',
],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,86 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * stock_inventory_extended
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-12-19 10:54+0000\n"
"PO-Revision-Date: 2011-12-19 10:54+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: stock_inventory_extended
#: code:addons/stock_inventory_extended/wizard/stock_fill_inventory.py:47
#, python-format
msgid "You cannot perform this operation on more than one Stock Inventories."
msgstr "Vous ne pouvez pas effectuer cette opération sur plusieurs inventaires de stock."
#. module: stock_inventory_extended
#: model:ir.model,name:stock_inventory_extended.model_stock_fill_inventory
msgid "Import Inventory"
msgstr "Importer un inventaire"
#. module: stock_inventory_extended
#: model:ir.model,name:stock_inventory_extended.model_stock_inventory_line
msgid "Inventory Line"
msgstr "Lignes d'inventaire"
#. module: stock_inventory_extended
#: field:stock.inventory.line,note:0
msgid "Notes"
msgstr "Notes"
#. module: stock_inventory_extended
#: code:addons/stock_inventory_extended/wizard/stock_fill_inventory.py:47
#, python-format
msgid "Error!"
msgstr "Erreur!"
#. module: stock_inventory_extended
#: code:addons/stock_inventory_extended/wizard/stock_fill_inventory.py:111
#, python-format
msgid "No product in this location."
msgstr "Aucun produit à cet endroit."
#. module: stock_inventory_extended
#: code:addons/stock_inventory_extended/wizard/stock_fill_inventory.py:53
#, python-format
msgid "Stock Inventory is already Validated."
msgstr "L'inventaire est déjà validé."
#. module: stock_inventory_extended
#: code:addons/stock_inventory_extended/stock.py:77
#: model:ir.model,name:stock_inventory_extended.model_stock_inventory
#, python-format
msgid "Inventory"
msgstr "Inventaire"
#. module: stock_inventory_extended
#: field:stock.inventory.line,date:0
msgid "Date"
msgstr "Date"
#. module: stock_inventory_extended
#: code:addons/stock_inventory_extended/wizard/stock_fill_inventory.py:111
#, python-format
msgid "Warning !"
msgstr "Attention !"
#. module: stock_inventory_extended
#: code:addons/stock_inventory_extended/stock.py:77
#, python-format
msgid "is done."
msgstr "est fait."
#. module: stock_inventory_extended
#: code:addons/stock_inventory_extended/wizard/stock_fill_inventory.py:53
#, python-format
msgid "Warning!"
msgstr "Attention!"

View File

@@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
class stock_inventory(osv.osv):
_inherit = "stock.inventory"
_columns = {
'comments':fields.text('Comments'),
}
def action_confirm(self, cr, uid, ids, context=None):
""" Confirm the inventory and writes its finished date
@return: True
"""
res = super(stock_inventory, self).action_confirm(cr, uid, ids, context)
if context is None:
context = {}
# to perform the correct inventory corrections we need analyze stock location by
# location, never recursively, so we use a special context
product_context = dict(context, compute_child=False)
location_obj = self.pool.get('stock.location')
for inv in self.browse(cr, uid, ids, context=context):
move_ids = []
self.write(cr, uid, [inv.id], {'move_ids': [(6, 0, move_ids)]})
for line in inv.inventory_line_id:
pid = line.product_id.id
date = line.date or inv.date
product_context.update(uom=line.product_uom.id, date=date, to_date=date, prodlot_id=line.prod_lot_id.id)
amount = location_obj._product_get(cr, uid, line.location_id.id, [pid], product_context)[pid]
change = line.product_qty - amount
lot_id = line.prod_lot_id.id
if change:
location_id = line.product_id.product_tmpl_id.property_stock_inventory.id
value = {
'name': 'INV:' + str(line.inventory_id.id) + ':' + line.inventory_id.name,
'product_id': line.product_id.id,
'product_uom': line.product_uom.id,
'prodlot_id': lot_id,
'date': date,
'note': line.note or inv.comments or False,
}
if change > 0:
value.update( {
'product_qty': change,
'location_id': location_id,
'location_dest_id': line.location_id.id,
})
else:
value.update( {
'product_qty': -change,
'location_id': line.location_id.id,
'location_dest_id': location_id,
})
move_ids.append(self._inventory_line_hook(cr, uid, line, value))
message = _('Inventory') + " '" + inv.name + "' "+ _("is done.")
self.log(cr, uid, inv.id, message)
self.write(cr, uid, [inv.id], {'state': 'confirm', 'move_ids': [(6, 0, move_ids)]})
return res
stock_inventory()
class stock_inventory_line(osv.osv):
_inherit = "stock.inventory.line"
_columns = {
'date': fields.datetime('Date'),
'note': fields.text('Notes'),
}
stock_inventory_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_inventory_form" model="ir.ui.view">
<field name="name">stock.inventory.form</field>
<field name="model">stock.inventory</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_inventory_form"/>
<field name="priority">16</field>
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="comments" colspan="4"/>
</field>
<xpath expr="/form/notebook/page/field[@name='inventory_line_id']/tree/field[@name='prod_lot_id']" position="after">
<field name="date"/>
<field name="note"/>
</xpath>
<xpath expr="/form/notebook/page/field[@name='inventory_line_id']/form/field[@name='product_uom']" position="after">
<field name="date"/>
<newline/>
<field name="note" colspan="4" nolabel="1"/>
<newline/>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import stock_fill_inventory
#import stock_inventory_line_split
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
class stock_fill_inventory(osv.osv_memory):
_inherit = "stock.fill.inventory"
# _description = "Import Inventory"
# _columns = {
# 'location_id': fields.many2one('stock.location', 'Location', required=True),
# 'recursive': fields.boolean("Include children",help="If checked, products contained in child locations of selected location will be included as well."),
# 'set_stock_zero': fields.boolean("Set to zero",help="If checked, all product quantities will be set to zero to help ensure a real physical inventory is done"),
# }
# def view_init(self, cr, uid, fields_list, context=None):
# """
# Creates view dynamically and adding fields at runtime.
# @param self: The object pointer.
# @param cr: A database cursor
# @param uid: ID of the user currently logged in
# @param context: A standard dictionary
# @return: New arch of view with new columns.
# """
# if context is None:
# context = {}
# super(stock_fill_inventory2, self).view_init(cr, uid, fields_list, context=context)
#
# if len(context.get('active_ids',[])) > 1:
# raise osv.except_osv(_('Error!'), _('You cannot perform this operation on more than one Stock Inventories.'))
#
# if context.get('active_id', False):
# stock = self.pool.get('stock.inventory').browse(cr, uid, context.get('active_id', False))
#
# if stock.state == 'done':
# raise osv.except_osv(_('Warning!'), _('Stock Inventory is already Validated.'))
# return True
def fill_inventory(self, cr, uid, ids, context=None):
""" To Import stock inventory according to products available in the selected locations.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
if context is None:
context = {}
inventory_line_obj = self.pool.get('stock.inventory.line')
location_obj = self.pool.get('stock.location')
product_obj = self.pool.get('product.product')
move_obj = self.pool.get('stock.move')
fill_inventory = self.browse(cr, uid, ids[0], context=context)
res = {}
res_location = {}
if fill_inventory.recursive:
location_ids = location_obj.search(cr, uid, [('location_id',
'child_of', [fill_inventory.location_id.id])],context=context)
else:
location_ids = [fill_inventory.location_id.id]
res = {}
flag = False
for location in location_ids:
datas = {}
res[location] = {}
domain = [('location_dest_id','=',location),('state','=','done')]
active_ids = context.get('active_ids', False)
if active_ids:
date = self.pool.get('stock.inventory').browse(cr, uid, active_ids[0]).date
domain.append(('date','<=',date))
move_ids = move_obj.search(cr, uid, domain, context=context)
for move in move_obj.browse(cr, uid, move_ids, context=context):
lot_id = move.prodlot_id.id
prod_id = move.product_id.id
qty = move.product_qty
if datas.get((prod_id, lot_id)):
qty += datas[(prod_id, lot_id)]['product_qty']
datas[(prod_id, lot_id)] = {'product_id': prod_id, 'location_id': location, 'product_qty': qty, 'product_uom': move.product_id.uom_id.id, 'prod_lot_id': lot_id}
if datas:
flag = True
res[location] = datas
if not flag:
raise osv.except_osv(_('Warning !'), _('No product in this location.'))
for stock_move in res.values():
for stock_move_details in stock_move.values():
stock_move_details.update({'inventory_id': context['active_ids'][0]})
domain = []
if fill_inventory.set_stock_zero:
stock_move_details.update({'product_qty': 0})
for field, value in stock_move_details.items():
domain.append((field, '=', value))
line_ids = inventory_line_obj.search(cr, uid, domain, context=context)
if not line_ids:
inventory_line_obj.create(cr, uid, stock_move_details, context=context)
return {'type': 'ir.actions.act_window_close'}
stock_fill_inventory()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_stock_fill_inventory2" model="ir.ui.view">
<field name="name">Import Inventory</field>
<field name="model">stock.fill.inventory2</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Import Inventory">
<separator string="Import current product inventory from the following location" colspan="4" />
<field name="location_id"/>
<newline/>
<field name="recursive"/>
<newline/>
<field name="set_stock_zero"/>
<separator string="" colspan="4" />
<button special="cancel" string="_Cancel" icon='gtk-cancel'/>
<button name="fill_inventory" string="Fill Inventory" type="object" icon="gtk-ok"/>
</form>
</field>
</record>
<act_window name="Import Inventory 2"
res_model="stock.fill.inventory2"
src_model="stock.inventory"
view_mode="form"
target="new"
context="{'search_default_in_location':1}"
key2="client_action_multi"
id="action_view_stock_fill_inventory2"/>
<!--<record id="view_stock_fill_inventory_inherit" model="ir.ui.view">
<field name="name">Import Inventory</field>
<field name="model">stock.fill.inventory</field>
<field name="inherit_id" ref="stock.view_stock_fill_inventory"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="recursive" position="replace">
<field name="recursive" string="Inclure les sous-stocks"/>
</field>
<field name="set_stock_zero" position="replace">
<field name="set_stock_zero" invisible="1"/>
</field>
</field>
</record>-->
</data>
</openerp>

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Move Invetory Extended",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This module get the product real location if exists instead of inventory location """,
"website" : "http://www.julius.fr",
"depends" : [
"stock",
"stock_tracking_extended",
],
"category" : "Customs/Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
class stock_inventory(osv.osv):
_inherit = "stock.inventory"
_columns = {
}
def action_confirm(self, cr, uid, ids, context=None):
""" Confirm the inventory and writes its finished date
@return: True
"""
res = super(stock_inventory, self).action_confirm(cr, uid, ids, context)
if context is None:
context = {}
location_obj = self.pool.get('stock.location')
move_obj = self.pool.get('stock.move')
for inv in self.browse(cr, uid, ids, context=context):
for line in inv.move_ids:
location_id = line.product_id.product_tmpl_id.property_stock_inventory.id
if line.location_id.id == location_id and line.prodlot_id:
move_ids = move_obj.search(cr, uid, [
('prodlot_id', '=', line.prodlot_id.id),
('state', '=', 'done'),
('date', '<=', line.date),
], order='date desc', limit=1)
if move_ids:
move_id = move_obj.browse(cr, uid , move_ids[0])
real_location_id = move_id.location_dest_id and move_id.location_dest_id.id
if real_location_id and real_location_id != location_id:
move_obj.write(cr, uid, line.id, {'location_id': real_location_id})
return res
stock_inventory()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Move Stock Location",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This module allows to move all stock in a stock location to an other one """,
"website" : "http://www.julius.fr",
"depends" : [
"stock",
"stock_barcode_reader",
],
"category" : "Customs/Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [
'stock_view.xml',
'stock_move_sequence.xml',
'wizard/move_location_view.xml',
],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,143 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * stock_move_location
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-12-19 10:48+0000\n"
"PO-Revision-Date: 2011-12-19 10:48+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: stock_move_location
#: field:stock.inventory,location_id:0
msgid "Location"
msgstr "Emplacement"
#. module: stock_move_location
#: view:stock.inventory:0
msgid "Start Acquisition"
msgstr "Demarrer la saisie"
#. module: stock_move_location
#: view:stock.inventory:0
msgid "Get Stock"
msgstr "Remplir"
#. module: stock_move_location
#: view:stock.inventory:0
msgid "Validate Move"
msgstr "Valider le transfert"
#. module: stock_move_location
#: model:ir.model,name:stock_move_location.model_stock_fill_inventory
msgid "Import Inventory"
msgstr "Importer un inventaire"
#. module: stock_move_location
#: code:addons/stock_move_location/stock.py:54
#, python-format
msgid "Error !"
msgstr "Erreur !"
#. module: stock_move_location
#: constraint:stock.move:0
msgid "You try to assign a lot which is not from the same product"
msgstr "Vous essayez d'affecter un lot qui n'est pas pour le bon produit."
#. module: stock_move_location
#: model:ir.model,name:stock_move_location.model_stock_move
msgid "Stock Move"
msgstr "Transfert de Stock à Stock"
#. module: stock_move_location
#: model:ir.module.module,description:stock_move_location.module_meta_information
msgid " This module allows to move all stock in a stock location to an other one "
msgstr " Ce module permet de déplacer tout le stock situé dans un ou plusieurs emplacement vers un autre emplacement "
#. module: stock_move_location
#: field:stock.inventory,location_dest_id:0
msgid "Destination Location"
msgstr "Emplacement de destination"
#. module: stock_move_location
#: model:ir.actions.act_window,name:stock_move_location.action_move_stock_form
#: model:ir.ui.menu,name:stock_move_location.menu_action_move_stock_form
msgid "Move stock"
msgstr "Transfert de Stock à Stock"
#. module: stock_move_location
#: code:addons/stock_move_location/stock.py:70
#, python-format
msgid "Move"
msgstr "Transfert"
#. module: stock_move_location
#: view:stock.inventory:0
msgid "Confirm Inventory"
msgstr "Confirmer l'inventaire"
#. module: stock_move_location
#: field:stock.inventory,comments:0
msgid "Comments"
msgstr "Commentaires"
#. module: stock_move_location
#: constraint:stock.move:0
msgid "You must assign a production lot for this product"
msgstr "Vous devez affecter un lot de fabrication pour ce produit."
#. module: stock_move_location
#: selection:stock.inventory,type:0
msgid "Location Move"
msgstr "Transfert de Stock à Stock"
#. module: stock_move_location
#: view:stock.inventory:0
msgid "Move Stock"
msgstr "Transfert de Stock à Stock"
#. module: stock_move_location
#: model:ir.model,name:stock_move_location.model_stock_inventory
#: selection:stock.inventory,type:0
msgid "Inventory"
msgstr "Inventaire"
#. module: stock_move_location
#: code:addons/stock_move_location/stock.py:54
#, python-format
msgid "Please inform the destination of your move"
msgstr "S'il vous plaît informer la destination de votre transfert"
#. module: stock_move_location
#: code:addons/stock_move_location/stock.py:70
#, python-format
msgid "is done."
msgstr "est fait."
#. module: stock_move_location
#: field:stock.inventory,type:0
msgid "Type"
msgstr "Type"
#. module: stock_move_location
#: model:ir.module.module,shortdesc:stock_move_location.module_meta_information
msgid "Move Stock Location"
msgstr "Tranfert d'emplacement de stock"
#. module: stock_move_location
#: model:ir.actions.act_window,help:stock_move_location.action_move_stock_form
msgid "You can use this to move a stock from a location to an other one."
msgstr "Vous pouvez l'utiliser pour passer d'un emplacement de stock à un autre."
#. module: stock_move_location
#: field:stock.move,pack_history_id:0
msgid "History pack"
msgstr "Historique du pack"

View File

@@ -0,0 +1,181 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
#class stock_fill_inventory(osv.osv_memory):
# _inherit = "stock.fill.inventory"
# def fill_inventory(self, cr, uid, ids, context=None):
# res = super(stock_fill_inventory, self).fill_inventory(cr, uid, ids, context=context)
# stock_inventory_obj = self.pool.get('stock.inventory')
# fill_inventory = self.browse(cr, uid, ids[0], context=context)
# if stock_inventory_obj.browse(cr, uid, context.get('active_id', False), context).location_id:
# stock_inventory_obj.write(cr, uid, context.get('active_id', False), {'location_id': fill_inventory.location_id.id})
# return res
#stock_fill_inventory()
class stock_inventory(osv.osv):
_inherit = "stock.inventory"
_columns = {
'type': fields.selection([('normal', 'Inventory'),('move', 'Location Move')], 'Type'),
'location_id': fields.many2one('stock.location', 'Location'),
'location_dest_id': fields.many2one('stock.location', 'Destination Location'),
'comments':fields.text('Comments'),
}
def get_sequence(self, cr , uid, context):
if context.get('type', False) == 'move':
return self.pool.get('ir.sequence').get(cr, uid, 'stock.inventory.move') or '/'
else:
return self.pool.get('ir.sequence').get(cr, uid, 'stock.inventory') or '/'
_defaults = {
'type': lambda *a: 'normal',
'name': lambda x, y, z, c: x.get_sequence(y,z,c),
}
def move_stock(self, cr, uid, ids, context=None):
if context is None:
context = {}
product_context = dict(context, compute_child=False)
location_obj = self.pool.get('stock.location')
for inv in self.browse(cr, uid, ids, context=context):
if not inv.location_dest_id:
raise osv.except_osv(_('Error !'), _('Please inform the destination of your move'))
move_ids = []
for line in inv.inventory_line_id:
location_id = inv.location_dest_id.id
date = line.date or inv.date
value = {
'name': 'MOVE:' + str(line.inventory_id.id) + ':' + line.inventory_id.name,
'product_id': line.product_id.id,
'product_uom': line.product_uom.id,
'prodlot_id': line.prod_lot_id.id,
'date': date,
'product_qty': line.product_qty,
'location_id': line.location_id.id,
'location_dest_id': location_id,
'note': line.note or inv.comments or False,
}
move_ids.append(self._inventory_line_hook(cr, uid, line, value))
message = _('Move') + " '" + inv.name + "' "+ _("is done.")
self.log(cr, uid, inv.id, message)
self.write(cr, uid, [inv.id], {'state': 'confirm', 'move_ids': [(6, 0, move_ids)]})
return True
def fill_inventory(self, cr, uid, ids, context=False):
res = {}
stock_fill_inventory_obj = self.pool.get('stock.fill.inventory')
inventory_data = self.browse(cr, uid, ids[0], context)
if context.get('type',[]) == 'move':
set_stock_zero = False
else:
set_stock_zero = True
if inventory_data.location_id:
context['location_id'] = inventory_data.location_id.id
fill_inventory_id = stock_fill_inventory_obj.create(cr, uid, {
'location_id': inventory_data.location_id.id,
'set_stock_zero': set_stock_zero})
context_temp = context
context_temp['active_ids'] = [inventory_data.id]
context_temp['active_id'] = inventory_data.id
stock_fill_inventory_obj.fill_inventory(cr, uid, [fill_inventory_id], context_temp)
if context.get('type',[]) == 'move':
act = {}
# mod_obj = self.pool.get('ir.model.data')
# act_obj = self.pool.get('ir.actions.act_window')
# model_id = mod_obj.search(cr, uid, [('name', '=', 'move_stock_acquisition_link_2')])[0]
# act_id = mod_obj.read(cr, uid, model_id, ['res_id'])['res_id']
# act = act_obj.read(cr, uid, act_id)
else:
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
model_id = mod_obj.search(cr, uid, [('name', '=', 'inventory_acquisition_link_1')])[0]
act_id = mod_obj.read(cr, uid, model_id, ['res_id'])['res_id']
act = act_obj.read(cr, uid, act_id)
context = eval(act['context'])
context['default_inventory_id'] = inventory_data.id
act['context'] = context
return act
stock_inventory()
class stock_move(osv.osv):
_inherit = 'stock.move'
# def _check_move(self, cr, uid, ids, context=None):
# """ Checks if the given production lot belong to a pack
# Return false if the production lot is in a pack
# """
# production_lot_obj = self.pool.get('stock.production.lot')
#
# for move in self.browse(cr, uid, ids, context=context):
# if move.prodlot_id:
# if self.search(cr, uid, [('prodlot_id', '=', move.prodlot_id.id), ('state','not in',('cancel','done')), ('id', '!=', move.id)]):
# if move.prodlot_id.tracking_id:
# return False
# return True
_columns = {
'pack_history_id': fields.many2one('stock.tracking.history', 'History pack'),
}
# _constraints =[
# (_check_move, 'You try to assign a move to a lot which is already in a pack', ['prodlot_id'])
# ]
''' Solution to move all pack and production lot if one in a pack is move '''
# def move_parent(self, cr, uid, ids, context=None):
# """ Checks if the given production lot belong to a pack
# Move the pack in the same destination
# """
# ''' variables '''
# production_lot_obj = self.pool.get('stock.production.lot')
# move_packaging_obj = self.pool.get('stock.move.packaging')
# ''' init '''
# if context == None:
# context = {}
# ''' process '''
# for move in self.browse(cr, uid, ids, context=context):
# if move.prodlot_id:
# if move.prodlot_id.tracking_id:
# move_packaging_obj.move_pack(cr, uid, move.prodlot_id.tracking_id, context)
# return {}
stock_move()
class stock_inventory_line(osv.osv):
_inherit = "stock.inventory.line"
_columns = {
'date': fields.datetime('Date'),
'note': fields.text('Notes'),
}
stock_inventory_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!-- Sequences for stock.inventory -->
<record id="seq_type_inventory_order" model="ir.sequence.type">
<field name="name">Inventory Order</field>
<field name="code">stock.inventory.move</field>
</record>
<record id="seq_sale_order" model="ir.sequence">
<field name="name">Inventory Order</field>
<field name="code">stock.inventory.move</field>
<field name="prefix">MOV</field>
<field name="padding">3</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_inventory_tree" model="ir.ui.view">
<field name="name">stock.inventory.tree</field>
<field name="model">stock.inventory</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock.view_inventory_tree"/>
<field name="arch" type="xml">
<field name="state" position="after">
<field name="type" invisible="1"/>
</field>
</field>
</record>
<record id="view_inventory_form" model="ir.ui.view">
<field name="name">stock.inventory.form</field>
<field name="model">stock.inventory</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_inventory_form"/>
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="type" invisible="1"/>
<group colspan="4"><!-- attrs="{'invisible':[('type','=','normal')]}">-->
<field name="location_id" required="1"/>
<field name="location_dest_id" attrs="{'required':[('type','=','move')],'invisible':[('type','=','normal')]}"/>
<button name="fill_inventory" string="Start Acquisition" type="object" icon="gtk-apply" colspan="4" attrs="{'invisible':['|',('type','=','move'),('state','!=','draft')]}"/>
<button name="fill_inventory" string="Get Stock" type="object" icon="gtk-apply" colspan="4" attrs="{'invisible':['|',('type','=','normal'),('state','!=','draft')]}" context="{'type':'move'}"/>
</group>
</field>
<button name="action_confirm" position="replace">
<button name="action_confirm" string="Confirm Inventory" type="object" icon="gtk-apply" attrs="{'invisible':['|',('type','=','move'),('state','!=','draft')]}"/>
<button name="move_stock" string="Move Stock" type="object" icon="gtk-apply" attrs="{'invisible':['|',('type','=','normal'),('state','!=','draft')]}"/>
</button>
<button name="action_done" position="replace">
<button name="action_done" string="Validate Inventory" attrs="{'invisible':['|',('type','=','move'),('state','!=','confirm')]}" type="object" icon="gtk-jump-to"/>
<button name="action_done" string="Validate Move" attrs="{'invisible':['|',('type','=','normal'),('state','!=','confirm')]}" type="object" icon="gtk-jump-to"/>
</button>
</field>
</record>
<record id="stock.action_inventory_form" model="ir.actions.act_window">
<field name="context">{'full':'1', 'type':'normal'}</field>
<field name="domain">[('type', '=', 'normal')]</field>
</record>
<record id="stock.action_inventory_form_draft" model="ir.actions.act_window">
<field name="domain">[('state','=','draft'), ('type', '=', 'normal')]</field>
</record>
<record id="action_move_stock_form" model="ir.actions.act_window">
<field name="name">Move stock</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.inventory</field>
<field name="view_type">form</field>
<field name="view_id" ref="stock.view_inventory_tree"/>
<field name="context">{'full':'1', 'type':'move'}</field>
<field name="domain">[('type', '=', 'move')]</field>
<field name="search_view_id" ref="stock.view_inventory_filter" />
<field name="help">You can use this to move a stock from a location to an other one.</field>
</record>
<menuitem action="action_move_stock_form" id="menu_action_move_stock_form" parent="stock.menu_stock_inventory_control" sequence="30"/>
</data>
</openerp>

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import move_location
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
class stock_fill_inventory(osv.osv_memory):
_inherit = "stock.fill.inventory"
def _get_location(self, cr, uid, active_id, context={}):
res = False
if active_id:
inv = self.pool.get('stock.inventory').browse(cr, uid, active_id)
if inv.location_id:
res = inv.location_id.id
return res
_columns = {
'location_id': fields.many2one('stock.location', 'Location', required=True),
}
_defaults = {
'location_id': lambda s,cr,uid,c: s._get_location(cr, uid, c.get('active_id',False), c),
}
stock_fill_inventory()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--<record id="view_stock_move_stock" model="ir.ui.view">
<field name="name">Import Stock</field>
<field name="model">stock.fill.inventory</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Import Stock">
<separator string="Import current product inventory from the following location" colspan="4" />
<field name="location_id"/>
<newline/>
<field name="recursive"/>
<newline/>
<field name="set_stock_zero"/>
<separator string="" colspan="4" />
<button special="cancel" string="_Cancel" icon='gtk-cancel'/>
<button name="fill_inventory" string="Fill Location" type="object" icon="gtk-ok"/>
</form>
</field>
</record>
<act_window name="Import Stock"
res_model="stock.fill.inventory"
src_model="stock.inventory"
view_mode="form"
target="new"
context="{'search_default_in_location':1}"
key2="client_action_multi"
id="action_view_stock_move_stock"/>-->
</data>
</openerp>

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock
import invoice
import product
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Stock On Hold Status",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This Module allows to hold pickings.
It's adding a button which holding the picking and workflow.
You should use the sale_prepayment module to be automated with sale orders and invoices.
""",
"website" : "http://www.julius.fr",
"depends" : [
"stock",
],
"category" : "Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [
'wizard/stock_invoice_onshipping_view.xml',
'stock_view.xml',
'stock_workflow.xml',
],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
class account_invoice(osv.osv):
_inherit = 'account.invoice'
def confirm_paid(self, cr, uid, ids, context=None):
if context is None:
context = {}
super(account_invoice, self).confirm_paid(cr, uid, ids, context)
cr.execute("""SELECT order_id FROM sale_order_invoice_rel WHERE invoice_id in %s """, (tuple(ids),))
order_ids = map(lambda x: x[0], cr.fetchall())
self.pool.get('sale.order').write(cr, uid, order_ids, {})
cr.execute("""SELECT id FROM stock_picking where state = 'on_hold_paym' and sale_id in (SELECT order_id FROM sale_order_invoice_rel WHERE invoice_id in %s) """, (tuple(ids),))
pickings = map(lambda x: x[0], cr.fetchall())
self.pool.get('stock.picking').action_assign(cr, uid, pickings)
return True
_columns = {
'is_advance': fields.boolean('Is an advance?'),
}
account_invoice()
class account_invoice_line(osv.osv):
_inherit = 'account.invoice.line'
_columns = {
'is_advance': fields.boolean('Is an advance?'),
}
account_invoice_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
import decimal_precision as dp
class product_product(osv.osv):
_inherit = "product.product"
def _product_available(self, cr, uid, ids, field_names=None, arg=False, context={}):
if not field_names:
field_names = []
res = {}
for id in ids:
res[id] = {}.fromkeys(field_names, 0.0)
for f in field_names:
c = context.copy()
if f == 'qty_available':
c.update({ 'states':('done',), 'what':('in', 'out') })
if f == 'virtual_available':
c.update({ 'states':('confirmed','waiting','assigned','on_hold','on_hold_billing','on_hold_paym','done'), 'what':('in', 'out') })
if f == 'incoming_qty':
c.update({ 'states':('confirmed','waiting','assigned','on_hold','on_hold_billing','on_hold_paym'), 'what':('in',) })
if f == 'outgoing_qty':
c.update({ 'states':('confirmed','waiting','assigned','on_hold','on_hold_billing','on_hold_paym'), 'what':('out',) })
stock = self.get_product_available(cr,uid,ids,context=c)
for id in ids:
res[id][f] = stock.get(id, 0.0)
return res
_columns = {
'qty_available': fields.function(_product_available, method=True, type='float', string='Real Stock', help="Current quantities of products in selected locations or all internal if none have been selected.", multi='qty_available', digits_compute=dp.get_precision('Product UoM')),
'virtual_available': fields.function(_product_available, method=True, type='float', string='Virtual Stock', help="Future stock for this product according to the selected location or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming.", multi='qty_available', digits_compute=dp.get_precision('Product UoM')),
'incoming_qty': fields.function(_product_available, method=True, type='float', string='Incoming', help="Quantities of products that are planned to arrive in selected locations or all internal if none have been selected.", multi='qty_available', digits_compute=dp.get_precision('Product UoM')),
'outgoing_qty': fields.function(_product_available, method=True, type='float', string='Outgoing', help="Quantities of products that are planned to leave in selected locations or all internal if none have been selected.", multi='qty_available', digits_compute=dp.get_precision('Product UoM')),
}
product_product()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

582
stock_move_on_hold/stock.py Normal file
View File

@@ -0,0 +1,582 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from datetime import datetime
from osv import fields, osv
from tools.translate import _
import netsvc
# ----------------------------------------------------
# Move
# ----------------------------------------------------
#
# Fields:
# location_dest_id is only used for predicting future stocks
#
class stock_move(osv.osv):
_inherit = 'stock.move'
_columns = {
'state': fields.selection([
('draft', 'Draft'),
('waiting', 'Waiting'),
('on_hold', 'Waiting for prepayment'),
('on_hold_billing', 'Waiting for billing'),
('on_hold_paym', 'Waiting for payment'),
('confirmed', 'Not Available'),
('assigned', 'Available'),
('done', 'Done'),
('cancel', 'Cancelled')
], 'State', readonly=True, select=True,
help="* When the stock move is created it is in the \'Draft\' state.\n"\
"* After that, it is set to \'Not Available\' state if the scheduler did not find the products.\n"\
"* When products are reserved it is set to \'Available\'.\n"\
"* When the picking is done the state is \'Done\'.\n"\
"* The state is \'Waiting\' if the move is waiting for another one.\n"\
"* The state is \'Waiting for prepayment\' if it's waiting for a prepayment of the sale order\n"\
"* The state is \'Waiting for billing\' if it's waiting for billing of the move\n"\
"* The state is \'Waiting for payment\' if it's waiting for the payment of the move"),
}
def action_on_hold(self, cr, uid, ids, context=None):
""" Holds stock move.
@return: List of ids.
"""
moves = self.browse(cr, uid, ids, context=context)
self.write(cr, uid, ids, {'state': 'on_hold'})
if moves:
picking = moves[0].picking_id
if picking:
moves = picking.move_lines
state = 'on_hold'
for move in moves:
if move.state not in ['on_hold','done','cancel']:
state = False
break
if state:
self.pool.get('stock.picking').write(cr, uid, picking.id, {'state': state}, context)
return []
def action_hold_to_confirm(self, cr, uid, ids, context=None):
""" Makes hold stock moves to the confirmed state.
@return: List of ids.
"""
moves = self.browse(cr, uid, ids, context=context)
self.write(cr, uid, ids, {'state': 'confirmed'})
if moves:
picking = moves[0].picking_id
if picking:
moves = picking.move_lines
state = 'confirmed'
for move in moves:
if move.state in ['on_hold','draft']:
state = False
break
if state:
self.pool.get('stock.picking').write(cr, uid, picking.id, {'state': state}, context)
return []
def action_confirm_waiting_bill(self, cr, uid, ids, context=None):
""" Makes hold stock moves to the wait for billing state.
@return: List of ids.
"""
moves = self.browse(cr, uid, ids, context=context)
self.write(cr, uid, ids, {'state': 'on_hold_billing'})
if moves:
picking = moves[0].picking_id
if picking:
moves = picking.move_lines
state = 'on_hold_billing'
for move in moves:
if move.state in ['on_hold','draft']:
state = False
break
if state:
self.pool.get('stock.picking').write(cr, uid, picking.id, {'state': state}, context)
return []
def action_waiting_bill_to_unpaid(self, cr, uid, ids, context=None):
""" Makes hold stock moves to the wait for payment state.
@return: List of ids.
"""
moves = self.browse(cr, uid, ids, context=context)
if moves:
picking = moves[0].picking_id
if picking:
moves = picking.move_lines
state = 'on_hold_paym'
for move in moves:
if move.state in ['on_hold','draft']:
state = False
break
if state:
self.pool.get('stock.picking').write(cr, uid, picking.id, {'state': state}, context)
return []
""" This part is replacing the usual one to be able to taking in account the new states. """
def action_assign(self, cr, uid, ids, *args):
""" Changes state to confirmed or waiting.
@return: List of values
"""
todo = []
for move in self.browse(cr, uid, ids):
if move.state in ('confirmed', 'waiting', 'on_hold_billing', 'on_hold_paym', 'assigned'):
todo.append(move.id)
res = self.check_assign(cr, uid, todo)
return res
""" This part is replacing the usual one to be able to taking in account the new states. """
def check_assign(self, cr, uid, ids, context=None):
""" Checks the product type and accordingly writes the state.
@return: No. of moves done
"""
done = []
count = 0
waiting = 0
pickings = {}
if context is None:
context = {}
for move in self.browse(cr, uid, ids, context=context):
if move.product_id.type == 'consu' or move.location_id.usage == 'supplier':
if move.state in ('confirmed', 'waiting'):
done.append(move.id)
pickings[move.picking_id.id] = 1
continue
if move.state in ('confirmed', 'waiting', 'on_hold_billing', 'on_hold_paym'):
if move.state in ('on_hold_billing', 'on_hold_paym'):
res = True
else:
# Important: we must pass lock=True to _product_reserve() to avoid race conditions and double reservations
res = self.pool.get('stock.location')._product_reserve(cr, uid, [move.location_id.id], move.product_id.id, move.product_qty, {'uom': move.product_uom.id}, lock=True)
if res:
if move.sale_line_id and move.sale_line_id.order_id.order_policy in ['ship_prepayment','wait_prepayment']:
if not move.sale_line_id.invoice_lines:
self.write(cr, uid, [move.id], {'state':'on_hold_billing'})
pickings[move.picking_id.id] = 1
waiting += 1
else:
for line in move.sale_line_id.invoice_lines:
if line.invoice_id and line.invoice_id.state == 'cancel':
self.write(cr, uid, [move.id], {'state':'on_hold_billing'})
pickings[move.picking_id.id] = 1
waiting += 1
elif line.invoice_id and line.invoice_id.state != 'paid':
self.write(cr, uid, [move.id], {'state':'on_hold_paym'})
pickings[move.picking_id.id] = 1
waiting += 1
elif line.invoice_id and line.invoice_id.state == 'paid':
self.write(cr, uid, [move.id], {'state':'assigned'})
pickings[move.picking_id.id] = 1
waiting += 1
#_product_available_test depends on the next status for correct functioning
#the test does not work correctly if the same product occurs multiple times
#in the same order. This is e.g. the case when using the button 'split in two' of
#the stock outgoing form
elif res != True:
self.write(cr, uid, [move.id], {'state':'assigned'})
done.append(move.id)
pickings[move.picking_id.id] = 1
r = res.pop(0)
cr.execute('update stock_move set location_id=%s, product_qty=%s where id=%s', (r[1], r[0], move.id))
while res:
r = res.pop(0)
move_id = self.copy(cr, uid, move.id, {'product_qty': r[0], 'location_id': r[1]})
done.append(move_id)
if done:
count += len(done)
self.write(cr, uid, done, {'state': 'assigned'})
if count or waiting:
for pick_id in pickings:
wf_service = netsvc.LocalService("workflow")
wf_service.trg_write(uid, 'stock.picking', pick_id, cr)
return count
stock_move()
class stock_picking(osv.osv):
_inherit = 'stock.picking'
_columns = {
'state': fields.selection([
('draft', 'Draft'),
('auto', 'Waiting'),
('on_hold', 'Waiting for prepayment'),
('on_hold_billing', 'Waiting for billing'),
('on_hold_paym', 'Waiting for payment'),
('confirmed', 'Confirmed'),
('assigned', 'Available'),
('done', 'Done'),
('cancel', 'Cancelled'),
], 'State', readonly=True, select=True,
help="* Draft: not confirmed yet and will not be scheduled until confirmed\n"\
"* Confirmed: still waiting for the availability of products\n"\
"* Waiting: waiting for another move to proceed before it becomes automatically available (e.g. in Make-To-Order flows)\n"\
"* On Hold: waiting for a payment, payment or billing\n"\
"* Waiting for billing: waiting for billing of the picking\n"\
"* Waiting for payment: waiting for the payment of the picking\n"\
"* Available: products reserved, simply waiting for confirmation.\n"\
"* Done: has been processed, can't be modified or cancelled anymore\n"\
"* Cancelled: has been cancelled, can't be confirmed anymore"),
}
def action_on_hold(self, cr, uid, ids, context=None):
""" Holds picking.
@return: True
"""
self.write(cr, uid, ids, {'state': 'on_hold'})
todo = []
for picking in self.browse(cr, uid, ids, context=context):
for r in picking.move_lines:
if r.state in ['draft','confirmed','waiting','assigned','on_hold_billing','on_hold_paym']:
todo.append(r.id)
self.log_picking(cr, uid, ids, context=context)
todo = self.action_explode(cr, uid, todo, context)
if len(todo):
self.pool.get('stock.move').action_on_hold(cr, uid, todo, context=context)
return True
def action_hold_to_confirm(self, cr, uid, ids, context=None):
""" Makes hold pickings to the confirmed state.
@return: True
"""
self.write(cr, uid, ids, {'state': 'confirmed'})
todo = []
for picking in self.browse(cr, uid, ids, context=context):
for r in picking.move_lines:
if r.state in ['on_hold']:
todo.append(r.id)
self.log_picking(cr, uid, ids, context=context)
todo = self.action_explode(cr, uid, todo, context)
if len(todo):
self.pool.get('stock.move').action_hold_to_confirm(cr, uid, todo, context=context)
return True
def action_confirm_waiting_bill(self, cr, uid, ids, context=None):
""" Makes hold pickings to the wait for billing state.
@return: True
"""
self.write(cr, uid, ids, {'state': 'on_hold_billing', 'invoice_state': '2binvoiced'})
todo = []
for picking in self.browse(cr, uid, ids, context=context):
for r in picking.move_lines:
if r.state in ['on_hold_billing']:
todo.append(r.id)
self.log_picking(cr, uid, ids, context=context)
todo = self.action_explode(cr, uid, todo, context)
if len(todo):
self.pool.get('stock.move').action_confirm_waiting_bill(cr, uid, todo, context=context)
return True
def action_waiting_bill_to_unpaid(self, cr, uid, ids, context=None):
""" Makes hold pickings to the wait for payment state.
@return: True
"""
self.write(cr, uid, ids, {'state': 'on_hold_paym'})
todo = []
for picking in self.browse(cr, uid, ids, context=context):
for r in picking.move_lines:
if r.state in ['on_hold_paym']:
todo.append(r.id)
self.log_picking(cr, uid, ids, context=context)
todo = self.action_explode(cr, uid, todo, context)
if len(todo):
self.pool.get('stock.move').action_waiting_bill_to_unpaid(cr, uid, todo, context=context)
return True
""" This part is replacing the usual one to be able to taking in account the new states. """
def action_assign(self, cr, uid, ids, *args):
""" Changes state of picking to available if all moves are confirmed.
@return: True
"""
for pick in self.browse(cr, uid, ids):
move_ids = [x.id for x in pick.move_lines if x.state in ['confirmed','on_hold_billing','on_hold_paym']]
if not move_ids:
raise osv.except_osv(_('Warning !'),_('Not enough stock, unable to reserve the products.'))
self.pool.get('stock.move').action_assign(cr, uid, move_ids)
return True
def test_billed(self, cr, uid, ids):
""" Tests whether the move has been billed or not.
@return: True or False
"""
ok = True
for pick in self.browse(cr, uid, ids):
mt = pick.move_type
for move in pick.move_lines:
if (move.state in ('confirmed', 'draft')) and (mt == 'one'):
return False
if (mt == 'direct') and (move.state == 'on_hold_billing') and (move.product_qty):
return True
ok = ok and (move.state in ('cancel', 'done', 'assigned', 'on_hold_paym'))
return ok
def test_bill_and_paid(self, cr, uid, ids):
""" Tests whether the move has been billed and paid or not.
@return: True or False
"""
ok = True
for pick in self.browse(cr, uid, ids):
mt = pick.move_type
for move in pick.move_lines:
if (move.state in ('confirmed', 'draft', 'on_hold', 'on_hold_billing')) and (mt == 'one'):
return False
if (mt == 'direct') and (move.state == 'on_hold_paym') and (move.product_qty):
return True
ok = ok and (move.state in ('cancel', 'done', 'assigned'))
return ok
def test_paid(self, cr, uid, ids):
""" Tests whether the move has been paid.
@return: True or False
"""
ok = True
for pick in self.browse(cr, uid, ids):
mt = pick.move_type
for move in pick.move_lines:
if (move.state in ('confirmed', 'draft', 'on_hold', 'on_hold_billing', 'on_hold_paym')) and (mt == 'one'):
return False
if (mt == 'direct') and (move.state == 'assigned') and (move.product_qty):
return True
ok = ok and (move.state in ('cancel', 'done', 'assigned'))
return ok
""" This part is replacing the usual one to be able to taking in account the new states. """
def log_picking(self, cr, uid, ids, context=None):
""" This function will create log messages for picking.
@param cr: the database cursor
@param uid: the current user's ID for security checks,
@param ids: List of Picking Ids
@param context: A standard dictionary for contextual values
"""
if context is None:
context = {}
data_obj = self.pool.get('ir.model.data')
for pick in self.browse(cr, uid, ids, context=context):
msg=''
if pick.auto_picking:
continue
type_list = {
'out':_("Delivery Order"),
'in':_('Reception'),
'internal': _('Internal picking'),
}
view_list = {
'out': 'view_picking_out_form',
'in': 'view_picking_in_form',
'internal': 'view_picking_form',
}
message = type_list.get(pick.type, _('Document')) + " '" + (pick.name or '?') + "' "
if pick.min_date:
msg= _(' for the ')+ datetime.strptime(pick.min_date, '%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y')
state_list = {
'confirmed': _("is scheduled") + msg +'.',
'assigned': _('is ready to process.'),
'cancel': _('is cancelled.'),
'done': _('is done.'),
'draft': _('is in draft state.'),
'auto': _('is waiting.'),
'on_hold': _('is hold, waiting for prepayment.'),
'on_hold_billing': _('is ready to process but waiting for a billing.'),
'on_hold_paym': _('is ready to process but waiting for the payment.'),
}
res = data_obj.get_object_reference(cr, uid, 'stock', view_list.get(pick.type, 'view_picking_form'))
context.update({'view_id': res and res[1] or False})
message += state_list[pick.state]
self.log(cr, uid, pick.id, message, context=context)
return True
def already_invoiced(self, cr, uid, ids, pick_invoice, context=None):
""" Looking for what have already been invoice to deduce it on the new invoice """
invoice_obj = self.pool.get('account.invoice')
sale_obj = self.pool.get('sale.order')
picking_ids = self.browse(cr, uid, ids, context)
res = {}
for pick in picking_ids:
sale_id = pick.sale_id and pick.sale_id.id
if sale_id:
amount_prepaid = 0.00
amount_total = 0.00
cr.execute("""SELECT invoice_id FROM sale_order_invoice_rel WHERE order_id = %s """, (sale_id,))
invoice_ids = map(lambda x: x[0], cr.fetchall())
invoice_open_paid = invoice_obj.search(cr, uid, [('id', 'in', invoice_ids),('state', 'in', ['open','paid'])])
invoice_id = pick_invoice[pick.id]
res[invoice_id] = invoice_open_paid
for invoice in invoice_obj.browse(cr, uid, invoice_open_paid):
if invoice.is_advance:
amount_prepaid += invoice.amount_untaxed or 0.00
else:
for line in invoice.invoice_line:
if not line.is_advance:
amount_total += line.price_subtotal or 0.00
sale_obj.write(cr, uid, [sale_id], {'amount_prepaid': amount_prepaid, 'amount_shipped': amount_total})
return res
def create_advance_line(self, cr, uid, pick_invoice, invoice_done, context=None):
invoice_obj = self.pool.get('account.invoice')
account_line_obj = self.pool.get('account.invoice.line')
for pick in pick_invoice:
picking_id = self.browse(cr, uid, pick, context)
sale_id = picking_id.sale_id
total_amount = sale_id.amount_untaxed or 0.00
prepaid_amount = sale_id.amount_prepaid or 0.00
amount_shipped = sale_id.amount_shipped or 0.00
invoice_id = pick_invoice[pick]
invoice_id = invoice_obj.browse(cr, uid, invoice_id)
invoice_amount = invoice_id.amount_untaxed
if prepaid_amount >= amount_shipped:
if (invoice_amount + amount_shipped) > prepaid_amount:
line_amount = - (prepaid_amount - amount_shipped)
else:
line_amount = - invoice_amount
res = account_line_obj.product_id_change(cr, uid, [], 7624, False, 1, partner_id=invoice_id.partner_id.id, fposition_id=invoice_id.fiscal_position.id, price_unit=line_amount, address_invoice_id=invoice_id.address_invoice_id.id, currency_id=invoice_id.currency_id.id, context=context)
account_line_obj = self.pool.get('account.invoice.line')
vals = res['value']
vals.update({'invoice_id': invoice_id.id, 'invoice_line_tax_id': [(6, 0, vals['invoice_line_tax_id'])], 'note':'', 'price_unit': line_amount, 'is_advance': True})
if vals['price_unit'] <> 0:
account_line_obj.create(cr, uid, vals)
invoice_amount = invoice_id.amount_untaxed
if sale_id:
self.pool.get('sale.order').write(cr, uid, [sale_id.id], {'amount_shipped': amount_shipped + invoice_amount})
invoice_obj.button_reset_taxes(cr, uid, [invoice_id.id], context=context)
return
def associate_lines(self, cr, uid, ids, pick_invoice, context):
inv_line_obj = self.pool.get('account.invoice.line')
move_line_obj = self.pool.get('stock.move')
for pick in pick_invoice:
picking_id = self.browse(cr, uid, pick, context)
invoice_id = pick_invoice[pick]
move_lines = picking_id.move_lines
for line in move_lines:
invoice_line_ids = inv_line_obj(cr, uid, [
('invoice_id', '=', invoice_id),
('product_id', '=', line.product_id.id),
('quantity', '=', line.product_qty),
])
if invoice_line_ids:
move_line_obj.write(cr, uid, [line.id], {'invoice_line_id': invoice_line_ids[0]})
def action_invoice_create(self, cr, uid, ids, journal_id=False,
group=False, type='out_invoice', context=None):
if context is None:
context = {}
if context.get('before_shipping', False):
picking_ids = self.browse(cr, uid, ids)
todo = []
sequence_obj = self.pool.get('ir.sequence')
for pick in picking_ids:
line_ids = [x.id for x in pick.move_lines if x.state == 'on_hold_billing']
old_lines_ids = [x.id for x in pick.move_lines if x.id not in line_ids]
if line_ids:
wf_service = netsvc.LocalService("workflow")
if old_lines_ids:
new_picking = self.copy(cr, uid, pick.id,
{
'name': sequence_obj.get(cr, uid, 'stock.picking.%s'%(pick.type)),
'move_lines' : [],
'state':'confirmed',
'backorder_id': pick.id,
})
self.pool.get('stock.move').write(cr, uid, old_lines_ids, {'picking_id': new_picking}),
wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
self.pool.get('stock.move').write(cr, uid, line_ids, {'state': 'on_hold_paym'}),
todo.append(pick.id)
ids = todo
res = super(stock_picking, self).action_invoice_create(cr, uid, ids, journal_id, group, type, context)
invoice_done = self.already_invoiced(cr, uid, ids, res, context)
self.create_advance_line(cr, uid, res, invoice_done, context)
return res
stock_picking()
class stock_location(osv.osv):
_inherit = "stock.location"
def _product_reserve(self, cr, uid, ids, product_id, product_qty, context=None, lock=False):
result = super(stock_location, self)._product_reserve(cr, uid, ids, product_id, product_qty, context, lock)
if context is None:
context = {}
result = []
for id in self.search(cr, uid, [('location_id', 'child_of', ids)]):
cr.execute("""SELECT product_uom, sum(product_qty) AS product_qty
FROM stock_move
WHERE location_dest_id=%s AND
location_id<>%s AND
product_id=%s AND
state='done'
GROUP BY product_uom
""",
(id, id, product_id))
results = cr.dictfetchall()
cr.execute("""SELECT product_uom,-sum(product_qty) AS product_qty
FROM stock_move
WHERE location_id=%s AND
location_dest_id<>%s AND
product_id=%s AND
state in ('done', 'assigned', 'on_hold_billing', 'on_hold_paym')
GROUP BY product_uom
""",
(id, id, product_id))
results += cr.dictfetchall()
total = 0.0
results2 = 0.0
for r in results:
amount = self.pool.get('product.uom')._compute_qty(cr, uid, r['product_uom'], r['product_qty'], context.get('uom', False))
results2 += amount
total += amount
if total <= 0.0:
continue
amount = results2
if amount > 0:
if amount > min(total, product_qty):
amount = min(product_qty, total)
result.append((amount, id))
product_qty -= amount
total -= amount
if product_qty <= 0.0:
return result
if total <= 0.0:
continue
return False
stock_location()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--<record id="stock_move_tree_on_hold_inherit" model="ir.ui.view">
<field name="name">Stock Moves inherit</field>
<field name="model">stock.move</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock.stock_move_tree"/>
<field name="arch" type="xml">
<button name="action_done" position="before">
<button name="action_hold_to_confirm" states="on_hold" string="Set to confirm" type="object" icon="gtk-media-play"/>
<button name="action_on_hold" states="confirmed,assigned" string="Hold it" type="object" icon="gtk-media-pause"/>
<button name="action_bill_available" states="on_hold_billing" string="Bill available products" type="object" icon="terp-dolar"/>
</button>
</field>
</record>
<record id="view_move_search_on_hold" model="ir.ui.view">
<field name="name">stock.move.search.inherit</field>
<field name="model">stock.move</field>
<field name="type">search</field>
<field name="inherit_id" ref="stock.view_move_search"/>
<field name="arch" type="xml">
<filter name="done" position="after">
<filter icon="gtk-media-pause" name="on_hold" string="On Hold" domain="[('state','in',['on_hold','on_hold_billing','on_hold_paym'])]"/>
</filter>
</field>
</record>
<record id="view_move_tree_reception_picking_on_hold" model="ir.ui.view">
<field name="name">stock.move.tree2.inherit</field>
<field name="model">stock.move</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock.view_move_tree_reception_picking"/>
<field name="arch" type="xml">
<button name="action_done" position="before">
<button name="action_hold_to_confirm" states="on_hold" string="Set to confirm" type="object" icon="gtk-media-play"/>
<button name="action_on_hold" states="confirmed,assigned" string="Hold it" type="object" icon="gtk-media-pause"/>
<button name="action_bill_available" states="on_hold_billing" string="Bill available products" type="object" icon="terp-dolar"/>
</button>
</field>
</record>
<record id="view_move_tree_reception_picking_board_on_hold" model="ir.ui.view">
<field name="name">stock.move.tree3</field>
<field name="model">stock.move</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock.view_move_tree_reception_picking_board"/>
<field name="arch" type="xml">
<button name="action_done" position="before">
<button name="action_hold_to_confirm" states="on_hold" string="Set to confirm" type="object" icon="gtk-media-play"/>
<button name="action_on_hold" states="confirmed,assigned" string="Hold it" type="object" icon="gtk-media-pause"/>
<button name="action_bill_available" states="on_hold_billing" string="Bill available products" type="object" icon="terp-dolar"/>
</button>
</field>
</record>
<record id="view_move_form_reception_picking_on_hold" model="ir.ui.view">
<field name="name">stock.move.form2.inherit</field>
<field name="model">stock.move</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_move_form_reception_picking"/>
<field name="arch" type="xml">
<button name="action_done" position="before">
<button name="action_hold_to_confirm" states="on_hold" string="Set to confirm" type="object" icon="gtk-media-play"/>
<button name="action_on_hold" states="confirmed,assigned" string="Hold it" type="object" icon="gtk-media-pause"/>
<button name="action_bill_available" states="on_hold_billing" string="Bill available products" type="object" icon="terp-dolar"/>
</button>
</field>
</record>-->
<record id="view_move_search_reception_outcoming_picking_on_hold" model="ir.ui.view">
<field name="name">stock.move.outgoing.search2.inherit</field>
<field name="model">stock.move</field>
<field name="type">search</field>
<field name="inherit_id" ref="stock.view_move_search_reception_outcoming_picking"/>
<field name="arch" type="xml">
<filter name="available" position="after">
<filter icon="gtk-media-pause" name="on_hold" string="On Hold" domain="[('state','in',['on_hold','on_hold_billing','on_hold_paym'])]"/>
</filter>
</field>
</record>
<record id="view_picking_out_form_on_hold" model="ir.ui.view">
<field name="name">stock.picking.out.form.inherit</field>
<field name="model">stock.picking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[@string='Products']/field[@name='move_lines']/tree/button[@name='action_done']" position="before">
<button name="action_cancel" states="assigned,on_hold" string="Cancel" type="object" icon="gtk-cancel"/>
<!--<button name="action_on_hold" states="confirmed,assigned" string="Hold it" type="object" icon="gtk-media-pause"/>
<button name="action_hold_to_confirm" states="on_hold" string="Set to confirm" type="object" icon="gtk-media-play"/>-->
<!--<button name="action_bill_available" states="on_hold_billing" string="Bill available products" type="object" icon="terp-dolar"/>-->
</xpath>
<xpath expr="/form/notebook/page[@string='Products']/field[@name='move_lines']/form/group/button[@name='action_cancel']" position="replace">
<!--<button name="action_cancel" states="assigned,on_hold" string="Cancel" type="object" icon="gtk-cancel"/>
<button name="action_hold_to_confirm" states="on_hold" string="Set to confirm" type="object" icon="gtk-media-play"/>-->
<!--<button name="action_bill_available" states="on_hold_billing" string="Bill available products" type="object" icon="terp-dolar"/>-->
</xpath>
<button name="button_cancel" position="replace">
<button name="button_cancel" states="assigned,confirmed,draft,on_hold,on_hold_billing,on_hold_paym" string="_Cancel" icon="gtk-cancel"/>
<button name="action_hold_to_confirm" states="on_hold" string="Set to confirm" type="object" icon="gtk-media-play"/>
<button name="action_on_hold" states="confirmed,assigned" string="Hold it" type="object" icon="gtk-media-pause"/>
<button name="%(stock.action_stock_invoice_before_shipping)d" states="on_hold_billing" string="Bill Available Products" type="action" icon="terp-dolar" context="{'before_shipping':True}"/>
</button>
<button name="action_assign" position="replace">
<button name="action_assign" states="confirmed,on_hold_billing,on_hold_paym,assigned" string="Check Availability" type="object" icon="gtk-find"/>
</button>
</field>
</record>
<record id="view_stock_picking_filter_on_hold" model="ir.ui.view">
<field name="name">stock.picking.list.select.inherit</field>
<field name="model">stock.picking</field>
<field name="type">search</field>
<field name="inherit_id" ref="stock.view_stock_picking_filter"/>
<field name="arch" type="xml">
<filter name="available" position="after">
<filter icon="gtk-media-pause" name="on_hold" string="On Hold" domain="[('state','in',['on_hold','on_hold_billing','on_hold_paym'])]" help="On Hold Pickings"/>
</filter>
</field>
</record>
<record id="view_picking_out_search_on_hold" model="ir.ui.view">
<field name="name">stock.picking.out.search.inherit</field>
<field name="model">stock.picking</field>
<field name="type">search</field>
<field name="inherit_id" ref="stock.view_picking_out_search"/>
<field name="arch" type="xml">
<filter name="available" position="after">
<filter icon="gtk-media-pause" name="on_hold" string="On Hold" domain="[('state','in',['on_hold','on_hold_billing','on_hold_paym'])]" help="On Hold Pickings"/>
</filter>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="stock.act_hold" model="workflow.activity">
<field name="wkf_id" ref="stock.wkf_picking"/>
<field name="name">on_hold</field>
<field name="kind">function</field>
<field name="action">action_on_hold()</field>
</record>
<record id="stock.trans_draft_hold" model="workflow.transition">
<field name="act_from" ref="stock.act_draft"/>
<field name="act_to" ref="stock.act_hold"/>
<field name="signal">button_on_hold</field>
</record>
<record id="stock.trans_confirmed_hold" model="workflow.transition">
<field name="act_from" ref="stock.act_confirmed"/>
<field name="act_to" ref="stock.act_hold"/>
<field name="signal">button_on_hold</field>
</record>
<record id="stock.trans_assigned_hold" model="workflow.transition">
<field name="act_from" ref="stock.act_assigned"/>
<field name="act_to" ref="stock.act_hold"/>
<field name="signal">button_on_hold</field>
</record>
<record id="stock.act_unhold" model="workflow.activity">
<field name="wkf_id" ref="stock.wkf_picking"/>
<field name="name">unhold</field>
<field name="kind">function</field>
<field name="action">action_hold_to_confirm()</field>
</record>
<record id="stock.act_wait_bill" model="workflow.activity">
<field name="wkf_id" ref="stock.wkf_picking"/>
<field name="name">unbilled</field>
<field name="kind">function</field>
<field name="action">action_confirm_waiting_bill()</field>
</record>
<record id="stock.act_wait_bill_paid" model="workflow.activity">
<field name="wkf_id" ref="stock.wkf_picking"/>
<field name="name">unpaid</field>
<field name="kind">function</field>
<field name="action">action_waiting_bill_to_unpaid()</field>
</record>
<record id="stock.trans_hold_confirm" model="workflow.transition">
<field name="act_from" ref="stock.act_hold"/>
<field name="act_to" ref="stock.act_unhold"/>
<field name="signal">button_unhold</field>
</record>
<record id="stock.trans_unhold_assigned" model="workflow.transition">
<field name="act_from" ref="stock.act_unhold"/>
<field name="act_to" ref="stock.act_assigned"/>
<field name="condition">test_assigned()</field>
</record>
<record id="stock.trans_unhold_confirmed" model="workflow.transition">
<field name="act_from" ref="stock.act_unhold"/>
<field name="act_to" ref="stock.act_confirmed"/>
</record>
<record id="stock.trans_confirmed_wait_bill" model="workflow.transition">
<field name="act_from" ref="stock.act_confirmed"/>
<field name="act_to" ref="stock.act_wait_bill"/>
<field name="condition">test_billed()</field>
</record>
<record id="stock.trans_confirmed_wait_bill_paid" model="workflow.transition">
<field name="act_from" ref="stock.act_wait_bill"/>
<field name="act_to" ref="stock.act_wait_bill_paid"/>
<field name="condition">test_bill_and_paid()</field>
</record>
<record id="stock.trans_wait_bill_paid_wait_bill" model="workflow.transition">
<field name="act_from" ref="stock.act_wait_bill_paid"/>
<field name="act_to" ref="stock.act_wait_bill"/>
<field name="condition">not test_bill_and_paid()</field>
</record>
<record id="stock.trans_paid_assigned" model="workflow.transition">
<field name="act_from" ref="stock.act_wait_bill_paid"/>
<field name="act_to" ref="stock.act_assigned"/>
<field name="condition">test_paid()</field>
</record>
<record id="stock.trans_unhold_cancel" model="workflow.transition">
<field name="act_from" ref="stock.act_unhold"/>
<field name="act_to" ref="stock.act_cancel"/>
<field name="condition">allow_cancel()</field>
<field name="signal">button_cancel</field>
</record>
<record id="stock.trans_unhold_cancel_auto" model="workflow.transition">
<field name="act_from" ref="stock.act_unhold"/>
<field name="act_to" ref="stock.act_cancel"/>
<field name="condition">test_cancel()</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="stock.view_stock_invoice_before_shipping" model="ir.ui.view">
<field name="name">Stock Invoice Onshipping</field>
<field name="model">stock.invoice.onshipping</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Create invoice">
<separator colspan="4" string="Create invoice" />
<field name="journal_id"/>
<newline/>
<field name="group"/>
<newline/>
<field name="invoice_date" />
<separator string="" colspan="4" />
<button special="cancel" string="_Cancel" icon='gtk-cancel'/>
<button name="open_invoice" string="Create" type="object" icon="terp-gtk-go-back-rtl"/>
</form>
</field>
</record>
<act_window name="Create invoice"
res_model="stock.invoice.onshipping"
src_model="stock.picking"
key2="client_action_multi"
multi="True"
view_mode="form"
view_type="form"
target="new"
id="stock.action_stock_invoice_before_shipping"/>
</data>
</openerp>

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Move Stock Packaging",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This module allows to move packing with a wizard """,
"website" : "http://www.julius.fr",
"depends" : [
"stock",
"stock_tracking_extended",
],
"category" : "Customs/Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [
'stock_view.xml',
'wizard/move_pack_view.xml',
],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,97 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * stock_move_packaging
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-12-19 10:47+0000\n"
"PO-Revision-Date: 2011-12-19 10:47+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: stock_move_packaging
#: code:addons/stock_move_packaging/wizard/move_pack.py:58
#, python-format
msgid "You cannot move this pack because there is a none closed pack inside of it: %s."
msgstr "Vous ne pouvez pas déplacer ce pack car il y a un pack non fermé à l'intérieur de celui-ci: %s."
#. module: stock_move_packaging
#: field:stock.move.packaging,pack_id:0
msgid "Pack to move"
msgstr "Pack à deplacer"
#. module: stock_move_packaging
#: model:ir.model,name:stock_move_packaging.model_stock_tracking_history
msgid "stock.tracking.history"
msgstr "stock.tracking.history"
#. module: stock_move_packaging
#: field:stock.tracking.history,location_id:0
msgid "Source Location"
msgstr "Emplacement source"
#. module: stock_move_packaging
#: field:stock.tracking.history,location_dest_id:0
msgid "Destination Location"
msgstr "Emplacement de destination"
#. module: stock_move_packaging
#: model:ir.module.module,description:stock_move_packaging.module_meta_information
msgid " This module allows to move packing with a wizard "
msgstr " Ce module permet de déplacer les packs avec un assistant "
#. module: stock_move_packaging
#: code:addons/stock_move_packaging/wizard/move_pack.py:55
#, python-format
msgid "You cannot move this pack because it's inside of an other pack: %s."
msgstr "Vous ne pouvez pas déplacer ce pack, car il est à l'intérieur d'un autre pack: %s."
#. module: stock_move_packaging
#: model:ir.actions.act_window,name:stock_move_packaging.move_pack
#: view:stock.move.packaging:0
msgid "Move Pack"
msgstr "Mouvement de packs"
#. module: stock_move_packaging
#: model:ir.model,name:stock_move_packaging.model_stock_move_packaging
msgid "stock.move.packaging"
msgstr "stock.move.packaging"
#. module: stock_move_packaging
#: code:addons/stock_move_packaging/wizard/move_pack.py:55
#: code:addons/stock_move_packaging/wizard/move_pack.py:58
#, python-format
msgid "Warning!"
msgstr "Attention!"
#. module: stock_move_packaging
#: field:stock.move.packaging,location_dest_id:0
msgid "Destination location"
msgstr "Emplacement de Destination"
#. module: stock_move_packaging
#: view:stock.move.packaging:0
msgid "Cancel"
msgstr "Annuler"
#. module: stock_move_packaging
#: view:stock.move.packaging:0
msgid "Move it"
msgstr "Déplacer"
#. module: stock_move_packaging
#: view:stock.tracking:0
msgid "Move pack"
msgstr "Déplacer le pack"
#. module: stock_move_packaging
#: model:ir.module.module,shortdesc:stock_move_packaging.module_meta_information
msgid "Move Stock Packaging"
msgstr "Mouvement de stocks de packs"

View File

@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
class stock_tracking_history(osv.osv):
_inherit = "stock.tracking.history"
def _get_types(self, cr, uid, context={}):
res = super(stock_tracking_history, self)._get_types(cr, uid, context)
if not res:
res = []
res = res + [('move','Move')]
return res
_columns = {
'type': fields.selection(_get_types, 'Type'),
'location_id': fields.many2one('stock.location', 'Source Location'),
'location_dest_id': fields.many2one('stock.location', 'Destination Location'),
# 'move_ids': fields.one2many('stock.move', 'pack_history_id', 'Associated moves'),
}
stock_tracking_history()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_tracking_history_tree" model="ir.ui.view">
<field name="name">stock.tracking.history.tree</field>
<field name="model">stock.tracking.history</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_history_tree"/>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="location_id"/>
<field name="location_dest_id"/>
</field>
</field>
</record>
<record id="view_tracking_history_form" model="ir.ui.view">
<field name="name">stock.tracking.history.form</field>
<field name="model">stock.tracking.history</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_history_form"/>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="location_id"/>
<field name="location_dest_id"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import move_pack
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
import time
class stock_move_packaging(osv.osv_memory):
_name = "stock.move.packaging"
_columns = {
'pack_id': fields.many2one('stock.tracking', 'Pack to move', required=True),
'location_dest_id': fields.many2one('stock.location', 'Destination location', required=True),
}
_defaults = {
'pack_id': lambda s,cr,uid,c: c.get('active_id',False),
}
def move_pack(self, cr, uid, ids, context=None):
barcode_obj = self.pool.get('tr.barcode')
tracking_obj = self.pool.get('stock.tracking')
move_obj = self.pool.get('stock.move')
history_obj = self.pool.get('stock.tracking.history')
picking_obj = self.pool.get('stock.picking')
if context == None:
context = {}
context.update({'from_pack':True})
for obj in self.browse(cr, uid, ids):
pack = obj.pack_id
if not pack or not obj.location_dest_id:
continue
if pack.parent_id:
raise osv.except_osv(_('Warning!'),_('You cannot move this pack because it\'s inside of an other pack: %s.') % (pack.parent_id.name))
for child in pack.child_ids:
if child.state != 'close':
raise osv.except_osv(_('Warning!'),_('You cannot move this pack because there is a none closed pack inside of it: %s.') % (child.name))
current_type = pack.location_id.usage
dest_type = obj.location_dest_id.usage
pick_type = 'out'
if type == 'internal':
pick_type = 'internal'
elif type == 'supplier':
pick_type = 'in'
elif type == 'customer':
pick_type = 'out'
pick_id = picking_obj.create(cr, uid, {
'type': pick_type,
'auto_picking': 'draft',
'company_id': self.pool.get('res.company')._company_default_get(cr, uid, 'stock.company', context=context),
'address_id': obj.location_dest_id.address_id and obj.location_dest_id.address_id.id or False,
'invoice_state': 'none',
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'state': 'done',
})
child_packs = tracking_obj.hierarchy_ids(pack)
for child_pack in child_packs:
hist_id = history_obj.create(cr, uid, {
'tracking_id': child_pack.id,
'type': 'move',
'location_id': child_pack.location_id.id,
'location_dest_id': obj.location_dest_id.id,
})
for move in child_pack.current_move_ids:
defaults = {
'location_id': move.location_dest_id.id,
'location_dest_id': obj.location_dest_id.id,
'picking_id': pick_id,
}
new_id = move_obj.copy(cr, uid, move.id, default=defaults, context=context)
move_obj.write(cr, uid, [move.id], {'pack_history_id': hist_id, 'move_dest_id': new_id})
tracking_obj.write(cr, uid, [child_pack.id], {'location_id': obj.location_dest_id.id})
return {'type': 'ir.actions.act_window_close'}
stock_move_packaging()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_move_pack" model="ir.ui.view">
<field name="name">Move Pack</field>
<field name="model">stock.move.packaging</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Move Pack">
<group width="660" height="275">
<group colspan="4">
<field name="pack_id" colspan="2"/>
<field name="location_dest_id" colspan="2"/>
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="move_pack" string="Move it"
type="object" icon="gtk-ok"/>
</group>
</group>
</form>
</field>
</record>
<record id="move_pack" model="ir.actions.act_window">
<field name="name">Move Pack</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.move.packaging</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<record id="view_tracking_form_move_inherit" model="ir.ui.view">
<field name="name">stock.tracking.form.inherit</field>
<field name="model">stock.tracking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_form_inherit"/>
<field name="arch" type="xml">
<button name="set_close" position="after">
<button name="%(move_pack)d" states="close" string="Move pack" colspan="2" type="action" icon="gtk-ok"/>
</button>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Stock tracking add moves",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This module add a wizard to fill in packaging """,
"website" : "http://www.julius.fr",
"depends" : [
"stock",
"stock_tracking_extended",
"tr_barcode",
],
"category" : "Customs/Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [
'wizard/add_move_view.xml',
'stock_view.xml',
"security/ir.model.access.csv",
],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,145 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * stock_tracking_add_move
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-12-19 10:45+0000\n"
"PO-Revision-Date: 2011-12-19 10:45+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: stock_tracking_add_move
#: field:stock.packaging.move,pack_id:0
msgid "Pack to move"
msgstr "Pack à déplacer"
#. module: stock_tracking_add_move
#: model:ir.module.module,description:stock_tracking_add_move.module_meta_information
msgid " This module add a wizard to fill in packaging "
msgstr " Ce module ajoute un assistant pour remplir les pack "
#. module: stock_tracking_add_move
#: field:stock.scan.to.validate,type:0
msgid "Type"
msgstr "Type"
#. module: stock_tracking_add_move
#: view:stock.packaging.move:0
msgid "Add Move"
msgstr "Ajouter des mouvements"
#. module: stock_tracking_add_move
#: selection:stock.scan.to.validate,type:0
msgid "To remove"
msgstr "A supprimer"
#. module: stock_tracking_add_move
#: field:stock.scan.to.validate,tracking_id:0
msgid "Parent"
msgstr "Parent"
#. module: stock_tracking_add_move
#: model:ir.model,name:stock_tracking_add_move.model_stock_tracking
msgid "Packs"
msgstr "Pack"
#. module: stock_tracking_add_move
#: sql_constraint:stock.scan.to.validate:0
msgid "This barcode is already in the list to add or to remove !"
msgstr "Ce code-barres est déjà dans la liste à ajouter ou à enlever !"
#. module: stock_tracking_add_move
#: constraint:stock.tracking:0
msgid "Bad parent type selection. Please try again."
msgstr "Mauvais choix du type de parent. S'il vous plaît essayez de nouveau."
#. module: stock_tracking_add_move
#: field:stock.scan.to.validate,barcode_id:0
msgid "Barcode"
msgstr "code-barres"
#. module: stock_tracking_add_move
#: selection:stock.scan.to.validate,type:0
#: field:stock.tracking,to_add:0
msgid "To add"
msgstr "A ajouter"
#. module: stock_tracking_add_move
#: field:stock.tracking.history,parent_id:0
msgid "Parent pack"
msgstr "Pack parent"
#. module: stock_tracking_add_move
#: model:ir.actions.act_window,name:stock_tracking_add_move.pack_remove_move
#: view:stock.tracking:0
msgid "Remove object"
msgstr "Retirer l'objet"
#. module: stock_tracking_add_move
#: model:ir.module.module,shortdesc:stock_tracking_add_move.module_meta_information
msgid "Stock tracking add moves"
msgstr "Le suivi du stock ajoute des mouvements"
#. module: stock_tracking_add_move
#: model:ir.actions.act_window,name:stock_tracking_add_move.pack_add_move
#: view:stock.tracking:0
msgid "Add object"
msgstr "Ajouter un objet"
#. module: stock_tracking_add_move
#: model:ir.model,name:stock_tracking_add_move.model_stock_tracking_history
msgid "stock.tracking.history"
msgstr "stock.tracking.history"
#. module: stock_tracking_add_move
#: view:stock.packaging.move:0
msgid "Remove Move"
msgstr "Retirer mouvement"
#. module: stock_tracking_add_move
#: model:ir.model,name:stock_tracking_add_move.model_stock_packaging_move
msgid "stock.packaging.move"
msgstr "stock.packaging.move"
#. module: stock_tracking_add_move
#: view:stock.scan.to.validate:0
#: field:stock.tracking,to_remove:0
msgid "To validate"
msgstr "Valider"
#. module: stock_tracking_add_move
#: model:ir.model,name:stock_tracking_add_move.model_stock_scan_to_validate
msgid "stock.scan.to.validate"
msgstr "stock.scan.to.validate"
#. module: stock_tracking_add_move
#: field:stock.packaging.move,reference:0
msgid "Reference"
msgstr "Référence"
#. module: stock_tracking_add_move
#: code:addons/stock_tracking_add_move/stock.py:97
#: code:addons/stock_tracking_add_move/stock.py:142
#, python-format
msgid "Barcode Not found!"
msgstr "Code-barres introuvable!"
#. module: stock_tracking_add_move
#: code:addons/stock_tracking_add_move/stock.py:97
#: code:addons/stock_tracking_add_move/stock.py:142
#, python-format
msgid "Warning!"
msgstr "Attention!"
#. module: stock_tracking_add_move
#: view:stock.packaging.move:0
msgid "Cancel"
msgstr "Annuler"

View File

@@ -0,0 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_stock_scan_to_validate_user","stock.scan.to.validate user","model_stock_scan_to_validate","stock.group_stock_user",1,1,1,1
"access_stock_scan_to_validate_manager","stock.scan.to.validate manager","model_stock_scan_to_validate","stock.group_stock_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_stock_scan_to_validate_user stock.scan.to.validate user model_stock_scan_to_validate stock.group_stock_user 1 1 1 1
3 access_stock_scan_to_validate_manager stock.scan.to.validate manager model_stock_scan_to_validate stock.group_stock_manager 1 1 1 1

View File

@@ -0,0 +1,203 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
class stock_tracking(osv.osv):
_inherit = 'stock.tracking'
_columns = {
'parent_id': fields.many2one('stock.tracking', 'Parent', readonly=True),
'child_ids': fields.one2many('stock.tracking', 'parent_id', 'Children', readonly=True),
'to_add': fields.one2many('stock.scan.to.validate', 'tracking_id', 'To add', domain=[('type','=','in')]),
'to_remove': fields.one2many('stock.scan.to.validate', 'tracking_id', 'To validate', domain=[('type','=','out')]),
}
def add_validation(self, cr, uid, ids, barcode_ids, context=None):
barcode_obj = self.pool.get('tr.barcode')
tracking_obj = self.pool.get('stock.tracking')
move_obj = self.pool.get('stock.move')
product_obj = self.pool.get('product.product')
history_obj = self.pool.get('stock.tracking.history')
validate_obj = self.pool.get('stock.scan.to.validate')
if context == None:
context = {}
if barcode_ids:
for obj in self.browse(cr, uid, ids):
barcode = barcode_obj.browse(cr, uid, barcode_ids[0])
model = barcode.res_model
res_id = barcode.res_id
if model == 'stock.tracking':
'''Pack Case'''
pack = tracking_obj.browse(cr, uid, res_id)
''' We can only add a closed pack '''
if pack.state == 'close':
tracking_obj.write(cr, uid, res_id, {'parent_id': obj.id,})
history_obj.create(cr, uid, {'type': 'pack_in',
'tracking_id': res_id,
'parent_id': obj.id,
})
tracking_obj.write(cr, uid, pack.id, {'location_id': obj.location_id and obj.location_id.id or False,})
tracking_obj.write(cr, uid, obj.id, {'modified': True})
for move_data in pack.move_ids:
if move_data.location_dest_id != tracking_obj.browse(cr, uid, obj.id).location_id:
new_move_id = move_obj.create(cr, uid, {'name': move_data.name,
'state': 'draft',
'product_id': move_data.product_id.id,
'product_uom': move_data.product_uom.id,
'prodlot_id': move_data.prodlot_id.id,
'location_id': move_data.location_dest_id.id,
'location_dest_id': obj.location_id.id,
})
elif model == 'stock.production.lot':
'''Production-lot Case'''
pack = tracking_obj.browse(cr, uid, obj.id)
move_ids = move_obj.search(cr, uid, [('state', '=', 'done'),
('prodlot_id', '=', res_id),
('date', '<=', pack.date)
# ('tracking_id', '=', False),
# ('location_dest_id', '=', pack.location_id and pack.location_id.id or False)
], order='date desc', limit=1)
if move_ids:
move_data = move_obj.browse(cr, uid, move_ids[0])
if move_data.location_dest_id != pack.location_id:
new_move_id = move_obj.create(cr, uid, {'name': move_data.name,
'state': 'draft',
'product_id': move_data.product_id.id,
'product_uom': move_data.product_uom.id,
'prodlot_id': move_data.prodlot_id.id,
'location_id': move_data.location_dest_id.id,
'location_dest_id': obj.location_id.id,
})
move_obj.write(cr, uid, new_move_id, {'tracking_id': obj.id})
tracking_obj.write(cr, uid, obj.id, {'modified': True})
else:
move_obj.write(cr, uid, move_ids, {'tracking_id': obj.id})
tracking_obj.write(cr, uid, obj.id, {'modified': True})
elif model == 'product.product':
'''Product Case'''
pack = tracking_obj.browse(cr, uid, obj.id)
product_data = product_obj.browse(cr, uid,res_id)
move_id = move_obj.create(cr, uid, {
'name': product_data.name,
'product_id': product_data.id,
'product_uom': product_data.uom_id.id,
'location_id': pack.location_id.id,
'location_dest_id': pack.location_id.id,
'tracking_id': obj.id,
'state': 'draft',
})
tracking_obj.write(cr, uid, obj.id, {'modified': True})
'''Call for a function who will display serial code list and product list in the pack layout'''
tracking_obj.get_products(cr, uid, ids, context=None)
tracking_obj.get_serials(cr, uid, ids, context=None)
else:
raise osv.except_osv(_('Warning!'),_('Barcode Not found!'))
return {}
def remove_validation(self, cr, uid, ids, barcode_ids, context=None):
barcode_obj = self.pool.get('tr.barcode')
tracking_obj = self.pool.get('stock.tracking')
move_obj = self.pool.get('stock.move')
product_obj = self.pool.get('product.product')
history_obj = self.pool.get('stock.tracking.history')
validate_obj = self.pool.get('stock.scan.to.validate')
if context == None:
context = {}
if barcode_ids:
for obj in self.browse(cr, uid, ids):
barcode = barcode_obj.browse(cr, uid, barcode_ids[0])
model = barcode.res_model
res_id = barcode.res_id
'''Pack Case'''
if model == 'stock.tracking':
pack = tracking_obj.browse(cr, uid, res_id)
tracking_obj.write(cr, uid, res_id, {'parent_id': False})
tracking_obj.write(cr, uid, obj.id, {'modified': True})
elif model == 'stock.production.lot':
pack = tracking_obj.browse(cr, uid, obj.id)
move_ids = move_obj.search(cr, uid, [
('prodlot_id', '=', res_id),
], limit=1)
if move_ids:
move_obj.write(cr, uid, move_ids, {'tracking_id': False})
tracking_obj.write(cr, uid, obj.id, {'modified': True})
elif model == 'product.product':
pack = tracking_obj.browse(cr, uid, obj.id)
product_data = product_obj.browse(cr, uid,res_id)
move_ids = move_obj.search(cr, uid, [
('product_id', '=', product_data.id),
], limit=1)
if move_ids:
move_obj.write(cr, uid, move_ids, {'tracking_id': False})
tracking_obj.write(cr, uid, obj.id, {'modified': True})
'''Call for a function who will display serial code list and product list in the pack layout'''
tracking_obj.get_serials(cr, uid, ids, context=None)
tracking_obj.get_products(cr, uid, ids, context=None)
else:
raise osv.except_osv(_('Warning!'),_('Barcode Not found!'))
return {}
stock_tracking()
class stock_scan_to_validate(osv.osv):
_name = 'stock.scan.to.validate'
_columns = {
'tracking_id': fields.many2one('stock.tracking', 'Parent', readonly=True),
'type': fields.selection([('in','To add'),('out','To remove')], 'Type', readonly=True),
'barcode_id': fields.many2one('tr.barcode', 'Barcode', readonly=True),
}
_sql_constraints = [
('tracking_barcode_unique', 'unique (tracking_id,barcode_id)', 'This barcode is already in the list to add or to remove !')
]
stock_scan_to_validate()
class stock_tracking_history(osv.osv):
_inherit = "stock.tracking.history"
def _get_types(self, cr, uid, context={}):
res = super(stock_tracking_history, self)._get_types(cr, uid, context)
if not res:
res = []
res = res + [('pack_in','Add parent'),('pack_out','Unlink parent')]
return res
_columns = {
'type': fields.selection(_get_types, 'Type'),
'parent_id': fields.many2one('stock.tracking', 'Parent pack'),
}
stock_tracking_history()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_scan_to_validate_tree" model="ir.ui.view">
<field name="name">stock.scan.to.validate.tree</field>
<field name="model">stock.scan.to.validate</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="To validate">
<!--<field name="type"/>-->
<field name="barcode_id"/>
</tree>
</field>
</record>
<!--<record id="view_tracking_form_add_remove" model="ir.ui.view">
<field name="name">stock.tracking.form.add.remove</field>
<field name="model">stock.tracking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_tracking_form"/>
<field name="arch" type="xml">
<page string="Stock Moves" position="after">
<page string="To add" attrs="{'invisible':[('state', '=', 'close')]}">
<separator string="Objects to add into this pack" colspan="4"/>
<field name="to_add" nolabel="1" colspan="4"/>
<button name="add_validation" states="open" string="Confirm ADD" colspan="2" type="object" icon="gtk-ok"/>
</page>
<page string="To remove" attrs="{'invisible':[('state', '=', 'close')]}">
<separator string="Objects to remove from this pack" colspan="4"/>
<field name="to_remove" nolabel="1" colspan="4"/>
<button name="remove_validation" states="open" string="Confirm REMOVE" colspan="2" type="object" icon="gtk-ok"/>
</page>
</page>
</field>
</record>-->
<record id="view_tracking_history_tree" model="ir.ui.view">
<field name="name">stock.tracking.history.tree</field>
<field name="model">stock.tracking.history</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_history_tree"/>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="parent_id"/>
</field>
</field>
</record>
<record id="view_tracking_history_form" model="ir.ui.view">
<field name="name">stock.tracking.history.form</field>
<field name="model">stock.tracking.history</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_history_form"/>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="parent_id"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import add_move
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
class stock_packaging_move(osv.osv_memory):
_name = "stock.packaging.move"
_columns = {
'reference': fields.char('Reference', size=128, required=True),
'pack_id': fields.many2one('stock.tracking', 'Pack to move', required=True),
}
_defaults = {
'pack_id': lambda s,cr,uid,c: c.get('active_id',False),
}
def add_move(self, cr, uid, ids, context=None):
'''Init'''
barcode_obj = self.pool.get('tr.barcode')
tracking_obj = self.pool.get('stock.tracking')
if context == None:
context = {}
'''Get parent id'''
parent_id = context.get('active_id',False)
for obj in self.browse(cr, uid, ids):
ref = obj.reference
barcode_ids = barcode_obj.search(cr, uid, [('code', '=', ref)], limit=1)
''' Call for the adding function '''
tracking_obj.add_validation(cr, uid, [parent_id], barcode_ids, context=None)
return {'type': 'ir.actions.act_window_close'}
def remove_move(self, cr, uid, ids, context=None):
'''Init'''
barcode_obj = self.pool.get('tr.barcode')
tracking_obj = self.pool.get('stock.tracking')
move_obj = self.pool.get('stock.move')
to_validate_obj = self.pool.get('stock.scan.to.validate')
if context == None:
context = {}
'''Get parent id'''
parent_id = context.get('active_id',False)
for obj in self.browse(cr, uid, ids):
ref = obj.reference
barcode_ids = barcode_obj.search(cr, uid, [('code', '=', ref)], limit=1)
''' Call for the removal function '''
tracking_obj.remove_validation(cr, uid, [parent_id], barcode_ids, context=None)
return {'type': 'ir.actions.act_window_close'}
stock_packaging_move()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_pack_add_move" model="ir.ui.view">
<field name="name">Add object</field>
<field name="model">stock.packaging.move</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Add Move">
<group width="400" height="100">
<group colspan="4">
<field name="reference" colspan="2"/>
<field name="pack_id" colspan="2" invisible="1"/>
<newline/>
<separator string="Add Move" colspan="4"/>
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="add_move" string="Add Move"
type="object" icon="gtk-ok"/>
</group>
</group>
</form>
</field>
</record>
<record id="pack_add_move" model="ir.actions.act_window">
<field name="name">Add object</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.packaging.move</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_pack_add_move"/>
<field name="target">new</field>
</record>
<record id="view_pack_remove_move" model="ir.ui.view">
<field name="name">Remove object</field>
<field name="model">stock.packaging.move</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Remove Move">
<group width="400" height="100">
<group colspan="4">
<field name="reference" colspan="2"/>
<newline/>
<separator string="Remove Move" colspan="4"/>
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="remove_move" string="Remove Move"
type="object" icon="gtk-ok"/>
</group>
</group>
</form>
</field>
</record>
<record id="pack_remove_move" model="ir.actions.act_window">
<field name="name">Remove object</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.packaging.move</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_pack_remove_move"/>
<field name="target">new</field>
</record>
<record id="view_tracking_form_inherit" model="ir.ui.view">
<field name="name">stock.tracking.form.inherit</field>
<field name="model">stock.tracking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_form_inherit"/>
<field name="arch" type="xml">
<button name="reset_open" position="after">
<button name="%(pack_add_move)d" states="open" string="Add object" colspan="2" type="action" icon="gtk-ok"/>
<button name="%(pack_remove_move)d" states="open" string="Remove object" colspan="2" type="action" icon="gtk-ok"/>
</button>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock_tracking
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Stock Packaging extended",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This Module allows to have parent/child packaging """,
"website" : "http://www.julius.fr",
"depends" : [
"stock",
],
"category" : "Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [
'stock_tracking_view.xml',
'inventory_sequence.xml',
"security/ir.model.access.csv",
],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,279 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * stock_tracking_extended
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-12-19 10:42+0000\n"
"PO-Revision-Date: 2011-12-19 10:42+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_stock_production_lot
msgid "Production lot"
msgstr "Numéro de série"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_product_stock_tracking
msgid "product.stock.tracking"
msgstr "product.stock.tracking"
#. module: stock_tracking_extended
#: field:product.ul,capacity_index:0
msgid "Capacity index"
msgstr "Indice de capacité"
#. module: stock_tracking_extended
#: constraint:stock.move:0
msgid "You must assign a production lot for this product"
msgstr "Vous devez affecter un numéro de série pour ce produit."
#. module: stock_tracking_extended
#: field:stock.tracking,state:0
msgid "State"
msgstr "Etat"
#. module: stock_tracking_extended
#: field:stock.production.lot,tracking_id:0
msgid "pack"
msgstr "Pack"
#. module: stock_tracking_extended
#: field:stock.tracking,location_id:0
msgid "Location"
msgstr "Emplacement"
#. module: stock_tracking_extended
#: view:stock.tracking:0
msgid "Serial Code"
msgstr "Numéro de série"
#. module: stock_tracking_extended
#: sql_constraint:stock.production.lot:0
msgid "The combination of serial number and internal reference must be unique !"
msgstr "La combinaison du numéro de série et de la référence interne doit être unique !"
#. module: stock_tracking_extended
#: field:stock.tracking.history,type:0
msgid "Type"
msgstr "Type"
#. module: stock_tracking_extended
#: code:addons/stock_tracking_extended/stock_tracking.py:118
#, python-format
msgid "You can't re-open this pack because there is at least one not closed child"
msgstr "Vous ne pouvez pas rouvrir ce pack parce qu'il y a au moins un pack enfant non fermé"
#. module: stock_tracking_extended
#: field:product.stock.tracking,product_id:0
#: field:serial.stock.tracking,product_id:0
msgid "Product"
msgstr "Produit"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_product_category
msgid "Product Category"
msgstr "Catégorie de produits"
#. module: stock_tracking_extended
#: field:stock.tracking,parent_id:0
msgid "Parent"
msgstr "Parent"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_stock_tracking
msgid "Packs"
msgstr "Packs"
#. module: stock_tracking_extended
#: constraint:stock.move:0
msgid "You try to assign a lot which is not from the same product"
msgstr "Vous essayez d'affecter un lot qui appartient à une autre référence."
#. module: stock_tracking_extended
#: constraint:stock.tracking:0
msgid "Bad parent type selection. Please try again."
msgstr "Mauvais choix du type parent. Veuillez ressayez à nouveau."
#. module: stock_tracking_extended
#: view:stock.tracking:0
msgid "Reset Open"
msgstr "Réouvrir"
#. module: stock_tracking_extended
#: field:product.stock.tracking,quantity:0
#: field:serial.stock.tracking,quantity:0
msgid "Quantity"
msgstr "Quantité"
#. module: stock_tracking_extended
#: code:addons/stock_tracking_extended/stock_tracking.py:113
#: code:addons/stock_tracking_extended/stock_tracking.py:118
#: code:addons/stock_tracking_extended/stock_tracking.py:131
#, python-format
msgid "Not allowed !"
msgstr "Non autorisé !"
#. module: stock_tracking_extended
#: field:stock.tracking,current_move_ids:0
msgid "Current moves"
msgstr "Mouvements actuels"
#. module: stock_tracking_extended
#: view:stock.tracking:0
#: field:stock.tracking,history_ids:0
#: view:stock.tracking.history:0
msgid "History"
msgstr "Historique"
#. module: stock_tracking_extended
#: model:ir.module.module,description:stock_tracking_extended.module_meta_information
msgid " This Module allows to have parent/child packaging "
msgstr " Ce module permet d'avoir des packs parent/enfant "
#. module: stock_tracking_extended
#: field:product.category,tracked:0
msgid "Need a serial code ?"
msgstr "Suivre les numéros de série ?"
#. module: stock_tracking_extended
#: field:product.stock.tracking,tracking_id:0
#: field:serial.stock.tracking,tracking_id:0
msgid "Tracking"
msgstr "Suivi"
#. module: stock_tracking_extended
#: view:stock.tracking:0
msgid "Downstream traceability"
msgstr "Traçabilité aval"
#. module: stock_tracking_extended
#: field:stock.tracking,ul_id:0
msgid "Logistic unit"
msgstr "Unité logistique"
#. module: stock_tracking_extended
#: model:ir.actions.act_window,name:stock_tracking_extended.action_stock_tracking_tree
#: model:ir.ui.menu,name:stock_tracking_extended.menu_action_stock_tracking_tree
msgid "Packs Structure"
msgstr "Structure de Packs"
#. module: stock_tracking_extended
#: field:stock.tracking,child_serial_ids:0
msgid "Child Serials"
msgstr "Numéros de séries enfant"
#. module: stock_tracking_extended
#: code:addons/stock_tracking_extended/stock_tracking.py:131
#, python-format
msgid "You can't close this pack because there is at least one not closed child"
msgstr "Vous ne pouvez pas fermer ce pack parce qu'il y a au moins un enfant non fermé"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_stock_tracking_history
msgid "stock.tracking.history"
msgstr "stock.tracking.history"
#. module: stock_tracking_extended
#: view:stock.tracking:0
msgid "Update product list"
msgstr "MàJ de la liste de produit"
#. module: stock_tracking_extended
#: view:stock.tracking:0
msgid "Child Packs"
msgstr "Packs enfants"
#. module: stock_tracking_extended
#: view:product.stock.tracking:0
#: view:serial.stock.tracking:0
#: view:stock.tracking:0
#: field:stock.tracking,product_ids:0
#: field:stock.tracking,serial_ids:0
msgid "Products"
msgstr "Produits"
#. module: stock_tracking_extended
#: view:stock.tracking:0
msgid "Update Serial list"
msgstr "MàJ de la liste des NS"
#. module: stock_tracking_extended
#: field:stock.tracking.history,tracking_id:0
msgid "Pack"
msgstr "Pack"
#. module: stock_tracking_extended
#: model:ir.module.module,shortdesc:stock_tracking_extended.module_meta_information
msgid "Stock Packaging extended"
msgstr "Gestion des packs étendu"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_stock_move
msgid "Stock Move"
msgstr "Mouvement de stock"
#. module: stock_tracking_extended
#: field:stock.tracking,child_product_ids:0
msgid "Child Products"
msgstr "Produits enfants"
#. module: stock_tracking_extended
#: constraint:product.category:0
msgid "Error ! You can not create recursive categories."
msgstr "Erreur ! Vous ne pouvez pas créer de catégories récursives"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_product_ul
msgid "Shipping Unit"
msgstr "Unité de livraison"
#. module: stock_tracking_extended
#: code:addons/stock_tracking_extended/stock_tracking.py:113
#, python-format
msgid "You can't re-open this pack because the parent pack is close"
msgstr "Vous ne pouvez pas ré-ouvrir ce pack, car le pack parent est fermé"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_serial_stock_tracking
msgid "serial.stock.tracking"
msgstr "serial.stock.tracking"
#. module: stock_tracking_extended
#: view:stock.tracking:0
#: selection:stock.tracking,state:0
msgid "Close"
msgstr "Fermer"
#. module: stock_tracking_extended
#: field:serial.stock.tracking,serial_id:0
msgid "Serial"
msgstr "Série"
#. module: stock_tracking_extended
#: view:stock.tracking:0
msgid "Stock Moves"
msgstr "Mouvements de stocks"
#. module: stock_tracking_extended
#: selection:stock.tracking,state:0
msgid "Open"
msgstr "Ouvert"
#. module: stock_tracking_extended
#: field:stock.tracking,child_ids:0
msgid "Children"
msgstr "Enfant"
#. module: stock_tracking_extended
#: model:ir.model,name:stock_tracking_extended.model_stock_inventory
msgid "Inventory"
msgstr "Inventaire"

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!-- Sequences for stock.inventory -->
<record id="seq_type_inventory_order" model="ir.sequence.type">
<field name="name">Inventory Order</field>
<field name="code">stock.inventory</field>
</record>
<record id="seq_sale_order" model="ir.sequence">
<field name="name">Inventory Order</field>
<field name="code">stock.inventory</field>
<field name="prefix">INV</field>
<field name="padding">3</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,10 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_product_stock_tracking_user","product.stock.tracking user","model_product_stock_tracking","stock.group_stock_user",1,1,1,1
"access_product_stock_tracking_manager","product.stock.tracking manager","model_product_stock_tracking","stock.group_stock_manager",1,1,1,1
"access_product_stock_tracking_all","product.stock.tracking all","model_product_stock_tracking",,1,0,0,0
"access_serial_stock_tracking_user","serial.stock.tracking user","model_serial_stock_tracking","stock.group_stock_user",1,1,1,1
"access_serial_stock_tracking_manager","serial.stock.tracking manager","model_serial_stock_tracking","stock.group_stock_manager",1,1,1,1
"access_serial_stock_tracking_all","serial.stock.tracking all","model_serial_stock_tracking",,1,0,0,0
"access_stock_tracking_history_user","serial.stock.tracking user","model_stock_tracking_history","stock.group_stock_user",1,1,1,1
"access_stock_tracking_history_manager","serial.stock.tracking manager","model_stock_tracking_history","stock.group_stock_manager",1,1,1,1
"access_stock_tracking_history_all","serial.stock.tracking all","model_stock_tracking_history",,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_product_stock_tracking_user product.stock.tracking user model_product_stock_tracking stock.group_stock_user 1 1 1 1
3 access_product_stock_tracking_manager product.stock.tracking manager model_product_stock_tracking stock.group_stock_manager 1 1 1 1
4 access_product_stock_tracking_all product.stock.tracking all model_product_stock_tracking 1 0 0 0
5 access_serial_stock_tracking_user serial.stock.tracking user model_serial_stock_tracking stock.group_stock_user 1 1 1 1
6 access_serial_stock_tracking_manager serial.stock.tracking manager model_serial_stock_tracking stock.group_stock_manager 1 1 1 1
7 access_serial_stock_tracking_all serial.stock.tracking all model_serial_stock_tracking 1 0 0 0
8 access_stock_tracking_history_user serial.stock.tracking user model_stock_tracking_history stock.group_stock_user 1 1 1 1
9 access_stock_tracking_history_manager serial.stock.tracking manager model_stock_tracking_history stock.group_stock_manager 1 1 1 1
10 access_stock_tracking_history_all serial.stock.tracking all model_stock_tracking_history 1 0 0 0

View File

@@ -0,0 +1,316 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from datetime import datetime
from osv import fields, osv
from tools.translate import _
import netsvc
class one2many_special(fields.one2many):
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
if not values:
values = {}
res = {}
location_ids = []
for id in ids:
res[id] = []
location_id = obj.pool.get('stock.tracking').read(cr, user, id, ['location_id'])['location_id']
if location_id and location_id[0] and location_id[0] not in location_ids:
location_ids.append(location_id[0])
ids2 = obj.pool.get(self._obj).search(cr, user, self._domain + [(self._fields_id, 'in', ids), ('location_dest_id', 'in', location_ids)], limit=self._limit)
for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
res[r[self._fields_id]].append( r['id'] )
return res
class stock_tracking(osv.osv):
_inherit = 'stock.tracking'
def hierarchy_ids(self, tracking):
result_list = [tracking]
for child in tracking.child_ids:
result_list.extend(self.hierarchy_ids(child))
return result_list
def _get_child_products(self, cr, uid, ids, field_name, arg, context=None):
packs = self.browse(cr, uid, ids)
res = {}
for pack in packs:
res[pack.id] = []
childs = self.hierarchy_ids(pack)
for child in childs:
for prod in child.product_ids:
res[pack.id].append(prod.id)
return res
def _get_child_serials(self, cr, uid, ids, field_name, arg, context=None):
packs = self.browse(cr, uid, ids)
res = {}
for pack in packs:
res[pack.id] = []
childs = self.hierarchy_ids(pack)
for child in childs:
for serial in child.serial_ids:
res[pack.id].append(serial.id)
return res
_columns = {
'parent_id': fields.many2one('stock.tracking', 'Parent'),
'child_ids': fields.one2many('stock.tracking', 'parent_id', 'Children'),
'ul_id': fields.many2one('product.ul', 'Logistic unit', readonly=True, states={'open':[('readonly',False)]}),
'location_id': fields.many2one('stock.location', 'Location', required=True, readonly=True, states={'open':[('readonly',False)]}),
'state': fields.selection([('open','Open'),('close','Close')], 'State', readonly=True),
'product_ids': fields.one2many('product.stock.tracking', 'tracking_id', 'Products', readonly=True, states={'open':[('readonly',False)]}),
'child_product_ids': fields.function(_get_child_products, method=True, type='one2many', obj='product.stock.tracking', string='Child Products'),
'history_ids': fields.one2many('stock.tracking.history', 'tracking_id', 'History'),
'current_move_ids': one2many_special('stock.move', 'tracking_id', 'Current moves', domain=[('pack_history_id', '=', False)], readonly=True),
'name': fields.char('Pack Reference', size=64, required=True, readonly=True, states={'open':[('readonly',False)]}),
'date': fields.datetime('Creation Date', required=True, readonly=True, states={'open':[('readonly',False)]}),
'serial_ids': fields.one2many('serial.stock.tracking', 'tracking_id', 'Products', readonly=True, states={'open':[('readonly',False)]}),
'child_serial_ids': fields.function(_get_child_serials, method=True, type='one2many', obj='serial.stock.tracking', string='Child Serials'),
}
def _check_parent_id(self, cr, uid, ids, context=None):
lines = self.browse(cr, uid, ids, context=context)
if lines[0].parent_id:
if lines[0].ul_id.capacity_index > lines[0].parent_id.ul_id.capacity_index:
return False
return True
_constraints = [(_check_parent_id, 'Bad parent type selection. Please try again.',['parent_id'] ),]
_defaults = {
'state': 'open',
}
def reset_open(self, cr, uid, ids, context=None):
pack_ids = self.browse(cr, uid, ids, context)
for pack in pack_ids:
allowed = True
if pack.parent_id:
if pack.parent_id and pack.parent_id != 'open':
self.write(cr, uid, [pack.parent_id.id], {'state': 'open'})
# allowed = False
# raise osv.except_osv(_('Not allowed !'),_('You can\'t re-open this pack because the parent pack is close'))
if allowed:
for child in pack.child_ids:
if child.state == 'open':
allowed = False
raise osv.except_osv(_('Not allowed !'),_('You can\'t re-open this pack because there is at least one not closed child'))
break
if allowed:
self.write(cr, uid, [pack.id], {'state': 'open'})
return True
def set_close(self, cr, uid, ids, context=None):
pack_ids = self.browse(cr, uid, ids, context)
for pack in pack_ids:
allowed = True
for child in pack.child_ids:
if child.state == 'open':
allowed = False
raise osv.except_osv(_('Not allowed !'),_('You can\'t close this pack because there is at least one not closed child'))
break
# if allowed:
# self.write(cr, uid, [pack.id], {'state': 'close'})
return True
def get_products(self, cr, uid, ids, context=None):
pack_ids = self.browse(cr, uid, ids, context)
stock_track = self.pool.get('product.stock.tracking')
for pack in pack_ids:
childs = self.hierarchy_ids(pack)
for child in childs:
product_ids = [x.id for x in child.product_ids]
stock_track.unlink(cr, uid, product_ids)
product_list = {}
for x in child.current_move_ids:
if x.location_dest_id.id == child.location_id.id:
if x.product_id.id not in product_list.keys():
product_list.update({x.product_id.id:x.product_qty})
else:
product_list[x.product_id.id] += x.product_qty
for product in product_list.keys():
stock_track.create(cr, uid, {'product_id': product, 'quantity': product_list[product], 'tracking_id': child.id})
return True
def get_serials(self, cr, uid, ids, context=None):
pack_ids = self.browse(cr, uid, ids, context)
serial_track = self.pool.get('serial.stock.tracking')
serial_obj = self.pool.get('stock.production.lot')
for pack in pack_ids:
childs = self.hierarchy_ids(pack)
for child in childs:
serial_ids = [x.id for x in child.serial_ids]
serial_track.unlink(cr, uid, serial_ids)
serial_list = {}
for x in child.current_move_ids:
if x.location_dest_id.id == child.location_id.id:
if x.prodlot_id.id not in serial_list.keys():
serial_list.update({x.prodlot_id.id:x.product_qty})
else:
serial_list[x.prodlot_id.id] += x.product_qty
for serial in serial_list.keys():
if serial:
serial_track.create(cr, uid, {'serial_id': serial, 'quantity': serial_list[serial], 'tracking_id': child.id})
serial_obj.write(cr, uid, [serial], {'tracking_id': child.id})
return True
stock_tracking()
class product_ul(osv.osv):
_inherit = "product.ul"
_description = "Shipping Unit"
_columns = {
'capacity_index': fields.integer('Capacity index'),
}
_order = 'capacity_index'
product_ul()
class product_stock_tracking(osv.osv):
_name = 'product.stock.tracking'
_columns = {
'product_id': fields.many2one('product.product', 'Product'),
'quantity': fields.float('Quantity'),
'tracking_id': fields.many2one('stock.tracking', 'Tracking'),
# 'tracking_history_id': fields.many2one('stock.tracking.history', 'Tracking History'),
}
product_stock_tracking()
class serial_stock_tracking(osv.osv):
_name = 'serial.stock.tracking'
_order = 'tracking_id,serial_id'
_columns = {
'serial_id': fields.many2one('stock.production.lot', 'Serial'),
'product_id': fields.related('serial_id', 'product_id', type='many2one', relation='product.product', string='Product'),
'quantity': fields.float('Quantity'),
'tracking_id': fields.many2one('stock.tracking', 'Tracking'),
# 'tracking_history_id': fields.many2one('stock.tracking.history', 'Tracking History'),
}
serial_stock_tracking()
class stock_tracking_history(osv.osv):
_name = "stock.tracking.history"
def _get_types(self, cr, uid, context={}):
# res = [('pack_in','Add parent'),('pack_out','Unlink parent'),('move','Move')]
res = []
return res
# def hierarchy_ids(self, tracking):
# result_list = [tracking]
# for child in tracking.child_ids:
# result_list.extend(self.hierarchy_ids(child))
# return result_list
#
# def _get_child_products(self, cr, uid, ids, field_name, arg, context=None):
# packs = self.browse(cr, uid, ids)
# res = {}
# for pack in packs:
# res[pack.id] = []
# childs = self.hierarchy_ids(pack)
# for child in childs:
# for prod in child.product_ids:
# res[pack.id].append(prod.id)
# return res
_columns = {
'tracking_id': fields.many2one('stock.tracking', 'Pack', required=True),
'type': fields.selection(_get_types, 'Type'),
# 'product_ids': fields.one2many('product.stock.tracking', 'tracking_history_id', 'Products'),
# 'child_product_ids': fields.function(_get_child_products, method=True, type='one2many', obj='product.stock.tracking', string='Child Products'),
# 'parent_hist_id': fields.many2one('stock.tracking.history', 'Parent history pack'),
# 'child_ids': fields.one2many('stock.tracking.history', 'parent_hist_id', 'Child history pack'),
}
_rec_name = "tracking_id"
stock_tracking_history()
'''Add a field in order to store the current pack in a production lot'''
class stock_production_lot(osv.osv):
_inherit = 'stock.production.lot'
_columns = {
'tracking_id': fields.many2one('stock.tracking', 'pack'),
}
stock_production_lot()
class product_category(osv.osv):
_inherit = 'product.category'
_columns = {
'tracked': fields.boolean('Need a serial code ?'),
}
product_category()
class stock_inventory(osv.osv):
_inherit = 'stock.inventory'
_defaults = {
'name': lambda x, y, z, c: x.pool.get('ir.sequence').get(y, z, 'stock.inventory') or '/'
}
stock_inventory()
class stock_move(osv.osv):
_inherit = 'stock.move'
_columns = {
# 'cancel_cascade': fields.boolean('Cancel Cascade', help='If checked, when this move is cancelled, cancel the linked move too')
}
def create(self, cr, uid, vals, context=None):
production_lot_obj = self.pool.get('stock.production.lot')
stock_tracking_obj = self.pool.get('stock.tracking')
if vals.get('prodlot_id',False):
production_lot_data = production_lot_obj.browse(cr, uid, vals['prodlot_id'])
last_production_lot_move_id = self.search(cr, uid, [('prodlot_id', '=', production_lot_data.id)], limit=1, order='date')
if last_production_lot_move_id:
last_production_lot_move = self.browse(cr,uid,last_production_lot_move_id[0])
if last_production_lot_move.tracking_id:
ids = [last_production_lot_move.tracking_id.id]
stock_tracking_obj.reset_open(cr, uid, ids, context=None)
return super(stock_move,self).create(cr, uid, vals, context)
stock_move()
class split_in_production_lot(osv.osv_memory):
_inherit = "stock.move.split"
_columns = {
'use_exist' : fields.boolean('Existing Lots', invisible=True),
}
_defaults = {
'use_exist': lambda *a: True,
}
def default_get(self, cr, uid, fields, context=None):
res = super(split_in_production_lot, self).default_get(cr, uid, fields, context)
res.update({'use_exist': True})
return res
split_in_production_lot()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,270 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--<record id="search_stock_packs_inherit" model="ir.ui.view">
<field name="name">Pack Search inherit</field>
<field name="model">stock.tracking</field>
<field name="type">search</field>
<field name="inherit_id" ref="stock.search_stock_packs"/>
<field name="arch" type="xml">
<filter name="available" position="after">
<filter icon="gtk-media-pause" name="on_hold" string="On Hold" domain="[('state','in',['on_hold','on_hold_billing','on_hold_paym'])]" help="On Hold Pickings"/>
</filter>
</field>
</record>-->
<record id="product_category_tracked_form" model="ir.ui.view">
<field name="name">product.category.property.form.inherit</field>
<field name="model">product.category</field>
<field name="type">form</field>
<field name="inherit_id" ref="product.product_category_form_view"/>
<field name="arch" type="xml">
<field name="parent_id" position="after">
<field name="tracked"/>
</field>
</field>
</record>
<record id="view_tracking_tree_inherit" model="ir.ui.view">
<field name="name">stock.tracking.tree.inherit</field>
<field name="model">stock.tracking</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock.view_tracking_tree"/>
<field name="arch" type="xml">
<field name="serial" position="after">
<field name="parent_id"/>
<field name="ul_id"/>
<field name="location_id"/>
<field name="state"/>
</field>
</field>
</record>
<record id="lot_line_tree_inherit" model="ir.ui.view">
<field name="name">stock.tracking.tree.inherit</field>
<field name="model">stock.tracking</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock.lot_line_tree"/>
<field name="arch" type="xml">
<field name="serial" position="after">
<field name="parent_id"/>
<field name="ul_id"/>
</field>
</field>
</record>
<record id="view_tracking_form_inherit" model="ir.ui.view">
<field name="name">stock.tracking.form.inherit</field>
<field name="model">stock.tracking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_tracking_form"/>
<field name="arch" type="xml">
<field name="serial" position="after">
<field name="parent_id"/>
<field name="ul_id"/>
</field>
<page string="Stock Moves" position="before">
<page string="Products">
<field name="child_product_ids" nolabel="1" colspan="4" context="{'group_by':'product_id'}"/>
<field name="product_ids" nolabel="1" colspan="4" invisible="True"/>
<button name="get_products" string="Update product list" colspan="2" type="object" icon="gtk-ok"/>
</page>
<page string="Serial Code">
<field name="child_serial_ids" nolabel="1" colspan="4"/>
<field name="serial_ids" nolabel="1" colspan="4" invisible="True"/>
<button name="get_serials" string="Update Serial list" colspan="2" type="object" icon="gtk-ok"/>
<!--
<field name="current_move_ids" nolabel="1" colspan="4">
<tree string="Stock Moves">
<field name="product_id"/>
<field name="prodlot_id" groups="base.group_extended"/>
</tree>
</field>
-->
</page>
<page string="Child Packs">
<field name="child_ids" nolabel="1" colspan="2"/>
</page>
<page string="History">
<field name="history_ids" nolabel="1" colspan="4"/>
</page>
</page>
<button name="action_traceability" string="Downstream traceability" position="after">
<field name="location_id"/>
</button>
<form position="inside">
<group colspan="4" col="12">
<field name="state" colspan="3"/>
<group colspan="9" col="10">
<button name="reset_open" states="close" string="Reset Open" colspan="2" type="object" icon="gtk-ok"/>
<button name="set_close" states="open" string="Close" colspan="2" type="object" icon="gtk-ok"/>
</group>
</group>
</form>
<!--
<field name="move_ids" position="before">
<separator string="Current moves" colspan="4"/>
<field name="current_move_ids" nolabel="1" colspan="4"/>
<separator string="All moves" colspan="4"/>
</field>
-->
</field>
</record>
<record id="view_stock_tracking_tree" model="ir.ui.view">
<field name="name">stock.tracking.tree</field>
<field name="model">stock.tracking</field>
<field name="type">tree</field>
<field name="field_parent">child_ids</field>
<field name="arch" type="xml">
<tree toolbar="1">
<field name="name"/>
<field name="serial"/>
<field name="ul_id"/>
</tree>
</field>
</record>
<record id="action_stock_tracking_tree" model="ir.actions.act_window">
<field name="name">Packs Structure</field>
<field name="res_model">stock.tracking</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">tree</field>
<field name="view_id" ref="view_stock_tracking_tree"/>
<field name="domain">[('parent_id','=',False)]</field>
</record>
<menuitem
action="action_stock_tracking_tree"
id="menu_action_stock_tracking_tree"
parent="stock.menu_stock_inventory_control" />
<record id="view_picking_form" model="ir.ui.view">
<field name="name">stock.picking.form</field>
<field name="model">stock.picking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='move_lines']/form/group/field[@name='tracking_id']" position="replace">
<field name="tracking_id" domain="[('state', '=', 'open')]" colspan="3"/>
</xpath>
</field>
</record>
<record id="view_picking_out_form" model="ir.ui.view">
<field name="name">stock.picking.out.form</field>
<field name="model">stock.picking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='move_lines']/form/group/field[@name='tracking_id']" position="replace">
<field name="tracking_id" domain="[('state', '=', 'open')]" colspan="3"/>
</xpath>
</field>
</record>
<record id="view_picking_in_form" model="ir.ui.view">
<field name="name">stock.picking.in.form</field>
<field name="model">stock.picking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_picking_in_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='move_lines']/form/group/field[@name='tracking_id']" position="replace">
<field name="tracking_id" domain="[('state', '=', 'open')]" colspan="3"/>
</xpath>
</field>
</record>
<record id="view_product_stock_tracking_tree_inherit" model="ir.ui.view">
<field name="name">product.stock.tracking.tree</field>
<field name="model">product.stock.tracking</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Products">
<field name="product_id"/>
<field name="quantity"/>
</tree>
</field>
</record>
<record id="view_serial_stock_tracking_tree_inherit" model="ir.ui.view">
<field name="name">serial.stock.tracking.tree</field>
<field name="model">serial.stock.tracking</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Products">
<field name="tracking_id"/>
<field name="serial_id"/>
<field name="product_id"/>
<field name="quantity"/>
</tree>
</field>
</record>
<!--<record id="view_tracking_form_inherit" model="ir.ui.view">
<field name="name">stock.tracking.form.inherit</field>
<field name="model">stock.tracking</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_form_inherit"/>
<field name="arch" type="xml">
<notebook position="inside">
</notebook>
</field>
</record>-->
<record id="view_tracking_history_tree" model="ir.ui.view">
<field name="name">stock.tracking.history.tree</field>
<field name="model">stock.tracking.history</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="History">
<field name="type"/>
</tree>
</field>
</record>
<record id="view_tracking_history_form" model="ir.ui.view">
<field name="name">stock.tracking.history.form</field>
<field name="model">stock.tracking.history</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="History">
<field name="type"/>
<!--<newline/>
<separator string="Products" colspan="4"/>
<field name="child_product_ids" nolabel="1" colspan="4"/>
<separator string="Child Packs" colspan="4"/>
<field name="child_pack_ids" nolabel="1" colspan="4"/>-->
</form>
</field>
</record>
<record id="product_ul_tree" model="ir.ui.view">
<field name="name">product.ul.tree.inherit</field>
<field name="model">product.ul</field>
<field name="inherit_id" ref="product.product_ul_tree"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="capacity_index"/>
</field>
</field>
</record>
<record id="product_ul_form_view" model="ir.ui.view">
<field name="name">product.ul.form.inherit</field>
<field name="model">product.ul</field>
<field name="inherit_id" ref="product.product_ul_form_view"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="capacity_index"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
import stock
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
{
"name" : "Stock tracking Re-open",
"version" : "1.0",
"author" : "Julius Network Solutions",
"description" : """ This module Change reference of the packaging if it's re-open """,
"website" : "http://www.julius.fr",
"depends" : [
"stock",
"stock_tracking_extended",
"tr_barcode",
],
"category" : "Customs/Stock",
"init_xml" : [],
"demo_xml" : [],
"update_xml" : [
'stock_view.xml',
],
'test': [],
'installable': True,
'active': False,
'certificate': '',
}

View File

@@ -0,0 +1,57 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * stock_tracking_reopen
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-12-19 10:48+0000\n"
"PO-Revision-Date: 2011-12-19 10:48+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: stock_tracking_reopen
#: field:stock.tracking,previous_id:0
msgid "Previous Pack"
msgstr "Pack précédent"
#. module: stock_tracking_reopen
#: field:stock.tracking.history,previous_ref:0
msgid "Previous reference"
msgstr "Référence précédente"
#. module: stock_tracking_reopen
#: model:ir.model,name:stock_tracking_reopen.model_stock_tracking
msgid "Packs"
msgstr "Packs"
#. module: stock_tracking_reopen
#: constraint:stock.tracking:0
msgid "Bad parent type selection. Please try again."
msgstr "Mauvais choix du type parent. Veuillez réessayez à nouveau."
#. module: stock_tracking_reopen
#: model:ir.model,name:stock_tracking_reopen.model_stock_tracking_history
msgid "stock.tracking.history"
msgstr "stock.tracking.history"
#. module: stock_tracking_reopen
#: field:stock.tracking,modified:0
msgid "Modified"
msgstr "Mis à jour"
#. module: stock_tracking_reopen
#: model:ir.module.module,shortdesc:stock_tracking_reopen.module_meta_information
msgid "Stock tracking Re-open"
msgstr "Réouverture de packs"
#. module: stock_tracking_reopen
#: model:ir.module.module,description:stock_tracking_reopen.module_meta_information
msgid " This module Change reference of the packaging if it's re-open "
msgstr " Ce module change la référence du pack si il est ré-ouvert "

View File

@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
#################################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
from osv import fields, osv
from tools.translate import _
import time
class stock_tracking(osv.osv):
_inherit = 'stock.tracking'
_columns = {
'previous_id': fields.many2one('stock.tracking', 'Previous Pack', readonly=True),
'modified': fields.boolean('Modified'),
}
_default = {
'modified': False,
}
'''Function for pack creation'''
def create_pack(self, cr, uid, ids, context=None):
'''Init'''
if context == None:
context = {}
'''Location determination'''
stock_tracking_data = self.browse(cr, uid, ids[0])
'''Pack Creation'''
tracking_id = self.create(cr, uid, {'ul_id': stock_tracking_data.ul_id.id, 'location_id': stock_tracking_data.location_id.id})
'''Pack name is returned'''
return tracking_id
def reset_open(self, cr, uid, ids, context=None):
res = super(stock_tracking, self).reset_open(cr, uid, ids, context)
pack_ids = self.browse(cr, uid, ids, context)
for pack in pack_ids:
if pack.state == 'open':
self.pool.get('stock.tracking.history').create(cr, uid, {
'type': 'reopen',
'previous_ref': pack.name,
'tracking_id': pack.id
}, context)
return True
def set_close(self, cr, uid, ids, context=None):
barcode_obj = self.pool.get('tr.barcode')
stock_move_obj = self.pool.get('stock.move')
history_obj = self.pool.get('stock.tracking.history')
res = super(stock_tracking, self).set_close(cr, uid, ids, context)
if res:
pack_ids = self.browse(cr, uid, ids, context)
for pack in pack_ids:
if pack.state == 'open':
if self.pool.get('stock.tracking.history').search(cr,uid,[('type','=','reopen'),('tracking_id','=',pack.id)]) and pack.modified == True:
new_pack_id = self.create_pack(cr, uid, ids, context)
new_pack_data = self.browse(cr, uid, new_pack_id, context)
'''loop on each move form the old pack to the new pack'''
for pack_move in pack.current_move_ids:
''''stock move creation'''
barcode_name = pack_move.prodlot_id.name
barcode_data = barcode_obj.search(cr, uid,[('code', '=', barcode_name)], limit=1)
move_id = stock_move_obj.create(cr, uid, {
'name': pack_move.name,
'state': pack_move.state,
'product_id': pack_move.product_id.id,
'product_uom': pack_move.product_uom.id,
'prodlot_id': pack_move.prodlot_id.id,
'location_id': pack.location_id.id,
'location_dest_id': new_pack_data.location_id.id,
'tracking_id': new_pack_data.id,
})
'''end of loop'''
if pack.child_ids:
for child_pack_data in pack.child_ids:
if child_pack_data.state == 'close':
self.write(cr, uid, child_pack_data.id, {'active': False})
self.write(cr, uid, [new_child_pack_id], {'parent_id': new_pack_data.id,})
history_obj.create(cr, uid, {'type': 'pack_in',
'tracking_id': child_pack_data.id,
'parent_id': new_pack_data.id,
})
self.write(cr, uid, new_pack_data.id, {'location_id': child_pack_data.location_id and child_pack_data.location_id.id or False,})
self.write(cr, uid, [pack.id], {'state': 'close',
'active': False,
'modified': False})
'''Call for a function who will display serial code list and product list in the pack layout'''
self.get_products(cr, uid, [new_pack_data.id], context=None)
self.get_serials(cr, uid, [new_pack_data.id], context=None)
self.write(cr, uid, [pack.id], {'state': 'close'})
return res
stock_tracking()
class stock_tracking_history(osv.osv):
_inherit = "stock.tracking.history"
def _get_types(self, cr, uid, context={}):
res = super(stock_tracking_history, self)._get_types(cr, uid, context)
if not res:
res = []
res = res + [('reopen','Re Open')]
return res
_columns = {
'type': fields.selection(_get_types, 'Type'),
'previous_ref': fields.char('Previous reference', size=128),
# 'previous_id': fields.many2one('stock.tracking', 'Previous pack'),
}
stock_tracking_history()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_tracking_history_tree" model="ir.ui.view">
<field name="name">stock.tracking.history.tree.reopen</field>
<field name="model">stock.tracking.history</field>
<field name="type">tree</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_history_tree"/>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="previous_ref"/>
</field>
</field>
</record>
<record id="view_tracking_history_form" model="ir.ui.view">
<field name="name">stock.tracking.history.form.reopen</field>
<field name="model">stock.tracking.history</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock_tracking_extended.view_tracking_history_form"/>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="previous_ref"/>
</field>
</field>
</record>
</data>
</openerp>