[MERGE] merge with parent
bzr revid: rma@tinyerp.com-20130814053737-oomjqp7cxhp0yb1c bzr revid: rma@tinyerp.com-20130821053211-2x0xf1mv4sv3lc2y
This commit is contained in:
commit
e480e3d00d
|
@ -16,11 +16,13 @@
|
|||
</record>
|
||||
|
||||
<record id="stock.property_stock_account_input_categ" model="ir.property">
|
||||
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_stock_account_input_categ')]"/>
|
||||
<field eval="'account.account,'+str(ref('chart2141_en'))" model="account.account" name="value"/>
|
||||
<field eval="'product.category,'+str(ref('product.product_category_all'))" model="product.category" name="res_id"/>
|
||||
</record>
|
||||
|
||||
<record id="stock.property_stock_account_output_categ" model="ir.property">
|
||||
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_stock_account_output_categ')]"/>
|
||||
<field eval="'account.account,'+str(ref('chart1145_en'))" model="account.account" name="value"/>
|
||||
<field eval="'product.category,'+str(ref('product.product_category_all'))" model="product.category" name="res_id"/>
|
||||
</record>
|
||||
|
|
|
@ -15,11 +15,13 @@
|
|||
</record>
|
||||
|
||||
<record id="stock.property_stock_account_input_categ" model="ir.property">
|
||||
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_stock_account_input_categ')]"/>
|
||||
<field eval="'account.account,'+str(ref('chart2171_fr'))" model="account.account" name="value"/>
|
||||
<field eval="'product.category,'+str(ref('product.product_category_all'))" model="product.category" name="res_id"/>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
<record id="stock.property_stock_account_output_categ" model="ir.property">
|
||||
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_stock_account_output_categ')]"/>
|
||||
<field eval="'account.account,'+str(ref('chart1145_fr'))" model="account.account" name="value"/>
|
||||
<field eval="'product.category,'+str(ref('product.product_category_all'))" model="product.category" name="res_id"/>
|
||||
</record>
|
||||
|
|
|
@ -452,6 +452,25 @@ class mrp_production(osv.osv):
|
|||
result[mrp_production.id] = done / mrp_production.product_qty * 100
|
||||
return result
|
||||
|
||||
def _moves_assigned(self, cr, uid, ids, name, arg, context=None):
|
||||
""" Test whether all the consume lines are assigned """
|
||||
res = True
|
||||
for production in self.browse(cr, uid, ids, context=context):
|
||||
states = [x.state != 'assigned' for x in production.move_lines if x]
|
||||
if any(states) or len(states) == 0:
|
||||
return False
|
||||
return res
|
||||
|
||||
|
||||
def _mrp_from_move(self, cr, uid, ids, context=None):
|
||||
""" Return mrp"""
|
||||
res = []
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
res += self.pool.get("mrp.production").search(cr, uid, [('move_lines', 'in', move.id)], context=context)
|
||||
return res
|
||||
|
||||
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Reference', size=64, required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'origin': fields.char('Source Document', size=64, readonly=True, states={'draft': [('readonly', False)]},
|
||||
|
@ -510,6 +529,8 @@ class mrp_production(osv.osv):
|
|||
'cycle_total': fields.function(_production_calc, type='float', string='Total Cycles', multi='workorder', store=True),
|
||||
'user_id':fields.many2one('res.users', 'Responsible'),
|
||||
'company_id': fields.many2one('res.company','Company',required=True),
|
||||
'ready_production': fields.function(_moves_assigned, type='boolean', store={'stock.move': (_mrp_from_move, ['state'], 10)}),
|
||||
|
||||
}
|
||||
_defaults = {
|
||||
'priority': lambda *a: '1',
|
||||
|
@ -554,7 +575,6 @@ class mrp_production(osv.osv):
|
|||
'move_created_ids2' : [],
|
||||
'product_lines' : [],
|
||||
'move_prod_id' : False,
|
||||
'picking_id' : False
|
||||
})
|
||||
return super(mrp_production, self).copy(cr, uid, id, default, context)
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<field name="wkf_id" ref="wkf_prod"/>
|
||||
<field name="flow_stop">True</field>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">action_production_end()</field>
|
||||
<field name="action">action_production_end()</field>
|
||||
<field name="name">done</field>
|
||||
</record>
|
||||
<record id="prod_act_cancel" model="workflow.activity">
|
||||
|
@ -70,7 +70,7 @@
|
|||
<field name="act_from" ref="prod_act_picking"/>
|
||||
<field name="act_to" ref="prod_act_ready"/>
|
||||
<field name="signal"></field>
|
||||
<field name="condition">picking_id and picking_id.state=='done'</field>
|
||||
<field name="condition">ready_production</field>
|
||||
</record>
|
||||
<record id="prod_trans_ready_in_production" model="workflow.transition">
|
||||
<field name="act_from" ref="prod_act_ready"/>
|
||||
|
|
|
@ -44,7 +44,7 @@ class procurement_order(osv.osv):
|
|||
rule_id = super(procurement_order, self)._find_suitable_rule(cr, uid, procurement, context=context)
|
||||
if not rule_id:
|
||||
#if there isn't any specific procurement.rule defined for the product, we try to directly supply it from a supplier
|
||||
if procurement.product_id.supply_method == 'manufacture' and self.check_bom_exists(cr, uid, [procurement.id], context=context):
|
||||
if procurement.product_id.supply_method == 'manufacture':
|
||||
rule_id = self._search_suitable_rule(cr, uid, procurement, [('action', '=', 'manufacture'), ('location_id', '=', procurement.location_id.id)], context=context)
|
||||
rule_id = rule_id and rule_id[0] or False
|
||||
return rule_id
|
||||
|
@ -52,7 +52,7 @@ class procurement_order(osv.osv):
|
|||
def _run(self, cr, uid, procurement, context=None):
|
||||
if procurement.rule_id and procurement.rule_id.action == 'manufacture':
|
||||
#make a manufacturing order for the procurement
|
||||
return self.make_mo(cr, uid, [procurement.id], context=context)
|
||||
return self.make_mo(cr, uid, [procurement.id], context=context)[procurement.id]
|
||||
return super(procurement_order, self)._run(cr, uid, procurement, context=context)
|
||||
|
||||
def _check(self, cr, uid, procurement, context=None):
|
||||
|
@ -92,10 +92,9 @@ class procurement_order(osv.osv):
|
|||
|
||||
def get_phantom_bom_id(self, cr, uid, ids, context=None):
|
||||
for procurement in self.browse(cr, uid, ids, context=context):
|
||||
if procurement.move_id and procurement.move_id.product_id.supply_method=='produce' \
|
||||
and procurement.move_id.product_id.procure_method=='make_to_order':
|
||||
if procurement.move_dest_id and procurement.move_dest_id.product_id.supply_method=='produce':
|
||||
phantom_bom_id = self.pool.get('mrp.bom').search(cr, uid, [
|
||||
('product_id', '=', procurement.move_id.product_id.id),
|
||||
('product_id', '=', procurement.move_dest_id.product_id.id),
|
||||
('bom_id', '=', False),
|
||||
('type', '=', 'phantom')])
|
||||
return phantom_bom_id
|
||||
|
@ -120,32 +119,36 @@ class procurement_order(osv.osv):
|
|||
move_obj = self.pool.get('stock.move')
|
||||
procurement_obj = self.pool.get('procurement.order')
|
||||
for procurement in procurement_obj.browse(cr, uid, ids, context=context):
|
||||
res_id = procurement.move_id.id
|
||||
newdate = datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - relativedelta(days=procurement.product_id.produce_delay or 0.0)
|
||||
newdate = newdate - relativedelta(days=company.manufacturing_lead)
|
||||
produce_id = production_obj.create(cr, uid, {
|
||||
'origin': procurement.origin,
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_qty': procurement.product_qty,
|
||||
'product_uom': procurement.product_uom.id,
|
||||
'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
|
||||
'product_uos': procurement.product_uos and procurement.product_uos.id or False,
|
||||
'location_src_id': procurement.location_id.id,
|
||||
'location_dest_id': procurement.location_id.id,
|
||||
'bom_id': procurement.bom_id and procurement.bom_id.id or False,
|
||||
'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'move_prod_id': res_id,
|
||||
'company_id': procurement.company_id.id,
|
||||
})
|
||||
|
||||
res[procurement.id] = produce_id
|
||||
self.write(cr, uid, [procurement.id], {'state': 'running', 'production_id': produce_id})
|
||||
bom_result = production_obj.action_compute(cr, uid,
|
||||
[produce_id], properties=[x.id for x in procurement.property_ids])
|
||||
production_obj.signal_button_confirm(cr, uid, [produce_id])
|
||||
if res_id:
|
||||
move_obj.write(cr, uid, [res_id],
|
||||
{'location_id': procurement.location_id.id})
|
||||
if self.check_bom_exists(cr, uid, [procurement.id], context=context):
|
||||
res_id = procurement.move_dest_id and procurement.move_dest_id.id or False
|
||||
newdate = datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - relativedelta(days=procurement.product_id.produce_delay or 0.0)
|
||||
newdate = newdate - relativedelta(days=company.manufacturing_lead)
|
||||
produce_id = production_obj.create(cr, uid, {
|
||||
'origin': procurement.origin,
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_qty': procurement.product_qty,
|
||||
'product_uom': procurement.product_uom.id,
|
||||
'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
|
||||
'product_uos': procurement.product_uos and procurement.product_uos.id or False,
|
||||
'location_src_id': procurement.location_id.id,
|
||||
'location_dest_id': procurement.location_id.id,
|
||||
'bom_id': procurement.bom_id and procurement.bom_id.id or False,
|
||||
'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'move_prod_id': res_id,
|
||||
'company_id': procurement.company_id.id,
|
||||
})
|
||||
|
||||
res[procurement.id] = produce_id
|
||||
self.write(cr, uid, [procurement.id], {'production_id': produce_id})
|
||||
bom_result = production_obj.action_compute(cr, uid,
|
||||
[produce_id], properties=[x.id for x in procurement.property_ids])
|
||||
production_obj.signal_button_confirm(cr, uid, [produce_id])
|
||||
if res_id:
|
||||
move_obj.write(cr, uid, [res_id],
|
||||
{'location_id': procurement.location_id.id})
|
||||
else:
|
||||
res[procurement.id] = False
|
||||
self.message_post(cr, uid, [procurement.id], body=_("No BoM exists for this product!"), context=context)
|
||||
self.production_order_create_note(cr, uid, ids, context=context)
|
||||
return res
|
||||
|
||||
|
|
|
@ -129,7 +129,6 @@ class StockMove(osv.osv):
|
|||
for move in self.browse(cr, uid, ids, context=context):
|
||||
new_moves = super(StockMove, self).action_scrap(cr, uid, [move.id], product_qty, location_id, context=context)
|
||||
#If we are not scrapping our whole move, tracking and lot references must not be removed
|
||||
#self.write(cr, uid, [move.id], {'prodlot_id': False, 'tracking_id': False})
|
||||
production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
|
||||
for prod_id in production_ids:
|
||||
production_obj.signal_button_produce(cr, uid, [prod_id])
|
||||
|
|
|
@ -27,6 +27,7 @@ class procurement_order(osv.osv):
|
|||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
procurement_id = super(procurement_order, self).create(cr, uid, vals, context=context)
|
||||
# TODO: maybe this is not necessary anymore as we do this already
|
||||
self.run(cr, uid, [procurement_id], context=context)
|
||||
self.check(cr, uid, [procurement_id], context=context)
|
||||
return procurement_id
|
||||
|
|
|
@ -513,7 +513,6 @@ class mrp_repair(osv.osv):
|
|||
'partner_id': repair.address_id and repair.address_id.id or False,
|
||||
'location_id': move.location_id.id,
|
||||
'location_dest_id': move.location_dest_id.id,
|
||||
'tracking_id': False,
|
||||
'state': 'done',
|
||||
})
|
||||
repair_line_obj.write(cr, uid, [move.id], {'move_id': move_id, 'state': 'done'}, context=context)
|
||||
|
@ -536,7 +535,6 @@ class mrp_repair(osv.osv):
|
|||
'partner_id': repair.address_id and repair.address_id.id or False,
|
||||
'location_id': repair.location_id.id,
|
||||
'location_dest_id': repair.location_dest_id.id,
|
||||
'tracking_id': False,
|
||||
'state': 'assigned',
|
||||
})
|
||||
pick_obj.signal_button_confirm(cr, uid, [picking])
|
||||
|
|
|
@ -723,7 +723,6 @@ class pos_order(osv.osv):
|
|||
'product_id': line.product_id.id,
|
||||
'product_uos_qty': abs(line.qty),
|
||||
'product_uom_qty': abs(line.qty),
|
||||
'tracking_id': False,
|
||||
'state': 'draft',
|
||||
'location_id': location_id,
|
||||
'location_dest_id': output_id,
|
||||
|
|
|
@ -125,7 +125,7 @@ class procurement_order(osv.osv):
|
|||
('running', 'Running'),
|
||||
('done', 'Done')
|
||||
], 'Status', required=True, track_visibility='onchange'),
|
||||
'message': fields.text('Latest error', help="Exception occurred while computing procurement orders."),
|
||||
'message': fields.text('Latest error', help="Exception occurred while computing procurement orders.", track_visibility='onchange'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -154,13 +154,17 @@ class procurement_order(osv.osv):
|
|||
|
||||
def run(self, cr, uid, ids, context=None):
|
||||
for procurement in self.browse(cr, uid, ids, context=context):
|
||||
if self._assign(cr, uid, procurement, context=context):
|
||||
procurement.refresh()
|
||||
self._run(cr, uid, procurement, context=context or {})
|
||||
self.write(cr, uid, [procurement.id], {'state': 'running'}, context=context)
|
||||
else:
|
||||
self.message_post(cr, uid, [procurement.id], body=_('No rule matching this procurement'), context=context)
|
||||
self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
|
||||
if procurement.state not in ("running", "done"):
|
||||
if self._assign(cr, uid, procurement, context=context):
|
||||
procurement.refresh()
|
||||
res = self._run(cr, uid, procurement, context=context or {})
|
||||
if res:
|
||||
self.write(cr, uid, [procurement.id], {'state': 'running'}, context=context)
|
||||
else:
|
||||
self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
|
||||
else:
|
||||
self.message_post(cr, uid, [procurement.id], body=_('No rule matching this procurement'), context=context)
|
||||
self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
|
||||
return True
|
||||
|
||||
def check(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -32,7 +32,7 @@ class procurement_order(osv.osv):
|
|||
}
|
||||
|
||||
def _is_procurement_task(self, cr, uid, procurement, context=None):
|
||||
return procurement.product_id.type == 'service' and procurement.product_it.auto_create_task or False
|
||||
return procurement.product_id.type == 'service' and procurement.product_id.auto_create_task or False
|
||||
|
||||
def _assign(self, cr, uid, procurement, context=None):
|
||||
res = super(procurement_order, self)._assign(cr, uid, procurement, context=context)
|
||||
|
@ -123,9 +123,9 @@ class product_product(osv.osv):
|
|||
class sale_order(osv.osv):
|
||||
_inherit = 'sale.order'
|
||||
|
||||
def _prepare_order_line_procurement(self, cr, uid, order, line, move_id, date_planned, context=None):
|
||||
def _prepare_order_line_procurement(self, cr, uid, order, line, group_id=False, context=None):
|
||||
proc_data = super(sale_order, self)._prepare_order_line_procurement(cr,
|
||||
uid, order, line, move_id, date_planned, context=context)
|
||||
uid, order, line, group_id = group_id, context=context)
|
||||
proc_data['sale_line_id'] = line.id
|
||||
return proc_data
|
||||
|
||||
|
|
|
@ -49,13 +49,6 @@
|
|||
<xpath expr="//field[@name='supply_method']" position="attributes">
|
||||
<attribute name="invisible">False</attribute>
|
||||
</xpath>
|
||||
<group name="procurement_help" position="inside">
|
||||
<p attrs="{'invisible': ['|','|',('type','<>','service'),('procure_method','<>','make_to_order'),('supply_method','<>','produce')]}">
|
||||
When you sell this service to a customer, <b>a task</b> will be
|
||||
created to follow up the job to do. This task will appear
|
||||
in the project related to the contract of the sales order.
|
||||
</p>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
|
|
|
@ -290,6 +290,7 @@ class purchase_order(osv.osv):
|
|||
return {}
|
||||
return {'value': {'currency_id': self.pool.get('product.pricelist').browse(cr, uid, pricelist_id, context=context).currency_id.id}}
|
||||
|
||||
#Destination address is used when dropshipping
|
||||
def onchange_dest_address_id(self, cr, uid, ids, address_id):
|
||||
if not address_id:
|
||||
return {}
|
||||
|
@ -653,7 +654,6 @@ class purchase_order(osv.osv):
|
|||
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'),
|
||||
'origin': order.name + ((order.origin and (':' + order.origin)) or ''),
|
||||
|
@ -663,11 +663,14 @@ 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': type_id,
|
||||
}
|
||||
|
||||
def _prepare_order_line_move(self, cr, uid, order, order_line, picking_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]
|
||||
type = self.pool.get("stock.picking.type").browse(cr, uid, type_id, context=context)
|
||||
|
||||
return {
|
||||
'name': order_line.name or '',
|
||||
'product_id': order_line.product_id.id,
|
||||
|
@ -685,7 +688,8 @@ class purchase_order(osv.osv):
|
|||
'state': 'draft',
|
||||
'purchase_line_id': order_line.id,
|
||||
'company_id': order.company_id.id,
|
||||
'price_unit': order_line.price_unit,
|
||||
'price_unit': order_line.price_unit,
|
||||
'picking_type_id': type_id,
|
||||
}
|
||||
|
||||
def _create_pickings(self, cr, uid, order, order_lines, picking_id=False, context=None):
|
||||
|
@ -1111,7 +1115,7 @@ class procurement_order(osv.osv):
|
|||
def _run(self, cr, uid, procurement, context=None):
|
||||
if procurement.rule_id and procurement.rule_id.action == 'buy':
|
||||
#make a purchase order for the procurement
|
||||
return self.make_po(cr, uid, [procurement.id], context=context)
|
||||
return self.make_po(cr, uid, [procurement.id], context=context)[procurement.id]
|
||||
return super(procurement_order, self)._run(cr, uid, procurement, context=context)
|
||||
|
||||
def _check(self, cr, uid, procurement, context=None):
|
||||
|
@ -1217,63 +1221,66 @@ class procurement_order(osv.osv):
|
|||
acc_pos_obj = self.pool.get('account.fiscal.position')
|
||||
seq_obj = self.pool.get('ir.sequence')
|
||||
warehouse_obj = self.pool.get('stock.warehouse')
|
||||
pass_ids = []
|
||||
for procurement in self.browse(cr, uid, ids, context=context):
|
||||
res_id = procurement.move_id.id
|
||||
res_id = procurement.move_dest_id and procurement.move_dest_id.id or False
|
||||
partner = procurement.product_id.seller_id # Taken Main Supplier of Product of Procurement.
|
||||
assert partner, ('There is no supplier associated to product %s', (procurements.product_id.name))
|
||||
seller_qty = procurement.product_id.seller_qty
|
||||
partner_id = partner.id
|
||||
address_id = partner_obj.address_get(cr, uid, [partner_id], ['delivery'])['delivery']
|
||||
pricelist_id = partner.property_product_pricelist_purchase.id
|
||||
warehouse_id = warehouse_obj.search(cr, uid, [('company_id', '=', procurement.company_id.id or company.id)], context=context)
|
||||
uom_id = procurement.product_id.uom_po_id.id
|
||||
if not partner:
|
||||
self.message_post(cr, uid, [procurement.id],_('There is no supplier associated to product %s') % (procurement.product_id.name))
|
||||
res[procurement.id] = False
|
||||
else:
|
||||
seller_qty = procurement.product_id.seller_qty
|
||||
partner_id = partner.id
|
||||
address_id = partner_obj.address_get(cr, uid, [partner_id], ['delivery'])['delivery']
|
||||
pricelist_id = partner.property_product_pricelist_purchase.id
|
||||
warehouse_id = warehouse_obj.search(cr, uid, [('company_id', '=', procurement.company_id.id or company.id)], context=context)
|
||||
uom_id = procurement.product_id.uom_po_id.id
|
||||
qty = uom_obj._compute_qty(cr, uid, procurement.product_uom.id, procurement.product_qty, uom_id)
|
||||
if seller_qty:
|
||||
qty = max(qty,seller_qty)
|
||||
|
||||
qty = uom_obj._compute_qty(cr, uid, procurement.product_uom.id, procurement.product_qty, uom_id)
|
||||
if seller_qty:
|
||||
qty = max(qty,seller_qty)
|
||||
price = pricelist_obj.price_get(cr, uid, [pricelist_id], procurement.product_id.id, qty, partner_id, {'uom': uom_id})[pricelist_id]
|
||||
|
||||
price = pricelist_obj.price_get(cr, uid, [pricelist_id], procurement.product_id.id, qty, partner_id, {'uom': uom_id})[pricelist_id]
|
||||
schedule_date = self._get_purchase_schedule_date(cr, uid, procurement, company, context=context)
|
||||
purchase_date = self._get_purchase_order_date(cr, uid, procurement, company, schedule_date, context=context)
|
||||
|
||||
schedule_date = self._get_purchase_schedule_date(cr, uid, procurement, company, context=context)
|
||||
purchase_date = self._get_purchase_order_date(cr, uid, procurement, company, schedule_date, context=context)
|
||||
|
||||
#Passing partner_id to context for purchase order line integrity of Line name
|
||||
new_context = context.copy()
|
||||
new_context.update({'lang': partner.lang, 'partner_id': partner_id})
|
||||
|
||||
product = prod_obj.browse(cr, uid, procurement.product_id.id, context=new_context)
|
||||
taxes_ids = procurement.product_id.supplier_taxes_id
|
||||
taxes = acc_pos_obj.map_tax(cr, uid, partner.property_account_position, taxes_ids)
|
||||
|
||||
name = product.partner_ref
|
||||
if product.description_purchase:
|
||||
name += '\n'+ product.description_purchase
|
||||
line_vals = {
|
||||
'name': name,
|
||||
'product_qty': qty,
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_uom': uom_id,
|
||||
'price_unit': price or 0.0,
|
||||
'date_planned': schedule_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'move_dest_id': res_id,
|
||||
'taxes_id': [(6,0,taxes)],
|
||||
}
|
||||
name = seq_obj.get(cr, uid, 'purchase.order') or _('PO: %s') % procurement.name
|
||||
po_vals = {
|
||||
'name': name,
|
||||
'origin': procurement.origin,
|
||||
'partner_id': partner_id,
|
||||
'location_id': procurement.location_id.id,
|
||||
'warehouse_id': warehouse_id and warehouse_id[0] or False,
|
||||
'pricelist_id': pricelist_id,
|
||||
'date_order': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'company_id': procurement.company_id.id,
|
||||
'fiscal_position': partner.property_account_position and partner.property_account_position.id or False,
|
||||
'payment_term_id': partner.property_supplier_payment_term.id or False,
|
||||
}
|
||||
res[procurement.id] = self.create_procurement_purchase_order(cr, uid, procurement, po_vals, line_vals, context=new_context)
|
||||
self.write(cr, uid, [procurement.id], {'state': 'running', 'purchase_id': res[procurement.id]})
|
||||
self.message_post(cr, uid, ids, body=_("Draft Purchase Order created"), context=context)
|
||||
#Passing partner_id to context for purchase order line integrity of Line name
|
||||
new_context = context.copy()
|
||||
new_context.update({'lang': partner.lang, 'partner_id': partner_id})
|
||||
product = prod_obj.browse(cr, uid, procurement.product_id.id, context=new_context)
|
||||
taxes_ids = procurement.product_id.supplier_taxes_id
|
||||
taxes = acc_pos_obj.map_tax(cr, uid, partner.property_account_position, taxes_ids)
|
||||
name = product.partner_ref
|
||||
if product.description_purchase:
|
||||
name += '\n'+ product.description_purchase
|
||||
line_vals = {
|
||||
'name': name,
|
||||
'product_qty': qty,
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_uom': uom_id,
|
||||
'price_unit': price or 0.0,
|
||||
'date_planned': schedule_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'move_dest_id': res_id,
|
||||
'taxes_id': [(6,0,taxes)],
|
||||
}
|
||||
name = seq_obj.get(cr, uid, 'purchase.order') or _('PO: %s') % procurement.name
|
||||
po_vals = {
|
||||
'name': name,
|
||||
'origin': procurement.origin,
|
||||
'partner_id': partner_id,
|
||||
'location_id': procurement.location_id.id,
|
||||
'warehouse_id': warehouse_id and warehouse_id[0] or False,
|
||||
'pricelist_id': pricelist_id,
|
||||
'date_order': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'company_id': procurement.company_id.id,
|
||||
'fiscal_position': partner.property_account_position and partner.property_account_position.id or False,
|
||||
'payment_term_id': partner.property_supplier_payment_term.id or False,
|
||||
}
|
||||
res[procurement.id] = self.create_procurement_purchase_order(cr, uid, procurement, po_vals, line_vals, context=new_context)
|
||||
self.write(cr, uid, [procurement.id], {'purchase_id': res[procurement.id]})
|
||||
pass_ids += [procurement.id]
|
||||
if pass_ids:
|
||||
self.message_post(cr, uid, pass_ids, body=_("Draft Purchase Order created"), context=context)
|
||||
return res
|
||||
|
||||
def _product_virtual_get(self, cr, uid, order_point):
|
||||
|
|
|
@ -391,7 +391,7 @@ class procurement_order(osv.osv):
|
|||
'date_end': procurement.date_planned,
|
||||
'warehouse_id': warehouse_id and warehouse_id[0] or False,
|
||||
'company_id': procurement.company_id.id,
|
||||
'move_dest_id': procurement.move_id.id,
|
||||
'move_dest_id': procurement.move_dest_id and procurement.move_dest_id.id or False,
|
||||
'line_ids': [(0, 0, {
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_uom_id': procurement.product_uom.id,
|
||||
|
|
|
@ -633,7 +633,6 @@ class sale_order(osv.osv):
|
|||
'product_uos_qty': (line.product_uos and line.product_uos_qty) or line.product_uom_qty,
|
||||
'product_uos': (line.product_uos and line.product_uos.id) or line.product_uom.id,
|
||||
'company_id': order.company_id.id,
|
||||
'note': line.name,
|
||||
'group_id': group_id,
|
||||
'invoice_state': (order.order_policy=='picking') and '2binvoiced' or 'none',
|
||||
'sale_line_id': line.id
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_internal_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group/filter[@string='Journal']" position="after">
|
||||
<xpath expr="//group/filter[@string='Picking Type']" position="after">
|
||||
<filter string="Invoice Type" domain="[]" context="{'group_by':'invoice_type_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
|
|
@ -205,16 +205,20 @@ class sale_order(osv.osv):
|
|||
write_done_ids = []
|
||||
write_cancel_ids = []
|
||||
for order in self.browse(cr, uid, ids, context={}):
|
||||
#TODO: Need to rethink what happens when cancelling
|
||||
for line in order.order_line:
|
||||
for procurement in line.procurement_ids:
|
||||
if procurement.state != 'done':
|
||||
write_done_ids.append(line.id)
|
||||
else:
|
||||
finished = False
|
||||
if (procurement.state == 'cancel'):
|
||||
canceled = True
|
||||
if line.state != 'exception':
|
||||
states = [x.state for x in line.procurement_ids]
|
||||
cancel = all([x == 'cancel' for x in states])
|
||||
doneorcancel = all([x in ('done', 'cancel') for x in states])
|
||||
if cancel:
|
||||
canceled = True
|
||||
if line.state != 'exception':
|
||||
write_cancel_ids.append(line.id)
|
||||
if not doneorcancel:
|
||||
finished = False
|
||||
if doneorcancel and not cancel:
|
||||
write_done_ids.append(line.id)
|
||||
|
||||
if write_done_ids:
|
||||
self.pool.get('sale.order.line').write(cr, uid, write_done_ids, {'state': 'done'})
|
||||
if write_cancel_ids:
|
||||
|
@ -256,8 +260,7 @@ class sale_order(osv.osv):
|
|||
res = []
|
||||
for order in self.browse(cr, uid, ids, context={}):
|
||||
for line in order.order_line:
|
||||
if line.procurement_id:
|
||||
res.append(line.procurement_id.id)
|
||||
res += [x.id for x in line.procurement_ids]
|
||||
return res
|
||||
|
||||
class sale_order_line(osv.osv):
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
||||
class stock_picking(osv.osv):
|
||||
_inherit = 'stock.picking'
|
||||
def __get_invoice_state(self, cr, uid, ids, name, arg, context=None):
|
||||
|
@ -45,16 +46,24 @@ class stock_picking(osv.osv):
|
|||
result[move.picking_id.id] = True
|
||||
return result.keys()
|
||||
|
||||
def __get_picking_move(self, cr, uid, ids, context={}):
|
||||
res = []
|
||||
for move in self.pool.get('stock.move').browse(cr, uid, ids, context=context):
|
||||
if move.picking_id:
|
||||
res.append(move.picking_id.id)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'invoice_state': fields.function(__get_invoice_state, type='selection', selection=[
|
||||
("invoiced", "Invoiced"),
|
||||
("2binvoiced", "To Be Invoiced"),
|
||||
("none", "Not Applicable")
|
||||
], string="Invoice Control", required=False,
|
||||
store={
|
||||
'procurement.order': (__get_picking_procurement, ['invoice_state'], 10),
|
||||
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['state'], 10)
|
||||
},
|
||||
], string="Invoice Control", required=False,
|
||||
store={
|
||||
'procurement.order': (__get_picking_procurement, ['invoice_state'], 10),
|
||||
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['state'], 10),
|
||||
'stock.move': (__get_picking_move, ['picking_id'], 10),
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
!record {model: product.product, id: product_onchange1}:
|
||||
name: 'Devil Worship Book'
|
||||
list_price: 66.6
|
||||
procure_method: 'make_to_order'
|
||||
-
|
||||
Now i create a sale order that uses my new product
|
||||
-
|
||||
|
@ -19,4 +18,3 @@
|
|||
!assert {model: sale.order, id: sale_order_onchange1, string: The onchange function of product was not correctly triggered}:
|
||||
- order_line[0].name == u'Devil Worship Book'
|
||||
- order_line[0].price_unit == 66.6
|
||||
- order_line[0].type == 'make_to_order'
|
||||
|
|
|
@ -107,7 +107,6 @@ class procurement_order(osv.osv):
|
|||
return False
|
||||
else:
|
||||
return True
|
||||
return procurement.move_id.state == 'done'
|
||||
return super(procurement_order, self)._check(cr, uid, procurement, context)
|
||||
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('picking_type_id','=',ref("picking_type_in")), ('location_id.usage','!=','internal'), ('location_dest_id.usage', '=', 'internal')]</field>
|
||||
<field name="domain" eval="[('picking_type_id','=',ref('picking_type_in')), ('location_id.usage','!=','internal'), ('location_dest_id.usage', '=', 'internal')]"/>
|
||||
<field name="view_id" ref="view_move_tree_reception_picking"/>
|
||||
<field name="context" eval="'{\'search_default_product_id\': [active_id]}'"/>
|
||||
<field name="help" type="html">
|
||||
|
@ -69,7 +69,7 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_move_tree_reception_picking"/>
|
||||
<field name="domain">[('picking_type_id','=',ref("picking_type_out")), ('location_id.usage','=','internal'), ('location_dest_id.usage', '!=', 'internal')]</field>
|
||||
<field name="domain" eval="[('picking_type_id','=',ref('picking_type_out')), ('location_id.usage','=','internal'), ('location_dest_id.usage', '!=', 'internal')]"/>
|
||||
<field name="context" eval="'{\'search_default_product_id\': [active_id]}'"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
|
|
|
@ -6,7 +6,5 @@
|
|||
<variant type="field" name="product_id.variants"/>
|
||||
<uom type="field" name="product_uom.name"/>
|
||||
<quantity type="field" name="product_uom_qty"/>
|
||||
<tracking type="field" name="tracking_id.name"/>
|
||||
<serial type="field" name="tracking_id.serial"/>
|
||||
</lot-line>
|
||||
</lots>
|
||||
|
|
|
@ -54,10 +54,6 @@
|
|||
<xsl:template match="lot-line" mode="story">
|
||||
<para style="nospace"><xsl:value-of select="code"/><xsl:text>, </xsl:text><xsl:value-of select="quantity"/><xsl:text> </xsl:text><xsl:value-of select="uom"/></para>
|
||||
<para style="nospace"><xsl:value-of select="product"/><xsl:text> </xsl:text><xsl:value-of select="variant"/></para>
|
||||
<para style="nospace">Serial: <xsl:value-of select="serial"/></para>
|
||||
<para style="nospace">Tracking: <xsl:value-of select="serial"/></para>
|
||||
<spacer length="0.3cm"/>
|
||||
<barCode><xsl:value-of select="tracking"/></barCode>
|
||||
<nextFrame/>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
|
|
@ -61,7 +61,7 @@ class stock_location(osv.osv):
|
|||
_order = 'parent_left'
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
res = self._complete_name(cr, uid, ids, 'complete_name', None, context=context)
|
||||
return res.items()
|
||||
return res.items()
|
||||
|
||||
def _complete_name(self, cr, uid, ids, name, args, context=None):
|
||||
""" Forms complete name of location from parent location to child location.
|
||||
|
@ -140,7 +140,8 @@ class stock_quant(osv.osv):
|
|||
"""
|
||||
res = {}
|
||||
for q in self.browse(cr, uid, ids, context=context):
|
||||
res[q.id] = q.product_id.code
|
||||
|
||||
res[q.id] = q.product_id.code or ''
|
||||
if q.lot_id:
|
||||
res[q.id] = q.lot_id.name
|
||||
res[q.id] += ': '+ str(q.qty) + q.product_id.uom_id.name
|
||||
|
@ -152,6 +153,7 @@ class stock_quant(osv.osv):
|
|||
'location_id': fields.many2one('stock.location', 'Location', required=True),
|
||||
'qty': fields.float('Quantity', required=True, help="Quantity of products in this quant, in the default unit of measure of the product"),
|
||||
'package_id': fields.many2one('stock.quant.package', string='Package', help="The package containing this quant"),
|
||||
'packaging_type_id': fields.related('package_id', 'packaging_id', type='many2one', relation='product.packaging', string='Type of packaging', store=True),
|
||||
'reservation_id': fields.many2one('stock.move', 'Reserved for Move', help="Is this quant reserved for a stock.move?"),
|
||||
'lot_id': fields.many2one('stock.production.lot', 'Lot'),
|
||||
'cost': fields.float('Unit Cost'),
|
||||
|
@ -430,7 +432,7 @@ class stock_picking(osv.osv):
|
|||
res[pick.id] = 'done'
|
||||
continue
|
||||
|
||||
order = {'confirmed':0, 'auto':1, 'assigned':2}
|
||||
order = {'confirmed':0, 'waiting':1, 'assigned':2}
|
||||
order_inv = dict(zip(order.values(),order.keys()))
|
||||
lst = [order[x.state] for x in pick.move_lines if x.state not in ('cancel','done')]
|
||||
if pick.move_lines == 'one':
|
||||
|
@ -465,7 +467,7 @@ class stock_picking(osv.osv):
|
|||
'stock.move': (_get_pickings, ['state', 'picking_id'], 20)}, selection = [
|
||||
('draft', 'Draft'),
|
||||
('cancel', 'Cancelled'),
|
||||
('auto', 'Waiting Another Operation'),
|
||||
('waiting', 'Waiting Another Operation'),
|
||||
('confirmed', 'Waiting Availability'),
|
||||
('assigned', 'Ready to Transfer'),
|
||||
('done', 'Transferred'),
|
||||
|
@ -695,7 +697,8 @@ class stock_picking(osv.osv):
|
|||
self.action_done(cr, uid, [picking.id], context=context)
|
||||
continue
|
||||
for op in picking.pack_operation_ids:
|
||||
if op.package_id:
|
||||
#TODO: op.package_id can not work as quants_get is not defined on quant package => gives traceback
|
||||
if op.package_id:
|
||||
for quant in quant_package_obj.quants_get(cr, uid, op.package_id, context=context):
|
||||
self._do_partial_product_move(cr, uid, picking, quant.product_id, quant.qty, quant, context=context)
|
||||
op.package_id.write(cr, uid, {
|
||||
|
@ -703,12 +706,14 @@ class stock_picking(osv.osv):
|
|||
}, context=context)
|
||||
elif op.product_id:
|
||||
moves = self._do_partial_product_move(cr, uid, picking, op.product_id, op.product_qty, op.quant_id, context=context)
|
||||
|
||||
quants = []
|
||||
for m in moves:
|
||||
for quant in m.quant_ids:
|
||||
quants.append(quant.id)
|
||||
quant_obj.write(cr, uid, quants, {
|
||||
'package_id': op.result_package_id.id
|
||||
|
||||
}, context=context)
|
||||
|
||||
self._create_backorder(cr, uid, picking, context=context)
|
||||
|
@ -903,6 +908,21 @@ class stock_move(osv.osv):
|
|||
res[move.id] = [q.id for q in move.reserved_quant_ids]
|
||||
return res
|
||||
|
||||
def _get_product_availability(self, cr, uid, ids, field_name, args, context=None):
|
||||
quant_obj = self.pool.get('stock.quant')
|
||||
res = dict.fromkeys(ids, False)
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
if move.state == 'done':
|
||||
res[move.id] = move.product_qty
|
||||
else:
|
||||
sublocation_ids = self.pool.get('stock.location').search(cr, uid, [('id', 'child_of', [move.location_id.id])], context=context)
|
||||
quant_ids = quant_obj.search(cr, uid, [('location_id', 'in', sublocation_ids), ('product_id', '=', move.product_id.id), ('reservation_id', '=', False)], context=context)
|
||||
availability = 0
|
||||
for quant in quant_obj.browse(cr, uid, quant_ids, context=context):
|
||||
availability += quant.qty
|
||||
res[move.id] = min(move.product_qty, availability)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Description', required=True, select=True),
|
||||
'priority': fields.selection([('0', 'Not urgent'), ('1', 'Urgent')], 'Priority'),
|
||||
|
@ -978,6 +998,7 @@ class stock_move(osv.osv):
|
|||
'lot_ids': fields.function(_get_lot_ids, type='many2many', relation='stock.quant', string='Lots'),
|
||||
'origin_returned_move_id': fields.many2one('stock.move', 'Origin return move', help='move that created the return move'),
|
||||
'returned_move_ids': fields.one2many('stock.move', 'origin_returned_move_id', 'All returned moves', help='Optional: all returned moves created from this move'),
|
||||
'availability': fields.function(_get_product_availability, type='float', string='Availability'),
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
|
@ -1181,7 +1202,7 @@ class stock_move(osv.osv):
|
|||
('group_id', '=', move.group_id.id),
|
||||
('location_id', '=', move.location_id.id),
|
||||
('location_dest_id', '=', move.location_dest_id.id),
|
||||
('state', 'in', ['confirmed', 'auto'])], context=context)
|
||||
('state', 'in', ['confirmed', 'waiting'])], context=context)
|
||||
if picks:
|
||||
pick = picks[0]
|
||||
else:
|
||||
|
@ -1379,13 +1400,13 @@ class stock_move(osv.osv):
|
|||
uos_qty = quantity / move_qty * move.product_uos_qty
|
||||
default_val = {
|
||||
'location_id': source_location.id,
|
||||
'product_qty': quantity,
|
||||
'product_uom_qty': quantity,
|
||||
'product_uos_qty': uos_qty,
|
||||
'state': move.state,
|
||||
'scrapped': True,
|
||||
'location_dest_id': location_id,
|
||||
'tracking_id': move.tracking_id.id,
|
||||
'lot_id': move.lot_id.id,
|
||||
#TODO lot_id is now on quant and not on move, need to do something for this
|
||||
#'lot_id': move.lot_id.id,
|
||||
}
|
||||
new_move = self.copy(cr, uid, move.id, default_val)
|
||||
|
||||
|
@ -1488,20 +1509,10 @@ class stock_move(osv.osv):
|
|||
self.write(cr, uid, [move.id], {
|
||||
'product_uom_qty': move.product_uom_qty - uom_qty,
|
||||
'product_uos_qty': move.product_uos_qty - uos_qty,
|
||||
'reserved_quant_ids': []
|
||||
'reserved_quant_ids': [(6,0,[])]
|
||||
}, context=context)
|
||||
return new_move
|
||||
|
||||
def get_type_from_usage(self, cr, uid, location, location_dest, context=None):
|
||||
'''
|
||||
Returns the type to be chosen based on the usages of the locations
|
||||
'''
|
||||
if location.usage == 'internal' and location_dest.usage in ['supplier', 'customer']:
|
||||
return 'out'
|
||||
if location.usage in ['supplier', 'customer'] and location_dest.usage == 'internal' :
|
||||
return 'in'
|
||||
return 'internal'
|
||||
|
||||
class stock_inventory(osv.osv):
|
||||
_name = "stock.inventory"
|
||||
_description = "Inventory"
|
||||
|
@ -1924,7 +1935,6 @@ class stock_pack_operation(osv.osv):
|
|||
'lot_id': fields.many2one('stock.production.lot', 'Lot/Serial Number'),
|
||||
'result_package_id': fields.many2one('stock.quant.package', 'Container Package', help="If set, the operations are packed into this package", required=False, ondelete='cascade'),
|
||||
'date': fields.datetime('Date', required=True),
|
||||
#'lot_id': fields.many2one('stock.production.lot', 'Serial Number', ondelete='CASCADE'),
|
||||
#'update_cost': fields.boolean('Need cost update'),
|
||||
'cost': fields.float("Cost", help="Unit Cost for this product line"),
|
||||
'currency': fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", ondelete='CASCADE'),
|
||||
|
|
|
@ -803,6 +803,7 @@
|
|||
<field name="scrapped" invisible="1"/>
|
||||
<field name="location_dest_id" groups="stock.group_locations"/>
|
||||
<field name="state"/>
|
||||
<field name="availability"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -1045,7 +1046,7 @@
|
|||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">['|','&',('picking_id','=',False),('location_id.usage', 'in', ['customer','supplier']),'&',('picking_id','!=',False)]</field>
|
||||
<field name="domain" eval="['|','&',('picking_id','=',False),('location_dest_id.usage', 'in', ['customer','supplier']),'&',('picking_id','!=',False),('picking_type_id','=',ref('picking_type_in'))]"/>
|
||||
<field name="view_id" ref="view_move_tree_reception_picking"/>
|
||||
<field name="context">{'product_receive': True, 'search_default_future': True}</field>
|
||||
<field name="help" type="html">
|
||||
|
@ -1140,7 +1141,7 @@
|
|||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">['|','&',('picking_id','=',False),('location_dest_id.usage', 'in', ['customer','supplier']),'&',('picking_id','!=',False)]</field>
|
||||
<field name="domain" eval="['|','&',('picking_id','=',False),('location_dest_id.usage', 'in', ['customer','supplier']),'&',('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">
|
||||
|
@ -1477,8 +1478,10 @@
|
|||
</group>
|
||||
<group expand='0' string='Group by...'>
|
||||
<filter name="productgroup" string='Product' context="{'group_by' : 'product_id'}"/>
|
||||
<filter string='Lot' context="{'group_by' : 'lot_id'}"/>
|
||||
<filter name="locationgroup" string='Location' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'location_id'}"/>
|
||||
<filter string='Packaging' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'package_id'}"/>
|
||||
<filter string='Packaging Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'packaging_type_id'}"/>
|
||||
<filter name="partnergroup" string='Partner' domain="[]" context="{'group_by': 'partner_id'}"/>
|
||||
<filter string='Company' icon="terp-go-home" domain="[]" context="{'group_by' : 'company_id'}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
|
@ -1521,6 +1524,9 @@
|
|||
<field name="product_id"/>
|
||||
<field name="qty"/>
|
||||
<field name="location_id"/>
|
||||
<field name="lot_id"/>
|
||||
<field name="package_id" invisible="1"/>
|
||||
<field name="packaging_type_id" invisible="1"/>
|
||||
<field name="in_date"/>
|
||||
<field name="reservation_id" invisible='1'/>
|
||||
<field name="propagated_from_id" invisible='1'/>
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
-
|
||||
Create new delivery order from output -> customers
|
||||
Create new global procurement rule from Stock -> Output
|
||||
-
|
||||
!record {model: procurement.rule, ref:}
|
||||
location_id: stock
|
||||
location_dest_id: output
|
||||
-
|
||||
Create Delivery Order from Output -> Customer
|
||||
-
|
||||
!record {model: stock.picking, ref:}
|
||||
-
|
||||
|
|
|
@ -103,7 +103,7 @@ class stock_move_scrap(osv.osv_memory):
|
|||
res = super(stock_move_consume, self).default_get(cr, uid, fields, context=context)
|
||||
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
|
||||
location_obj = self.pool.get('stock.location')
|
||||
scrpaed_location_ids = location_obj.search(cr, uid, [('scrap_location','=',True)])
|
||||
scrap_location_id = location_obj.search(cr, uid, [('scrap_location','=',True)])
|
||||
|
||||
if 'product_id' in fields:
|
||||
res.update({'product_id': move.product_id.id})
|
||||
|
@ -112,8 +112,8 @@ class stock_move_scrap(osv.osv_memory):
|
|||
if 'product_qty' in fields:
|
||||
res.update({'product_qty': move.product_qty})
|
||||
if 'location_id' in fields:
|
||||
if scrpaed_location_ids:
|
||||
res.update({'location_id': scrpaed_location_ids[0]})
|
||||
if scrap_location_id:
|
||||
res.update({'location_id': scrap_location_id[0]})
|
||||
else:
|
||||
res.update({'location_id': False})
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
-
|
||||
Create product with no seller_ids
|
||||
-
|
||||
|
||||
-
|
||||
Create a sales order with 1 piece for that product and route crossdock
|
||||
-
|
||||
!record{sale.order}
|
||||
-
|
||||
Confirm sales order
|
||||
-
|
||||
!python {
|
||||
-
|
||||
Check there is a procurement in exception that has the procurement group of the sales order
|
||||
-
|
||||
!python {
|
||||
assert
|
||||
-
|
||||
Adjust the product that it has at least one seller_id
|
||||
-
|
||||
!record{id: model: product.product) or in !python
|
||||
-
|
||||
Run the Scheduler
|
||||
-
|
||||
!python
|
||||
-
|
||||
Check the status changed there is no procurement order in exception any more from that procurement group
|
||||
-
|
||||
!python{model: procurement.order}
|
||||
search procurement from
|
||||
-
|
||||
Check a purchase quotation was created
|
||||
-
|
||||
|
||||
|
||||
|
||||
|
|
@ -21,29 +21,29 @@
|
|||
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
class invoice_directly(osv.osv_memory):
|
||||
_inherit = 'stock.partial.picking'
|
||||
|
||||
def do_partial(self, cr, uid, ids, context=None):
|
||||
"""Launch Create invoice wizard if invoice state is To be Invoiced,
|
||||
after processing the partial picking.
|
||||
"""
|
||||
if context is None: context = {}
|
||||
result = super(invoice_directly, self).do_partial(cr, uid, ids, context)
|
||||
partial = self.browse(cr, uid, ids[0], context)
|
||||
context.update(active_model='stock.picking',
|
||||
active_ids=[partial.picking_id.id])
|
||||
if partial.picking_id.invoice_state == '2binvoiced':
|
||||
return {
|
||||
'name': 'Create Invoice',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'stock.invoice.onshipping',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
'context': context
|
||||
}
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
# class invoice_directly(osv.osv_memory):
|
||||
# _inherit = 'stock.partial.picking'
|
||||
#
|
||||
# def do_partial(self, cr, uid, ids, context=None):
|
||||
# """Launch Create invoice wizard if invoice state is To be Invoiced,
|
||||
# after processing the partial picking.
|
||||
# """
|
||||
# if context is None: context = {}
|
||||
# result = super(invoice_directly, self).do_partial(cr, uid, ids, context)
|
||||
# partial = self.browse(cr, uid, ids[0], context)
|
||||
# context.update(active_model='stock.picking',
|
||||
# active_ids=[partial.picking_id.id])
|
||||
# if partial.picking_id.invoice_state == '2binvoiced':
|
||||
# return {
|
||||
# 'name': 'Create Invoice',
|
||||
# 'view_type': 'form',
|
||||
# 'view_mode': 'form',
|
||||
# 'res_model': 'stock.invoice.onshipping',
|
||||
# 'type': 'ir.actions.act_window',
|
||||
# 'target': 'new',
|
||||
# 'context': context
|
||||
# }
|
||||
# return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -52,9 +52,6 @@ class stock_location_path(osv.osv):
|
|||
'name': fields.char('Operation', size=64),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'route_id': fields.many2one('stock.location.route', 'Route'),
|
||||
|
||||
'product_id' : fields.many2one('product.product', 'Products', ondelete='cascade', select=1),
|
||||
|
||||
'location_from_id' : fields.many2one('stock.location', 'Source Location', ondelete='cascade', select=1, required=True),
|
||||
'location_dest_id' : fields.many2one('stock.location', 'Destination Location', ondelete='cascade', select=1, required=True),
|
||||
'delay': fields.integer('Delay (days)', help="Number of days to do this transition"),
|
||||
|
@ -62,7 +59,7 @@ class stock_location_path(osv.osv):
|
|||
("invoiced", "Invoiced"),
|
||||
("2binvoiced", "To Be Invoiced"),
|
||||
("none", "Not Applicable")], "Invoice Status",
|
||||
required=True,),
|
||||
required=True,),
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type', 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')],
|
||||
|
@ -102,7 +99,6 @@ class stock_location_path(osv.osv):
|
|||
'date_expected': newdate,
|
||||
'picking_id': False,
|
||||
'picking_type_id': rule.picking_type_id and rule.picking_type_id.id or False,
|
||||
'type': move_obj.get_type_from_usage(cr, uid, move.location_id, move.location_dest_id, context=context),
|
||||
'rule_id': rule.id,
|
||||
'propagate': rule.propagate,
|
||||
})
|
||||
|
@ -255,14 +251,15 @@ class stock_move(osv.osv):
|
|||
|
||||
def _push_apply(self, cr, uid, moves, context):
|
||||
for move in moves:
|
||||
for route in move.product_id.route_ids:
|
||||
found = False
|
||||
for rule in route.push_ids:
|
||||
if rule.location_from_id.id == move.location_dest_id.id:
|
||||
self.pool.get('stock.location.path')._apply(cr, uid, rule, move, context=context)
|
||||
found = True
|
||||
break
|
||||
if found: break
|
||||
if not move.move_dest_id:
|
||||
for route in move.product_id.route_ids:
|
||||
found = False
|
||||
for rule in route.push_ids:
|
||||
if rule.location_from_id.id == move.location_dest_id.id:
|
||||
self.pool.get('stock.location.path')._apply(cr, uid, rule, move, context=context)
|
||||
found = True
|
||||
break
|
||||
if found: break
|
||||
return True
|
||||
|
||||
# Create the stock.move.putaway records
|
||||
|
@ -273,16 +270,16 @@ class stock_move(osv.osv):
|
|||
if putaway:
|
||||
# Should call different methods here in later versions
|
||||
# TODO: take care of lots
|
||||
if putaway.method == 'fixed' and putaway.location_id:
|
||||
if putaway.method == 'fixed' and putaway.location_spec_id:
|
||||
moveputaway_obj.create(cr, uid, {'move_id': move.id,
|
||||
'location_id': putaway.location_id.id,
|
||||
'location_id': putaway.location_spec_id.id,
|
||||
'quantity': move.product_uom_qty}, context=context)
|
||||
return True
|
||||
|
||||
def action_assign(self, cr, uid, ids, context=None):
|
||||
result = super(stock_move, self).action_assign(cr, uid, ids, context=context)
|
||||
self._putaway_apply(cr, uid, ids, context=context)
|
||||
return result
|
||||
result = super(stock_move, self).action_assign(cr, uid, ids, context=context)
|
||||
self._putaway_apply(cr, uid, ids, context=context)
|
||||
return result
|
||||
|
||||
def action_confirm(self, cr, uid, ids, context=None):
|
||||
result = super(stock_move, self).action_confirm(cr, uid, ids, context)
|
||||
|
@ -290,6 +287,8 @@ class stock_move(osv.osv):
|
|||
self._push_apply(cr, uid, moves, context=context)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def _create_procurement(self, cr, uid, move, context=None):
|
||||
"""
|
||||
Next to creating the procurement order, it will propagate the routes
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
-
|
||||
!record {model: stock.location.path, id: push_pick}:
|
||||
name: Pick List
|
||||
product_id: product.product_product_10
|
||||
location_from_id: stock.stock_location_output
|
||||
location_dest_id: location_pack_zone
|
||||
picking_type_id: stock.picking_type_internal
|
|
@ -87,14 +87,15 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Location Paths" version="7.0">
|
||||
<group col="4">
|
||||
<field name="name" />
|
||||
<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="auto" />
|
||||
<field name="delay" />
|
||||
<field name="location_from_id"/>
|
||||
<field name="location_dest_id"/>
|
||||
<field name="picking_type_id"/>
|
||||
<field name="auto"/>
|
||||
<field name="delay"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
|
Loading…
Reference in New Issue