[IMP] pocurement, stock, purchase, sale_stock, stock_account: misc changes in usabilty, code refactoring and new option on procurement group propagation.
1) form view of procurement.order and procurement.rule reviewed 2) added buttons on procurement.order to jump on other procurements or pickings of same procurement.group 3) tracked some fields on procurement.order 4) used the short name of warehouse for the rule names 5) added a new choice for the procurement.group propagation in order to allow having only one reception picking for several po lines grouped in the same PO but belonging to different procurement.group at first 6) some code refactored for easiness, modularity, clarity and other obvious reasons bzr revid: qdp-launchpad@openerp.com-20131107112053-knracfslqkfitg8b
This commit is contained in:
parent
6fc076087c
commit
d2d0184587
|
@ -82,12 +82,19 @@ class procurement_rule(osv.osv):
|
|||
_columns = {
|
||||
'name': fields.char('Name', required=True,
|
||||
help="This field will fill the packing origin and the name of its moves"),
|
||||
'group_id': fields.many2one('procurement.group', 'Procurement Group'),
|
||||
'group_propagation_option': fields.selection([('none', 'Leave Empty'), ('propagate', 'Propagate'), ('fixed', 'Fixed')], string="Propagation of Procurement Group"),
|
||||
'group_id': fields.many2one('procurement.group', 'Fixed Procurement Group'),
|
||||
'action': fields.selection(selection=lambda s, cr, uid, context=None: s._get_action(cr, uid, context=context),
|
||||
string='Action', required=True),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'group_propagation_option': 'propagate',
|
||||
'sequence': 20,
|
||||
}
|
||||
|
||||
|
||||
class procurement_order(osv.osv):
|
||||
"""
|
||||
|
@ -107,11 +114,11 @@ class procurement_order(osv.osv):
|
|||
'company_id': fields.many2one('res.company', 'Company', required=True),
|
||||
|
||||
# These two fields are used for shceduling
|
||||
'priority': fields.selection([('0', 'Not urgent'), ('1', 'Normal'), ('2', 'Urgent'), ('3', 'Very Urgent')], 'Priority', required=True, select=True),
|
||||
'date_planned': fields.datetime('Scheduled date', required=True, select=True),
|
||||
'priority': fields.selection([('0', 'Not urgent'), ('1', 'Normal'), ('2', 'Urgent'), ('3', 'Very Urgent')], 'Priority', required=True, select=True, track_visibility='onchange'),
|
||||
'date_planned': fields.datetime('Scheduled Date', required=True, select=True, track_visibility='onchange'),
|
||||
|
||||
'group_id': fields.many2one('procurement.group', 'Procurement Group'),
|
||||
'rule_id': fields.many2one('procurement.rule', 'Rule'),
|
||||
'rule_id': fields.many2one('procurement.rule', 'Rule', track_visibility='onchange'),
|
||||
|
||||
'product_id': fields.many2one('product.product', 'Product', required=True, states={'confirmed': [('readonly', False)]}, readonly=True),
|
||||
'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True, states={'confirmed': [('readonly', False)]}, readonly=True),
|
||||
|
@ -141,14 +148,27 @@ class procurement_order(osv.osv):
|
|||
procurements = self.read(cr, uid, ids, ['state'], context=context)
|
||||
unlink_ids = []
|
||||
for s in procurements:
|
||||
if s['state'] in ['draft','cancel']:
|
||||
if s['state'] in ['draft', 'cancel']:
|
||||
unlink_ids.append(s['id'])
|
||||
else:
|
||||
raise osv.except_osv(_('Invalid Action!'),
|
||||
_('Cannot delete Procurement Order(s) which are in %s state.') % \
|
||||
s['state'])
|
||||
_('Cannot delete Procurement Order(s) which are in %s state.') % s['state'])
|
||||
return osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
|
||||
|
||||
def do_view_procurements(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
This function returns an action that display existing procurement orders
|
||||
of same procurement group of given ids.
|
||||
'''
|
||||
mod_obj = self.pool.get('ir.model.data')
|
||||
act_obj = self.pool.get('ir.actions.act_window')
|
||||
result = mod_obj.get_object_reference(cr, uid, 'procurement', 'do_view_procurements')
|
||||
id = result and result[1] or False
|
||||
result = act_obj.read(cr, uid, [id], context=context)[0]
|
||||
group_ids = set([proc.group_id.id for proc in self.browse(cr, uid, ids, context=context) if proc.group_id])
|
||||
result['domain'] = "[('group_id','in',[" + ','.join(map(str, list(group_ids))) + "])]"
|
||||
return result
|
||||
|
||||
def onchange_product_id(self, cr, uid, ids, product_id, context=None):
|
||||
""" Finds UoM and UoS of changed product.
|
||||
@param product_id: Changed id of product.
|
||||
|
@ -215,8 +235,6 @@ class procurement_order(osv.osv):
|
|||
if procurement.product_id.type != 'service':
|
||||
rule_id = self._find_suitable_rule(cr, uid, procurement, context=context)
|
||||
if rule_id:
|
||||
rule = self.pool.get('procurement.rule').browse(cr, uid, rule_id, context=context)
|
||||
self.message_post(cr, uid, [procurement.id], body=_('Following rule %s for the procurement resolution.') % (rule.name), context=context)
|
||||
self.write(cr, uid, [procurement.id], {'rule_id': rule_id}, context=context)
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
<field name="state" readonly="1" widget="statusbar" statusbar_visible="draft,confirmed,running,done" />
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
<button name="do_view_procurements" string="Group's Procurements" type="object"/>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="product_id" on_change="onchange_product_id(product_id)"/>
|
||||
|
@ -50,25 +53,30 @@
|
|||
<field name="product_uos" class="oe_inline"/>
|
||||
</div>
|
||||
</group>
|
||||
<newline/>
|
||||
<group>
|
||||
<field name="rule_id"/>
|
||||
<group name="scheduling">
|
||||
<field name="date_planned"/>
|
||||
<field name="priority"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="group_id"/>
|
||||
<field name="origin" class="oe_inline" placeholder="e.g. SO005"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Extra Information">
|
||||
<page string="Notes">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<field name="name" placeholder="External note..."/>
|
||||
<label for="message" class="oe_edit_only"/>
|
||||
<field name="message"/>
|
||||
</page>
|
||||
<page string="Extra Information">
|
||||
<group>
|
||||
<group>
|
||||
<field name="origin" placeholder="e.g. SO005"/>
|
||||
<field name="group_id" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="rule_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
|
@ -80,7 +88,7 @@
|
|||
</record>
|
||||
|
||||
<record id="do_view_procurements" model="ir.actions.act_window">
|
||||
<field name="name">Procurement for Groups </field>
|
||||
<field name="name">Group's Procurements</field>
|
||||
<field name="res_model">procurement.order</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
|
@ -93,8 +101,8 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Procurement group" version="7.0">
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<button name="%(do_view_procurements)d" string="View related procurements" type="action" />
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
<button name="%(do_view_procurements)d" string="Procurements" type="action"/>
|
||||
</div>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
|
@ -174,5 +182,45 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('state','=','exception')]</field>
|
||||
</record>
|
||||
|
||||
<!-- Procurement Rules -->
|
||||
<record model="ir.ui.view" id="view_procurement_rule_tree">
|
||||
<field name="name">procurement.rule.tree</field>
|
||||
<field name="model">procurement.rule</field>
|
||||
<field eval="10" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Pull Rules">
|
||||
<field name="name"/>
|
||||
<field name="action"/>
|
||||
<field name='company_id' groups="base.group_multi_company"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_procurement_rule_form">
|
||||
<field name="name">procurement.rule.form</field>
|
||||
<field name="model">procurement.rule</field>
|
||||
<field eval="10" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Pull Rule" version="7.0">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
</div>
|
||||
<group>
|
||||
<group string="General Information">
|
||||
<field name="action"/>
|
||||
<field name="sequence"/>
|
||||
</group>
|
||||
<group name="propagation_group" string="Propagation Options" groups="base.group_no_one">
|
||||
<field name="group_propagation_option"/>
|
||||
<field name="group_id" attrs="{'invisible': [('group_propagation_option', '!=', 'fixed')], 'required': [('group_propagation_option', '=', 'fixed')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1186,67 +1186,69 @@ class procurement_order(osv.osv):
|
|||
seller_delay = int(procurement.product_id.seller_delay)
|
||||
return schedule_date - relativedelta(days=seller_delay)
|
||||
|
||||
def _get_product_supplier(self, cr, uid, procurement, context=None):
|
||||
''' returns the main supplier of the procurement's product given as argument'''
|
||||
return procurement.product_id.seller_id
|
||||
|
||||
def _get_po_line_values_from_proc(self, cr, uid, procurement, partner, company, schedule_date, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
uom_obj = self.pool.get('product.uom')
|
||||
pricelist_obj = self.pool.get('product.pricelist')
|
||||
prod_obj = self.pool.get('product.product')
|
||||
acc_pos_obj = self.pool.get('account.fiscal.position')
|
||||
|
||||
seller_qty = procurement.product_id.seller_qty
|
||||
pricelist_id = partner.property_product_pricelist_purchase.id
|
||||
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)
|
||||
price = pricelist_obj.price_get(cr, uid, [pricelist_id], procurement.product_id.id, qty, partner.id, {'uom': uom_id})[pricelist_id]
|
||||
|
||||
#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
|
||||
|
||||
return {
|
||||
'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': procurement.move_dest_id and procurement.move_dest_id.id or False,
|
||||
'taxes_id': [(6, 0, taxes)],
|
||||
}
|
||||
|
||||
def make_po(self, cr, uid, ids, context=None):
|
||||
""" Make purchase order from procurement
|
||||
@return: New created Purchase Orders procurement wise
|
||||
"""
|
||||
res = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
po_obj = self.pool.get('purchase.order')
|
||||
po_line_obj = self.pool.get('purchase.order.line')
|
||||
uom_obj = self.pool.get('product.uom')
|
||||
pricelist_obj = self.pool.get('product.pricelist')
|
||||
prod_obj = self.pool.get('product.product')
|
||||
acc_pos_obj = self.pool.get('account.fiscal.position')
|
||||
seq_obj = self.pool.get('ir.sequence')
|
||||
pass_ids = []
|
||||
linked_po_ids = []
|
||||
for procurement in self.browse(cr, uid, ids, context=context):
|
||||
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.
|
||||
partner = self._get_product_supplier(cr, uid, procurement, context=context)
|
||||
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
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
#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)],
|
||||
}
|
||||
line_vals = self._get_po_line_values_from_proc(cr, uid, procurement, partner, company, schedule_date, context=context)
|
||||
#look for any other draft PO for the same supplier, to attach the new line on instead of creating a new draft one
|
||||
available_draft_po_ids = po_obj.search(cr, uid, [
|
||||
('partner_id', '=', partner_id), ('state', '=', 'draft'), ('picking_type_id', '=', procurement.rule_id.picking_type_id.id),
|
||||
('partner_id', '=', partner.id), ('state', '=', 'draft'), ('picking_type_id', '=', procurement.rule_id.picking_type_id.id),
|
||||
('location_id', '=', procurement.location_id.id), ('company_id', '=', procurement.company_id.id)], context=context)
|
||||
if available_draft_po_ids:
|
||||
po_id = available_draft_po_ids[0]
|
||||
|
@ -1254,20 +1256,21 @@ class procurement_order(osv.osv):
|
|||
po_line_id = po_line_obj.create(cr, uid, line_vals, context=context)
|
||||
linked_po_ids.append(procurement.id)
|
||||
else:
|
||||
purchase_date = self._get_purchase_order_date(cr, uid, procurement, company, schedule_date, context=context)
|
||||
name = seq_obj.get(cr, uid, 'purchase.order') or _('PO: %s') % procurement.name
|
||||
po_vals = {
|
||||
'name': name,
|
||||
'origin': procurement.origin,
|
||||
'partner_id': partner_id,
|
||||
'partner_id': partner.id,
|
||||
'location_id': procurement.location_id.id,
|
||||
'picking_type_id': procurement.rule_id.picking_type_id.id,
|
||||
'pricelist_id': pricelist_id,
|
||||
'pricelist_id': partner.property_product_pricelist_purchase.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,
|
||||
}
|
||||
po_id = self.create_procurement_purchase_order(cr, uid, procurement, po_vals, line_vals, context=new_context)
|
||||
po_id = self.create_procurement_purchase_order(cr, uid, procurement, po_vals, line_vals, context=context)
|
||||
po_line_id = po_obj.browse(cr, uid, po_id, context=context).order_line[0].id
|
||||
pass_ids.append(procurement.id)
|
||||
res[procurement.id] = po_line_id
|
||||
|
|
|
@ -63,26 +63,21 @@ class sale_order(osv.osv):
|
|||
if move.procurement_id and move.procurement_id.sale_line_id:
|
||||
res.add(move.procurement_id.sale_line_id.order_id.id)
|
||||
return list(res)
|
||||
|
||||
|
||||
def _get_orders_procurements(self, cr, uid, ids, context=None):
|
||||
res = set()
|
||||
for proc in self.pool.get('procurement.order').browse(cr, uid, ids, context=context):
|
||||
if proc.sale_line_id:
|
||||
res.add(proc.sale_line_id.order_id.id)
|
||||
return list(res)
|
||||
|
||||
|
||||
def _get_picking_ids(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
for sale in self.browse(cr, uid, ids, context=context):
|
||||
if not sale.procurement_group_id:
|
||||
res[sale.id] = []
|
||||
continue
|
||||
picking_ids = set()
|
||||
for procurement in sale.procurement_group_id.procurement_ids:
|
||||
for move in procurement.move_ids:
|
||||
if move.picking_id:
|
||||
picking_ids.add(move.picking_id.id)
|
||||
res[sale.id] = list(picking_ids)
|
||||
res[sale.id] = self.pool.get('stock.picking').search(cr, uid, [('group_id', '=', sale.procurement_group_id.id)], context=context)
|
||||
return res
|
||||
|
||||
def _prepare_order_line_procurement(self, cr, uid, order, line, group_id=False, context=None):
|
||||
|
|
|
@ -72,7 +72,6 @@ class procurement_rule(osv.osv):
|
|||
'stock.location.route': (_get_rules, ['sequence'], 10),
|
||||
'procurement.rule': (lambda self, cr, uid, ids, c={}: ids, ['route_id'], 10),
|
||||
}),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type',
|
||||
help="Picking Type determines the way the picking should be shown in the view, reports, ..."),
|
||||
'active': fields.related('route_id', 'active', type='boolean', string='Active', store={
|
||||
|
@ -88,10 +87,9 @@ class procurement_rule(osv.osv):
|
|||
|
||||
_defaults = {
|
||||
'procure_method': 'make_to_stock',
|
||||
'sequence': 20,
|
||||
'active': True,
|
||||
'propagate': True,
|
||||
'delay': 0,
|
||||
'active': True,
|
||||
'propagate': True,
|
||||
'delay': 0,
|
||||
}
|
||||
|
||||
class procurement_order(osv.osv):
|
||||
|
@ -100,7 +98,7 @@ class procurement_order(osv.osv):
|
|||
'location_id': fields.many2one('stock.location', 'Procurement Location'), # not required because task may create procurements that aren't linked to a location with project_mrp
|
||||
'move_ids': fields.one2many('stock.move', 'procurement_id', 'Moves', help="Moves created by the procurement"),
|
||||
'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Move which caused (created) the procurement"),
|
||||
'route_ids': fields.many2many('stock.location.route', 'stock_location_route_procurement', 'procurement_id', 'route_id', 'Followed Route', help="Preferred route to be followed by the procurement order"),
|
||||
'route_ids': fields.many2many('stock.location.route', 'stock_location_route_procurement', 'procurement_id', 'route_id', 'Preferred Routes', help="Preferred route to be followed by the procurement order. Usually copied from the generating document (SO) but could be set up manually."),
|
||||
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', help="Warehouse to consider for the route selection"),
|
||||
}
|
||||
|
||||
|
@ -161,7 +159,19 @@ class procurement_order(osv.osv):
|
|||
return rule_id
|
||||
|
||||
def _run_move_create(self, cr, uid, procurement, context=None):
|
||||
vals = {
|
||||
''' Returns a dictionary of values that will be sued to create a stock move from a procurement.
|
||||
This function assumes that the given procurement has a rule (action == 'move') set on it.
|
||||
|
||||
:param procurement: browse record
|
||||
:rtype: dictionary
|
||||
'''
|
||||
newdate = (datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - relativedelta(days=procurement.rule_id.delay or 0)).strftime('%Y-%m-%d %H:%M:%S')
|
||||
group_id = False
|
||||
if procurement.rule_id.group_propagation_option == 'propagate':
|
||||
group_id = procurement.group_id and procurement.group_id.id or False
|
||||
elif procurement.rule_id.group_propagation_option == 'fixed':
|
||||
group_id = procurement.rule_id.group_id and procurement.rule_id.group_id.id or False
|
||||
vals = {
|
||||
'name': procurement.name,
|
||||
'company_id': procurement.company_id.id,
|
||||
'product_id': procurement.product_id.id,
|
||||
|
@ -170,12 +180,9 @@ class procurement_order(osv.osv):
|
|||
'product_qty': procurement.product_qty,
|
||||
'product_uom': procurement.product_uom.id,
|
||||
'product_uom_qty': procurement.product_qty,
|
||||
'product_uos_qty': (procurement.product_uos and procurement.product_uos_qty)\
|
||||
or procurement.product_qty,
|
||||
'product_uos': (procurement.product_uos and procurement.product_uos.id)\
|
||||
or procurement.product_uom.id,
|
||||
'partner_id': procurement.group_id and procurement.group_id.partner_id and \
|
||||
procurement.group_id.partner_id.id or False,
|
||||
'product_uos_qty': (procurement.product_uos and procurement.product_uos_qty) or procurement.product_qty,
|
||||
'product_uos': (procurement.product_uos and procurement.product_uos.id) or procurement.product_uom.id,
|
||||
'partner_id': procurement.group_id and procurement.group_id.partner_id and procurement.group_id.partner_id.id or False,
|
||||
'location_id': procurement.rule_id.location_src_id.id,
|
||||
'location_dest_id': procurement.rule_id.location_id.id,
|
||||
'move_dest_id': procurement.move_dest_id and procurement.move_dest_id.id or False,
|
||||
|
@ -184,16 +191,12 @@ class procurement_order(osv.osv):
|
|||
'procure_method': procurement.rule_id.procure_method,
|
||||
'origin': procurement.origin,
|
||||
'picking_type_id': procurement.rule_id.picking_type_id.id,
|
||||
'group_id': procurement.group_id and procurement.group_id.id or False,
|
||||
'group_id': group_id,
|
||||
'route_ids': [(4, x.id) for x in procurement.route_ids],
|
||||
'warehouse_id': procurement.rule_id.propagate_warehouse_id and procurement.rule_id.propagate_warehouse_id.id or procurement.rule_id.warehouse_id.id,
|
||||
}
|
||||
if procurement.rule_id:
|
||||
newdate = (datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - relativedelta(days=procurement.rule_id.delay or 0)).strftime('%Y-%m-%d %H:%M:%S')
|
||||
vals.update({
|
||||
'date': newdate,
|
||||
'propagate': procurement.rule_id.propagate,
|
||||
})
|
||||
'date': newdate,
|
||||
'propagate': procurement.rule_id.propagate,
|
||||
}
|
||||
return vals
|
||||
|
||||
def _run(self, cr, uid, procurement, context=None):
|
||||
|
@ -229,7 +232,19 @@ class procurement_order(osv.osv):
|
|||
|
||||
return super(procurement_order, self)._check(cr, uid, procurement, context)
|
||||
|
||||
|
||||
def do_view_pickings(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
This function returns an action that display the pickings of the procurements belonging
|
||||
to the same procurement group of given ids.
|
||||
'''
|
||||
mod_obj = self.pool.get('ir.model.data')
|
||||
act_obj = self.pool.get('ir.actions.act_window')
|
||||
result = mod_obj.get_object_reference(cr, uid, 'stock', 'do_view_pickings')
|
||||
id = result and result[1] or False
|
||||
result = act_obj.read(cr, uid, [id], context=context)[0]
|
||||
group_ids = set([proc.group_id.id for proc in self.browse(cr, uid, ids, context=context) if proc.group_id])
|
||||
result['domain'] = "[('group_id','in',[" + ','.join(map(str, list(group_ids))) + "])]"
|
||||
return result
|
||||
|
||||
#
|
||||
# Scheduler
|
||||
|
|
|
@ -1322,7 +1322,7 @@ class stock_move(osv.osv):
|
|||
'stock.quant': (_get_move, ['reservation_id'], 10)}),
|
||||
'procurement_id': fields.many2one('procurement.order', 'Procurement'),
|
||||
'group_id': fields.many2one('procurement.group', 'Procurement Group'),
|
||||
'rule_id': fields.many2one('procurement.rule', 'Procurement Rule'),
|
||||
'rule_id': fields.many2one('procurement.rule', 'Procurement Rule', help='The pull rule that created this stock move'),
|
||||
'propagate': fields.boolean('Propagate cancel and split', help='If checked, when this move is cancelled, cancel the linked move too'),
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type'),
|
||||
'inventory_id': fields.many2one('stock.inventory', 'Inventory'),
|
||||
|
@ -1384,8 +1384,14 @@ class stock_move(osv.osv):
|
|||
}
|
||||
|
||||
def _prepare_procurement_from_move(self, cr, uid, move, context=None):
|
||||
origin = (move.group_id and (move.group_id.name+":") or "") + (move.rule_id and move.rule_id.name or "/")
|
||||
return {
|
||||
origin = (move.group_id and (move.group_id.name + ":") or "") + (move.rule_id and move.rule_id.name or "/")
|
||||
group_id = move.group_id and move.group_id.id or False
|
||||
if move.rule_id:
|
||||
if move.rule_id.group_propagation_option == 'fixed' and move.rule_id.group_id:
|
||||
group_id = move.rule_id.group_id.id
|
||||
elif move.rule_id.group_propagation_option == 'none':
|
||||
group_id = False
|
||||
return {
|
||||
'name': move.rule_id and move.rule_id.name or "/",
|
||||
'origin': origin,
|
||||
'company_id': move.company_id and move.company_id.id or False,
|
||||
|
@ -1397,8 +1403,8 @@ class stock_move(osv.osv):
|
|||
'product_uos': (move.product_uos and move.product_uos.id) or move.product_uom.id,
|
||||
'location_id': move.location_id.id,
|
||||
'move_dest_id': move.id,
|
||||
'group_id': move.group_id and move.group_id.id or False,
|
||||
'route_ids' : [(4, x.id) for x in move.route_ids],
|
||||
'group_id': group_id,
|
||||
'route_ids': [(4, x.id) for x in move.route_ids],
|
||||
'warehouse_id': move.warehouse_id and move.warehouse_id.id or False,
|
||||
}
|
||||
|
||||
|
@ -2690,7 +2696,7 @@ class stock_warehouse(osv.osv):
|
|||
return new_id
|
||||
|
||||
def _format_rulename(self, cr, uid, obj, from_loc, dest_loc, context=None):
|
||||
return obj.name + ': ' + from_loc.name + ' -> ' + dest_loc.name
|
||||
return obj.code + ': ' + from_loc.name + ' -> ' + dest_loc.name
|
||||
|
||||
def _format_routename(self, cr, uid, obj, name, context=None):
|
||||
return obj.name + ': ' + name
|
||||
|
|
|
@ -1540,7 +1540,7 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_picking_type_list" model="ir.actions.act_window">
|
||||
<record id="action_picking_type_list" model="ir.actions.act_window">
|
||||
<field name="name">All Operations</field>
|
||||
<field name="res_model">stock.picking.type</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
|
@ -1554,10 +1554,10 @@
|
|||
parent="menu_stock_warehouse_mgmt" sequence="1"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_pickingtype"
|
||||
name="Types of Operation"
|
||||
parent="stock.menu_stock_configuration"
|
||||
action="action_picking_type_list" />
|
||||
id="menu_pickingtype"
|
||||
name="Types of Operation"
|
||||
parent="stock.menu_stock_configuration"
|
||||
action="action_picking_type_list" />
|
||||
|
||||
|
||||
<!-- Order Point -->
|
||||
|
@ -1669,12 +1669,15 @@
|
|||
<field name="model">procurement.order</field>
|
||||
<field name="inherit_id" ref="procurement.procurement_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='origin']" position="after">
|
||||
<field name="warehouse_id" on_change="change_warehouse_id(warehouse_id, context)"/>
|
||||
<field name="location_id" domain="[('usage', '=', 'internal')]"/>
|
||||
<xpath expr="//group[@name='scheduling']" position="before">
|
||||
<group>
|
||||
<field name="warehouse_id" on_change="change_warehouse_id(warehouse_id, context)"/>
|
||||
<field name="location_id" domain="[('usage', '=', 'internal')]"/>
|
||||
<field name="route_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='rule_id']" position="after">
|
||||
<field name="route_ids" widget="many2many_tags"/>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button name="do_view_pickings" string="Group's Pickings" type="object"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -1688,73 +1691,51 @@
|
|||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_procurement_rule_tree">
|
||||
<field name="name">stock.procurement.tree</field>
|
||||
<record id="view_procurement_rule_tree_stock_inherit" model="ir.ui.view">
|
||||
<field name="name">procurement.rule.tree.stock.inherit</field>
|
||||
<field name="model">procurement.rule</field>
|
||||
<field eval="10" name="priority"/>
|
||||
|
||||
<field name="inherit_id" ref="procurement.view_procurement_rule_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Procurement Rules">
|
||||
<field name="location_src_id"/>
|
||||
<xpath expr="//field[@name='action']" position="after">
|
||||
<field name="picking_type_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_procurement_rule_form_stock_inherit" model="ir.ui.view">
|
||||
<field name="name">procurement.rule.form.stock.inherit</field>
|
||||
<field name="model">procurement.rule</field>
|
||||
<field name="inherit_id" ref="procurement.view_procurement_rule_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='action']" position="before">
|
||||
<field name="location_id"/>
|
||||
<field name="action"/>
|
||||
<field name="warehouse_id" groups="base.group_no_one"/>
|
||||
<field name="route_id" groups="base.group_no_one"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='action']" position="after">
|
||||
<field name="picking_type_id" attrs="{'required': [('action', '!=', 'manufacture')]}"/>
|
||||
</tree>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='group_id']" position="after">
|
||||
<field name="propagate"/>
|
||||
<field name="propagate_warehouse_id"/>
|
||||
</xpath>
|
||||
<xpath expr="//group[@name='propagation_group']" position="before">
|
||||
<group attrs="{'invisible': [('action', '!=', 'move')]}" string="Moving Options">
|
||||
<field name="procure_method"/>
|
||||
<field name="location_src_id" attrs="{'required': [('action', '=', 'move')]}"/>
|
||||
<field name="partner_address_id" groups="stock.group_adv_location" context="{'show_address': 1}" options="{'always_reload': 1}"/>
|
||||
<label for="delay" string="Delay" groups="stock.group_adv_location"/>
|
||||
<div>
|
||||
<field name="delay" class="oe_inline" groups="stock.group_adv_location"/>days
|
||||
</div>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_procurement_rule_form">
|
||||
<field name="name">stock.procurement.form</field>
|
||||
<field name="model">procurement.rule</field>
|
||||
<field eval="10" name="priority"/>
|
||||
|
||||
<field name="arch" type="xml">
|
||||
<form string="Procurement Rules" version="7.0">
|
||||
<sheet>
|
||||
<separator string="Pull Rule"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="action"/>
|
||||
</group>
|
||||
</group>
|
||||
<separator string="Informations"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="procure_method" attrs="{'invisible': [('action', '!=', 'move')]}"/>
|
||||
<field name="location_src_id" attrs="{'invisible': [('action', '!=', 'move')]}"/>
|
||||
<field name="location_id"/>
|
||||
<field name="partner_address_id" groups="stock.group_adv_location"/>
|
||||
|
||||
</group>
|
||||
<group>
|
||||
<field name="picking_type_id" attrs="{'required': [('action', '!=', 'manufacture')]}"/>
|
||||
<field name="route_id"/>
|
||||
<field name="group_id" groups="base.group_no_one"/>
|
||||
<field name="propagate" groups="stock.group_adv_location"/>
|
||||
<label for="delay" string="Delay" groups="stock.group_adv_location"/>
|
||||
<div>
|
||||
<field name="delay" class="oe_inline" groups="stock.group_adv_location"/>days
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<record model="ir.actions.act_window" id="procrules">
|
||||
<field name="context">{}</field>
|
||||
<field name="name">Global procurement rules</field>
|
||||
<field name="name">Pull Rules</field>
|
||||
<field name="res_model">procurement.rule</field>
|
||||
</record>
|
||||
|
||||
|
@ -1971,8 +1952,8 @@
|
|||
<group>
|
||||
<group>
|
||||
<field name="packaging_id"/>
|
||||
<field name='company_id' groups="base.group_multi_company"/>
|
||||
<field name='owner_id' groups="stock.group_tracking_owner"/>
|
||||
<field name='company_id' groups="base.group_multi_company"/>
|
||||
<field name='owner_id' groups="stock.group_tracking_owner"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="location_id"/>
|
||||
|
@ -2141,16 +2122,16 @@
|
|||
<field name="res_model">stock.picking</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('group_id','=',active_id)]</field>
|
||||
<field name="domain">[('group_id','=',active_id)]</field>
|
||||
</record>
|
||||
<record id="procurement_group_form_view_herited" model="ir.ui.view">
|
||||
<field name="name">procurement.group.form.herited</field>
|
||||
<field name="model">procurement.group</field>
|
||||
<field name="inherit_id" ref="procurement.procurement_group_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/sheet/div/button" position="after">
|
||||
<button name="%(do_view_pickings)d" string="View related pickings" type="action" />
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button name="%(do_view_pickings)d" string="Pickings" type="action"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -42,14 +42,14 @@
|
|||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_procurement_rule_form_inherit">
|
||||
<record model="ir.ui.view" id="view_procurement_rule_form_stockaccount_inherit">
|
||||
<field name="name">stock.procurement.rule.inherit.form</field>
|
||||
<field name="model">procurement.rule</field>
|
||||
<field name="inherit_id" ref="stock.view_procurement_rule_form"/>
|
||||
<field name="inherit_id" ref="stock.view_procurement_rule_form_stock_inherit"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="location_id" position="after">
|
||||
<xpath expr="//field[@name='picking_type_id']" position="after">
|
||||
<field name="invoice_state"/>
|
||||
</field>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
|
|
Loading…
Reference in New Issue