#TODO Review materials in function in_prod and prod_end.
def action_production_end(self, cr, uid, ids):
--# move_ids = []
++ move_ids = []
for production in self.browse(cr, uid, ids):
for res in production.move_lines:
for move in production.move_created_ids:
cr.execute('INSERT INTO stock_move_history_ids \
(parent_id, child_id) VALUES (%s,%s)',
(res.id, move.id))
--# move_ids.append(res.id)
++ move_ids.append(res.id)
vals= {'state':'confirmed'}
new_moves = [x.id for x in production.move_created_ids]
self.pool.get('stock.move').write(cr, uid, new_moves, vals)
return amount
def action_in_production(self, cr, uid, ids):
-- move_ids = []
-- for production in self.browse(cr, uid, ids):
-- for res in production.move_lines:
-- move_ids.append(res.id)
-- if not production.date_start:
-- self.write(cr, uid, [production.id],
-- {'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
- self.pool.get('stock.move').action_done(cr, uid, move_ids)
-# self.pool.get('stock.move').action_done(cr, uid, move_ids)
++ move_ids = []
self.write(cr, uid, ids, {'state': 'in_production'})
return True
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', m, 'button_wait_done', cr)
return True
+
- def _track_lines(self, cr, uid, ids, data, context=None):
- production_ids = []
- new_move = super(StockMove, self)._track_lines(cr, uid, ids, data, context=context)
- if new_move:
- production_obj = self.pool.get('mrp.production')
- move_obj = self.pool.get('stock.move')
- move = move_obj.browse(cr, uid, ids)
- production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
- for new in new_move:
- production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new)]})
- move_obj.action_done(cr, uid, [new])
- return {}
+
+ def consume_moves(self, cr, uid, ids, product_qty, location_id, context=None):
- new_move = super(StockMove, self).consume_moves(cr, uid, ids, product_qty, location_id, context=context)
- if new_move:
- production_obj = self.pool.get('mrp.production')
- move_obj = self.pool.get('stock.move')
- move = move_obj.browse(cr, uid, ids)
++ res = []
++ production_obj = self.pool.get('mrp.production')
++ for move in self.browse(cr, uid, ids):
++ new_moves = super(StockMove, self).consume_moves(cr, uid, ids, product_qty, location_id, context=context)
+ production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
- production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
- return {}
++ for new_move in new_moves:
++ production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
++ res.append(new_move)
++ return res
++
++ def split_lines(self, cr, uid, ids, quantity, split_by_qty=1, prefix=False, context=None):
++ res = []
++ production_obj = self.pool.get('mrp.production')
++ for move in self.browse(cr, uid, ids):
++ new_moves = super(StockMove, self).split_lines(cr, uid, [move.id], quantity, split_by_qty, prefix, context=context)
++ production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
++ for new_move in new_moves:
++ production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
++ res.append(new_move)
++ return res
+
- def scrap_moves(self, cr, uid, ids, product_qty, location_id, context=None):
- new_move = super(StockMove, self).scrap_moves(cr, uid, ids, product_qty, location_id, context=context)
- if new_move:
- production_obj = self.pool.get('mrp.production')
- move_obj = self.pool.get('stock.move')
- move = move_obj.browse(cr, uid, ids)
++ def scrap_moves(self, cr, uid, ids, quantity, location_dest_id, context=None):
++ res = []
++ production_obj = self.pool.get('mrp.production')
++ for move in self.browse(cr, uid, ids):
++ new_moves = super(StockMove, self).scrap_moves(cr, uid, [move.id], quantity, location_dest_id, context=context)
+ production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
- production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
- return {}
++ for new_move in new_moves:
++ production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
++ res.append(new_move)
++ return res
+
StockMove()
StockPicking()
++
++class spilt_in_production_lot(osv.osv_memory):
++ _inherit = "stock.move.spilt"
++ def split(self, cr, uid, ids, move_ids, context=None):
++ production_obj = self.pool.get('mrp.production')
++ move_obj = self.pool.get('stock.move')
++ res = []
++ for move in move_obj.browse(cr, uid, move_ids, context=context):
++ new_moves = super(spilt_in_production_lot, self).split(cr, uid, ids, move_ids, context=context)
++ production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
++ for new_move in new_moves:
++ production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
++ return res
++spilt_in_production_lot()
++
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<field name="state" select="2"/>
<button name="action_compute" states="draft" string="Compute Data" type="object" icon="gtk-execute"/>
<button name="button_confirm" states="draft" string="Confirm Production" icon="gtk-apply"/>
- <button name="button_produce" states="ready" string="Start Production" icon="gtk-media-play"/>
- <button name="button_produce_done" states="in_production" string="Production done" icon="gtk-ok"/>
-<!-- <button name="action_start" states="ready" string="Mark as Start" icon="gtk-media-play" type="object"/>-->
- <button name="button_produce" states="ready" string="Produce" icon="gtk-execute"/>
- <button name="button_produce_done" states="in_production" string="Production done" icon="gtk-ok"/>
++ <button name="button_produce" states="ready" string="Mark as Start" icon="gtk-execute"/>
++ <button name="button_produce_done" states="in_production" string="Production" icon="gtk-ok"/>
<button name="force_production" states="confirmed,picking_except" string="Force Reservation" type="object" icon="gtk-jump-to"/>
<button name="button_cancel" states="draft,ready,confirmed,in_production,picking_except" string="Cancel" icon="gtk-cancel"/>
<button name="button_recreate" states="picking_except" string="Recreate Picking" icon="gtk-convert"/>
"stock_data.xml",
"stock_incoterms.xml",
"stock_wizard.xml",
- "stock_osv_wizards.xml",
++ "stock_wizard_view.xml",
"stock_view.xml",
"stock_report.xml",
"stock_sequence.xml",
def name_get(self, cr, uid, ids, context={}):
if not ids:
return []
-- reads = self.read(cr, uid, ids, ['name', 'ref'], context)
++ reads = self.read(cr, uid, ids, ['name', 'prefix', 'ref'], context)
res = []
for record in reads:
name = record['name']
++ prefix = record['prefix']
++ if prefix:
++ name = prefix + '/' + name
if record['ref']:
-- name = name + '/' + record['ref']
++ name = '%s [%s]' % (name, record['ref'])
res.append((record['id'], name))
return res
_columns = {
'name': fields.char('Serial', size=64, required=True),
-- 'ref': fields.char('Internal Reference', size=64),
++ 'ref': fields.char('Internal Reference', size=256),
++ 'prefix': fields.char('Prefix', size=64),
'product_id': fields.many2one('product.product', 'Product', required=True),
'date': fields.datetime('Created Date', required=True),
'stock_available': fields.function(_get_stock, fnct_search=_stock_search, method=True, type="float", string="Available", select="2"),
stock_production_lot()
--class stock_split_production_lots(osv.osv_memory):
-- _name = "stock.split.production.lots"
-- _description = "Split Production Lots"
--
-- def _quantity_default_get(self, cr, uid, object=False, field=False, context=None):
-- cr.execute("select %s from %s where id=%s" %(field,object,context.get('active_id')))
-- res = cr.fetchone()[0]
-- return res
--
-- _columns = {
-- 'name': fields.char('Lot Number/Prefix', size=64, required=True),
-- 'qty': fields.float('Total Quantity'),
-- 'action': fields.selection([('split','Split'),('keepinone','Keep in one lot')],'Action'),
-- }
-- _defaults = {
-- 'qty': lambda self,cr,uid,c: self.pool.get('stock.split.production.lots')._quantity_default_get(cr, uid, 'stock_move', 'product_qty',context=c) or 1,
-- }
--
-- def split_lines(self, cr, uid, ids, context={}):
-- data = self.read(cr, uid, ids[0])
-- prodlot_obj = self.pool.get('stock.production.lot')
-- move_obj = self.pool.get('stock.move')
-- move_browse = move_obj.browse(cr, uid, context['active_id'])
--
-- quantity = data['qty']
-- if quantity <= 0 or move_browse.product_qty == 0:
-- return {}
-- uos_qty = quantity/move_browse.product_qty*move_browse.product_uos_qty
--
-- quantity_rest = move_browse.product_qty%quantity
-- uos_qty_rest = quantity_rest/move_browse.product_qty*move_browse.product_uos_qty
--
-- update_val = {
-- 'product_qty': quantity,
-- 'product_uos_qty': uos_qty,
-- }
--
-- new_move = []
-- for idx in range(int(move_browse.product_qty//quantity)):
-- if idx:
-- current_move = move_obj.copy(cr, uid, move_browse.id, {'state': move_browse.state})
-- new_move.append(current_move)
-- else:
-- current_move = move_browse.id
-- new_prodlot = prodlot_obj.create(cr, uid, {'name': data['name'], 'ref': '%d'%idx}, {'product_id': move_browse.product_id.id})
-- update_val['prodlot_id'] = new_prodlot
-- move_obj.write(cr, uid, [current_move], update_val)
--
-- if quantity_rest > 0:
-- idx = int(move_browse.product_qty//quantity)
-- update_val['product_qty'] = quantity_rest
-- update_val['product_uos_qty'] = uos_qty_rest
-- if idx:
-- current_move = move_obj.copy(cr, uid, move_browse.id, {'state': move_browse.state})
-- new_move.append(current_move)
-- else:
-- current_move = move_browse.id
-- new_prodlot = prodlot_obj.create(cr, uid, {'name': data['name'], 'ref': '%d'%idx}, {'product_id': move_browse.product_id.id})
-- update_val['prodlot_id'] = new_prodlot
-- move_obj.write(cr, uid, [current_move], update_val)
--
-- return {}
--
--stock_split_production_lots()
--
--
class stock_production_lot_revision(osv.osv):
_name = 'stock.production.lot.revision'
_description = 'Production lot revisions'
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 _track_lines(self, cr, uid, ids, lines, context=None):
++ def split_lines(self, cr, uid, ids, quantity, split_by_qty=1, prefix=False, context=None):
+ prodlot_obj = self.pool.get('stock.production.lot')
+ ir_sequence_obj = self.pool.get('ir.sequence')
++
+ sequence = ir_sequence_obj.get(cr, uid, 'stock.lot.serial')
+ if not sequence:
- raise osv.except_osv(_('Error!'), _('No production sequence defined'))
++ 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
++
++ for move in self.browse(cr, uid, ids):
++ if split_by_qty <= 0 or quantity == 0:
++ return res
++
++ uos_qty = split_by_qty / move.product_qty * move.product_uos_qty
++
++ quantity_rest = quantity % split_by_qty
++ uos_qty_rest = split_by_qty / move.product_qty * move.product_uos_qty
++
++ update_val = {
++ 'product_qty': split_by_qty,
++ 'product_uos_qty': uos_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:
++ current_move = move.id
++
+
- move = self.browse(cr, uid, [ids])[0]
- move_qty = move.product_qty
- quantity_rest = move.product_qty
- uos_qty_rest = move.product_uos_qty
- new_move = []
- cnt = 0
++ update_val['prodlot_id'] = _create_lot(current_move, move.product_id.id)
++ self.write(cr, uid, [current_move], update_val)
++
++
++ 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 idx:
++ current_move = self.copy(cr, uid, move.id, {'state': move.state})
++ new_move.append(current_move)
++ else:
++ current_move = move.id
++ update_val['prodlot_id'] = _create_lot(current_move, move.product_id.id)
++ self.write(cr, uid, [current_move], update_val)
++ return new_move
+
- for line in lines:
- quantity = line['quantity']
- sequence = (line['tracking_num'] and line['tracking_num'] + '/' \
- + sequence) or sequence
++ def consume_moves(self, cr, uid, ids, quantity, location_id, context=None):
++ new_move = []
++ if not context:
++ context = {}
++ if quantity <= 0:
++ raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
++
++ for move in self.browse(cr, uid, ids, context=context):
++ move_qty = move.product_qty
++ quantity_rest = move.product_qty
+
- if quantity <= 0 or move_qty == 0:
- continue
+ 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,
- 'state': move.state
++ 'product_uos_qty': uos_qty,
++ 'location_id' : location_id,
+ }
- current_move = self.copy(cr, uid, move.id, default_val)
- new_move.append(current_move)
- new_prodlot = prodlot_obj.create(cr, uid, {'name': sequence,
- 'ref': '%d' % (cnt)},
- {'product_id': move.product_id.id})
- self.write(cr, uid, [current_move], {'prodlot_id': new_prodlot})
- cnt += 1
-
- if quantity_rest > 0:
- new_prodlot = prodlot_obj.create(cr, uid, {'name': sequence,
- 'ref': '%d' % (cnt)},
- {'product_id': move.product_id.id})
- update_val= {'prodlot_id': new_prodlot,
- 'product_qty': quantity_rest,
- 'product_uos_qty': uos_qty_rest
- }
- self.write(cr, uid, [move.id], update_val)
++ 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:
++ update_val['product_qty'] = quantity_rest
++ update_val['product_uos_qty'] = uos_qty_rest
++ self.write(cr, uid, [move.id], update_val)
++
++ self.action_done(cr, uid, new_move)
+ return new_move
+
- def consume_moves(self, cr, uid, ids, product_qty, location_id, context=None):
- new_move = None
- if not context:
- context = {}
- qty = product_qty
- if qty <= 0:
++ def scrap_moves(self, cr, uid, ids, quantity, location_dest_id, context=None):
++ new_move = []
++ if quantity <= 0:
+ raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
+
- move = self.browse(cr, uid, ids, context=context)
- move_qty = move.product_qty
-
- if qty > move_qty:
- qty = move_qty
- rest = 0
-
- if qty <= move_qty:
- rest= move_qty - qty
- vals = {
- 'product_qty' : qty,
- 'product_uos_qty': qty,
- 'location_id': location_id
- }
- track = move.product_id.track_production
- self.write(cr, uid, move.id, vals)
- if track:
- data = [{'tracking_num': '', 'quantity': 1}]
- newmoves = self._track_lines(cr, uid, ids, data*int(math.floor(qty)), context=None)
- self.action_done(cr, uid, [move.id])
-
- if rest:
- defaults = {'product_qty': rest,
- 'product_uos_qty': rest,
- 'state': move.state}
- new_move = self.copy(cr, uid, move.id, default=defaults)
- return new_move
++ 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
+
- def scrap_moves(self, cr, uid, ids, product_qty, location_id, context=None):
- new_move = None
- qty = product_qty
- if qty <= 0:
- raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
++ 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
+
- move = self.browse(cr, uid, ids, context=context)
- location = move.location_dest_id.id
- move_qty = move.product_qty
-
- if qty > move_qty:
- qty = move_qty
- rest = 0
-
- if qty <= move_qty:
- rest= move_qty - qty
- vals = {
- 'product_qty': qty,
- 'state': move.state,
- 'location_dest_id': location_id
- }
- self.write(cr, uid, ids, vals)
-
- if rest:
- defaults = {'product_qty': rest,
- 'product_uos_qty': rest,
- 'location_dest_id': location,
- 'state': move.state}
- new_move = self.copy(cr, uid, move.id, default=defaults)
++ 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
stock_move()
<page string="Production Lot">
<field name="name" select="1"/>
<field name="ref" select="2"/>
++ <field name="prefix" select="1"/>
<field name="product_id" select="1"/>
<field name="stock_available"/>
<field name="date" select="2"/>
<field name="auto_refresh" eval="1"/>
<field name="target">new</field>
<field name="context">{'action_id': active_id}</field>
-- </record>
--
--
-- <record id="view_stock_split_production_lots" model="ir.ui.view">
-- <field name="name">Split Production Lots</field>
-- <field name="model">stock.split.production.lots</field>
-- <field name="type">form</field>
-- <field name="arch" type="xml">
-- <form string="Split Production Lots">
-- <group col="4" colspan="4">
-- <field name="name"/>
-- <field name="qty" attrs="{'readonly':[('action','!=','split')]}"/>
-- <field name="action" colspan="4"/>
-- </group>
-- <newline/>
-- <button name="split_lines" string="Ok" type="object" icon="gtk-go-forward"/>
-- </form>
-- </field>
-- </record>
--
-- <record id="action_view_stock_split_production_lots" model="ir.actions.act_window">
-- <field name="name">Split Production Lots</field>
-- <field name="type">ir.actions.act_window</field>
-- <field name="res_model">stock.split.production.lots</field>
-- <field name="view_type">form</field>
-- <field name="view_mode">form</field>
-- <field name="target">new</field>
-- </record>
++ </record>
<record model="ir.ui.view" id="stock_picking_calendar">
<field name="name">stock.picking.calendar</field>
<notebook colspan="4">
<page string="General Information">
<field colspan="4" name="move_lines" nolabel="1" widget="one2many_list" default_get="{'move_line':move_lines, 'address_out_id': address_id}">
++ <tree colors="grey:state in ('cancel');black:state not in ('cancel')" string="Stock Moves">
++ <field name="name" string="Move Name"/>
++ <field name="product_id"/>
++ <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
++ <field name="product_uom" string="UOM"/>
++ <field name="picking_id" select="1"/>
++ <field name="prodlot_id"/>
++ <field name="location_id"/>
++ <field name="location_dest_id"/>
++ <field name="date_planned"/>
++ <field name="state"/>
++ <button
++ name="%(stock.track_line)d"
++ string="Split in production lots"
++ type="action" icon="gtk-justify-fill"
++ states="done,cancel" />
++ <button
++ name="%(stock.move_scrap)d"
++ string="D" type="action"
++ icon="gtk-convert"
++ states="done,cancel" />
++ </tree>
<form string="Stock Moves">
<notebook colspan="4">
<page string="General Information">
<newline/>
<label/>
<button name="%(track_line)d" string="Split in production lots" type="action" icon="gtk-justify-fill"/>
++ <button name="%(move_scrap)d" string="Scrap Move Line" type="action" icon="gtk-justify-fill"/>
<separator colspan="4" string="Move State"/>
<field name="state" select="1"/>
<group>
<notebook colspan="4">
<page string="General Information">
<field colspan="4" name="move_lines" nolabel="1" widget="one2many_list" default_get="{'move_line':move_lines, 'address_out_id': address_id}">
++ <tree colors="grey:state in ('cancel');black:state not in ('cancel')" string="Stock Moves">
++ <field name="name" string="Move Name"/>
++ <field name="product_id"/>
++ <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
++ <field name="product_uom" string="UOM"/>
++ <field name="picking_id" select="1"/>
++ <field name="prodlot_id"/>
++ <field name="location_id"/>
++ <field name="location_dest_id"/>
++ <field name="date_planned"/>
++ <field name="state"/>
++ <button
++ name="%(stock.track_line)d"
++ string="Split in production lots"
++ type="action" icon="gtk-justify-fill"
++ states="done,cancel" />
++ <button
++ name="%(stock.move_scrap)d"
++ string="D" type="action"
++ icon="gtk-convert"
++ states="done,cancel" />
++ </tree>
<form string="Stock Moves">
<notebook colspan="4">
<page string="General Information">
<notebook colspan="4">
<page string="General Information">
<field colspan="4" name="move_lines" nolabel="1" widget="one2many_list" default_get="{'move_line':move_lines, 'address_out_id': address_id}">
++ <tree colors="grey:state in ('cancel');black:state not in ('cancel')" string="Stock Moves">
++ <field name="name" string="Move Name"/>
++ <field name="product_id"/>
++ <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
++ <field name="product_uom" string="UOM"/>
++ <field name="picking_id" select="1"/>
++ <field name="prodlot_id"/>
++ <field name="location_id"/>
++ <field name="location_dest_id"/>
++ <field name="date_planned"/>
++ <field name="state"/>
++ <button
++ name="%(stock.track_line)d"
++ string="Split in production lots"
++ type="action" icon="gtk-justify-fill"
++ states="done,cancel" />
++ <button
++ name="%(stock.move_scrap)d"
++ string="D" type="action"
++ icon="gtk-convert"
++ states="done,cancel" />
++ </tree>
<form string="Stock Moves">
<notebook colspan="4">
<page string="General Information">
<notebook colspan="4">
<page string="General Information">
<field colspan="4" name="move_lines" nolabel="1" widget="one2many_list" default_get="{'move_line':move_lines, 'address_in_id': address_id}">
-- <tree string="Stock Moves">
++ <tree colors="grey:state in ('cancel');black:state not in ('cancel')" string="Stock Moves">
<field name="product_id"/>
<field name="product_qty"/>
<field name="product_uom"/>
<field name="location_dest_id"/>
<field name="prodlot_id"/>
<field name="state"/>
-- </tree>
++ <button
++ name="%(stock.track_line)d"
++ string="Split in production lots"
++ type="action" icon="gtk-justify-fill"
++ states="done,cancel" />
++ <button
++ name="%(stock.move_scrap)d"
++ string="D" type="action"
++ icon="gtk-convert"
++ states="done,cancel" />
++ </tree>
<form string="Stock Moves">
<notebook colspan="4">
<page string="General Information">
<field name="location_id"/>
<field name="location_dest_id"/>
<field name="date_planned"/>
-- <field name="state"/>
++ <field name="state"/>
</tree>
</field>
</record>
--- /dev/null
+ # -*- coding: utf-8 -*-
+ ##############################################################################
+ #
+ # OpenERP, Open Source Management Solution
+ # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+ #
+ # This program is free software: you can redistribute it and/or modify
+ # it under the terms of the GNU Affero General Public License as
+ # published by the Free Software Foundation, either version 3 of the
+ # License, or (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU Affero General Public License for more details.
+ #
+ # You should have received a copy of the GNU Affero General Public License
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
+ #
+ ##############################################################################
+
+ from osv import fields, osv
+ from tools.translate import _
+
+ class stock_move_track(osv.osv_memory):
+ _name = "stock.move.track"
+ _description = "Track moves"
+
+ _columns = {
+ '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')
+ move_obj._track_lines(cr, uid, context['active_id'], datas, context=context)
+ return {}
+
+ 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),
- 'location_id': fields.many2one('stock.location', 'Source Location', 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,
+ 'location_id': _get_location_id
+ }
+
+ def do_move_consume(self, cr, uid, ids, context={}):
- datas = self.read(cr, uid, ids)[0]
+ move_obj = self.pool.get('stock.move')
- move_obj.consume_moves(cr, uid, context['active_id'],
- datas['product_qty'], datas['location_id'],
- context=context)
++ 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'],
++ context=context)
+ return {}
+
+ stock_move_consume()
+
+
+ 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={}):
- datas = self.read(cr, uid, ids)[0]
- move_obj = self.pool.get('stock.move')
- move_obj.scrap_moves(cr, uid, context['active_id'],
- datas['product_qty'], datas['location_id'],
- context=context)
++ 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'],
++ context=context)
+ return {}
+
+ stock_move_scrap()
+
+
-class spilt_in_lot(osv.osv_memory):
- _name = "spilt.in.lot"
- _description = "Split in lots"
++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('track.lines', 'lot_id', 'Lots Number')
- }
++ '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,
+ }
-
++
+ def split_lot(self, cr, uid, ids, context=None):
- datas = self.read(cr, uid, ids)[0]
- lines = []
- for line in self.pool.get('track.lines').browse(cr, uid, datas.get('line_ids', [])):
- lines.append({'tracking_num': line.name, 'quantity': line.quantity})
- move_obj = self.pool.get('stock.move')
- move_obj._track_lines(cr, uid, context['active_id'], lines, context=context)
++ self.split(cr, uid, ids, context.get('active_ids'), context=context)
+ return {}
+
-spilt_in_lot()
-
-class track_lines(osv.osv_memory):
- _name = "track.lines"
- _description = "Track lines"
++ def split(self, cr, uid, ids, move_ids, context=None):
++ 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 = []
++ 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 = []
++ for line in data.line_ids:
++ quantity = line.quantity
++
++
++ if quantity <= 0 or move_qty == 0:
++ continue
++ 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,
++ '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]
++ 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})
++ move_obj.write(cr, uid, [current_move], {'prodlot_id': prodlot_id})
++ prodlot = prodlot_obj.browse(cr, uid, prodlot_id)
++ ref = '%d' % (current_move)
++ if prodlot.ref:
++ ref = '%s, %s' % (prodlot.ref, ref)
++ prodlot_obj.write(cr, uid, [prodlot_id], {'ref': ref})
++
++ update_val = {}
++ if quantity_rest > 0:
++ update_val['product_qty'] = quantity_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'),
- 'lot_id': fields.many2one('spilt.in.lot', 'Lot')
- }
++ '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',
++ }
+
-track_lines()
++stock_move_spilt_lines()
--- /dev/null
--- /dev/null
++<?xml version="1.0" encoding="utf-8"?>
++<openerp>
++ <data>
++
++ <record id="view_stock_move_track_wizard" model="ir.ui.view">
++ <field name="name">Tracking a move</field>
++ <field name="model">stock.move.track</field>
++ <field name="type">form</field>
++ <field name="arch" type="xml">
++ <form string="Tracking a move">
++ <field name="tracking_prefix" colspan="4"/>
++ <field name="quantity" colspan="4"/>
++ <newline/>
++ <separator string="" colspan="4" />
++ <button icon='gtk-cancel' special="cancel"
++ string="Cancel" />
++ <button name="track_lines" string="Ok"
++ type="object" icon="gtk-ok" />
++ </form>
++ </field>
++ </record>
++
++ <record id="track_line_old" model="ir.actions.act_window">
++ <field name="name">Tracking a move</field>
++ <field name="type">ir.actions.act_window</field>
++ <field name="res_model">stock.move.track</field>
++ <field name="view_type">form</field>
++ <field name="view_mode">form</field>
++ <field name="target">new</field>
++ </record>
++
++
++ <!-- Consume, scrap move -->
++
++ <record id="view_stock_move_consume_wizard" model="ir.ui.view">
++ <field name="name">Consume Move</field>
++ <field name="model">stock.move.consume</field>
++ <field name="type">form</field>
++ <field name="arch" type="xml">
++ <form string="Consume Move">
++ <separator string="Consume Products" colspan="4"/>
++ <field name="product_id" colspan="4" readonly="1"/>
++ <field name="location_id" colspan="4"/>
++ <field name="product_qty" colspan="2"/>
++ <field name="product_uom" nolabel="1" readonly="1"/>
++ <newline/>
++ <separator string="" colspan="4" />
++ <label string="" colspan="2" />
++ <group col="2" colspan="1">
++ <button icon='gtk-cancel' special="cancel"
++ string="Cancel" />
++ <button name="do_move_consume" string="Ok"
++ colspan="1" type="object" icon="gtk-ok" />
++ </group>
++ </form>
++ </field>
++ </record>
++
++ <record id="move_consume" model="ir.actions.act_window">
++ <field name="name">Consume Move</field>
++ <field name="type">ir.actions.act_window</field>
++ <field name="res_model">stock.move.consume</field>
++ <field name="view_type">form</field>
++ <field name="view_mode">form</field>
++ <field name="target">new</field>
++ </record>
++
++ <record id="view_stock_move_scrap_wizard" model="ir.ui.view">
++ <field name="name">Scrap Move</field>
++ <field name="model">stock.move.scrap</field>
++ <field name="type">form</field>
++ <field name="arch" type="xml">
++ <form string="Scrap Move">
++ <separator string="Scrap Products" colspan="4"/>
++ <field name="product_id" colspan="4" readonly="1"/>
++ <field name="location_id" colspan="4" string="Dest. Location" domain="[('usage','<>','view')]"/>
++ <field name="product_qty" colspan="2"/>
++ <field name="product_uom" nolabel="1" readonly="1"/>
++ <newline/>
++ <separator string="" colspan="4" />
++ <label string="" colspan="2" />
++ <group col="2" colspan="1">
++ <button icon='gtk-cancel' special="cancel"
++ string="Cancel" />
++ <button name="move_scrap" string="Ok"
++ colspan="1" type="object" icon="gtk-ok" />
++ </group>
++ </form>
++ </field>
++ </record>
++
++ <record id="move_scrap" model="ir.actions.act_window">
++ <field name="name">Scrap Move</field>
++ <field name="type">ir.actions.act_window</field>
++ <field name="res_model">stock.move.scrap</field>
++ <field name="view_type">form</field>
++ <field name="view_mode">form</field>
++ <field name="target">new</field>
++ </record>
++
++ <record id="view_split_in_lots" model="ir.ui.view">
++ <field name="name">Split in lots</field>
++ <field name="model">stock.move.spilt</field>
++ <field name="type">form</field>
++ <field name="arch" type="xml">
++ <form string="Split in lots">
++ <field name="product_id" colspan="4" readonly="1"/>
++ <newline/>
++ <field name="line_ids" colspan="4" nolabel="1">
++ <tree string="Lots Number" editable="top">
++ <field name="name" string="Lots"/>
++ <field name="quantity" />
++ <field name="use_exist" />
++ </tree>
++ <form string="Lots Number">
++ <field name="name" string="Lots"/>
++ <field name="quantity" />
++ <field name="use_exist" />
++ </form>
++ </field>
++ <separator string="" colspan="4" />
++ <label string="" colspan="2" />
++ <button icon='gtk-cancel' special="cancel"
++ string="Cancel" />
++ <button name="split_lot" string="Ok"
++ type="object" icon="gtk-ok" />
++ </form>
++ </field>
++ </record>
++
++ <record id="track_line" model="ir.actions.act_window">
++ <field name="name">Split in lots</field>
++ <field name="type">ir.actions.act_window</field>
++ <field name="res_model">stock.move.spilt</field>
++ <field name="view_type">form</field>
++ <field name="view_mode">form</field>
++ <field name="target">new</field>
++ </record>
++
++ </data>
++</openerp>