[WIP] Link sale and procurement group, run procurement when creating from sale, view delivery order button with shipped field as a calculated field, quants search view, change yml tests in stock_location
bzr revid: jco@openerp.com-20130722143747-l680354are7bo0ow
This commit is contained in:
parent
f85da509e3
commit
a3cc2f8fdc
|
@ -666,7 +666,7 @@ class sale_order(osv.osv):
|
||||||
procurement_obj = self.pool.get('procurement.order')
|
procurement_obj = self.pool.get('procurement.order')
|
||||||
for order in self.browse(cr, uid, ids, context=context):
|
for order in self.browse(cr, uid, ids, context=context):
|
||||||
proc_ids = []
|
proc_ids = []
|
||||||
group_id = self.pool.get("procurement.group").create(cr, uid, {'name': order.name}, context=context)
|
group_id = self.pool.get("procurement.group").create(cr, uid, {'name': order.name, 'sale_id': order.id}, context=context)
|
||||||
for line in order.order_line:
|
for line in order.order_line:
|
||||||
if (line.state == 'done') or not line.product_id:
|
if (line.state == 'done') or not line.product_id:
|
||||||
continue
|
continue
|
||||||
|
@ -674,9 +674,8 @@ class sale_order(osv.osv):
|
||||||
proc_id = procurement_obj.create(cr, uid, self._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context))
|
proc_id = procurement_obj.create(cr, uid, self._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context))
|
||||||
proc_ids.append(proc_id)
|
proc_ids.append(proc_id)
|
||||||
line.write({'procurement_id': proc_id})
|
line.write({'procurement_id': proc_id})
|
||||||
|
#Confirm procurement order such that rules will be applied on it
|
||||||
procurement_obj.signal_button_confirm(cr, uid, proc_ids)
|
procurement_obj.run(cr, uid, proc_ids, context=context)
|
||||||
|
|
||||||
# FP NOTE: do we need this? isn't it the workflow that should set this
|
# FP NOTE: do we need this? isn't it the workflow that should set this
|
||||||
val = {}
|
val = {}
|
||||||
if order.state == 'shipping_except':
|
if order.state == 'shipping_except':
|
||||||
|
@ -1089,4 +1088,12 @@ class account_invoice(osv.Model):
|
||||||
wf_service.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr)
|
wf_service.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr)
|
||||||
return super(account_invoice, self).unlink(cr, uid, ids, context=context)
|
return super(account_invoice, self).unlink(cr, uid, ids, context=context)
|
||||||
|
|
||||||
|
class procurement_group(osv.osv):
|
||||||
|
_inherit = 'procurement.group'
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'sale_id': fields.many2one('sale.order', string = 'Sales Order')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -56,6 +56,28 @@ class sale_order(osv.osv):
|
||||||
raise osv.except_osv(_('Error!'), _('There is no warehouse defined for current company.'))
|
raise osv.except_osv(_('Error!'), _('There is no warehouse defined for current company.'))
|
||||||
return warehouse_ids[0]
|
return warehouse_ids[0]
|
||||||
|
|
||||||
|
def _get_shipped(self, cr, uid, ids, name, args, context=None):
|
||||||
|
res = {}
|
||||||
|
for sale in self.browse(cr, uid, ids, context=context):
|
||||||
|
res[sale.id]= True
|
||||||
|
#TODO: not better to use picking
|
||||||
|
pickingstates = []
|
||||||
|
for pick in sale.picking_ids:
|
||||||
|
pickingstates += [x.state not in ['cancel', 'done'] for x in pick.move_lines]
|
||||||
|
if any(pickingstates):
|
||||||
|
res[sale.id] = False
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _get_orders(self, cr, uid, ids, context=None):
|
||||||
|
res = set()
|
||||||
|
proc_obj = self.pool.get("procurement.order")
|
||||||
|
procs = proc_obj.search(cr, uid, [('move_id', 'in', ids)], context=context)
|
||||||
|
for proc in proc_obj.browse(cr, uid, procs, context=context):
|
||||||
|
if proc.group_id and proc.group_id.sale_id:
|
||||||
|
res.add(proc.group_id.sale_id.id)
|
||||||
|
return list(res)
|
||||||
|
|
||||||
|
|
||||||
def _get_picking_ids(self, cr, uid, ids, name, args, context=None):
|
def _get_picking_ids(self, cr, uid, ids, name, args, context=None):
|
||||||
res = {}
|
res = {}
|
||||||
if not ids: return res
|
if not ids: return res
|
||||||
|
@ -66,9 +88,9 @@ class sale_order(osv.osv):
|
||||||
LEFT JOIN procurement_order as po on (po.id = sol.procurement_id) \
|
LEFT JOIN procurement_order as po on (po.id = sol.procurement_id) \
|
||||||
LEFT JOIN stock_move as sm on (sm.id = po.move_id) \
|
LEFT JOIN stock_move as sm on (sm.id = po.move_id) \
|
||||||
LEFT JOIN stock_picking as sp on (sp.id = sm.picking_id) \
|
LEFT JOIN stock_picking as sp on (sp.id = sm.picking_id) \
|
||||||
WHERE sol.order_id in %s and sp.type = 'out'\
|
WHERE sol.order_id in %s \
|
||||||
GROUP BY sol.order_id, sm.picking_id ORDER BY sol.order_id''',(tuple(ids),))
|
GROUP BY sol.order_id, sm.picking_id ORDER BY sol.order_id''',(tuple(ids),))
|
||||||
result = cr.fetchall()
|
result = cr.fetchall() #and sp.type = 'out'\
|
||||||
for r in result:
|
for r in result:
|
||||||
res[r[0]].append(r[1])
|
res[r[0]].append(r[1])
|
||||||
return res
|
return res
|
||||||
|
@ -110,7 +132,8 @@ class sale_order(osv.osv):
|
||||||
('prepaid', 'Before Delivery'),
|
('prepaid', 'Before Delivery'),
|
||||||
], 'Create Invoice', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
|
], 'Create Invoice', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
|
||||||
help="""On demand: A draft invoice can be created from the sales order when needed. \nOn delivery order: A draft invoice can be created from the delivery order when the products have been delivered. \nBefore delivery: A draft invoice is created from the sales order and must be paid before the products can be delivered."""),
|
help="""On demand: A draft invoice can be created from the sales order when needed. \nOn delivery order: A draft invoice can be created from the delivery order when the products have been delivered. \nBefore delivery: A draft invoice is created from the sales order and must be paid before the products can be delivered."""),
|
||||||
'shipped': fields.boolean('Delivered', readonly=True, help="It indicates that the sales order has been delivered. This field is updated only after the scheduler(s) have been launched."),
|
'shipped': fields.function(_get_shipped, type='boolean', store = {'stock.move': (_get_orders, ['state'], 10)}),
|
||||||
|
#fields.boolean('Delivered', readonly=True, help="It indicates that the sales order has been delivered. This field is updated only after the scheduler(s) have been launched."),
|
||||||
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True),
|
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True),
|
||||||
'picking_ids': fields.function(_get_picking_ids, method=True, type='one2many', relation='stock.picking', string='Picking associated to this sale'),
|
'picking_ids': fields.function(_get_picking_ids, method=True, type='one2many', relation='stock.picking', string='Picking associated to this sale'),
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ Dashboard / Reports for Warehouse Management will include:
|
||||||
'stock_demo.xml',
|
'stock_demo.xml',
|
||||||
'procurement_demo.xml',
|
'procurement_demo.xml',
|
||||||
'stock_orderpoint.xml',
|
'stock_orderpoint.xml',
|
||||||
'stock_demo.yml',
|
# 'stock_demo.yml',
|
||||||
],
|
],
|
||||||
'data': [
|
'data': [
|
||||||
'security/stock_security.xml',
|
'security/stock_security.xml',
|
||||||
|
@ -95,7 +95,7 @@ Dashboard / Reports for Warehouse Management will include:
|
||||||
'test': [
|
'test': [
|
||||||
'test/inventory.yml',
|
'test/inventory.yml',
|
||||||
'test/move.yml',
|
'test/move.yml',
|
||||||
'test/shipment.yml',
|
# 'test/shipment.yml',
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'application': True,
|
'application': True,
|
||||||
|
|
|
@ -157,7 +157,7 @@ class stock_quant(osv.osv):
|
||||||
'product_id': fields.many2one('product.product', 'Product', required=True),
|
'product_id': fields.many2one('product.product', 'Product', required=True),
|
||||||
'location_id': fields.many2one('stock.location', 'Location', required=True),
|
'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"),
|
'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', help="The package containing this quant"),
|
'package_id': fields.many2one('stock.quant.package', string='Package', help="The package containing this quant"),
|
||||||
'reservation_id': fields.many2one('stock.move', 'Reserved for Move', help="Is this quant reserved for a stock.move?"),
|
'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'),
|
'lot_id': fields.many2one('stock.production.lot', 'Lot'),
|
||||||
'cost': fields.float('Unit Cost'),
|
'cost': fields.float('Unit Cost'),
|
||||||
|
|
|
@ -1586,17 +1586,60 @@
|
||||||
<field name="res_model">procurement.rule</field>
|
<field name="res_model">procurement.rule</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="quant_search_view" model="ir.ui.view">
|
||||||
|
<field name="name">stock.quant.search</field>
|
||||||
|
<field name="model">stock.quant</field>
|
||||||
|
<field eval="10" name="priority"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Quants">
|
||||||
|
<field name="product_id"/>
|
||||||
|
<field name="location_id"/>
|
||||||
|
<field name="package_id"/>
|
||||||
|
<field name="lot_id"/>
|
||||||
|
<group expand='0' string='Filters'>
|
||||||
|
<filter string="Internal Locations" domain="[('location_id.usage,'=', 'internal')]"/>
|
||||||
|
</group>
|
||||||
|
<group expand='0' string='Group by...'>
|
||||||
|
<filter name="productgroup" string='Product' context="{'group_by' : 'product_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 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>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<record model="ir.actions.act_window" id="quantsact">
|
<record model="ir.actions.act_window" id="quantsact">
|
||||||
<field name="context">{}</field>
|
|
||||||
<field name="name">Quants</field>
|
<field name="name">Quants</field>
|
||||||
|
<field name="context">{'search_default_productgroup':'1', 'search_default_locationgroup':'1'}</field>
|
||||||
<field name="res_model">stock.quant</field>
|
<field name="res_model">stock.quant</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="view_stock_quant_form">
|
||||||
|
<field name="name">stock.quant.form</field>
|
||||||
|
<field name="model">stock.quant</field>
|
||||||
|
<field eval="10" name="priority"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Quants">
|
||||||
|
<field name="product_id"/>
|
||||||
|
<field name="qty"/>
|
||||||
|
<field name="lot_id"/>
|
||||||
|
<field name="package_id"/>
|
||||||
|
<field name="location_id"/>
|
||||||
|
<field name="in_date"/>
|
||||||
|
<field name="reservation_id"/>
|
||||||
|
<field name="propagated_from_id"/>
|
||||||
|
<field name="history_ids"/>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
<record model="ir.ui.view" id="view_stock_quant_tree">
|
<record model="ir.ui.view" id="view_stock_quant_tree">
|
||||||
<field name="name">stock.quant.tree</field>
|
<field name="name">stock.quant.tree</field>
|
||||||
<field name="model">stock.quant</field>
|
<field name="model">stock.quant</field>
|
||||||
|
@ -1607,8 +1650,8 @@
|
||||||
<field name="qty"/>
|
<field name="qty"/>
|
||||||
<field name="location_id"/>
|
<field name="location_id"/>
|
||||||
<field name="in_date"/>
|
<field name="in_date"/>
|
||||||
<field name="reservation_id"/>
|
<field name="reservation_id" invisible='1'/>
|
||||||
<field name="propagated_from_id"/>
|
<field name="propagated_from_id" invisible='1'/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -10,13 +10,14 @@
|
||||||
uom_po_id: product.product_uom_unit
|
uom_po_id: product.product_uom_unit
|
||||||
property_account_expense: account.a_expense
|
property_account_expense: account.a_expense
|
||||||
property_account_income: account.rev
|
property_account_income: account.rev
|
||||||
flow_pull_ids:
|
route_ids:
|
||||||
|
- name: 'Route from one company to the other'
|
||||||
|
pull_ids:
|
||||||
- invoice_state: none
|
- invoice_state: none
|
||||||
location_id: stock.stock_location_shop0
|
location_id: stock.stock_location_shop0
|
||||||
location_src_id: stock.stock_location_intermediatelocation0
|
location_src_id: stock.stock_location_intermediatelocation0
|
||||||
name: E001
|
name: E001
|
||||||
picking_type: in
|
picking_type: in
|
||||||
procure_method: make_to_order
|
|
||||||
type_proc: move
|
type_proc: move
|
||||||
company_id: stock.res_company_1
|
company_id: stock.res_company_1
|
||||||
- invoice_state: none
|
- invoice_state: none
|
||||||
|
@ -56,13 +57,8 @@
|
||||||
-
|
-
|
||||||
I confirm the procurement order.
|
I confirm the procurement order.
|
||||||
-
|
-
|
||||||
!workflow {model: procurement.order, action: button_confirm, ref: procurement_order_test0}
|
!python {model: procurement.order}: |
|
||||||
-
|
self.run(cr, uid, ref("procurement_order_test0"))
|
||||||
I launch the scheduler to compute procurement.
|
|
||||||
-
|
|
||||||
!python {model: procurement.order.compute.all}: |
|
|
||||||
proc_obj = self.pool.get('procurement.order')
|
|
||||||
proc_obj._procure_confirm(cr,uid, ids=[ref('procurement_order_test0')])
|
|
||||||
-
|
-
|
||||||
I check the new procurement order has been created .
|
I check the new procurement order has been created .
|
||||||
-
|
-
|
||||||
|
|
|
@ -32,18 +32,16 @@
|
||||||
list_price: 1000.0
|
list_price: 1000.0
|
||||||
mes_type: fixed
|
mes_type: fixed
|
||||||
name: HP CD writers
|
name: HP CD writers
|
||||||
procure_method: make_to_stock
|
|
||||||
seller_ids:
|
seller_ids:
|
||||||
- delay: 1
|
- delay: 1
|
||||||
name: res_partner_microlinktechnologies0
|
name: res_partner_microlinktechnologies0
|
||||||
min_qty: 5.0
|
min_qty: 5.0
|
||||||
path_ids:
|
route_ids:
|
||||||
- auto: auto
|
- push_ids:
|
||||||
invoice_state: none
|
- invoice_state: none
|
||||||
location_dest_id: stock_location.stock_location_qualitytest0
|
location_dest_id: stock_location.stock_location_qualitytest0
|
||||||
location_from_id: stock.stock_location_stock
|
location_from_id: stock.stock_location_stock
|
||||||
- auto: auto
|
- invoice_state: none
|
||||||
invoice_state: none
|
|
||||||
location_dest_id: stock.stock_location_components
|
location_dest_id: stock.stock_location_components
|
||||||
location_from_id: stock_location.stock_location_qualitytest0
|
location_from_id: stock_location.stock_location_qualitytest0
|
||||||
supply_method: buy
|
supply_method: buy
|
||||||
|
|
Loading…
Reference in New Issue