[MERGE] merge with main branch

bzr revid: qdp-launchpad@openerp.com-20130924090225-1is038pb3sngz9qe
This commit is contained in:
Quentin (OpenERP)
2013-09-24 11:02:25 +02:00
20 changed files with 307 additions and 259 deletions
+18 -13
View File
@@ -229,19 +229,24 @@
<button name="%(report_shipping)d" string="Print Delivery Order" states="confirmed,assigned" type="action"/>
<button name="%(report_shipping)d" string="Print Delivery Order" states="done" type="action" class="oe_highlight"/>
</xpath>
<field name="min_date" position="after">
<field name="carrier_id"/>
<field name="carrier_tracking_ref"/>
<field name="number_of_packages"/>
</field>
<field name="company_id" position="before">
<label for="weight" string="Weight"/>
<div>
<field name="weight" class="oe_inline"/>
<field name="weight_uom_id" nolabel="1" class="oe_inline"/>
</div>
<field name="weight_net" groups="base.group_no_one"/>
</field>
<xpath expr="//page[@string='Additional Info']/group[last()]" position="after">
<separator string="Carrier Informations"/>
<group>
<group>
<field name="carrier_id"/>
<field name="carrier_tracking_ref"/>
<field name="number_of_packages"/>
</group>
<group>
<label for="weight" string="Weight"/>
<div>
<field name="weight" class="oe_inline"/>
<field name="weight_uom_id" nolabel="1" class="oe_inline"/>
</div>
<field name="weight_net" groups="base.group_no_one"/>
</group>
</group>
</xpath>
</field>
</record>
+3 -3
View File
@@ -10,9 +10,9 @@
<field name="event_ok" on_change="onchange_event_ok(event_ok, context)"/>
<label for="event_ok"/>
</div>
<div name='ean' position="after">
<field name="event_type_id" attrs="{'readonly': [('event_ok', '=', False)]}"/>
</div>
<field name='type' position="after">
<field name="event_type_id" attrs="{'readonly': [('event_ok', '=', False)], 'invisible': [('type', '!=', 'service')]}"/>
</field>
</field>
</record>
+2 -2
View File
@@ -935,10 +935,10 @@ class mrp_production(osv.osv):
'location_id': source_location_id,
'location_dest_id': destination_location_id,
'move_dest_id': production.move_prod_id.id,
'state': 'waiting',
'company_id': production.company_id.id,
}
move_id = stock_move.create(cr, uid, data, context=context)
stock_move.action_confirm(cr, uid, [move_id], context=context)
production.write({'move_created_ids': [(6, 0, [move_id])]}, context=context)
return move_id
@@ -962,10 +962,10 @@ class mrp_production(osv.osv):
'location_id': source_location_id,
'location_dest_id': destination_location_id,
'move_dest_id': parent_move_id,
'state': 'waiting',
'company_id': production.company_id.id,
'procure_method': 'make_to_order',
})
stock_move.action_confirm(cr, uid, [move_id], context=context)
production.write({'move_lines': [(4, move_id)]}, context=context)
return move_id
+1 -1
View File
@@ -32,7 +32,7 @@ This application supports complete integration and production scheduling for sto
-->
<record id="route_warehouse0_manufacture" model='stock.location.route'>
<field name="name">Your Company Manufacture</field>
<field name="name">Manufacture</field>
<field name="sequence">5</field>
</record>
+1
View File
@@ -74,6 +74,7 @@ class procurement_rule(osv.osv):
'''
_name = 'procurement.rule'
_description = "Procurement Rule"
_order = "name"
def _get_action(self, cr, uid, context=None):
return []
+1 -3
View File
@@ -18,9 +18,7 @@
<field name="arch" type="xml">
<field name="type" position="after">
<field name="project_id" attrs="{'invisible':[('type','!=','service')]}" />
</field>
<field name="standard_price" position="after">
<field name="auto_create_task"/>
<field name="auto_create_task" attrs="{'invisible': [('type', '!=', 'service')]}"/>
</field>
</field>
</record>
+15 -7
View File
@@ -667,10 +667,8 @@ class purchase_order(osv.osv):
return user_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
def _prepare_order_picking(self, cr, uid, order, context=None):
type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'picking_type_in')[1]
type = self.pool.get("stock.picking.type").browse(cr, uid, type_id, context=context)
return {
'name': self.pool.get('ir.sequence').get_id(cr, uid, type.sequence_id.id, 'id'),
'name': self.pool.get('ir.sequence').get_id(cr, uid, order.picking_type_id.sequence_id.id, 'id'),
'origin': order.name + ((order.origin and (':' + order.origin)) or ''),
'date': self.date_to_datetime(cr, uid, order.date_order, context),
'partner_id': order.dest_address_id.id or order.partner_id.id,
@@ -679,12 +677,11 @@ class purchase_order(osv.osv):
'purchase_id': order.id,
'company_id': order.company_id.id,
'move_lines' : [],
'picking_type_id': type_id,
'picking_type_id': order.picking_type_id.id,
}
def _prepare_order_line_move(self, cr, uid, order, order_line, picking_id, group_id, context=None):
''' prepare the stock move data from the PO line '''
type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'picking_type_in')[1]
price_unit = order_line.price_unit
if order_line.product_uom.id != order_line.product_id.uom_id.id:
price_unit *= order_line.product_uom.factor
@@ -709,7 +706,7 @@ class purchase_order(osv.osv):
'purchase_line_id': order_line.id,
'company_id': order.company_id.id,
'price_unit': price_unit,
'picking_type_id': type_id,
'picking_type_id': order.picking_type_id.id,
'group_id': group_id,
}
@@ -739,7 +736,7 @@ class purchase_order(osv.osv):
stock_move = self.pool.get('stock.move')
new_group = False
if any([(x.group_id == False) for x in order_lines]):
if any([(not x.group_id) for x in order_lines]):
new_group = self.pool.get("procurement.group").create(cr, uid, {'name':order.name, 'partner_id': order.partner_id.id}, context=context)
@@ -1379,4 +1376,15 @@ class account_invoice_line(osv.Model):
readonly=True),
}
class product_product(osv.osv):
_inherit = "product.product"
def _get_buy_route(self, cr, uid, context=None):
buy_route = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase', 'route_warehouse0_buy')[1]
return [buy_route]
_defaults = {
'route_ids': _get_buy_route,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1 -1
View File
@@ -71,7 +71,7 @@
-->
<record id="route_warehouse0_buy" model='stock.location.route'>
<field name="name">Your Company Buy</field>
<field name="name">Buy</field>
<field name="sequence">5</field>
</record>
+7 -1
View File
@@ -297,6 +297,12 @@
!python {model: stock.picking}: |
picking_obj = self.browse(cr, uid, ref("outgoing_fifo_shipment_neg"))
picking_obj.do_partial(context=context)
-
The behavior of fifo/lifo is not garantee if the quants are created at the same second, so i just wait one second
-
!python {model: stock.picking}: |
import time
time.sleep(1)
-
Let us create another out of 400 kg
-
@@ -392,4 +398,4 @@
quant_obj = self.pool.get("stock.quant")
quants = quant_obj.search(cr, uid, [('product_id','=',ref("product_fifo_negative"))])
print "Quants:", [(x.qty, x.location_id.name, x.in_date, x.cost, x.id) for x in quant_obj.browse(cr, uid, quants)]
assert self.browse(cr, uid, ref("product_fifo_negative")).standard_price == 65.0, "Product price not updated accordingly. %s found instead of 65" %(self.browse(cr, uid, ref("product_fifo_negative")).standard_price,)
assert self.browse(cr, uid, ref("product_fifo_negative")).standard_price == 65.0, "Product price not updated accordingly. %s found instead of 65" %(self.browse(cr, uid, ref("product_fifo_negative")).standard_price,)
-11
View File
@@ -85,17 +85,6 @@
<!-- Inherit stock picking's tree view -->
<record model="ir.ui.view" id="sale_journal_picking_order_tree">
<field name="name">stock.picking.journal.view.tree</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.vpicktree"/>
<field name="arch" type="xml">
<field name="state" position="before">
<field name="invoice_type_id"/>
</field>
</field>
</record>
<record id="view_partner_property_form" model="ir.ui.view">
<field name="name">res.partner.journal.property.form.inherit</field>
<field name="model">res.partner</field>
@@ -45,7 +45,7 @@
<field name="model">stock.location.route</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='warehouse_selectable']" position="after">
<field name="sale_selectable"/>
<field name="sale_selectable" string="Sale Order Lines"/>
</xpath>
</field>
</record>
+1 -1
View File
@@ -47,7 +47,7 @@ class procurement_rule(osv.osv):
return res
_columns = {
'location_id': fields.many2one('stock.location', 'Destination Location'),
'location_id': fields.many2one('stock.location', 'Procurement Location'),
'location_src_id': fields.many2one('stock.location', 'Source Location',
help="Source location is action=move"),
'route_id': fields.many2one('stock.location.route', 'Route',
@@ -52,9 +52,9 @@ openerp.stock = function(openerp) {
labelFontColor: '#000',
label: label,
levelColors: [
"#ff0000",
"#a9d70b",
"#f9c802",
"#a9d70b"
"#ff0000"
],
});
},
+82 -37
View File
@@ -215,7 +215,10 @@ class stock_quant(osv.osv):
# add location_dest_id in parameters (False=use the destination of the move)
def quants_move(self, cr, uid, quants, move, context=None):
for quant, qty in quants:
self.move_single_quant(cr, uid, quant, qty, move, context=context)
#quant may be a browse record or None
quant_record = self.move_single_quant(cr, uid, quant, qty, move, context=context)
#quant_record is the quant newly created or already split
self._quant_reconcile_negative(cr, uid, quant_record, context=context)
def check_preferred_location(self, cr, uid, move, context=None):
return move.location_dest_id
@@ -233,7 +236,6 @@ class stock_quant(osv.osv):
'history_ids': [(4, move.id)]
})
quant.refresh()
self._quant_reconcile_negative(cr, uid, quant, context=context)
return quant
def quants_get(self, cr, uid, location, product, qty, domain=None, prefered_order=False, reservedcontext=None, restrict_lot_id=False, restrict_partner_id=False, context=None):
@@ -317,19 +319,28 @@ class stock_quant(osv.osv):
move = m
return move
def _reconcile_single_negative_quant(self, cr, uid, to_solve_quant, quant, quant_neg, qty, context=None):
move = self._get_latest_move(cr, uid, to_solve_quant, context=context)
self._quant_split(cr, uid, quant, qty, context=context)
remaining_to_solve_quant = self._quant_split(cr, uid, to_solve_quant, qty, context=context)
remaining_neg_quant = self._quant_split(cr, uid, quant_neg, -qty, context=context)
#if the reconciliation was not complete, we need to link together the remaining parts
if remaining_to_solve_quant and remaining_neg_quant:
self.write(cr, uid, remaining_to_solve_quant.id, {'propagated_from_id': remaining_neg_quant.id}, context=context)
#delete the reconciled quants, as it is replaced by the solving quant
self.unlink(cr, SUPERUSER_ID, [quant_neg.id, to_solve_quant.id], context=context)
#call move_single_quant to ensure recursivity if necessary and do the stock valuation
self.move_single_quant(cr, uid, quant, qty, move, context=context)
return remaining_to_solve_quant
#def _reconcile_single_negative_quant(self, cr, uid, to_solve_quant, quant, quant_neg, qty, context=None):
# move = self._get_latest_move(cr, uid, to_solve_quant, context=context)
# remaining_solving_quant = self._quant_split(cr, uid, quant, qty, context=context)
# remaining_to_solve_quant = self._quant_split(cr, uid, to_solve_quant, qty, context=context)
# remaining_neg_quant = self._quant_split(cr, uid, quant_neg, -qty, context=context)
# #if the reconciliation was not complete, we need to link together the remaining parts
# if remaining_to_solve_quant and remaining_neg_quant:
# self.write(cr, uid, remaining_to_solve_quant.id, {'propagated_from_id': remaining_neg_quant.id}, context=context)
# #delete the reconciled quants, as it is replaced by the solving quant
# if remaining_neg_quant:
# otherquant_ids = self.search(cr, uid, [('propagated_from_id', '=', quant_neg.id)], context=context)
# self.write(cr, uid, otherquant_ids, {'propagated_from_id': remaining_neg_quant.id}, context=context)
# self.unlink(cr, SUPERUSER_ID, [quant_neg.id, to_solve_quant.id], context=context)
# #call move_single_quant to ensure recursivity if necessary and do the stock valuation
# self.move_single_quant(cr, uid, quant, qty, move, context=context)
# return remaining_solving_quant, remaining_to_solve_quant
def _quants_merge(self, cr, uid, solved_quant_ids, solving_quant, context=None):
path = []
for move in solving_quant.history_ids:
path.append((4, move.id))
self.write(cr, uid, solved_quant_ids, {'history_ids': path}, context=context)
def _quant_reconcile_negative(self, cr, uid, quant, context=None):
"""
@@ -339,18 +350,42 @@ class stock_quant(osv.osv):
"""
if quant.location_id.usage != 'internal':
return False
solving_quant = quant
quants = self.quants_get(cr, uid, quant.location_id, quant.product_id, quant.qty, [('qty', '<', '0')], context=context)
for quant_neg, qty in quants:
if not quant_neg:
continue
to_solve_quant = self.search(cr, uid, [('propagated_from_id', '=', quant_neg.id), ('id', '!=', quant.id)], context=context)
if not to_solve_quant:
to_solve_quant_ids = self.search(cr, uid, [('propagated_from_id', '=', quant_neg.id)], context=context)
if not to_solve_quant_ids:
continue
to_solve_quant = self.browse(cr, uid, to_solve_quant[0], context=context)
self._reconcile_single_negative_quant(cr, uid, to_solve_quant, quant, quant_neg, qty, context=context)
solving_qty = qty
solved_quant_ids = []
for to_solve_quant in self.browse(cr, uid, to_solve_quant_ids, context=context):
if solving_qty <= 0:
continue
solved_quant_ids.append(to_solve_quant.id)
self._quant_split(cr, uid, to_solve_quant, min(solving_qty, to_solve_quant.qty), context=context)
solving_qty -= min(solving_qty, to_solve_quant.qty)
#merge history (and cost?)
self._quants_merge(cr, uid, solved_quant_ids, solving_quant, context=context)
remaining_solving_quant = self._quant_split(cr, uid, solving_quant, qty, context=context)
remaining_neg_quant = self._quant_split(cr, uid, quant_neg, -qty, context=context)
#if the reconciliation was not complete, we need to link together the remaining parts
if remaining_neg_quant:
remaining_to_solve_quant_ids = self.search(cr, uid, [('propagated_from_id', '=', quant_neg.id), ('id', 'not in', solved_quant_ids)], context=context)
if remaining_to_solve_quant_ids:
self.write(cr, uid, remaining_to_solve_quant_ids, {'propagated_from_id': remaining_neg_quant.id}, context=context)
quant_cost = solving_quant.cost
#delete the reconciled quants, as it is replaced by the solving quant
self.unlink(cr, SUPERUSER_ID, [quant_neg.id, solving_quant.id], context=context)
#price update + accounting entries adjustments
self._price_update(cr, uid, solved_quant_ids, quant_cost, context=context)
solving_quant = remaining_solving_quant
def _price_update(self, cr, uid, quant, newprice, context=None):
self.write(cr, uid, [quant.id], {'cost': newprice}, context=context)
#solving_quant, dummy = self._reconcile_single_negative_quant(cr, uid, to_solve_quant, solving_quant, quant_neg, qty, context=context)
def _price_update(self, cr, uid, ids, newprice, context=None):
self.write(cr, uid, ids, {'cost': newprice}, context=context)
def write(self, cr, uid, ids, vals, context=None):
#We want to trigger the move with nothing on reserved_quant_ids for the store of the remaining quantity
@@ -379,8 +414,6 @@ class stock_quant(osv.osv):
domain += [('product_id','=',product.id)] + domain
res = []
offset = 0
#id is added at the end of the order to make sure the order is always the same for quants created at the same second
orderby += ', id asc'
while quantity > 0:
quants = self.search(cr, uid, domain, order=orderby, limit=10, offset=offset, context=context)
if not quants:
@@ -542,7 +575,7 @@ class stock_picking(osv.osv):
* Cancelled: has been cancelled, can't be confirmed anymore"""
),
'min_date': fields.function(get_min_max_date, multi="min_max_date",
store={'stock.move': (_get_pickings, ['state', 'date_expected'], 20)}, type='datetime', string='Scheduled Time', select=1, help="Scheduled time for the first part of the shipment to be processed"),
store={'stock.move': (_get_pickings, ['state', 'date_expected'], 20)}, type='datetime', string='Scheduled Date', select=1, help="Scheduled time for the first part of the shipment to be processed"),
'max_date': fields.function(get_min_max_date, multi="min_max_date",
store={'stock.move': (_get_pickings, ['state', 'date_expected'], 20)}, type='datetime', string='Max. Expected Date', select=2, help="Scheduled time for the last part of the shipment to be processed"),
'date': fields.datetime('Commitment Date', help="Date promised for the completion of the transfer order, usually set the time of the order and revised later on.", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
@@ -808,14 +841,18 @@ class stock_picking(osv.osv):
def rereserve(self, cr, uid, picking_ids, create=False, context=None):
"""
This will unreserve all products and reserve the quants from the operations
:return: tuple of dictionary with quantities of quant operation and product that can not be matched between ops and moves
:return: Tuple (res, res2)
res: dictionary of ops with quantity that could not be processed matching ops and moves
res2: dictionary of moves with quantity that could not be processed
resneg: the negative quants that should be created with ops and move (TODO)
tuple of dictionary with quantities of quant operation and product that can not be matched between ops and moves
and dictionary with remaining values on moves
"""
quant_obj = self.pool.get("stock.quant")
move_obj = self.pool.get("stock.move")
op_obj = self.pool.get("stock.pack.operation")
res = {}
res = {} # Qty still to do from ops
res2 = {} #what is left from moves
for picking in self.browse(cr, uid, picking_ids, context=context):
# unreserve everything and initialize res2
@@ -825,14 +862,14 @@ class stock_picking(osv.osv):
# Resort pack_operation_ids
orderedpackops = picking.pack_operation_ids
#Sort packing operations such that packing operations with most specific information
orderedpackops.sort(key = lambda x: (x.package_id and -1 or 0) + (x.lot_id and -1 or 0))
#Sort packing operations such that only transferring packages happens first and then packing operations with most specific information
orderedpackops.sort(key = lambda x: ((x.package_id and not x.product_id) and -3 or 0) + (x.package_id and -1 or 0) + (x.lot_id and -1 or 0))
for ops in orderedpackops:
#Find moves that correspond
if ops.product_id:
#TODO: Should have order such that things with lots and packings are searched first
move_ids = move_obj.search(cr, uid, [('picking_id','=',picking.id), ('product_id', '=', ops.product_id.id), ('remaining_qty', '>', 0.0)], context=context)
move_ids = move_obj.search(cr, uid, [('picking_id','=',picking.id), ('product_id', '=', ops.product_id.id), ('remaining_qty', '>', 0.0), ('state', '=', 'assigned')], context=context)
qty_to_do = ops.product_qty
while qty_to_do > 0 and move_ids:
move = move_obj.browse(cr, uid, move_ids.pop(), context=context)
@@ -862,8 +899,9 @@ class stock_picking(osv.osv):
else:
#Quants get
prefered_order = "reservation_id IS NOT NULL"
domain = op_obj._get_domain(cr, uid, ops, context=context)
quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=domain, prefered_order=prefered_order, context=context)
dom = op_obj._get_domain(cr, uid, ops, context=context)
dom = dom + [('reservation_id', 'not in', [x.id for x in picking.move_lines])]
quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=dom, prefered_order=prefered_order, context=context)
quant_obj.quants_reserve(cr, uid, quants, move, context=context)
#In the end, move quants in correct package
if create:
@@ -873,6 +911,7 @@ class stock_picking(osv.osv):
res[ops.id][ops.product_id.id] = qty_to_do
elif ops.package_id:
quants = ops.package_id.quant_ids #_get_package_lines
for quant in quants:
move_ids = move_obj.search(cr, uid, [('picking_id', '=', picking.id), ('product_id', '=', quant.product_id.id), ('remaining_qty', '>', 0.0)])
qty_to_do = quant.qty
@@ -908,6 +947,9 @@ class stock_picking(osv.osv):
#First thing that needs to happen is rereserving the quants
res = self.rereserve(cr, uid, [picking.id], create = True, context = context) #This time, quants need to be created
orig_moves = picking.move_lines
orig_qtys = {}
for orig in orig_moves:
orig_qtys[orig.id] = orig.product_qty
#Add moves that operations need extra
extra_moves = []
for ops in res[0].keys():
@@ -926,16 +968,19 @@ class stock_picking(osv.osv):
'location_dest_id': picking.location_dest_id.id,
'picking_id': picking.id,
'reserved_quant_ids': quant and [(4, quant.id)] or [],
'picking_type_id': picking.picking_type_id.id
'picking_type_id': picking.picking_type_id.id,
'group_id': picking.group_id.id,
}, context=context)
extra_moves.append(move_id)
res2 = res[1]
for move in res2.keys():
if res2[move] > 0:
mov = stock_move_obj.browse(cr, uid, move, context=context)
stock_move_obj.split(cr, uid, mov, res2[move], context=context)
new_move = stock_move_obj.split(cr, uid, mov, res2[move], context=context)
#Assign move as it was assigned before
stock_move_obj.action_assign(cr, uid, [new_move])
todo = []
orig_moves = [x for x in orig_moves if x.reserved_quant_ids]
orig_moves = [x for x in orig_moves if res[1][x.id] < orig_qtys[x.id]]
for move in orig_moves + stock_move_obj.browse(cr, uid, extra_moves, context=context):
if move.state == 'draft':
self.pool.get('stock.move').action_confirm(cr, uid, [move.id],
@@ -1533,7 +1578,6 @@ class stock_move(osv.osv):
"""
context = context or {}
quant_obj = self.pool.get("stock.quant")
uom_obj = self.pool.get("product.uom")
done = []
for move in self.browse(cr, uid, ids, context=context):
if move.state not in ('confirmed', 'waiting'):
@@ -1548,7 +1592,7 @@ class stock_move(osv.osv):
for q in m2.quant_ids:
dp.append(str(q.id))
qty -= q.qty
domain = ['|', ('reservation_id', '=', False), ('reservation_id', '=', move.id)]
domain = ['|', ('reservation_id', '=', False), ('reservation_id', '=', move.id), ('qty', '>', 0)]
quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=domain, prefered_order = dp and ('id not in ('+','.join(dp)+')') or False, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context)
#Will only reserve physical quants, no negative
quant_obj.quants_reserve(cr, uid, quants, move, context=context)
@@ -1802,7 +1846,7 @@ class stock_inventory(osv.osv):
_columns = {
'name': fields.char('Inventory Reference', size=64, required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Inventory Name."),
'date': fields.datetime('Creation Date', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Inventory Create Date."),
'date': fields.datetime('Inventory Date', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Inventory Create Date."),
'date_done': fields.datetime('Date done', help="Inventory Validation Date."),
'line_ids': fields.one2many('stock.inventory.line', 'inventory_id', 'Inventories', readonly=False, states={'done': [('readonly', True)]}, help="Inventory Lines."),
'move_ids': fields.one2many('stock.move', 'inventory_id', 'Created Moves', help="Inventory Moves."),
@@ -1814,6 +1858,7 @@ class stock_inventory(osv.osv):
'partner_id': fields.many2one('res.partner', 'Owner', readonly=True, states={'draft': [('readonly', False)]}, help="Specify Owner to focus your inventory on a particular Owner."),
'lot_id': fields.many2one('stock.production.lot', 'Lot/Serial Number', readonly=True, states={'draft': [('readonly', False)]}, help="Specify Lot/Serial Number to focus your inventory on a particular Lot/Serial Number."),
'move_ids_exist': fields.function(_get_move_ids_exist, type='boolean', string=' Stock Move Exists?', help='technical field for attrs in view'),
'filter': fields.selection([('product', 'Product'), ('owner', 'Owner'), ('product_owner','Product & Owner'), ('lot','Lot/Serial Number'), ('pack','Pack'), ('none', 'None')], 'Selection Filter'),
}
def _default_stock_location(self, cr, uid, context=None):
+83 -121
View File
@@ -8,15 +8,14 @@
groups="group_stock_manager,group_stock_user"
sequence="70"/>
<menuitem id="menu_stock_warehouse_mgmt" name="Receive/Deliver By Orders" parent="menu_stock_root" sequence="1"/>
<menuitem id="menu_stock_products_moves" name="Receive/Deliver Products" parent="menu_stock_root" sequence="2"/>
<menuitem id="menu_stock_warehouse_mgmt" name="Operations" parent="menu_stock_root" sequence="1"/>
<menuitem id="menu_stock_product" name="Products" parent="menu_stock_root" sequence="6"/>
<menuitem name="Products by Category" id="menu_product_by_category_stock_form" action="product.product_category_action"
parent="stock.menu_stock_product" sequence="0"/>
<menuitem action="product.product_normal_action" id="menu_stock_products_menu" parent="menu_stock_product" sequence="1"/>
<menuitem id="menu_stock_configuration" name="Configuration" parent="menu_stock_root" sequence="15" groups="group_stock_manager"/>
<menuitem id="menu_warehouse_config" name="Warehouse Management" parent="menu_stock_configuration" sequence="40" groups="base.group_no_one"/>
<menuitem id="menu_stock_inventory_control" name="Inventory Control" parent="menu_stock_root" sequence="4"/>
<menuitem id="menu_stock_inventory_control" name="Inventory Control" parent="menu_stock_root" sequence="2"/>
<menuitem
id="menu_product_in_config_stock" name="Products"
parent="stock.menu_stock_configuration" sequence="45" groups="base.group_no_one"/>
@@ -100,7 +99,7 @@
<field name="name">stock.inventory.form</field>
<field name="model">stock.inventory</field>
<field name="arch" type="xml">
<form string="Physical Inventory" version="7.0">
<form string="Inventory Adjustment" version="7.0">
<header>
<button name="prepare_inventory" states="draft" string="Start Inventory" type="object" class="oe_highlight" groups="stock.group_stock_user"/>
<button name="action_done" states="confirm" string="Validate Inventory" type="object" class="oe_highlight" groups="stock.group_stock_manager"/>
@@ -119,16 +118,20 @@
</group>
<group>
<field name="date"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
</group>
<div class="oe_grey" colspan="4">Specify filters to focus your inventory a on particular product, lot, pack and product's owner.</div>
<group>
<field name="product_id" domain="[('type','=','product')]"/>
<field name="lot_id"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
<label for="filter"/>
<div colspan="4">
<field name="filter" widget='radio'/>
</div>
</group>
<group>
<field name="partner_id"/>
<field name="package_id"/>
<field name="product_id" domain="[('type','=','product')]" attrs="{'invisible': [('filter', 'not in', ('product', 'product_owner'))]}"/>
<field name="lot_id" attrs="{'invisible': [('filter', '!=', 'lot')]}"/>
<field name="partner_id" attrs="{'invisible': [('filter', 'not in', ('owner', 'product_owner'))]}"/>
<field name="package_id" attrs="{'invisible': [('filter', '!=', 'pack')]}"/>
</group>
</group>
<notebook attrs="{'invisible':[('state','=','draft')]}">
@@ -148,8 +151,27 @@
</tree>
</field>
</page>
<page string="Stock Moves" attrs="{'invisible': [('state', '!=', 'done')]}">
<field name="move_ids"/>
<page string="Inventory Adjustments" attrs="{'invisible': [('state', '!=', 'done')]}">
<field name="move_ids">
<tree colors="grey:scrapped == True" string="Stock Moves">
<field name="product_id"/>
<field name="product_uom_qty" on_change="onchange_quantity(product_id, product_uom_qty, product_uom, product_uos)"/>
<field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
<field name="product_uos" groups="product.group_uos"/>
<field name="picking_id" invisible="1" />
<field name="create_date" invisible="1" />
<field name="date_expected" invisible="1" />
<button name="%(stock.move_scrap)d"
string="Scrap Products" type="action"
icon="terp-gtk-jump-to-ltr" context="{'scrap': True}"
states="draft,waiting,confirmed,assigned"
groups="base.group_user"/>
<field name="scrapped" invisible="1"/>
<field name="location_id" groups="stock.group_locations"/>
<field name="location_dest_id" groups="stock.group_locations"/>
<field name="state"/>
</tree>
</field>
</page>
</notebook>
</sheet>
@@ -158,7 +180,7 @@
</record>
<record id="action_inventory_form" model="ir.actions.act_window">
<field name="name">Physical Inventories</field>
<field name="name">Inventories Adjustment</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.inventory</field>
<field name="view_type">form</field>
@@ -177,14 +199,6 @@
</record>
<menuitem action="action_inventory_form" id="menu_action_inventory_form" parent="menu_stock_inventory_control" sequence="30"/>
<record id="action_inventory_form_draft" model="ir.actions.act_window">
<field name="name">Draft Physical Inventories</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.inventory</field>
<field name="view_type">form</field>
<field name="domain">[('state','=','draft')]</field>
<field name="filter" eval="True"/>
</record>
<menuitem id="menu_traceability" name="Traceability" parent="menu_stock_root"
sequence="3"/>
@@ -460,7 +474,7 @@
<field name="res_model">stock.move</field>
</record>
<record id="action_location_tree" model="ir.actions.act_window">
<field name="name">Location Structure</field>
<field name="name">Inventory by Location</field>
<field name="res_model">stock.location</field>
<field name="type">ir.actions.act_window</field>
<field name="domain">[('location_id','=',False)]</field>
@@ -489,11 +503,11 @@
<field name="arch" type="xml">
<form string="Warehouse" version="7.0">
<sheet>
<label for="name" class="oe_edit_only"/>
<label for="name" class="oe_edit_only" string="Warehouse Short Name"/>
<h1><field name="name"/></h1>
<group>
<group>
<field name="lot_stock_id" groups="stock.group_locations"/>
<field name="lot_stock_id" groups="stock.group_locations" string="Inventory Location"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
@@ -606,7 +620,7 @@
<tree editable="top">
<field name="product_id"/>
<field name="product_uom_id" groups="product.group_uom"/>
<field name="lot_id" groups="stock.group_production_lot"/>
<field name="lot_id" domain="[('product_id','=?', product_id)]" context="{'product_id': product_id}" groups="stock.group_production_lot"/>
<field name="package_id" groups="stock.group_tracking_lot"/>
<field name="owner_id" groups="stock.group_tracking_owner"/>
<field name="product_qty" attrs="{'required': [('product_id', '!=', False)]}"/>
@@ -1095,19 +1109,6 @@
</field>
</record>
<record model="ir.actions.act_window.view" id="action_move_reception_picking_tree">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_move_tree_reception_picking"/>
<field name="act_window_id" ref="action_reception_picking_move"/>
</record>
<record model="ir.actions.act_window.view" id="action_move_reception_picking_form">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="view_move_form"/>
<field name="act_window_id" ref="action_reception_picking_move"/>
</record>
<!-- Stock incoterms -->
<record id="view_incoterms_tree" model="ir.ui.view">
<field name="name">stock.incoterms.tree</field>
@@ -1166,47 +1167,6 @@
</record>
<record id="action_out_picking_move" model="ir.actions.act_window">
<field name="name">Deliver Products</field>
<field name="res_model">stock.move</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain" eval="['|','&amp;',('picking_id','=',False),('location_dest_id.usage', 'in', ['customer','supplier']),'&amp;',('picking_id','!=',False),('picking_type_id','=',ref('picking_type_out'))]"/>
<field name="view_id" ref="view_move_tree_reception_picking"/>
<field name="context">{'search_default_future': True}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to register a product delivery.
</p>
<p>
You will find in this list all products you have to deliver to
your customers. You can process the deliveries directly from
this list using the buttons on the right of each line. You can
filter the products to deliver by customer, products or sale
order (using the Origin field).
</p>
</field>
</record>
<record model="ir.actions.act_window.view" id="action_move_out_picking_tree">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_move_tree_reception_picking"/>
<field name="act_window_id" ref="action_out_picking_move"/>
</record>
<record model="ir.actions.act_window.view" id="action_move_out_picking_form">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="view_move_form"/>
<field name="act_window_id" ref="action_out_picking_move"/>
</record>
<menuitem action="action_reception_picking_move" id="menu_action_pdct_in" parent="menu_stock_products_moves" sequence="1"/>
<menuitem action="action_out_picking_move" id="menu_action_pdct_out" parent="menu_stock_products_moves" sequence="2"/>
<record id="view_pickingtype_filter" model="ir.ui.view">
<field name="name">stock.picking.type.filter</field>
<field name="model">stock.picking.type</field>
@@ -1264,7 +1224,7 @@
<field name="name">stock.picking.type.kanban</field>
<field name="model">stock.picking.type</field>
<field name="arch" type="xml">
<kanban version="7.0" class="oe_background_grey">
<kanban version="7.0" class="oe_background_grey" create="0">
<field name="complete_name"/>
<field name="color"/>
<field name="count_picking_ready"/>
@@ -1296,16 +1256,6 @@
</a>
</div>
<div class="oe_items_list oe_kanban_ellipsis">
<div>
<a name="%(action_picking_tree_draft)d" type="action">
<field name="count_picking_draft"/> Draft
</a>
<t t-if="record.count_picking_draft.raw_value &gt; 0">
<a name="%(action_picking_tree_draft)d" type="action">
<field name="weekly_picking" widget="stock_sparkline">Weekly Moves</field>
</a>
</t>
</div>
<div>
<a name="%(action_picking_tree_ready)d" type="action">
<field name="count_picking_ready"/> Ready
@@ -1316,14 +1266,6 @@
</a>
</t>
</div>
<div t-if="record.count_picking_waiting.raw_value &gt; 0">
<a name="%(action_picking_tree_waiting)d" type="action">
<field name="count_picking_waiting"/> Waiting
</a>
<a name="%(action_picking_tree_waiting)d" type="action" class="oe_sparkline_bar_link">
<field name="latest_picking_waiting" widget="stock_sparkline" options="{'type': 'tristate'}"/>
</a>
</div>
<div t-if="record.count_picking_late.raw_value &gt; 0">
<a name="%(action_picking_tree_late)d" type="action">
<field name="count_picking_late"/> Late
@@ -1340,6 +1282,21 @@
<field name="latest_picking_backorders" widget="stock_sparkline" options="{'type': 'tristate'}"/>
</a>
</div>
<div t-if="record.count_picking_waiting.raw_value &gt; 0">
<a name="%(action_picking_tree_waiting)d" type="action">
<field name="count_picking_waiting"/> Waiting
</a>
<a name="%(action_picking_tree_waiting)d" type="action" class="oe_sparkline_bar_link">
<field name="latest_picking_waiting" widget="stock_sparkline" options="{'type': 'tristate'}"/>
</a>
</div>
<div>
<t t-if="record.count_picking_draft.raw_value &gt; 0">
<a name="%(action_picking_tree_draft)d" type="action">
<field name="count_picking_draft"/> Draft
</a>
</t>
</div>
</div>
<div class="oe_center oe_stock_justgage">
<field name="rate_picking_late" widget="stock_gage" style="width:160px; height: 120px;">Late (%%)</field>
@@ -1355,7 +1312,7 @@
</record>
<record id="action_picking_type_form" model="ir.actions.act_window">
<field name="name">Inventory Moves</field>
<field name="name">All Operations</field>
<field name="res_model">stock.picking.type</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
@@ -1371,11 +1328,14 @@
</p>
</field>
</record>
<menuitem
action="action_picking_type_form"
id="menu_action_picking_type_form"
parent="menu_stock_warehouse_mgmt" sequence="1"/>
<!-- Order Point -->
<record id="view_warehouse_orderpoint_tree" model="ir.ui.view">
<field name="name">stock.warehouse.orderpoint.tree</field>
@@ -1528,25 +1488,27 @@
<field name="arch" type="xml">
<form string="Procurement Rules" version="7.0">
<sheet>
<div class="oe_title">
<h1>
<label string="Name"/>
<field name="name" class="oe_inline"/>
</h1>
</div>
<separator string="Pull Rule"/>
<group>
<group>
<field name="location_src_id" attrs="{'invisible': [('action', '!=', 'move')]}"/>
<field name="location_id"/>
<field name="route_id"/>
<field name="route_sequence"/>
<field name="sequence"/>
<field name="name"/>
</group>
<group>
<field name="action"/>
<field name="picking_type_id" attrs="{'required': [('action', '!=', 'manufacture')]}"/>
</group>
</group>
<separator string="Informations"/>
<group>
<group>
<field name="procure_method" attrs="{'invisible': [('action', '!=', 'move')]}"/>
<field name="group_id"/>
<field name="location_src_id" attrs="{'invisible': [('action', '!=', 'move')]}"/>
<field name="location_id"/>
</group>
<group>
<field name="picking_type_id" attrs="{'required': [('action', '!=', 'manufacture')]}"/>
<field name="route_id"/>
<field name="group_id" groups="base.group_no_one"/>
</group>
</group>
</sheet>
@@ -1645,7 +1607,7 @@
<menuitem action="procurement.procurement_exceptions" id="menu_stock_procurement_action" parent="menu_stock_sched" sequence="50" groups="stock.group_stock_manager"/>
<menuitem id="menu_stock_procurement" name="Automatic Procurements" parent="stock.menu_stock_configuration" sequence="5"/>
<menuitem action="action_orderpoint_form" id="menu_stock_order_points" parent="stock.menu_stock_configuration" sequence="10"/>
<menuitem id="menu_quants" name="Current Inventory Situation" parent="stock.menu_stock_inventory_control" sequence="20" action="quantsact"/>
<menuitem id="menu_quants" name="Current Inventory" parent="stock.menu_stock_inventory_control" sequence="20" action="quantsact"/>
<menuitem id="menu_procurement_rules" name="Procurement Rules" parent="stock.menu_stock_configuration" action="procrules" groups="base.group_no_one"/>
@@ -1870,15 +1832,15 @@
<field name="arch" type="xml">
<form string="Route" version="7.0">
<sheet>
<div class="oe_title">
<h1>
<label string="Route name"/>
</h1>
<h2>
<field name="name" class="oe_inline"/>
</h2>
</div>
<field name="sequence" groups="base.group_no_one"/>
<group string="Route">
<group>
<field name="name" class="oe_inline"/>
</group>
<group>
<field name="sequence" string="Sequence" groups="base.group_no_one"/>
</group>
</group>
<group string="Pull Rules" colspan="4" >
<field name="pull_ids" colspan="4" nolabel="1"/>
</group>
-2
View File
@@ -148,8 +148,6 @@
backorder = self.search(cr, uid, [('backorder_id.id', '=', picking.id)], context=context)
assert backorder, "Backorder should have been created"
backorder_id = self.browse(cr, uid, backorder, context=context)
self.action_confirm(cr, uid, backorder, context=context)
self.action_assign(cr, uid, backorder)
self.do_prepare_partial(cr, uid, backorder, context=context)
stock_pack = self.pool.get('stock.pack.operation').create(cr, uid, {'picking_id': backorder_id[0].id, 'product_qty': 20})
-
+47 -27
View File
@@ -59,27 +59,41 @@ class stock_quant(osv.osv):
return line.cost * line.qty
return super(stock_quant, self)._get_inventory_value(cr, uid, line, prodbrow, context=context)
# FP Note: this is where we should post accounting entries for adjustment
def _price_update(self, cr, uid, quant, newprice, context=None):
super(stock_quant, self)._price_update(cr, uid, quant, newprice, context=context)
# TODO: generate accounting entries
def _price_update(self, cr, uid, quant_ids, newprice, context=None):
if context is None:
context = {}
super(stock_quant, self)._price_update(cr, uid, quant_ids, newprice, context=context)
ctx = context.copy()
for quant in self.browse(cr, uid, quant_ids, context=context):
move = self._get_latest_move(cr, uid, quant, context=context)
ctx['force_valuation_amount'] = newprice - quant.cost
# this is where we post accounting entries for adjustment
self._account_entry_move(cr, uid, quant, move, context=ctx)
#update the standard price of the product, only if we would have done it if we'd have had enough stock at first, which means
#1) the product cost's method is 'real'
#2) we just fixed a negative quant caused by an outgoing shipment
if quant.product_id.cost_method == 'real' and quant.location_id.usage != 'internal':
self.pool.get('stock.move')._store_average_cost_price(cr, uid, move, context=context)
"""
Accounting Valuation Entries
location_from: can be None if it's a new quant
"""
def _account_entry_move(self, cr, uid, quant, location_from, location_to, move, context=None):
def _account_entry_move(self, cr, uid, quant, move, context=None):
location_from = move.location_id
location_to = move.location_dest_id
if context is None:
context = {}
if quant.product_id.valuation != 'real_time':
return False
if quant.lot_id and quant.lot_id.partner_id:
if quant.owner_id:
#if the quant isn't owned by the company, we don't make any valuation entry
return False
if quant.qty <= 0 or quant.propagated_from_id:
#we don't make any stock valuation for negative quants because we may not know the real cost price.
#The valuation will be made at the time of the reconciliation of the negative quant.
if quant.qty <= 0:
#we don't make any stock valuation for negative quants because the valuation is already made for the counterpart.
#At that time the valuation will be made at the product cost price and afterward there will be new accounting entries
#to make the adjustments when we know the real cost price.
return False
company_from = self._location_owner(cr, uid, quant, location_from, context=context)
company_to = self._location_owner(cr, uid, quant, location_to, context=context)
@@ -109,11 +123,9 @@ class stock_quant(osv.osv):
self._create_account_move_line(cr, uid, quant, move, acc_valuation, acc_dest, journal_id, context=ctx)
def move_single_quant(self, cr, uid, quant, qty, move, context=None):
location_from = quant and quant.location_id or False
quant = super(stock_quant, self).move_single_quant(cr, uid, quant, qty, move, context=context)
quant.refresh()
self._account_entry_move(cr, uid, quant, location_from, quant.location_id, move, context=context)
return quant
quant_record = super(stock_quant, self).move_single_quant(cr, uid, quant, qty, move, context=context)
self._account_entry_move(cr, uid, quant_record, move, context=context)
return quant_record
def _get_accounting_data_for_valuation(self, cr, uid, move, context=None):
"""
@@ -153,7 +165,12 @@ class stock_quant(osv.osv):
Generate the account.move.line values to post to track the stock valuation difference due to the
processing of the given quant.
"""
valuation_amount = quant.product_id.cost_method == 'real' and quant.cost or quant.product_id.standard_price
if context is None:
context = {}
if context.get('force_valuation_amount'):
valuation_amount = context.get('force_valuation_amount')
else:
valuation_amount = quant.product_id.cost_method == 'real' and quant.cost or quant.product_id.standard_price
partner_id = (move.picking_id.partner_id and self.pool.get('res.partner')._find_accounting_partner(move.picking_id.partner_id).id) or False
debit_line_vals = {
'name': move.name,
@@ -163,7 +180,8 @@ class stock_quant(osv.osv):
'ref': move.picking_id and move.picking_id.name or False,
'date': time.strftime('%Y-%m-%d'),
'partner_id': partner_id,
'debit': valuation_amount * quant.qty,
'debit': valuation_amount > 0 and valuation_amount * quant.qty or 0,
'credit': valuation_amount < 0 and -valuation_amount * quant.qty or 0,
'account_id': debit_account_id,
}
credit_line_vals = {
@@ -174,7 +192,8 @@ class stock_quant(osv.osv):
'ref': move.picking_id and move.picking_id.name or False,
'date': time.strftime('%Y-%m-%d'),
'partner_id': partner_id,
'credit': valuation_amount * quant.qty,
'credit': valuation_amount > 0 and valuation_amount * quant.qty or 0,
'debit': valuation_amount < 0 and -valuation_amount * quant.qty or 0,
'account_id': credit_account_id,
}
res = [(0, 0, debit_line_vals), (0, 0, credit_line_vals)]
@@ -187,16 +206,17 @@ class stock_quant(osv.osv):
'line_id': move_lines,
'ref': move.picking_id and move.picking_id.name}, context=context)
def _reconcile_single_negative_quant(self, cr, uid, to_solve_quant, quant, quant_neg, qty, context=None):
move = self._get_latest_move(cr, uid, to_solve_quant, context=context)
quant_neg_position = quant_neg.negative_dest_location_id.usage
remaining_to_solve_quant = super(stock_quant, self)._reconcile_single_negative_quant(cr, uid, to_solve_quant, quant, quant_neg, qty, context=context)
#update the standard price of the product, only if we would have done it if we'd have had enough stock at first, which means
#1) there isn't any negative quant anymore
#2) the product cost's method is 'real'
#3) we just fixed a negative quant caused by an outgoing shipment
if not remaining_to_solve_quant and move.product_id.cost_method == 'real' and quant_neg_position != 'internal':
self.pool.get('stock.move')._store_average_cost_price(cr, uid, move, context=context)
#def _reconcile_single_negative_quant(self, cr, uid, to_solve_quant, quant, quant_neg, qty, context=None):
# move = self._get_latest_move(cr, uid, to_solve_quant, context=context)
# quant_neg_position = quant_neg.negative_dest_location_id.usage
# remaining_solving_quant, remaining_to_solve_quant = super(stock_quant, self)._reconcile_single_negative_quant(cr, uid, to_solve_quant, quant, quant_neg, qty, context=context)
# #update the standard price of the product, only if we would have done it if we'd have had enough stock at first, which means
# #1) there isn't any negative quant anymore
# #2) the product cost's method is 'real'
# #3) we just fixed a negative quant caused by an outgoing shipment
# if not remaining_to_solve_quant and move.product_id.cost_method == 'real' and quant_neg_position != 'internal':
# self.pool.get('stock.move')._store_average_cost_price(cr, uid, move, context=context)
# return remaining_solving_quant, remaining_to_solve_quant
class stock_move(osv.osv):
_inherit = "stock.move"
+5 -4
View File
@@ -41,15 +41,16 @@ class stock_location_route(osv.osv):
class stock_warehouse(osv.osv):
_inherit = 'stock.warehouse'
_columns = {
'route_id': fields.many2one('stock.location.route', 'Default Route', domain="[('warehouse_selectable', '=', True)]", help='Default route through the warehouse'),
'route_id': fields.many2one('stock.location.route', 'Default Delivery Route', domain="[('warehouse_selectable', '=', True)]", help='Default route through the warehouse'),
}
class stock_location_path(osv.osv):
_name = "stock.location.path"
_description = "Pushed Flows"
_order = "name"
_columns = {
'name': fields.char('Operation', size=64, required=True),
'name': fields.char('Operation Name', size=64, required=True),
'company_id': fields.many2one('res.company', 'Company'),
'route_id': fields.many2one('stock.location.route', 'Route'),
'location_from_id': fields.many2one('stock.location', 'Source Location', ondelete='cascade', select=1, required=True),
@@ -60,7 +61,7 @@ class stock_location_path(osv.osv):
("2binvoiced", "To Be Invoiced"),
("none", "Not Applicable")], "Invoice Status",
required=True,),
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type', required=True, help="This is the picking type associated with the different pickings"),
'picking_type_id': fields.many2one('stock.picking.type', 'Type of the new Operation', required=True, help="This is the picking type associated with the different pickings"),
'auto': fields.selection(
[('auto','Automatic Move'), ('manual','Manual Operation'),('transparent','Automatic No Step Added')],
'Automatic Move',
@@ -113,7 +114,7 @@ class procurement_rule(osv.osv):
_inherit = 'procurement.rule'
_columns = {
'delay': fields.integer('Number of Hours'),
'delay': fields.integer('Number of Days'),
'partner_address_id': fields.many2one('res.partner', 'Partner Address'),
'propagate': fields.boolean('Propagate cancel and split', help='If checked, when the previous move of the move (which was generated by a next procurement) is cancelled or split, the move generated by this move will too'),
}
+34 -22
View File
@@ -7,11 +7,14 @@
<field name="model">procurement.rule</field>
<field name="inherit_id" ref="stock.view_procurement_rule_form"/>
<field name="arch" type="xml">
<field name="location_id" position="after">
<field name="delay"/>
<field name="propagate"/>
<field name="group_id" position="after">
<field name="propagate"/>
<label for="delay" string="Delay"/>
<div>
<field name="delay" class="oe_inline"/>days
</div>
</field>
<field name="group_id" position="before">
<field name="location_id" position="after">
<field name="partner_address_id"/>
</field>
</field>
@@ -101,15 +104,20 @@
<field name="arch" type="xml">
<form string="Location Paths" version="7.0">
<group col="4">
<field name="name"/>
<newline />
<field name="company_id" groups="base.group_multi_company" />
<newline />
<field name="location_from_id"/>
<field name="location_dest_id"/>
<field name="picking_type_id"/>
<field name="auto"/>
<field name="delay"/>
<group>
<field name="name"/>
<field name="location_from_id"/>
<field name="location_dest_id"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company" />
<field name="picking_type_id"/>
<field name="auto"/>
<label for="delay" string="Delay"/>
<div>
<field name="delay" class="oe_inline"/>days
</div>
</group>
</group>
</form>
</field>
@@ -125,7 +133,6 @@
<group string="Routes" colspan="4">
<div class="oe_inline">
<p attrs="{'invisible':[('route_ids','=',False)]}">
The routes on this category are:
<field name="route_ids" nolabel="1" widget="many2many_tags" class="oe_inline"/>
</p>
<p attrs="{'invisible':[('parent_id','=',False)]}">
@@ -140,7 +147,7 @@
Removal strategies define the method used for suggesting the
location to take the products from
</p>
<field name="removal_strategy_ids" class ="oe_inline">
<field name="removal_strategy_ids">
<tree editable="bottom" string="removal">
<field name="location_id"/>
<field name="method"/>
@@ -156,7 +163,7 @@
Putaway strategies define the method used for suggesting the
location to put the products
</p>
<field name="putaway_strategy_ids" class="oe_inline">
<field name="putaway_strategy_ids">
<tree string="Put Away" editable="bottom">
<field name="location_id"/>
<field name="method"/>
@@ -175,7 +182,10 @@
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="after">
<field name="route_id" attrs="{'invisible': [('route_id', '=', False)]}"/>
<button name="%(action_view_stock_configure_wh)d" string="Configure this warehouse" type="action" attrs="{'invisible': [('route_id', '!=', False)]}"/>
</xpath>
<xpath expr="//group[last()]" position="after">
<button name="%(action_view_stock_configure_wh)d" class="oe_right oe_highlight" string="Configure this warehouse" type="action" attrs="{'invisible': [('route_id', '!=', False)]}"/>
</xpath>
</field>
</record>
@@ -199,14 +209,16 @@
<field name="model">stock.location.route</field>
<field name="inherit_id" ref="stock.stock_location_route_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='sequence']" position="after">
<group>
<xpath expr="//group[@string='Pull Rules']" position="before">
<separator string="Applicable On"/>
<p class="oe_grey">Check these box so that the user can select this route during the following operations</p>
<group>
<group>
<field name="product_categ_selectable"/>
<field name="product_selectable"/>
<field name="product_categ_selectable" string="Product Categories"/>
<field name="product_selectable" string="Products"/>
</group>
<group>
<field name="warehouse_selectable"/>
<field name="warehouse_selectable" string="Warehouses"/>
</group>
</group>
<group string="Push Rules" colspan="4" >
@@ -1,3 +1,6 @@
-
!context
noupdate: 1
-
Create Two Customers
-