[ADD, REF]: Converted all simple wizards to osv_memory wizards in stock

bzr revid: rpa@openerp.co.in-20100302121614-24onu2psztoxh2yx
This commit is contained in:
KSA (Open ERP)
2010-03-02 17:46:14 +05:30
committed by rpa (Open ERP)
parent 6c6f070839
commit 253fcaafe3
24 changed files with 849 additions and 682 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -26,9 +26,9 @@ import product
import report
import wizard
import report_stock
import stock_wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+7 -2
View File
@@ -41,11 +41,16 @@ Thanks to the double entry management, the inventory controlling is powerful and
"init_xml" : [],
"demo_xml" : ["stock_demo.xml"],
"update_xml" : [
"stock_workflow.xml",
"stock_data.xml",
"wizard/inventory_merge_stock_zero_view.xml",
"wizard/stock_fill_inventory_view.xml",
"wizard/stock_invoice_onshipping_view.xml",
"wizard/stock_location_product_view.xml",
"wizard/stock_inventory_line_split_view.xml",
"stock_workflow.xml",
"stock_incoterms.xml",
"stock_wizard.xml",
"stock_wizard_view.xml",
"stock_wizard_view.xml",
"stock_view.xml",
"stock_report.xml",
"stock_sequence.xml",
+134 -56
View File
@@ -219,7 +219,7 @@ class stock_location(osv.osv):
# Take the user company and pricetype
price_type_id=self.pool.get('res.users').browse(cr,uid,uid).company_id.property_valuation_price_type.id
pricetype=self.pool.get('product.price.type').browse(cr,uid,price_type_id)
if not product_ids:
product_ids = product_obj.search(cr, uid, [])
@@ -250,10 +250,10 @@ class stock_location(osv.osv):
continue
product = products_by_id[product_id]
quantity_total += qty[product_id]
# Compute based on pricetype
# Choose the right filed standard_price to read
amount_unit=product.price_get(pricetype.field, context)[product.id]
amount_unit=product.price_get(pricetype.field, context)[product.id]
price = qty[product_id] * amount_unit
# price = qty[product_id] * product.standard_price
@@ -662,8 +662,8 @@ class stock_picking(osv.osv):
if type in ('in_invoice', 'in_refund'):
# Take the user company and pricetype
price_type_id=self.pool.get('res.users').browse(cr,users,users).company_id.property_valuation_price_type.id
pricetype=self.pool.get('product.price.type').browse(cr,uid,price_type_id)
amount_unit=move_line.product_id.price_get(pricetype.field, context)[move_line.product_id.id]
pricetype=self.pool.get('product.price.type').browse(cr,uid,price_type_id)
amount_unit=move_line.product_id.price_get(pricetype.field, context)[move_line.product_id.id]
return amount_unit
else:
return move_line.product_id.list_price
@@ -1379,12 +1379,12 @@ class stock_move(osv.osv):
# Base computation on valuation price type
else:
company_id=move.company_id.id
pricetype=self.pool.get('product.price.type').browse(cr,uid,move.company_id.property_valuation_price_type.id)
amount_unit=move.product_id.price_get(pricetype.field, context)[move.product_id.id]
amount=amount_unit * q or 1.0
# amount = q * move.product_id.standard_price
partner_id = False
if move.picking_id:
partner_id = move.picking_id.address_id and (move.picking_id.address_id.partner_id and move.picking_id.address_id.partner_id.id or False) or False
@@ -1430,7 +1430,7 @@ class stock_move(osv.osv):
raise osv.except_osv(_('UserError'),
_('You can only delete draft moves.'))
return super(stock_move, self).unlink(
cr, uid, ids, context=context)
cr, uid, ids, context=context)
def _create_lot(self, cr, uid, ids, product_id, prefix=False):
prodlot_obj = self.pool.get('stock.production.lot')
@@ -1438,23 +1438,31 @@ class stock_move(osv.osv):
sequence = ir_sequence_obj.get(cr, uid, 'stock.lot.serial')
if not sequence:
raise wizard.except_wizard(_('Error!'), _('No production sequence defined'))
new_move = []
def _create_lot(move_id, product_id):
prodlot_id = prodlot_obj.create(cr, uid, {'name': sequence, 'prefix': prefix}, {'product_id': product_id})
prodlot = prodlot_obj.browse(cr, uid, prodlot_id)
ref = '%d' % (move_id)
if prodlot.ref:
ref = '%s, %s' % (prodlot.ref, ref)
prodlot_obj.write(cr, uid, [prodlot_id], {'ref': ref})
return prodlot_id
prodlot_id = prodlot_obj.create(cr, uid, {'name': sequence, 'prefix': prefix}, {'product_id': product_id})
prodlot = prodlot_obj.browse(cr, uid, prodlot_id)
prodlot = prodlot_obj.browse(cr, uid, prodlot_id)
ref = ','.join(map(lambda x:str(x),ids))
if prodlot.ref:
ref = '%s, %s' % (prodlot.ref, ref)
ref = '%s, %s' % (prodlot.ref, ref)
prodlot_obj.write(cr, uid, [prodlot_id], {'ref': ref})
return prodlot_id
def split_lines(self, cr, uid, ids, quantity, split_by_qty=1, prefix=False, with_lot=True, context=None):
if quantity <= 0:
raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
res = []
for move in self.browse(cr, uid, ids):
for move in self.browse(cr, uid, ids):
if split_by_qty <= 0 or quantity == 0:
return res
@@ -1466,8 +1474,18 @@ class stock_move(osv.osv):
update_val = {
'product_qty': split_by_qty,
'product_uos_qty': uos_qty,
}
for idx in range(int(quantity//split_by_qty)):
}
for idx in range(int(quantity//split_by_qty)):
if idx:
current_move = self.copy(cr, uid, move.id, {'state': move.state})
new_move.append(current_move)
else:
update_val = {
'product_qty': split_by_qty,
'product_uos_qty': uos_qty,
}
for idx in range(int(quantity//split_by_qty)):
if not idx and move.product_qty<=quantity:
current_move = move.id
else:
@@ -1477,94 +1495,154 @@ class stock_move(osv.osv):
update_val['prodlot_id'] = self._create_lot(cr, uid, [current_move], move.product_id.id)
self.write(cr, uid, [current_move], update_val)
if quantity_rest > 0:
idx = int(quantity//split_by_qty)
if quantity_rest > 0:
idx = int(quantity//split_by_qty)
if quantity_rest > 0:
idx = int(quantity//split_by_qty)
update_val['product_qty'] = quantity_rest
update_val['product_uos_qty'] = uos_qty_rest
if not idx and move.product_qty<=quantity:
current_move = move.id
update_val['product_uos_qty'] = uos_qty_rest
if idx:
current_move = self.copy(cr, uid, move.id, {'state': move.state})
new_move.append(current_move)
update_val['product_uos_qty'] = uos_qty_rest
if not idx and move.product_qty<=quantity:
current_move = move.id
else:
current_move = self.copy(cr, uid, move.id, {'state': move.state})
current_move = move.id
update_val['prodlot_id'] = _create_lot(current_move, move.product_id.id)
current_move = self.copy(cr, uid, move.id, {'state': move.state})
res.append(current_move)
if with_lot:
if with_lot:
update_val['prodlot_id'] = self._create_lot(cr, uid, [current_move], move.product_id.id)
self.write(cr, uid, [current_move], update_val)
return res
return res
def consume_moves(self, cr, uid, ids, quantity, location_id=False, location_dest_id=False, consume=True, context=None):
def consume_moves(self, cr, uid, ids, quantity, location_id=False, location_dest_id=False, consume=True, context=None):
if not context:
context = {}
context = {}
if quantity <= 0:
raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
res = []
for move in self.browse(cr, uid, ids, context=context):
for move in self.browse(cr, uid, ids, context=context):
res = []
for move in self.browse(cr, uid, ids, context=context):
move_qty = move.product_qty
quantity_rest = move.product_qty
quantity_rest -= quantity
quantity_rest -= quantity
uos_qty_rest = quantity_rest / move_qty * move.product_uos_qty
if quantity_rest <= 0:
quantity_rest = 0
quantity_rest = quantity
break
default_val = {
'product_qty': quantity,
'product_uos_qty': uos_qty,
'location_id': location_id or move.location_id.id,
}
if move.product_id.track_production:
new_move = self.split_lines(cr, uid, [move.id], quantity, split_by_qty=1, context=context)
else:
current_move = self.copy(cr, uid, move.id, default_val)
new_move.append(current_move)
update_val = {}
if quantity_rest > 0:
quantity_rest = 0
uos_qty_rest = 0
quantity = move.product_qty
uos_qty = quantity / move_qty * move.product_uos_qty
if quantity_rest > 0:
if quantity_rest > 0:
default_val = {
'product_qty': quantity,
'product_uos_qty': uos_qty,
'state': move.state,
'product_qty': quantity,
'product_uos_qty': uos_qty,
'state': move.state,
}
if location_dest_id:
default_val.update({'location_dest_id': location_dest_id})
default_val.update({'location_dest_id': location_dest_id})
if location_id:
default_val.update({'location_id': location_id})
default_val.update({'location_id': location_id})
if move.product_id.track_production and location_id:
res += self.split_lines(cr, uid, [move.id], quantity, split_by_qty=1, context=context)
else:
current_move = self.copy(cr, uid, move.id, default_val)
res += [current_move]
update_val = {}
update_val = {}
update_val['product_qty'] = quantity_rest
update_val['product_uos_qty'] = uos_qty_rest
self.write(cr, uid, [move.id], update_val)
update_val['product_uos_qty'] = uos_qty_rest
self.write(cr, uid, [move.id], update_val)
else:
quantity_rest = quantity
self.action_done(cr, uid, new_move)
return new_move
update_val['product_uos_qty'] = uos_qty_rest
self.write(cr, uid, [move.id], update_val)
else:
quantity_rest = quantity
uos_qty_rest = uos_qty
if move.product_id.track_production and location_id:
res += self.split_lines(cr, uid, [move.id], quantity_rest, split_by_qty=1, context=context)
else:
res += [move.id]
update_val = {}
else:
res += [move.id]
update_val = {}
update_val['product_qty'] = quantity_rest
update_val['product_uos_qty'] = uos_qty_rest
if location_dest_id:
update_val.update({'location_dest_id': location_dest_id})
update_val.update({'location_dest_id': location_dest_id})
if location_id:
update_val.update({'location_id': location_id})
update_val.update({'location_id': location_id})
self.write(cr, uid, [move.id], update_val)
if consume:
self.action_done(cr, uid, res)
self.action_done(cr, uid, res)
return res
def scrap_moves(self, cr, uid, ids, quantity, location_dest_id, context=None):
return self.consume_moves(cr, uid, ids, quantity, location_id=False, location_dest_id=location_dest_id, consume=False, context=context)
new_move = []
if quantity <= 0:
raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
for move in self.browse(cr, uid, ids, context=context):
location = move.location_dest_id.id
move_qty = move.product_qty
quantity_rest = move.product_qty
quantity_rest -= quantity
uos_qty = quantity / move_qty * move.product_uos_qty
uos_qty_rest = quantity_rest / move_qty * move.product_uos_qty
if quantity_rest <= 0:
quantity_rest = quantity
break
default_val = {
'product_qty': quantity,
'product_uos_qty': uos_qty,
'location_dest_id': location_dest_id,
'state': move.state
}
current_move = self.copy(cr, uid, move.id, default_val)
new_move.append(current_move)
update_val = {}
if quantity_rest > 0:
update_val['product_qty'] = quantity_rest
update_val['product_uos_qty'] = uos_qty_rest
self.write(cr, uid, [move.id], update_val)
return new_move
return self.consume_moves(cr, uid, ids, quantity, location_id=False, location_dest_id=location_dest_id, consume=False, context=context)
stock_move()
@@ -1595,7 +1673,7 @@ class stock_inventory(osv.osv):
move_line = []
for line in inv.inventory_line_id:
pid = line.product_id.id
# price = line.product_id.standard_price or 0.0
amount = self.pool.get('stock.location')._product_get(cr, uid, line.location_id.id, [pid], {'uom': line.product_uom.id})[pid]
change = line.product_qty - amount
+46 -17
View File
@@ -33,7 +33,9 @@
<field name="product_uom"/>
<field name="prod_lot_id"/>
<field colspan="4" domain="[('usage','=','internal')]" name="location_id" select="1"/>
<button name="%(split_inventory_lots)d" string="Split Inventory Lines" type="action" icon="gtk-justify-fill"/>
<button name="%(stock.action_view_stock_inventory_line_split)d"
string="Split inventory lines"
type="action" icon="gtk-justify-fill"/>
</form>
</field>
</record>
@@ -50,6 +52,7 @@
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
</group>
</search>
</field>
</record>
@@ -64,6 +67,7 @@
<field name="state"/>
</tree>
</field>
</record>
<record id="view_inventory_form" model="ir.ui.view">
<field name="name">stock.inventory.form</field>
@@ -89,11 +93,12 @@
<field name="product_qty"/>
<field name="product_uom"/>
<field domain="[('usage','=','internal')]" name="location_id" select="1"/>
<field name="prod_lot_id"/>
<group colspan="2" col="3">
<field name="prod_lot_id"/>
<button name="%(split_inventory_lots)d" string="Split in Production Lots" type="action" icon="gtk-justify-fill"/>
</group>
<button name="%(stock.action_view_stock_inventory_line_split)d"
string="Split inventory lines"
type="action" icon="gtk-justify-fill"/>
</group>
</form>
</field>
</page><page string="Posted Inventory">
@@ -105,7 +110,18 @@
<button name="action_done" states="draft" string="Confirm Inventory" type="object" icon="gtk-apply"/>
<button name="action_cancel" states="cancel" string="Set to Draft" type="object" icon="gtk-cancel"/>
<button name="action_cancel_inventary" states="draft" string="Cancel Inventory" type="object" icon="gtk-cancel"/>
<group col="4" colspan="2">
<button name="%(stock.action_view_inventory_merge_stock_zero)d"
string="Set Stock to Zero"
type="action"/>
<button name="%(stock.action_view_stock_fill_inventory)d"
string="Fill Inventory"
type="action"/>
</group>
</group>
</form>
</field>
</record>
@@ -138,6 +154,9 @@
<field name="name" select="1"/>
<field name="serial" select="1"/>
<field name="date" select="1"/>
<field name="active" select="1"/>
<group colspan="4">
</group>
<field name="active" />
</form>
</field>
@@ -410,6 +429,9 @@
</group>
<separator string="Additional Information" colspan="4"/>
<field colspan="4" name="comment" nolabel="1"/>
<button name="%(stock.action_view_stock_location_product)d"
string="Products by Location"
type="action"/>
</form>
</field>
</record>
@@ -524,7 +546,7 @@
<field name="auto_refresh" eval="1"/>
<field name="target">new</field>
<field name="context">{'action_id': active_id}</field>
</record>
</record>
<record model="ir.ui.view" id="stock_picking_calendar">
<field name="name">stock.picking.calendar</field>
@@ -585,7 +607,7 @@
<field name="location_id"/>
<field name="location_dest_id"/>
<field name="date_planned"/>
<field name="state"/>
<field name="state"/>
<button
name="%(stock.track_line)d"
string="Split in production lots"
@@ -662,6 +684,9 @@
<field name="move_type"/>
</page>
</notebook>
<button name="%(stock.action_stock_invoice_onshipping)d"
string="Create Invoices"
type="action"/>
</form>
</field>
</record>
@@ -726,6 +751,7 @@
<field name="min_date" select="1"/>
<field name="type"/>
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
</group>
<notebook colspan="4">
<page string="General Information">
@@ -740,7 +766,7 @@
<field name="location_id"/>
<field name="location_dest_id"/>
<field name="date_planned"/>
<field name="state"/>
<field name="state"/>
<button
name="%(stock.track_line)d"
string="Split in production lots"
@@ -812,7 +838,10 @@
<field name="move_type"/>
</page>
</notebook>
</form>
<button name="%(stock.action_stock_invoice_onshipping)d"
string="Get Type"
type="action"/>
</form>
</field>
</record>
@@ -890,8 +919,8 @@
<field name="state"/>
<button name="%(partial_picking)d" states="assigned" string="Validate" type="action" icon="gtk-go-forward" help="Validate Picking"/>
<button name="button_cancel" states="assigned,confirmed,draft" string="Cancel" icon="gtk-cancel" help="Cancel" confirm="This operation will cancel the picking. Do you want to continue?"/>
<button name="%(wizard_invoice_onshipping)d" states="done" string="Invoice" type="action"
icon="gtk-execute" help="Create invoice"
<button name="%(wizard_invoice_onshipping)d" states="done" string="Invoice" type="action"
icon="gtk-execute" help="Create invoice"
attrs="{'invisible': [('invoice_state', '!=', '2binvoiced')]}" />
</tree>
</field>
@@ -925,7 +954,7 @@
<field name="location_id"/>
<field name="location_dest_id"/>
<field name="date_planned"/>
<field name="state"/>
<field name="state"/>
<button
name="%(stock.track_line)d"
string="Split in production lots"
@@ -1110,8 +1139,8 @@
name="%(stock.move_scrap)d"
string="D" type="action"
icon="gtk-convert"
states="draft,waiting,confirmed,assigned" />
</tree>
states="done,cancel" />
</tree>
<form string="Stock Moves">
<notebook colspan="4">
<page string="General Information">
@@ -1278,7 +1307,7 @@
<field name="location_id"/>
<field name="location_dest_id"/>
<field name="date_planned"/>
<field name="state"/>
<field name="state"/>
</tree>
</field>
</record>
@@ -1317,7 +1346,7 @@
<field name="date"/>
<field name="date_planned"/>
<field name="priority"/>
</group>
</group>
<group colspan="2" col="4">
<separator string="Tracability" colspan="4" />
@@ -1327,7 +1356,7 @@
domain="[('product_id','=?',product_id)]"
on_change="onchange_lot_id(prodlot_id,product_qty, location_id, product_id)"/>
<button name="%(track_line)d" string="Split in production lots" type="action" icon="gtk-justify-fill" colspan="2" />
</group>
</group>
</page>
<page string="Return Picking History">
<field name="move_stock_return_history" nolabel="1"/>
+46 -46
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -25,16 +25,16 @@ from tools.translate import _
class stock_move_track(osv.osv_memory):
_name = "stock.move.track"
_description = "Track moves"
_columns = {
'tracking_prefix': fields.char('Tracking prefix', size=64),
'tracking_prefix': fields.char('Tracking prefix', size=64),
'quantity': fields.float("Quantity per lot")
}
_defaults = {
'quantity': lambda *x: 1
}
def track_lines(self, cr, uid, ids, context={}):
datas = self.read(cr, uid, ids)[0]
move_obj = self.pool.get('stock.move')
@@ -46,43 +46,43 @@ stock_move_track()
class stock_move_consume(osv.osv_memory):
_name = "stock.move.consume"
_description = "Consume Products"
_columns = {
'product_id': fields.many2one('product.product', 'Product', required=True, select=True),
'product_qty': fields.float('Quantity', required=True),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_id': fields.many2one('product.product', 'Product', required=True, select=True),
'product_qty': fields.float('Quantity', required=True),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'location_id': fields.many2one('stock.location', 'Location', required=True)
}
def _get_product_id(self, cr, uid, context):
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
return move.product_id.id
def _get_product_qty(self, cr, uid, context):
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
return move.product_qty
def _get_product_uom(self, cr, uid, context):
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
return move.product_uom.id
def _get_location_id(self, cr, uid, context):
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
return move.location_id.id
_defaults = {
'product_id': _get_product_id,
'product_qty': _get_product_qty,
'product_uom': _get_product_uom,
'product_id': _get_product_id,
'product_qty': _get_product_qty,
'product_uom': _get_product_uom,
'location_id': _get_location_id
}
def do_move_consume(self, cr, uid, ids, context={}):
move_obj = self.pool.get('stock.move')
move_ids = context['active_ids']
for data in self.read(cr, uid, ids):
move_obj.consume_moves(cr, uid, move_ids,
data['product_qty'], data['location_id'],
for data in self.read(cr, uid, ids):
move_obj.consume_moves(cr, uid, move_ids,
data['product_qty'], data['location_id'],
context=context)
return {}
@@ -93,17 +93,17 @@ class stock_move_scrap(osv.osv_memory):
_name = "stock.move.scrap"
_description = "Scrap Products"
_inherit = "stock.move.consume"
_defaults = {
'location_id': lambda *x: False
}
}
def move_scrap(self, cr, uid, ids, context={}):
move_obj = self.pool.get('stock.move')
move_obj = self.pool.get('stock.move')
move_ids = context['active_ids']
for data in self.read(cr, uid, ids):
move_obj.scrap_moves(cr, uid, move_ids,
data['product_qty'], data['location_id'],
move_obj.scrap_moves(cr, uid, move_ids,
data['product_qty'], data['location_id'],
context=context)
return {}
@@ -113,18 +113,18 @@ stock_move_scrap()
class spilt_in_production_lot(osv.osv_memory):
_name = "stock.move.spilt"
_description = "Split in Production lots"
_columns = {
'product_id': fields.many2one('product.product', 'Product', required=True, select=True),
'line_ids': fields.one2many('stock.move.spilt.lines', 'lot_id', 'Lots Number')
}
def _get_product_id(self, cr, uid, context):
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
return move.product_id.id
_defaults = {
'product_id': _get_product_id,
'product_id': _get_product_id,
}
def split_lot(self, cr, uid, ids, context=None):
@@ -135,16 +135,15 @@ class spilt_in_production_lot(osv.osv_memory):
prodlot_obj = self.pool.get('stock.production.lot')
ir_sequence_obj = self.pool.get('ir.sequence')
move_obj = self.pool.get('stock.move')
new_move = []
new_move = []
for data in self.browse(cr, uid, ids):
for move in move_obj.browse(cr, uid, move_ids):
move_qty = move.product_qty
quantity_rest = move.product_qty
uos_qty_rest = move.product_uos_qty
new_move = []
new_move = []
for line in data.line_ids:
quantity = line.quantity
if quantity <= 0 or move_qty == 0:
continue
@@ -155,52 +154,53 @@ class spilt_in_production_lot(osv.osv_memory):
quantity_rest = quantity
break
default_val = {
'product_qty': quantity,
'product_uos_qty': uos_qty,
'product_qty': quantity,
'product_uos_qty': uos_qty,
'state': move.state
}
current_move = move_obj.copy(cr, uid, move.id, default_val)
new_move.append(current_move)
prodlot_id = False
if line.use_exist and line.name:
prodlot_id = prodlot_obj.search(cr, uid, [('prefix','=',line.name),('product_id','=',data.product_id.id)])
if prodlot_id:
prodlot_id = prodlot_id[0]
prodlot_id = prodlot_id[0]
if not prodlot_id:
sequence = ir_sequence_obj.get(cr, uid, 'stock.lot.serial')
prodlot_id = prodlot_obj.create(cr, uid, {'name': sequence, 'prefix' : line.name},
{'product_id': move.product_id.id})
prodlot_id = prodlot_obj.create(cr, uid, {'name': sequence, 'prefix' : line.name},
{'product_id': move.product_id.id})
move_obj.write(cr, uid, [current_move], {'prodlot_id': prodlot_id})
prodlot = prodlot_obj.browse(cr, uid, prodlot_id)
prodlot = prodlot_obj.browse(cr, uid, prodlot_id)
ref = '%d' % (current_move)
if prodlot.ref:
ref = '%s, %s' % (prodlot.ref, ref)
ref = '%s, %s' % (prodlot.ref, ref)
prodlot_obj.write(cr, uid, [prodlot_id], {'ref': ref})
update_val = {}
if quantity_rest > 0:
if quantity_rest > 0:
update_val['product_qty'] = quantity_rest
update_val['product_uos_qty'] = uos_qty_rest
update_val['product_uos_qty'] = uos_qty_rest
move_obj.write(cr, uid, [move.id], update_val)
return new_move
spilt_in_production_lot()
class stock_move_spilt_lines(osv.osv_memory):
_name = "stock.move.spilt.lines"
_description = "Split lines"
_columns = {
'name': fields.char('Tracking serial', size=64),
'quantity': fields.integer('Quantity'),
'name': fields.char('Tracking serial', size=64),
'quantity': fields.integer('Quantity'),
'use_exist' : fields.boolean('Use Exist'),
'lot_id': fields.many2one('stock.move.spilt', 'Lot'),
'action': fields.selection([('split','Split'),('keepinone','Keep in one lot')],'Action'),
}
_defaults = {
'quantity': lambda *x: 1,
'action' : lambda *x: 'split',
'action' : lambda *x: 'split',
}
stock_move_spilt_lines()
+3 -3
View File
@@ -78,6 +78,6 @@
model="stock.location"
name="stock.location.products"
string="Products by Location"/>
</data>
</openerp>
</data>
</openerp>
+8 -7
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -27,12 +27,13 @@ import wizard_replacement
import wizard_return
import wizard_split_lot_line
import wizard_ups
import wizard_invoice_onshipping
import wizard_location_product
import wizard_inventory
import wizard_split_inventory_lots
import inventory_merge_zero
import inventory_merge
import inventory_merge_stock_zero
import stock_fill_inventory
import stock_inventory_line_split
import stock_invoice_onshipping
import stock_location_product
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1
View File
@@ -41,6 +41,7 @@ def do_merge(self, cr, uid, data, context):
invent_lines = {}
if len(data['ids']) < 2:
raise wizard.except_wizard(_('Warning'),
_('Please select at least two inventories.'))
@@ -0,0 +1,72 @@
# -*- 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 service import web_services
from tools.misc import UpdateableStr, UpdateableDict
from tools.translate import _
import netsvc
import pooler
import time
import wizard
class inventory_merge_stock_zero(osv.osv_memory):
_name = "stock.inventory.merge.stock.zero"
_description = "Set Stock to 0"
_columns = {
'location_id': fields.many2one('stock.location', 'Location', required=True),
}
def do_merge(self, cr, uid, ids, context):
invent_obj = pooler.get_pool(cr.dbname).get('stock.inventory')
invent_line_obj = pooler.get_pool(cr.dbname).get('stock.inventory.line')
prod_obj = pooler.get_pool(cr.dbname).get('product.product')
if len(context['active_ids']) <> 1:
raise wizard.except_wizard(_('Warning'),
_('Please select one and only one inventory !'))
for id in ids:
datas = self.read(cr, uid, id)
loc = str(datas['location_id'])
cr.execute('select distinct location_id,product_id \
from stock_inventory_line \
where inventory_id=%s', (context['active_ids'][0],))
inv = cr.fetchall()
cr.execute('select distinct product_id from stock_move where \
location_dest_id=%s or location_id=%s', (loc, loc,))
stock = cr.fetchall()
for s in stock:
if (loc, s[0]) not in inv:
p = prod_obj.browse(cr, uid, s[0])
invent_line_obj.create(cr, uid, {
'inventory_id': context['active_ids'][0],
'location_id': loc,
'product_id': s[0],
'product_uom': p.uom_id.id,
'product_qty': 0.0,
})
return {}
inventory_merge_stock_zero()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_inventory_merge_stock_zero" model="ir.ui.view">
<field name="name">Set Stock to Zero</field>
<field name="model">stock.inventory.merge.stock.zero</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Set Stock to Zero">
<separator string="Set Stocks to Zero" colspan="4" />
<group colspan="4">
<field name="location_id"/>
</group>
<newline/>
<label colspan="4" string="Do you want to set stocks to zero ?"/>
<separator string="" colspan="4" />
<button special="cancel" string="Cancel" />
<button name="do_merge" string="Set Stock to Zero" type="object"/>
</form>
</field>
</record>
<record id="action_view_inventory_merge_stock_zero" model="ir.actions.act_window">
<field name="name">Set Stock to Zero</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.inventory.merge.stock.zero</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>
@@ -1,94 +0,0 @@
# -*- 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 wizard
import pooler
from tools.translate import _
_form = """<?xml version="1.0"?>
<form string="Set Stock to Zero">
<separator colspan="4" string="Set Stocks to Zero" />
<field name="location_id"/>
<newline/>
<label colspan="4" string="Do you want to set stocks to zero ?"/>
</form>
"""
_inventory_fields = {
'location_id' : {
'string':'Location',
'type':'many2one',
'relation':'stock.location',
'required':True
}
}
def do_merge(self, cr, uid, data, context):
invent_obj = pooler.get_pool(cr.dbname).get('stock.inventory')
invent_line_obj = pooler.get_pool(cr.dbname).get('stock.inventory.line')
prod_obj = pooler.get_pool(cr.dbname).get('product.product')
if len(data['ids']) <> 1:
raise wizard.except_wizard(_('Warning'),
_('Please select one and only one inventory !'))
loc = str(data['form']['location_id'])
cr.execute('select distinct location_id,product_id from stock_inventory_line where inventory_id=%s', (data['ids'][0],))
inv = cr.fetchall()
cr.execute('select distinct product_id from stock_move where location_dest_id=%s or location_id=%s',(loc,loc,))
stock = cr.fetchall()
for s in stock:
if (loc,s[0]) not in inv:
p = prod_obj.browse(cr, uid, s[0])
invent_line_obj.create(cr, uid, {
'inventory_id': data['ids'][0],
'location_id': loc,
'product_id': s[0],
'product_uom': p.uom_id.id,
'product_qty': 0.0,
})
return {}
class merge_inventory(wizard.interface):
states = {
'init' : {
'actions' : [],
'result' : {'type' : 'form',
'arch' : _form,
'fields' : _inventory_fields,
'state' : [('end', 'Cancel', 'gtk-cancel'),
('merge', 'Set to Zero', 'gtk-apply', True) ]}
},
'merge' : {
'actions' : [],
'result' : {'type' : 'action',
'action': do_merge,
'state' : 'end'}
},
}
merge_inventory("inventory.merge.stock.zero")
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,89 @@
# -*- 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 wizard
import netsvc
import pooler
import time
from osv import fields, osv
from tools.translate import _
from service import web_services
from tools.misc import UpdateableStr, UpdateableDict
class stock_fill_inventory(osv.osv_memory):
_name = "stock.fill.inventory"
_description = "Fill Inventory"
_columns = {
'location_id': fields.many2one('stock.location', 'Location', required=True),
'recursive': fields.boolean("Include all childs for the location"),
}
def _fill_inventory(self, cr, uid, ids, context):
inventory_line_obj = self.pool.get('stock.inventory.line')
location_obj = self.pool.get('stock.location')
for fill_inventory in self.browse(cr, uid, ids):
res={}
res_location = {}
if fill_inventory.recursive :
location_ids = location_obj.search(cr, uid, [('location_id',
'child_of', fill_inventory.location_id.id)])
for location in location_ids :
res=location_obj._product_get(cr, uid, location)
res_location[location]=res
else:
context.update({'compute_child':False})
res=location_obj._product_get(cr, uid, fill_inventory.location_id.id, context=context)
res_location[fill_inventory.location_id.id]=res
product_ids=[]
for location in res_location.keys():
res=res_location[location]
for product_id in res.keys():
prod = self.pool.get('product.product').browse(cr, uid, [product_id])[0]
uom = prod.uom_id.id
context.update({'uom': uom})
amount=self.pool.get('stock.location')._product_get(cr, uid,
location, [product_id], context=context)[product_id]
if(amount):
line_ids=inventory_line_obj.search(cr, uid,
[('inventory_id', '=', context['active_ids']),
('location_id', '=', location),
('product_id', '=', product_id),
('product_uom', '=', uom),
('product_qty', '=', amount)])
if not len(line_ids):
inventory_line={'inventory_id': context['active_ids'][0],
'location_id': location,
'product_id': product_id,
'product_uom': uom,
'product_qty': amount}
inventory_line_obj.create(cr, uid, inventory_line)
product_ids.append(product_id)
if(len(product_ids)==0):
raise osv.except_osv(_('Message !'), _('No product in this location.'))
return {}
stock_fill_inventory()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_stock_fill_inventory" model="ir.ui.view">
<field name="name">Fill Inventory</field>
<field name="model">stock.fill.inventory</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Fill Inventory">
<separator string="Fill Inventory for specific location" colspan="4" />
<field name="location_id"/>
<newline/>
<field name="recursive"/>
<newline/>
<separator string="" colspan="4" />
<button special="cancel" string="Cancel" />
<button name="_fill_inventory" string="Fill Inventory" type="object"/>
</form>
</field>
</record>
<record id="action_view_stock_fill_inventory" model="ir.actions.act_window">
<field name="name">Fill Inventory</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.fill.inventory</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="context">{'record_id' : active_id}</field>
</record>
</data>
</openerp>
@@ -0,0 +1,104 @@
# -*- 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 service import web_services
from tools.misc import UpdateableStr, UpdateableDict
from tools.translate import _
import netsvc
import pooler
import time
import wizard
class stock_inventory_line_split(osv.osv_memory):
_name = "stock.inventory.line.split"
_description = "Split inventory lines"
_columns = {
'prefix': fields.char('Prefix', size=64),
'quantity': fields.float('Quantity per lot'),
}
def _check_production_lot(self, cr, uid, context):
for inv_obj in self.pool.get('stock.inventory.line').browse(cr, uid, context['active_ids']):
if not inv_obj.prod_lot_id:
raise osv.except_osv(_('Caution!'), _('Before splitting the inventory lines, \
make sure the production lot is assigned to this product.'))
return
_defaults = {
'quantity': lambda *a: '1',
'prefix': _check_production_lot,
}
def _split_lines(self, cr, uid, ids, context):
inv_id = context['active_id']
inv_line_obj = self.pool.get('stock.inventory.line')
prodlot_obj = self.pool.get('stock.production.lot')
for linesplit_obj in self.browse(cr, uid, ids):
ir_sequence_obj = self.pool.get('ir.sequence')
sequence = ir_sequence_obj.get(cr, uid, 'stock.lot.serial')
if not sequence:
raise wizard.except_wizard(_('Error!'), _('No production sequence defined'))
if linesplit_obj.prefix:
sequence=linesplit_obj.prefix + '/'+(sequence or '')
inv = inv_line_obj.browse(cr, uid, [inv_id])[0]
quantity = linesplit_obj.quantity
prodlot_obj.write(cr, uid, inv.prod_lot_id.id, {'name':sequence})
if quantity <= 0 or inv.product_qty == 0:
return {}
quantity_rest = inv.product_qty%quantity
update_val = {
'product_qty': quantity,
}
new_line = []
for idx in range(int(inv.product_qty//quantity)):
if idx:
current_line = inv_line_obj.copy(cr, uid, inv.id,
{'prod_lot_id': inv.prod_lot_id.id})
new_line.append(current_line)
else:
current_line = inv.id
inv_line_obj.write(cr, uid, [current_line], update_val)
if quantity_rest > 0:
idx = int(inv.product_qty//quantity)
update_val['product_qty']=quantity_rest
if idx:
current_line = inv_line_obj.copy(cr, uid, inv.id,
{'prod_lot_id': inv.prod_lot_id.id})
new_line.append(current_line)
else:
current_line = inv_line_obj.id
inv_line_obj.write(cr, uid, [current_line], update_val)
return {}
stock_inventory_line_split()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_stock_inventory_line_split" model="ir.ui.view">
<field name="name">Split inventory lines</field>
<field name="model">stock.inventory.line.split</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Split Inventory Line">
<field name="prefix"/>
<newline/>
<field name="quantity"/>
<separator string="" colspan="4" />
<label string=""/>
<button special="cancel" string="Cancel" icon="gtk-cancel" />
<button name="_split_lines" string="Ok" type="object" icon="gtk-ok"/>
</form>
</field>
</record>
<record id="action_view_stock_inventory_line_split" model="ir.actions.act_window">
<field name="name">Split inventory lines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.inventory.line.split</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>
@@ -0,0 +1,111 @@
# -*- 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 service import web_services
from tools.misc import UpdateableStr, UpdateableDict
from tools.translate import _
import netsvc
import pooler
import time
import wizard
class stock_invoice_onshipping(osv.osv_memory):
_name = "stock.invoice.onshipping"
_description = "Stock Invoice Onshipping"
_columns = {
'journal_id': fields.many2one('account.journal', 'Destination Journal', required=True),
'group': fields.boolean("Group by partner"),
'type': fields.selection([('out_invoice', 'Customer Invoice'),
('in_invoice', 'Supplier Invoice'),
('out_refund', 'Customer Refund'),
('in_refund', 'Supplier Refund')] , 'Type', required=True),
'invoice_date': fields.date('Invoiced date'),
}
def _get_type(self, cr, uid, context):
picking_obj = self.pool.get('stock.picking')
usage = 'customer'
pick = picking_obj.browse(cr, uid, context['active_id'])
if pick.invoice_state == 'invoiced':
raise osv.except_osv(_('UserError'), _('Invoice is already created.'))
if pick.invoice_state == 'none':
raise osv.except_osv(_('UserError'), _('Invoice cannot be created from Picking.'))
if pick.move_lines:
usage = pick.move_lines[0].location_id.usage
if pick.type == 'out' and usage == 'supplier':
type = 'in_refund'
elif pick.type == 'out' and usage == 'customer':
type = 'out_invoice'
elif pick.type == 'in' and usage == 'supplier':
type = 'in_invoice'
elif pick.type == 'in' and usage == 'customer':
type = 'out_refund'
else:
type = 'out_invoice'
return type
_defaults = {
'type': _get_type,
}
def _create_invoice(self, cr, uid, ids, context):
result = []
for onshipdata_obj in self.read(cr, uid, ids, ['journal_id', 'group', 'type', 'invoice_date']):
if context.get('new_picking', False):
onshipdata_obj[id] = onshipdata_obj.new_picking
onshipdata_obj[ids] = onshipdata_obj.new_picking
picking_obj = self.pool.get('stock.picking')
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
type = onshipdata_obj['type']
context['date_inv'] = onshipdata_obj['invoice_date']
res = picking_obj.action_invoice_create(cr, uid, [onshipdata_obj['id']],
journal_id = onshipdata_obj['journal_id'],
group=onshipdata_obj['group'],
type=type,
context=context)
invoice_ids = res.values()
if not invoice_ids:
raise osv.except_osv(_('Error'), _('Invoice is not created'))
if type == 'out_invoice':
xml_id = 'action_invoice_tree1'
elif type == 'in_invoice':
xml_id = 'action_invoice_tree2'
elif type == 'out_refund':
xml_id = 'action_invoice_tree3'
else:
xml_id = 'action_invoice_tree4'
result = mod_obj._get_id(cr, uid, 'account', xml_id)
id = mod_obj.read(cr, uid, result, ['res_id'])
result = act_obj.read(cr, uid, id['res_id'])
result['res_id'] = invoice_ids
return result
stock_invoice_onshipping()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_stock_invoice_onshipping" 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 invoices">
<separator colspan="4" string="Create invoices" />
<field name="journal_id"/>
<newline/>
<field name="group"/>
<newline/>
<field name="type"/>
<newline/>
<field name="invoice_date" />
<separator string="" colspan="4" />
<button special="cancel" string="Cancel" />
<button name="_create_invoice" string="Create Invoices" type="object"/>
</form>
</field>
</record>
<record id="action_stock_invoice_onshipping" model="ir.actions.act_window">
<field name="name">Stock Invoice Onshipping</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.invoice.onshipping</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>
+59
View File
@@ -0,0 +1,59 @@
# -*- 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 service import web_services
from tools.misc import UpdateableStr, UpdateableDict
from tools.translate import _
import netsvc
import pooler
import time
import wizard
class stock_location_product(osv.osv_memory):
_name = "stock.location.product"
_description = "Products by Location"
_columns = {
'from_date': fields.datetime('From'),
'to_date': fields.datetime('To'),
}
def _action_open_window(self, cr, uid, ids, context):
mod_obj = self.pool.get('ir.model.data')
for product_obj in self.read(cr, uid, ids, ['from_date', 'to_date']):
result = mod_obj._get_id(cr, uid, 'product', 'product_search_form_view')
id = mod_obj.read(cr, uid, result, ['res_id'])
return {
'name': 'product',
'view_type': 'form',
"view_mode": 'tree,form',
'res_model': 'product.product',
'type': 'ir.actions.act_window',
'context':{'location':product_obj['id'],
'from_date':product_obj['from_date'],
'to_date':product_obj['to_date']},
'domain':[('type', '<>', 'service')],
'search_view_id': id['res_id']
}
stock_location_product()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_stock_location_product" model="ir.ui.view">
<field name="name">Products by Location</field>
<field name="model">stock.location.product</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="View Stock of Products">
<separator string="Stock Location Analysis" colspan="4"/>
<field name="from_date" colspan="4"/>
<newline/>
<field name="to_date" colspan="4"/>
<newline/>
<label string=""/>
<label string="(Keep empty to open the current situation. Adjust HH:MM:SS to 00:00:00 to filter all resources of the day for the 'From' date and 23:59:59 for the 'To' date)" align="0.0" colspan="3"/>
<separator string="" colspan="4" />
<label string=""/>
<button special="cancel" string="Cancel" icon="gtk-cancel" />
<button name="_action_open_window" string="Open Product" type="object" icon="gtk-ok"/>
</form>
</field>
</record>
<record id="action_view_stock_location_product" model="ir.actions.act_window">
<field name="name">Products by Location</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.location.product</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>
+2 -2
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
-111
View File
@@ -1,111 +0,0 @@
# -*- 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 time
import wizard
import ir
import pooler
from osv.osv import except_osv
from osv import fields,osv
import netsvc
from tools.translate import _
inventory_form = """<?xml version="1.0"?>
<form string="Fill Inventory">
<separator colspan="4" string="Fill Inventory for specific location" />
<field name="location_id"/>
<newline/>
<field name="recursive"/>
<newline/>
</form>
"""
inventory_fields = {
'location_id' : {
'string':'Location',
'type':'many2one',
'relation':'stock.location',
'required':True
},
'recursive' : {'string':'Include all childs for the location', 'type':'boolean'}
}
def _fill_inventory(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
inventory_line_obj = pooler.get_pool(cr.dbname).get('stock.inventory.line')
location_obj = pooler.get_pool(cr.dbname).get('stock.location')
res={}
res_location={}
if data['form']['recursive'] :
location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', [data['form']['location_id']])])
for location in location_ids :
res=location_obj._product_get(cr, uid, location)
res_location[location]=res
else:
context.update({'compute_child':False})
res=location_obj._product_get(cr, uid, data['form']['location_id'],context=context)
res_location[data['form']['location_id']]=res
product_ids=[]
for location in res_location.keys():
res=res_location[location]
for product_id in res.keys():
#product_ids.append(product_id)
prod = pool.get('product.product').browse(cr, uid, [product_id])[0]
uom = prod.uom_id.id
context.update({'uom': uom})
amount=pool.get('stock.location')._product_get(cr, uid, location, [product_id], context=context)[product_id]
if(amount):
line_ids=inventory_line_obj.search(cr,uid,[('inventory_id','=',data['id']),('location_id','=',location),('product_id','=',product_id),('product_uom','=',uom),('product_qty','=',amount)])
if not len(line_ids):
inventory_line={'inventory_id':data['id'],'location_id':location,'product_id':product_id,'product_uom':uom,'product_qty':amount}
inventory_line_obj.create(cr, uid, inventory_line)
product_ids.append(product_id)
if(len(product_ids)==0):
raise wizard.except_wizard(_('Message !'), _('No product in this location.'))
return {}
class fill_inventory(wizard.interface):
states = {
'init' : {
'actions' : [],
'result' : {'type' : 'form',
'arch' : inventory_form,
'fields' : inventory_fields,
'state' : [('end', 'Cancel', 'gtk-cancel'),('fill_inventory', 'Fill Inventory', 'gtk-apply', True) ]}
},
'fill_inventory' : {
'actions' : [],
'result' : {'type' : 'action', 'action': _fill_inventory, 'state' : 'end'}
},
}
fill_inventory("stock.fill_inventory")
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,167 +0,0 @@
# -*- 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 wizard
import pooler
from tools.translate import _
invoice_form = """<?xml version="1.0"?>
<form string="Create invoices">
<separator colspan="4" string="Create invoices" />
<field name="journal_id"/>
<newline/>
<field name="group"/>
<newline/>
<field name="type"/>
<newline/>
<field name="invoice_date" />
</form>
"""
invoice_fields = {
'journal_id': {
'string': 'Destination Journal',
'type': 'many2one',
'relation': 'account.journal',
'required': True
},
'group': {
'string': 'Group by partner',
'type': 'boolean'
},
'type': {
'string': 'Type',
'type': 'selection',
'selection': [],
'required': True
},
'invoice_date': {'string': 'Invoiced date', 'type':'date' }
}
def _get_type(obj, cr, uid, data, context):
picking_obj = pooler.get_pool(cr.dbname).get('stock.picking')
usage = 'customer'
pick = picking_obj.browse(cr, uid, data['id'], context)
if pick.invoice_state == 'invoiced':
raise wizard.except_wizard(_('UserError'), _('Invoice is already created.'))
if pick.invoice_state == 'none':
raise wizard.except_wizard(_('UserError'), _('Invoice cannot be created from Picking.'))
if pick.move_lines:
usage = pick.move_lines[0].location_id.usage
if pick.type =='out':
invoice_fields['type']['selection'] = [
('out_invoice', 'Customer Invoice'),
('in_refund', 'Supplier Refund'),
]
elif pick.type =='in':
invoice_fields['type']['selection'] = [
('in_invoice', 'Supplier Invoice'),
('out_refund', 'Customer Refund'),
]
else:
invoice_fields['type']['selection']=[
('out_invoice', 'Customer Invoice'),
('in_invoice', 'Supplier Invoice'),
('out_refund', 'Customer Refund'),
('in_refund', 'Supplier Refund'),
]
if pick.type == 'out' and usage == 'supplier':
type = 'in_refund'
elif pick.type == 'out' and usage == 'customer':
type = 'out_invoice'
elif pick.type == 'in' and usage == 'supplier':
type = 'in_invoice'
elif pick.type == 'in' and usage == 'customer':
type = 'out_refund'
else:
type = 'out_invoice'
return {'type': type}
def _create_invoice(obj, cr, uid, data, context):
if data['form'].get('new_picking', False):
data['id'] = data['form']['new_picking']
data['ids'] = [data['form']['new_picking']]
pool = pooler.get_pool(cr.dbname)
picking_obj = pooler.get_pool(cr.dbname).get('stock.picking')
mod_obj = pool.get('ir.model.data')
act_obj = pool.get('ir.actions.act_window')
type = data['form']['type']
context['date_inv'] = data['form']['invoice_date']
res = picking_obj.action_invoice_create(cr, uid, data['ids'],
journal_id = data['form']['journal_id'], group=data['form']['group'],
type=type, context= context)
invoice_ids = res.values()
if not invoice_ids:
raise wizard.except_wizard(_('Error'), _('Invoice is not created'))
if type == 'out_invoice':
xml_id = 'action_invoice_tree1'
elif type == 'in_invoice':
xml_id = 'action_invoice_tree2'
elif type == 'out_refund':
xml_id = 'action_invoice_tree3'
else:
xml_id = 'action_invoice_tree4'
result = mod_obj._get_id(cr, uid, 'account', xml_id)
id = mod_obj.read(cr, uid, result, ['res_id'])
result = act_obj.read(cr, uid, id['res_id'])
result['res_id'] = invoice_ids
return result
class make_invoice_onshipping(wizard.interface):
states = {
'init': {
'actions': [_get_type],
'result': {
'type': 'form',
'arch': invoice_form,
'fields': invoice_fields,
'state': [
('end', 'Cancel', 'gtk-cancel'),
('create_invoice', 'Create invoice', 'gtk-apply', True)
]
}
},
'create_invoice': {
'actions': [],
'result': {
'type': 'action',
'action': _create_invoice,
'state': 'end'
}
},
}
make_invoice_onshipping("stock.invoice_onshipping")
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,76 +0,0 @@
# -*- 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 wizard
import pooler
import time
def _action_open_window(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
mod_obj = pool.get('ir.model.data')
result = mod_obj._get_id(cr, uid, 'product', 'product_search_form_view')
id = mod_obj.read(cr, uid, result, ['res_id'])
return {
'name': False,
'view_type': 'form',
"view_mode": 'tree,form',
'res_model': 'product.product',
'type': 'ir.actions.act_window',
'context':{'location': data['ids'][0],'from_date':data['form']['from_date'],'to_date':data['form']['to_date']},
'domain':[('type','<>','service')],
'search_view_id': id['res_id']
}
class product_by_location(wizard.interface):
form1 = '''<?xml version="1.0"?>
<form string="View Stock of Products">
<separator string="Stock Location Analysis" colspan="4"/>
<field name="from_date"/>
<newline/>
<field name="to_date"/>
<newline/>
<label string=""/>
<label string="(Keep empty to open the current situation. Adjust HH:MM:SS to 00:00:00 to filter all resources of the day for the 'From' date and 23:59:59 for the 'To' date)" align="0.0" colspan="3"/>
</form>'''
form1_fields = {
'from_date': {
'string': 'From',
'type': 'datetime',
},
'to_date': {
'string': 'To',
'type': 'datetime',
},
}
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', 'Cancel', 'gtk-cancel'),('open', 'Open Products', 'gtk-apply', True)]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
}
}
product_by_location('stock.location.products')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,98 +0,0 @@
import wizard
import netsvc
import pooler
import time
from osv import osv
from tools.translate import _
inv_form = '''<?xml version="1.0"?>
<form string="Split Inventory Line">
<field name="prefix"/>
<newline/>
<field name="quantity"/>
</form>
'''
inv_fields = {
'prefix': {
'string': 'Prefix',
'type': 'char',
'size': 64,
},
'quantity': {
'string': 'Quantity per lot',
'type': 'float',
'default': 1,
}
}
def _check_production_lot(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
inv_obj = pool.get('stock.inventory.line').browse(cr, uid, data['id'])
if not inv_obj.prod_lot_id:
raise wizard.except_wizard(_('Caution!'), _('Before splitting the inventory lines, make sure the production lot is assigned to this product.'))
return data['form']
def _split_lines(self, cr, uid, data, context):
inv_id = data['id']
pool = pooler.get_pool(cr.dbname)
inv_line_obj = pool.get('stock.inventory.line')
prodlot_obj = pool.get('stock.production.lot')
ir_sequence_obj = pool.get('ir.sequence')
sequence = ir_sequence_obj.get(cr, uid, 'stock.lot.serial')
if not sequence:
raise wizard.except_wizard(_('Error!'), _('No production sequence defined'))
if data['form']['prefix']:
sequence=data['form']['prefix']+'/'+(sequence or '')
inv = inv_line_obj.browse(cr, uid, [inv_id])[0]
quantity=data['form']['quantity']
prodlot_obj.write(cr, uid, inv.prod_lot_id.id, {'name':sequence})
if quantity <= 0 or inv.product_qty == 0:
return {}
quantity_rest = inv.product_qty%quantity
update_val = {
'product_qty': quantity,
}
new_line = []
for idx in range(int(inv.product_qty//quantity)):
if idx:
current_line = inv_line_obj.copy(cr, uid, inv.id, {'prod_lot_id': inv.prod_lot_id.id})
new_line.append(current_line)
else:
current_line = inv.id
inv_line_obj.write(cr, uid, [current_line], update_val)
if quantity_rest > 0:
idx = int(inv.product_qty//quantity)
update_val['product_qty']=quantity_rest
if idx:
current_line = inv_line_obj.copy(cr, uid, inv.id, {'prod_lot_id': inv.prod_lot_id.id})
new_line.append(current_line)
else:
current_line = inv.id
inv_line_obj.write(cr, uid, [current_line], update_val)
return {}
class wizard_split_inventory_lots(wizard.interface):
states = {
'init': {
'actions': [_check_production_lot],
'result': {'type': 'form', 'arch': inv_form, 'fields': inv_fields, 'state': [('end', 'Cancel', 'gtk-cancel'), ('split', 'Ok', 'gtk-apply', True)]},
},
'split': {
'actions': [_split_lines],
'result': {'type':'state', 'state':'end'}
}
}
wizard_split_inventory_lots('stock.inventory.line.split')