[IMP] procurement: removed the schedule_range field on res.company which was error...
authorQuentin (OpenERP) <qdp-launchpad@openerp.com>
Thu, 3 Apr 2014 07:10:10 +0000 (09:10 +0200)
committerQuentin (OpenERP) <qdp-launchpad@openerp.com>
Thu, 3 Apr 2014 07:10:10 +0000 (09:10 +0200)
bzr revid: qdp-launchpad@openerp.com-20140403071010-5mrox75rkufur2nw

addons/mrp/procurement.py
addons/procurement/__init__.py
addons/procurement/__openerp__.py
addons/procurement/company.py [deleted file]
addons/procurement/company_view.xml [deleted file]
addons/procurement/procurement.py
addons/purchase/purchase.py
addons/sale_stock/sale_stock.py
addons/stock/procurement.py

index 9ee5875..c1519ea 100644 (file)
@@ -21,9 +21,9 @@
 
 from datetime import datetime
 from dateutil.relativedelta import relativedelta
-from openerp.osv import fields
-from openerp.osv import osv
+from openerp.osv import osv, fields
 from openerp.tools.translate import _
+from openerp import SUPERUSER_ID
 
 class procurement_rule(osv.osv):
     _inherit = 'procurement.rule'
@@ -75,7 +75,6 @@ class procurement_order(osv.osv):
         company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
         production_obj = self.pool.get('mrp.production')
         bom_obj = self.pool.get('mrp.bom')
-        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):
             if self.check_bom_exists(cr, uid, [procurement.id], context=context):
