diff --git a/addons/procurement/schedulers.py b/addons/procurement/schedulers.py
index 0c5446cb4e6..9b3704e8df7 100644
--- a/addons/procurement/schedulers.py
+++ b/addons/procurement/schedulers.py
@@ -157,7 +157,9 @@ class procurement_order(osv.osv):
warehouse_ids = warehouse_obj.search(cr, uid, [], context=context)
- cr.execute('select id from product_product')
+ cr.execute('select p.id from product_product p \
+ join product_template t on (p.product_tmpl_id=t.id) \
+ where p.active=True and t.purchase_ok=True')
products_id = [x for x, in cr.fetchall()]
for warehouse in warehouse_obj.browse(cr, uid, warehouse_ids, context=context):
diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml
index 290ad0d4587..b0463957e9a 100644
--- a/addons/purchase/purchase_view.xml
+++ b/addons/purchase/purchase_view.xml
@@ -8,6 +8,18 @@
+
+
+
+
+
+
+
Addresses
@@ -162,7 +174,7 @@
-
+
@@ -312,12 +324,12 @@
-
+
-
-
-
+
+
+
@@ -375,7 +387,7 @@
-
+
diff --git a/addons/purchase/wizard/purchase_line_invoice.py b/addons/purchase/wizard/purchase_line_invoice.py
index f57ae82e51f..26dedb158a7 100644
--- a/addons/purchase/wizard/purchase_line_invoice.py
+++ b/addons/purchase/wizard/purchase_line_invoice.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL ().
#
@@ -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 .
+# along with this program. If not, see .
#
##############################################################################
@@ -26,26 +26,26 @@ from tools.translate import _
class purchase_line_invoice(osv.osv_memory):
-
+
""" To create invoice for purchase order line"""
-
+
_name = 'purchase.order.line_invoice'
_description = 'Purchase Order Line Make Invoice'
-
+
def makeInvoices(self, cr, uid, ids, context=None):
-
- """
+
+ """
To get Purchase Order line and create Invoice
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
- @param context: A standard dictionary
+ @param context: A standard dictionary
@return : retrun view of Invoice
"""
-
+
if context is None:
context={}
-
+
record_ids = context.get('active_ids',[])
if record_ids:
res = False
@@ -55,28 +55,28 @@ class purchase_line_invoice(osv.osv_memory):
property_obj=self.pool.get('ir.property')
account_fiscal_obj=self.pool.get('account.fiscal.position')
invoice_line_obj=self.pool.get('account.invoice.line')
-
-
+ account_jrnl_obj=self.pool.get('account.journal')
+
def multiple_order_invoice_name(orders):
name = "PO";
for order in orders:
name += "-%d" % order.id
return name
-
+
def multiple_order_invoice_reference(partner, orders):
reference = "P%dPO" % partner.id
- for order in orders:
+ for order in orders:
reference += "-%d" % order.id
return reference
-
+
def multiple_order_invoice_notes(orders):
notes = ""
for order in orders:
notes += "%s \n" % order.notes
return notes
-
-
-
+
+
+
def make_invoice_by_partner(partner, orders, lines_ids):
"""
create a new invoice for one supplier
@@ -84,23 +84,25 @@ class purchase_line_invoice(osv.osv_memory):
@param orders : The set of orders to add in the invoice
@param lines : The list of line's id
"""
-
+ journal_id = account_jrnl_obj.search(cr, uid, [('type', '=', 'purchase')], context=None)
+ journal_id = journal_id and journal_id[0] or False
a = partner.property_account_payable.id
if partner and partner.property_payment_term.id:
pay_term = partner.property_payment_term.id
else:
pay_term = False
inv = {
- 'name': multiple_order_invoice_name(orders),
- 'origin': multiple_order_invoice_name(orders),
+ 'name': multiple_order_invoice_name(orders),
+ 'origin': multiple_order_invoice_name(orders),
'type': 'in_invoice',
+ 'journal_id':journal_id,
'reference': multiple_order_invoice_reference(partner, orders),
'account_id': a,
'partner_id': partner.id,
'address_invoice_id': orders[0].partner_address_id.id,
'address_contact_id': orders[0].partner_address_id.id,
'invoice_line': [(6,0,lines_ids)],
- 'currency_id' : orders[0].pricelist_id.currency_id.id,
+ 'currency_id' : orders[0].pricelist_id.currency_id.id,
'comment': multiple_order_invoice_notes(orders),
'payment_term': pay_term,
'fiscal_position': partner.property_account_position.id
@@ -136,7 +138,7 @@ class purchase_line_invoice(osv.osv_memory):
'uos_id': line.product_uom.id,
'product_id': line.product_id.id or False,
'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])],
- 'note': line.notes,
+ 'note': line.notes,
'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False,
})
cr.execute('insert into purchase_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
@@ -147,7 +149,7 @@ class purchase_line_invoice(osv.osv_memory):
for result in invoices.values():
il = map(lambda x: x[1], result)
orders = list(set(map(lambda x : x[0].order_id, result)))
-
+
res.append(make_invoice_by_partner(orders[0].partner_id, orders, il))
return {
diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py
index 0b85511050d..987a0e12493 100644
--- a/addons/stock/__openerp__.py
+++ b/addons/stock/__openerp__.py
@@ -45,10 +45,11 @@ Thanks to the double entry management, the inventory controlling is powerful and
"init_xml" : [],
"demo_xml" : ["stock_demo.xml"],
"update_xml" : [
- "security/stock_security.xml",
- "security/ir.model.access.csv",
+ "security/stock_security.xml",
+ "security/ir.model.access.csv",
"stock_data.xml",
"wizard/stock_move_view.xml",
+ "wizard/stock_change_product_qty_view.xml",
"wizard/stock_partial_picking_view.xml",
"wizard/stock_partial_move_view.xml",
"wizard/stock_fill_inventory_view.xml",
diff --git a/addons/stock/product_view.xml b/addons/stock/product_view.xml
index 35715a9e1fb..05b2f83c15b 100644
--- a/addons/stock/product_view.xml
+++ b/addons/stock/product_view.xml
@@ -102,9 +102,12 @@
-
+
+
+
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 054dc6f37aa..6723c1b142b 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -110,6 +110,7 @@ class stock_location(osv.osv):
@param field_names: Name of field
@return: Dictionary of values
"""
+ prod_id = context and context.get('product_id', False)
product_product_obj = self.pool.get('product.product')
@@ -122,9 +123,10 @@ class stock_location(osv.osv):
currency_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id
currency_obj = self.pool.get('res.currency')
- currency = self.pool.get('res.currency').browse(cr, uid, currency_id)
- currency_obj.round(cr, uid, currency, 300)
+ currency = currency_obj.browse(cr, uid, currency_id, context=context)
for loc_id, product_ids in products_by_location.items():
+ if prod_id:
+ product_ids = [prod_id]
c = (context or {}).copy()
c['location'] = loc_id
for prod in product_product_obj.browse(cr, uid, product_ids, context=c):
@@ -1494,8 +1496,8 @@ class stock_move(osv.osv):
'location_dest_id': fields.many2one('stock.location', 'Destination Location', required=True,states={'done': [('readonly', True)]}, select=True, help="Location where the system will stock the finished products."),
'address_id': fields.many2one('res.partner.address', 'Destination Address', help="Optional address where goods are to be delivered, specifically used for allotment"),
- 'prodlot_id': fields.many2one('stock.production.lot', 'Production Lot', help="Production lot is used to put a serial number on the production", select=True),
- 'tracking_id': fields.many2one('stock.tracking', 'Pack', select=True, help="Logistical shipping unit: pallet, box, pack ..."),
+ 'prodlot_id': fields.many2one('stock.production.lot', 'Production Lot', states={'done': [('readonly', True)]}, help="Production lot is used to put a serial number on the production", select=True),
+ 'tracking_id': fields.many2one('stock.tracking', 'Pack', select=True, states={'done': [('readonly', True)]}, help="Logistical shipping unit: pallet, box, pack ..."),
'auto_validate': fields.boolean('Auto Validate'),
@@ -2466,7 +2468,6 @@ class stock_inventory(osv.osv):
"""
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)
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index d1368ae5165..feb7cc178fe 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -670,15 +670,15 @@
attrs="{'invisible': [('tracking_id','<>',False)]}"
icon="terp-stock_effects-object-colorize"
groups="base.group_extended"
- states="draft,assigned,confirmed,done"/>
+ states="draft,assigned,confirmed"/>
+ states="draft,assigned,confirmed"/>
+ states="draft,assigned,confirmed"/>
@@ -719,14 +719,14 @@
+ states="draft,assigned,confirmed" colspan="1"/>
@@ -859,18 +859,18 @@
+ states="draft,assigned,confirmed"/>
+ states="draft,assigned,confirmed"/>
@@ -912,14 +912,14 @@
+ states="draft,assigned,confirmed" colspan="1"/>
@@ -1089,7 +1089,7 @@
+ states="draft,assigned,confirmed"/>
+ states="draft,assigned,confirmed" colspan="1"/>
@@ -1399,14 +1399,14 @@
+ states="draft,assigned,confirmed" colspan="1"/>
diff --git a/addons/stock/wizard/__init__.py b/addons/stock/wizard/__init__.py
index 5e35e0e7297..b903f020f82 100644
--- a/addons/stock/wizard/__init__.py
+++ b/addons/stock/wizard/__init__.py
@@ -33,6 +33,6 @@ import stock_invoice_onshipping
import stock_location_product
import stock_change_standard_price
import stock_return_picking
-
+import stock_change_product_qty
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock/wizard/stock_change_product_qty.py b/addons/stock/wizard/stock_change_product_qty.py
new file mode 100644
index 00000000000..c4e0e0f5e2e
--- /dev/null
+++ b/addons/stock/wizard/stock_change_product_qty.py
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from osv import fields, osv
+from tools.translate import _
+import time
+
+class stock_change_product_qty(osv.osv_memory):
+ _name = "stock.change.product.qty"
+ _description = "Change Product Quantity"
+ _columns = {
+ 'new_quantity': fields.float('Quantity', required=True),
+ 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"),
+ 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade", domain="[('usage', '=', 'internal')]"),
+ }
+
+ def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context={}):
+ """ Finds location id for changed warehouse.
+ @param warehouse_id: Changed id of warehouse.
+ @return: Dictionary of values.
+ """
+ if warehouse_id:
+ warehouse = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id, context)
+ val = {'location_id': warehouse.lot_stock_id.id}
+ return {'value': val}
+ return {}
+
+ def default_get(self, cr, uid, fields, context):
+ """ To get default values for the object.
+ @param self: The object pointer.
+ @param cr: A database cursor
+ @param uid: ID of the user currently logged in
+ @param fields: List of fields for which we want default values
+ @param context: A standard dictionary
+ @return: A dictionary which of fields with values.
+ """
+ res = super(stock_change_product_qty, self).default_get(cr, uid, fields, context=context)
+
+ wids = self.pool.get('stock.warehouse').search(cr, uid, [], context=context)
+ if 'warehouse_id' in fields:
+ res.update({'warehouse_id': wids and wids[0] or False})
+
+ if 'new_quantity' in fields:
+ res.update({'new_quantity': 1})
+ return res
+
+ def change_product_qty(self, cr, uid, ids, context=None):
+ """ Changes the Product Quantity by making a Physical Inventory.
+ @param self: The object pointer.
+ @param cr: A database cursor
+ @param uid: ID of the user currently logged in
+ @param ids: List of IDs selected
+ @param context: A standard dictionary
+ @return:
+ """
+ if context is None:
+ context = {}
+
+ move_ids = []
+ rec_id = context and context.get('active_id', False)
+ assert rec_id, _('Active ID is not set in Context')
+
+ inventry_obj = self.pool.get('stock.inventory')
+ inventry_line_obj = self.pool.get('stock.inventory.line')
+ prod_obj_pool = self.pool.get('product.product')
+
+ res_original = prod_obj_pool.browse(cr, uid, rec_id, context=context)
+ for data in self.browse(cr, uid, ids, context=context):
+ invntry_id = inventry_obj.create(cr , uid, {'name': 'INV:' + str(res_original.name)}, context=context)
+ line_data ={
+ 'inventory_id' : invntry_id,
+ 'product_qty' : data.new_quantity,
+ 'location_id' : data.location_id.id,
+ 'product_id' : rec_id,
+ 'product_uom' : res_original.uom_id.id,
+ 'company_id' : self.pool.get('res.users').browse(cr, uid, uid).company_id.id or False ,
+ }
+ line_id = inventry_line_obj.create(cr , uid, line_data, context=context)
+
+ inventry_obj.action_confirm(cr, uid, [invntry_id], context=context)
+ inventry_obj.action_done(cr, uid, [invntry_id], context=context)
+
+ return {}
+
+stock_change_product_qty()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock/wizard/stock_change_product_qty_view.xml b/addons/stock/wizard/stock_change_product_qty_view.xml
new file mode 100644
index 00000000000..ee7b1b66b1d
--- /dev/null
+++ b/addons/stock/wizard/stock_change_product_qty_view.xml
@@ -0,0 +1,38 @@
+
+
+
+
+ Change Product Quantity
+ stock.change.product.qty
+ form
+
+
+
+
+
+
+ Change Product Quantity
+ ir.actions.act_window
+ stock.change.product.qty
+ form
+ form
+
+ new
+
+
+
+
+
diff --git a/addons/stock/wizard/stock_return_picking.py b/addons/stock/wizard/stock_return_picking.py
index cf6f7c4b1bd..a2d70b91a4b 100644
--- a/addons/stock/wizard/stock_return_picking.py
+++ b/addons/stock/wizard/stock_return_picking.py
@@ -56,16 +56,16 @@ class stock_return_picking(osv.osv_memory):
return res
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
+ @param context: A standard dictionary
@return: New arch of view with new columns.
"""
res = super(stock_return_picking, self).view_init(cr, uid, fields_list, context=context)
- record_id = context and context.get('active_id', False)
+ record_id = context and context.get('active_id', False)
if record_id:
pick_obj = self.pool.get('stock.picking')
pick = pick_obj.browse(cr, uid, record_id)
@@ -87,15 +87,15 @@ class stock_return_picking(osv.osv_memory):
if not valid_lines:
raise osv.except_osv(_('Warning !'), _("There are no products to return (only lines in Done state and not fully returned yet can be returned)!"))
return res
-
- def fields_view_get(self, cr, uid, view_id=None, view_type='form',
+
+ def fields_view_get(self, cr, uid, view_id=None, view_type='form',
context=None, toolbar=False, submenu=False):
- """
+ """
Changes the view dynamically
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
- @param context: A standard dictionary
+ @param context: A standard dictionary
@return: New arch of view.
"""
res = super(stock_return_picking, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)
@@ -116,7 +116,7 @@ class stock_return_picking(osv.osv_memory):
quantity = m.product_qty
if m.state=='done' and quantity > return_history[m.id]:
arch_lst.append('\n' % (m.id,))
- res['fields']['return%s' % m.id]={'string':m.name, 'type':'float', 'required':True}
+ res['fields']['return%s' % m.id]={'string':m.name, 'type':'float', 'required':True}
res.setdefault('returns', []).append(m.id)
arch_lst.append('\n')
res['fields']['invoice_state']={'string':_('Invoicing'), 'type':'selection','required':True, 'selection':[('2binvoiced', _('To be refunded/invoiced')), ('none', _('No invoicing'))]}
@@ -129,26 +129,26 @@ class stock_return_picking(osv.osv_memory):
return res
def create_returns(self, cr, uid, ids, context):
- """
+ """
Creates return picking.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
- @param ids: List of ids selected
- @param context: A standard dictionary
- @return: A dictionary which of fields with values.
- """
+ @param ids: List of ids selected
+ @param context: A standard dictionary
+ @return: A dictionary which of fields with values.
+ """
record_id = context and context.get('active_id', False) or False
move_obj = self.pool.get('stock.move')
pick_obj = self.pool.get('stock.picking')
uom_obj = self.pool.get('product.uom')
wf_service = netsvc.LocalService("workflow")
-
+
pick = pick_obj.browse(cr, uid, record_id)
data = self.read(cr, uid, ids[0])
new_picking = None
date_cur = time.strftime('%Y-%m-%d %H:%M:%S')
-
+
set_invoice_state_to_none = True
returned_lines = 0
for move in pick.move_lines:
@@ -159,22 +159,22 @@ class stock_return_picking(osv.osv_memory):
new_type = 'out'
else:
new_type = 'internal'
- new_picking = pick_obj.copy(cr, uid, pick.id, {'name':'%s (return)' % pick.name,
+ new_picking = pick_obj.copy(cr, uid, pick.id, {'name':'%s-return' % pick.name,
'move_lines':[], 'state':'draft', 'type':new_type,
'date':date_cur, 'invoice_state':data['invoice_state'],})
new_location=move.location_dest_id.id
if move.state=='done':
new_qty = data['return%s' % move.id]
returned_qty = move.product_qty
-
+
for rec in move.move_history_ids2:
returned_qty -= rec.product_qty
-
+
if returned_qty != new_qty:
set_invoice_state_to_none = False
if new_qty:
- returned_lines += 1
+ returned_lines += 1
new_move=move_obj.copy(cr, uid, move.id, {
'product_qty': new_qty,
'product_uos_qty': uom_obj._compute_qty(cr, uid, move.product_uom.id,
diff --git a/addons/stock/wizard/stock_traceability.py b/addons/stock/wizard/stock_traceability.py
index 815f90810ed..3906fa4fabf 100644
--- a/addons/stock/wizard/stock_traceability.py
+++ b/addons/stock/wizard/stock_traceability.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL ().
#
@@ -15,34 +15,34 @@
# 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 .
+# along with this program. If not, see .
#
##############################################################################
from osv import fields, osv
class action_traceability(osv.osv_memory):
- """
+ """
This class defines a function action_traceability for wizard
"""
_name = "action.traceability"
_description = "Action traceability "
-
+
def action_traceability(self, cr, uid, ids, context={}):
""" It traces the information of a product
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
- @param ids: List of IDs selected
- @param context: A standard dictionary
+ @param ids: List of IDs selected
+ @param context: A standard dictionary
@return: A dictionary of values
"""
-
+ lot_id = ids
type1 = context['type'] or 'move_history_ids2'
field = context['field'] or 'tracking_id'
obj = self.pool.get('stock.move')
- ids = obj.search(cr, uid, [(field, 'in',context['active_ids'])])
+ ids = obj.search(cr, uid, [(field, 'in',lot_id)])
cr.execute('select id from ir_ui_view where model=%s and field_parent=%s and type=%s', ('stock.move', type1, 'tree'))
view_id = cr.fetchone()[0]
value = {
@@ -53,7 +53,7 @@ class action_traceability(osv.osv_memory):
'field_parent': type1,
'view_id': (view_id,'View'),
'type': 'ir.actions.act_window',
- 'nodestroy':True,
+ 'nodestroy':True,
}
return value