'purchase_workflow.xml',
'purchase_sequence.xml',
'purchase_data.xml',
+ 'wizard/purchase_order_group_view.xml',
'purchase_view.xml',
'purchase_report.xml',
- 'purchase_wizard.xml',
'stock_view.xml',
'partner_view.xml',
'process/purchase_process.xml'
name="Product purchases"
res_model="purchase.order.line"
src_model="product.product"/>
-
+<!--
<record model="ir.values" id="action_merge_purchase_order">
<field name="object" eval="1" />
<field name="name">Purchase Order</field>
<field name="key">action</field>
<field name="model">purchase.order</field>
</record>
+ -->
</data>
</openerp>
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
+ <!--
<wizard id="purchase_order_merge"
model="purchase.order"
multi="True"
keyword="client_action_multi"
name="purchase.order.merge"
string="Merge purchases"/>
+ -->
</data>
</openerp>
#
##############################################################################
-import wizard_group
+import purchase_order_group
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+++ /dev/null
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from osv import fields, osv
-from service import web_services
-import netsvc
-import pooler
-import time
-import wizard
-from osv.orm import browse_record, browse_null
-
-class purchase_order_group(osv.osv_memory):
- _name = "purchase.order.group"
- _description = "Purchase Wizard"
- _columns = {
-
- }
-
- def merge_orders(self, cr, uid, ids, context):
- order_obj = self.pool.get('purchase.order')
- mod_obj =self.pool.get('ir.model.data')
- result = mod_obj._get_id(cr, uid, 'purchase', 'view_purchase_order_filter')
- id = mod_obj.read(cr, uid, result, ['res_id'])
-
-
-
- def make_key(br, fields):
- list_key = []
- for field in fields:
- field_val = getattr(br, field)
- if field in ('product_id', 'move_dest_id', 'account_analytic_id'):
- if not field_val:
- field_val = False
- if isinstance(field_val, browse_record):
- field_val = field_val.id
- elif isinstance(field_val, browse_null):
- field_val = False
- elif isinstance(field_val, list):
- field_val = ((6, 0, tuple([v.id for v in field_val])),)
- list_key.append((field, field_val))
- list_key.sort()
- return tuple(list_key)
-
- # compute what the new orders should contain
-
- new_orders = {}
-
- for porder in [order for order in order_obj.browse(cr, uid, context['active_ids']) if order.state == 'draft']:
- order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id'))
-
- new_order = new_orders.setdefault(order_key, ({}, []))
- new_order[1].append(porder.id)
- order_infos = new_order[0]
- if not order_infos:
- order_infos.update({
- 'origin': porder.origin,
- 'date_order': time.strftime('%Y-%m-%d'),
- 'partner_id': porder.partner_id.id,
- 'partner_address_id': porder.partner_address_id.id,
- 'dest_address_id': porder.dest_address_id.id,
- 'warehouse_id': porder.warehouse_id.id,
- 'location_id': porder.location_id.id,
- 'pricelist_id': porder.pricelist_id.id,
- 'state': 'draft',
- 'order_line': {},
- 'notes': '%s' % (porder.notes or '',),
- })
- else:
- #order_infos['name'] += ', %s' % porder.name
- if porder.notes:
- order_infos['notes'] = (order_infos['notes'] or '') + ('\n%s' % (porder.notes,))
- if porder.origin:
- order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin
-
- for order_line in porder.order_line:
- line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'notes', 'product_id', 'move_dest_id', 'account_analytic_id'))
- o_line = order_infos['order_line'].setdefault(line_key, {})
- if o_line:
- # merge the line with an existing line
- o_line['product_qty'] += order_line.product_qty * order_line.product_uom.factor / o_line['uom_factor']
- else:
- # append a new "standalone" line
- for field in ('product_qty', 'product_uom'):
- field_val = getattr(order_line, field)
- if isinstance(field_val, browse_record):
- field_val = field_val.id
- o_line[field] = field_val
- o_line['uom_factor'] = order_line.product_uom and order_line.product_uom.factor or 1.0
-
- wf_service = netsvc.LocalService("workflow")
-
- allorders = []
- for order_key, (order_data, old_ids) in new_orders.iteritems():
- # skip merges with only one order
- if len(old_ids) < 2:
- allorders += (old_ids or [])
- continue
-
- # cleanup order line data
- for key, value in order_data['order_line'].iteritems():
- del value['uom_factor']
- value.update(dict(key))
- order_data['order_line'] = [(0, 0, value) for value in order_data['order_line'].itervalues()]
-
- # create the new order
- neworder_id = order_obj.create(cr, uid, order_data)
- allorders.append(neworder_id)
-
- # make triggers pointing to the old orders point to the new order
- for old_id in old_ids:
- wf_service.trg_redirect(uid, 'purchase.order', old_id, neworder_id, cr)
- wf_service.trg_validate(uid, 'purchase.order', old_id, 'purchase_cancel', cr)
-
- return {
- 'domain': "[('id','in', [" + ','.join(map(str, allorders)) + "])]",
- 'name': 'Purchase Orders',
- 'view_type': 'form',
- 'view_mode': 'tree,form',
- 'res_model': 'purchase.order',
- 'view_id': False,
- 'type': 'ir.actions.act_window',
- 'search_view_id': id['res_id']
- }
-
-
-
-
-purchase_order_group()
-
--- /dev/null
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from osv import fields, osv
+from service import web_services
+import netsvc
+import pooler
+import time
+import wizard
+from osv.orm import browse_record, browse_null
+
+class purchase_order_group(osv.osv_memory):
+ _name = "purchase.order.group"
+ _description = "Purchase Wizard"
+ _columns = {
+
+ }
+
+ def merge_orders(self, cr, uid, ids, context):
+ """
+ To merge similar type of purchase orders.
+
+ @param self: The object pointer.
+ @param cr: A database cursor
+ @param uid: ID of the user currently logged in
+ @param ids: the ID or list of IDs
+ @param context: A standard dictionary
+
+ @return: purchase order view
+
+ """
+ order_obj = self.pool.get('purchase.order')
+ mod_obj =self.pool.get('ir.model.data')
+ result = mod_obj._get_id(cr, uid, 'purchase', 'view_purchase_order_filter')
+ id = mod_obj.read(cr, uid, result, ['res_id'])
+
+
+
+ def make_key(br, fields):
+ """
+ Returns tuple indicating the value corresponding to fields
+
+ @param br: record object
+ @param fields: name of fields
+ @return: Returns tuple indicating the value corresponding to fields
+
+ """
+ list_key = []
+ for field in fields:
+ field_val = getattr(br, field)
+ if field in ('product_id', 'move_dest_id', 'account_analytic_id'):
+ if not field_val:
+ field_val = False
+ if isinstance(field_val, browse_record):
+ field_val = field_val.id
+ elif isinstance(field_val, browse_null):
+ field_val = False
+ elif isinstance(field_val, list):
+ field_val = ((6, 0, tuple([v.id for v in field_val])),)
+ list_key.append((field, field_val))
+ list_key.sort()
+ return tuple(list_key)
+
+ # compute what the new orders should contain
+
+ new_orders = {}
+
+ for porder in [order for order in order_obj.browse(cr, uid, context['active_ids']) if order.state == 'draft']:
+ order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id'))
+ new_order = new_orders.setdefault(order_key, ({}, []))
+ new_order[1].append(porder.id)
+ order_infos = new_order[0]
+ if not order_infos:
+ order_infos.update({
+ 'origin': porder.origin,
+ 'date_order': time.strftime('%Y-%m-%d'),
+ 'partner_id': porder.partner_id.id,
+ 'partner_address_id': porder.partner_address_id.id,
+ 'dest_address_id': porder.dest_address_id.id,
+ 'warehouse_id': porder.warehouse_id.id,
+ 'location_id': porder.location_id.id,
+ 'pricelist_id': porder.pricelist_id.id,
+ 'state': 'draft',
+ 'order_line': {},
+ 'notes': '%s' % (porder.notes or '',),
+ })
+ else:
+ #order_infos['name'] += ', %s' % porder.name
+ if porder.notes:
+ order_infos['notes'] = (order_infos['notes'] or '') + ('\n%s' % (porder.notes,))
+ if porder.origin:
+ order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin
+
+ for order_line in porder.order_line:
+ line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'notes', 'product_id', 'move_dest_id', 'account_analytic_id'))
+ o_line = order_infos['order_line'].setdefault(line_key, {})
+ if o_line:
+ # merge the line with an existing line
+ o_line['product_qty'] += order_line.product_qty * order_line.product_uom.factor / o_line['uom_factor']
+ else:
+ # append a new "standalone" line
+ for field in ('product_qty', 'product_uom'):
+ field_val = getattr(order_line, field)
+ if isinstance(field_val, browse_record):
+ field_val = field_val.id
+ o_line[field] = field_val
+ o_line['uom_factor'] = order_line.product_uom and order_line.product_uom.factor or 1.0
+
+ wf_service = netsvc.LocalService("workflow")
+
+ allorders = []
+ for order_key, (order_data, old_ids) in new_orders.iteritems():
+ # skip merges with only one order
+ if len(old_ids) < 2:
+ allorders += (old_ids or [])
+ continue
+
+ # cleanup order line data
+ for key, value in order_data['order_line'].iteritems():
+ del value['uom_factor']
+ value.update(dict(key))
+ order_data['order_line'] = [(0, 0, value) for value in order_data['order_line'].itervalues()]
+
+ # create the new order
+ neworder_id = order_obj.create(cr, uid, order_data)
+ allorders.append(neworder_id)
+
+ # make triggers pointing to the old orders point to the new order
+ for old_id in old_ids:
+ wf_service.trg_redirect(uid, 'purchase.order', old_id, neworder_id, cr)
+ wf_service.trg_validate(uid, 'purchase.order', old_id, 'purchase_cancel', cr)
+
+ return {
+ 'domain': "[('id','in', [" + ','.join(map(str, allorders)) + "])]",
+ 'name': 'Purchase Orders',
+ 'view_type': 'form',
+ 'view_mode': 'tree,form',
+ 'res_model': 'purchase.order',
+ 'view_id': False,
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': id['res_id']
+ }
+purchase_order_group()
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record id="view_purchase_order_group" model="ir.ui.view">
+ <field name="name">Merger Purchase Orders</field>
+ <field name="model">purchase.order.group</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Merge orders">
+ <separator string="Are you sure you want to merge these orders ?" colspan="4"/>
+ <newline/>
+ <label string="Please note that:" colspan="4"/>
+ <newline/>
+ <label string="-orders will only be merged if:" colspan="4"/>
+ <newline/>
+ <label string="* their status is draft" colspan="4"/>
+ <newline/>
+ <label string="* they belong to the same partner" colspan="4"/>
+ <newline/>
+ <label string="* are going to the same location" colspan="4"/>
+ <newline/>
+ <label string="* have the same pricelist" colspan="4"/>
+ <newline/>
+ <label string="- lines will only be merged if:" colspan="4"/>
+ <newline/>
+ <label string="* they are exactly the same except for the quantity and unit" colspan="4"/>
+ <separator string="" colspan="4" />
+ <button special="cancel" string="Cancel" />
+ <button name="merge_orders" string="Merge orders" type="object" />
+ </form>
+ </field>
+ </record>
+
+ <act_window name="Merge Purchase orders"
+ res_model="purchase.order.group"
+ src_model="purchase.order"
+ view_mode="form"
+ target="new"
+ key2="client_action_multi"
+ id="action_view_purchase_order_group"/>
+
+ </data>
+</openerp>
+
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
- <data>
- <record id="view_purchase_order_group" model="ir.ui.view">
- <field name="name">Merger Purchase Orders</field>
- <field name="model">purchase.order.group</field>
- <field name="type">form</field>
- <field name="arch" type="xml">
- <form string="Merge orders">
- <separator string="Are you sure you want to merge these orders ?" colspan="4"/>
- <newline/>
- <label string="Please note that:" colspan="4"/>
- <newline/>
- <label string="-orders will only be merged if:" colspan="4"/>
- <newline/>
- <label string="* their status is draft" colspan="4"/>
- <newline/>
- <label string="* they belong to the same partner" colspan="4"/>
- <newline/>
- <label string="* are going to the same location" colspan="4"/>
- <newline/>
- <label string="* have the same pricelist" colspan="4"/>
- <newline/>
- <label string="- lines will only be merged if:" colspan="4"/>
- <newline/>
- <label string="* they are exactly the same except for the quantity and unit" colspan="4"/>
- <separator string="" colspan="4" />
- <button special="cancel" string="Cancel" />
- <button name="merge_orders" string="Merge orders" type="object" />
- </form>
- </field>
- </record>
-
- <record id="action_view_purchase_order_group" model="ir.actions.act_window">
- <field name="name">Merge Purchase order</field>
- <field name="type">ir.actions.act_window</field>
- <field name="res_model">purchase.order.group</field>
- <field name="view_type">form</field>
- <field name="view_mode">form</field>
- <field name="target">new</field>
- <field name="view_id" ref="view_purchase_order_group"/>
- </record>
-
- </data>
-</openerp>
-