@@ -91,7 +90,8 @@ class procurement_order(osv.osv):
                 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, {
+                #create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
+                produce_id = production_obj.create(cr, SUPERUSER_ID, {
                     'origin': procurement.origin,
                     'product_id': procurement.product_id.id,
                     'product_qty': procurement.product_qty,
index 5629564..a46f8a0 100644 (file)
@@ -21,5 +21,4 @@
 
 import procurement
 import wizard
-import company
 
index ca2ae09..76fab3b 100644 (file)
@@ -49,7 +49,6 @@ depending on the product's configuration.
         'procurement_data.xml',
         'wizard/schedulers_all_view.xml',
         'procurement_view.xml',
-        'company_view.xml',
     ],
     'demo': [],
     'test': ['test/procurement.yml'],
diff --git a/addons/procurement/company.py b/addons/procurement/company.py
deleted file mode 100644 (file)
index 1fd08d9..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- 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 openerp.osv import osv,fields
-
-class company(osv.osv):
-    _inherit = 'res.company'
-    _columns = {
-        'schedule_range': fields.float('Scheduler Range Days', required=True,
-            help="This is the time frame analysed by the scheduler when "\
-            "computing procurements. All procurements that are not between "\
-            "today and today+range are skipped for future computation."),
-    }
-    _defaults = {
-        'schedule_range': 730.0,
-    }
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/procurement/company_view.xml b/addons/procurement/company_view.xml
deleted file mode 100644 (file)
index dadd24a..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" ?>
-<openerp>
-    <data>
-
-        <record id="mrp_company" model="ir.ui.view">
-            <field name="name">res.company.mrp.config</field>
-            <field name="model">res.company</field>
-            <field name="priority">17</field>
-            <field name="inherit_id" ref="base.view_company_form"/>
-            <field name="arch" type="xml">
-                <xpath expr="//group[@name='account_grp']" position="after">
-                    <group name="logistics_grp" string="Logistics">
-                        <field name="schedule_range"/>
-                    </group>
-                </xpath>
-            </field>
-       </record>
-    
-    </data>
-</openerp>
index b35a775..1439b32 100644 (file)
@@ -21,9 +21,7 @@
 
 import time
 
-from datetime import datetime
-from dateutil.relativedelta import relativedelta
-
+from openerp import SUPERUSER_ID
 from openerp.osv import fields, osv
 import openerp.addons.decimal_precision as dp
 from openerp.tools.translate import _
@@ -31,7 +29,7 @@ import openerp
 
 class procurement_group(osv.osv):
     '''
-    The procurement requirement class is used to group products together
+    The procurement group class is used to group products together
     when computing procurements. (tasks, physical products, ...)
 
     The goal is that when you have one sale order of several products
@@ -56,12 +54,11 @@ class procurement_group(osv.osv):
     _description = 'Procurement Requisition'
     _order = "id desc"
     _columns = {
-        'name': fields.char('Reference', required=True), 
+        'name': fields.char('Reference', required=True),
         'move_type': fields.selection([
             ('direct', 'Partial'), ('one', 'All at once')],
             'Delivery Method', required=True),
-        'partner_id': fields.many2one('res.partner', string = 'Partner'), #Sale should pass it here 
-        'procurement_ids': fields.one2many('procurement.order', 'group_id', 'Procurements'), 
+        'procurement_ids': fields.one2many('procurement.order', 'group_id', 'Procurements'),
     }
     _defaults = {
         'name': lambda self, cr, uid, c: self.pool.get('ir.sequence').get(cr, uid, 'procurement.group') or '',
@@ -266,7 +263,8 @@ class procurement_order(osv.osv):
     #
     def run_scheduler(self, cr, uid, use_new_cursor=False, context=None):
         '''
-        Call the scheduler to check the procurement order
+        Call the scheduler to check the procurement order. This is intented to be done for all existing companies at
+        the same time, so we're running all the methods as SUPERUSER to avoid intercompany and access rights issues.
 
         @param self: The object pointer
         @param cr: The current row, from the database cursor,
@@ -282,25 +280,22 @@ class procurement_order(osv.osv):
             if use_new_cursor:
                 cr = openerp.registry(use_new_cursor).db.cursor()
 
-            company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
-            maxdate = (datetime.today() + relativedelta(days=company.schedule_range)).strftime('%Y-%m-%d %H:%M:%S')
-
             # Run confirmed procurements
             while True:
-                ids = self.search(cr, uid, [('state', '=', 'confirmed'), ('date_planned', '<=', maxdate)], context=context)
+                ids = self.search(cr, SUPERUSER_ID, [('state', '=', 'confirmed')], context=context)
                 if not ids:
                     break
-                self.run(cr, uid, ids, context=context)
+                self.run(cr, SUPERUSER_ID, ids, context=context)
                 if use_new_cursor:
                     cr.commit()
 
             # Check if running procurements are done
             offset = 0
             while True:
-                ids = self.search(cr, uid, [('state', '=', 'running'), ('date_planned', '<=', maxdate)], offset=offset, context=context)
+                ids = self.search(cr, SUPERUSER_ID, [('state', '=', 'running')], offset=offset, context=context)
                 if not ids:
                     break
-                done = self.check(cr, uid, ids, context=context)
+                done = self.check(cr, SUPERUSER_ID, ids, context=context)
                 offset += len(ids) - len(done)
                 if use_new_cursor:
                     cr.commit()
index a0d2180..df516b2 100644 (file)
@@ -1262,8 +1262,10 @@ class procurement_order(osv.osv):
         }
 
     def make_po(self, cr, uid, ids, context=None):
-        """ Make purchase order from procurement
-        @return: New created Purchase Orders procurement wise
+        """ Resolve the purchase from procurement, which may result in a new PO creation, a new PO line creation or a quantity change on existing PO line.
+        Note that some operations (as the PO creation) are made as SUPERUSER because the current user may not have rights to do it (mto product launched by a sale for example)
+
+        @return: dictionary giving for each procurement its related resolving PO line.
         """
         res = {}
         company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
@@ -1291,12 +1293,12 @@ class procurement_order(osv.osv):
                     available_po_line_ids = po_line_obj.search(cr, uid, [('order_id', '=', po_id), ('product_id', '=', line_vals['product_id']), ('product_uom', '=', line_vals['product_uom'])], context=context)
                     if available_po_line_ids:
                         po_line = po_line_obj.browse(cr, uid, available_po_line_ids[0], context=context)
-                        po_line_obj.write(cr, uid, po_line.id, {'product_qty': po_line.product_qty + line_vals['product_qty']}, context=context)
+                        po_line_obj.write(cr, SUPERUSER_ID, po_line.id, {'product_qty': po_line.product_qty + line_vals['product_qty']}, context=context)
                         po_line_id = po_line.id
                         sum_po_line_ids.append(procurement.id)
                     else:
                         line_vals.update(order_id=po_id)
-                        po_line_id = po_line_obj.create(cr, uid, line_vals, context=context)
+                        po_line_id = po_line_obj.create(cr, SUPERUSER_ID, 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)
@@ -1314,7 +1316,7 @@ class procurement_order(osv.osv):
                         'payment_term_id': partner.property_supplier_payment_term.id or False,
                         'dest_address_id': procurement.partner_dest_id.id,
                     }
-                    po_id = self.create_procurement_purchase_order(cr, uid, procurement, po_vals, line_vals, context=context)
+                    po_id = self.create_procurement_purchase_order(cr, SUPERUSER_ID, 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
index c7afb69..65727c2 100644 (file)
@@ -176,12 +176,6 @@ class sale_order(osv.osv):
                     raise osv.except_osv(
                         _('Cannot cancel sales order!'),
                         _('You must first cancel all delivery order(s) attached to this sales order.'))
-                 # FP Note: not sure we need this
-                 #if pick.state == 'cancel':
-                 #    for mov in pick.move_lines:
-                 #        proc_ids = proc_obj.search(cr, uid, [('move_id', '=', mov.id)])
-                 #        if proc_ids:
-                 #            proc_obj.signal_button_check(cr, uid, proc_ids)
             stock_obj.signal_button_cancel(cr, uid, [p.id for p in sale.picking_ids])
         return super(sale_order, self).action_cancel(cr, uid, ids, context=context)
 
index cb19c3b..cdcb864 100644 (file)
@@ -23,6 +23,7 @@ from openerp.osv import fields, osv
 from openerp.tools.translate import _
 
 from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
+from openerp import SUPERUSER_ID
 from dateutil.relativedelta import relativedelta
 from datetime import datetime
 import openerp
@@ -216,7 +217,8 @@ class procurement_order(osv.osv):
                 return False
             move_obj = self.pool.get('stock.move')
             move_dict = self._run_move_create(cr, uid, procurement, context=context)
-            move_obj.create(cr, uid, move_dict, context=context)
+            #create the move as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
+            move_obj.create(cr, SUPERUSER_ID, move_dict, context=context)
             self.message_post(cr, uid, [procurement.id], body=_("Supply Move created"), context=context)
             return True
         return super(procurement_order, self)._run(cr, uid, procurement, context=context)
@@ -278,15 +280,11 @@ class procurement_order(osv.osv):
         result['domain'] = "[('group_id','in',[" + ','.join(map(str, list(group_ids))) + "])]"
         return result
 
-    #
-    # Scheduler
-    # When stock is installed, it should also check for the different confirmed stock moves
-    # if they can not be installed
-    #
-    #
     def run_scheduler(self, cr, uid, use_new_cursor=False, context=None):
         '''
-        Call the scheduler in order to 
+        Call the scheduler in order to check the running procurements (super method), to check the minimum stock rules
+        and the availability of moves. This function is intended to be run for all the companies at the same time, so
+        we run functions as SUPERUSER to avoid intercompanies and access rights issues.
 
         @param self: The object pointer
         @param cr: The current row, from the database cursor,
@@ -296,7 +294,6 @@ class procurement_order(osv.osv):
         @param context: A standard dictionary for contextual values
         @return:  Dictionary of values
         '''
-
         super(procurement_order, self).run_scheduler(cr, uid, use_new_cursor=use_new_cursor, context=context)
         if context is None:
             context = {}
@@ -304,19 +301,19 @@ class procurement_order(osv.osv):
             if use_new_cursor:
                 cr = openerp.registry(use_new_cursor).db.cursor()
 
-            company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
             move_obj = self.pool.get('stock.move')
+
             #Minimum stock rules
-            self. _procure_orderpoint_confirm(cr, uid, use_new_cursor=False, context=context, user_id=False)
+            company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
+            self._procure_orderpoint_confirm(cr, SUPERUSER_ID, use_new_cursor=False, company_id=company.id, context=context)
 
             #Search all confirmed stock_moves and try to assign them
-            confirmed_ids = move_obj.search(cr, uid, [('state', '=', 'confirmed'), ('company_id','=', company.id)], limit=None, order='picking_priority desc, date_expected asc', context=context)
+            confirmed_ids = move_obj.search(cr, uid, [('state', '=', 'confirmed')], limit=None, order='picking_priority desc, date_expected asc', context=context)
             for x in xrange(0, len(confirmed_ids), 100):
-                move_obj.action_assign(cr, uid, confirmed_ids[x:x+100], context=context)
+                move_obj.action_assign(cr, uid, confirmed_ids[x:x + 100], context=context)
                 if use_new_cursor:
                     cr.commit()
-            
-            
+
             if use_new_cursor:
                 cr.commit()
         finally:
@@ -327,7 +324,6 @@ class procurement_order(osv.osv):
                     pass
         return {}
 
-
     def _get_orderpoint_date_planned(self, cr, uid, orderpoint, start_date, context=None):
         date_planned = start_date
         return date_planned.strftime(DEFAULT_SERVER_DATE_FORMAT)
@@ -349,17 +345,11 @@ class procurement_order(osv.osv):
                 [order_point.product_id.id],
                 {'location': order_point.location_id.id})[order_point.product_id.id]['virtual_available']
 
-    def _procure_orderpoint_confirm(self, cr, uid, \
-            use_new_cursor=False, context=None, user_id=False):
+    def _procure_orderpoint_confirm(self, cr, uid, use_new_cursor=False, company_id=False, context=None):
         '''
         Create procurement based on Orderpoint
         use_new_cursor: False or the dbname
 
-        @param self: The object pointer
-        @param cr: The current row, from the database cursor,
-        @param user_id: The current user ID for security checks
-        @param context: A standard dictionary for contextual values
-        @param param: False or the dbname
         @return:  Dictionary of values
         """
         '''
@@ -368,18 +358,18 @@ class procurement_order(osv.osv):
         if use_new_cursor:
             cr = openerp.registry(use_new_cursor).db.cursor()
         orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
-        
+
         procurement_obj = self.pool.get('procurement.order')
         offset = 0
         ids = [1]
         while ids:
-            ids = orderpoint_obj.search(cr, uid, [], offset=offset, limit=100)
+            ids = orderpoint_obj.search(cr, uid, [('company_id', '=', company_id)], offset=offset, limit=100)
             for op in orderpoint_obj.browse(cr, uid, ids, context=context):
                 prods = self._product_virtual_get(cr, uid, op)
                 if prods is None:
                     continue
                 if prods < op.product_min_qty:
-                    qty = max(op.product_min_qty, op.product_max_qty)-prods
+                    qty = max(op.product_min_qty, op.product_max_qty) - prods
 
                     reste = qty % op.qty_multiple
                     if reste > 0:
@@ -409,8 +399,7 @@ class procurement_order(osv.osv):
                                                          context=context)
                         self.check(cr, uid, [proc_id])
                         self.run(cr, uid, [proc_id])
-                        orderpoint_obj.write(cr, uid, [op.id],
-                                {'procurement_id': proc_id}, context=context)
+                        orderpoint_obj.write(cr, uid, [op.id], {'procurement_id': proc_id}, context=context)
             offset += len(ids)
             if use_new_cursor:
                 cr.commit()