[MERGE]: Merged with lp:~openerp-dev/openobject-addons/rpa-dev-addons2
authorrpa (Open ERP) <rpa@tinyerp.com>
Wed, 22 Dec 2010 12:38:57 +0000 (18:08 +0530)
committerrpa (Open ERP) <rpa@tinyerp.com>
Wed, 22 Dec 2010 12:38:57 +0000 (18:08 +0530)
bzr revid: rpa@tinyerp.com-20101222123857-m2s1iencohdnqmtv

17 files changed:
addons/base_report_creator/base_report_creator.py
addons/mrp/mrp_view.xml
addons/procurement/procurement_view.xml
addons/product/product.py
addons/purchase/purchase_view.xml
addons/purchase/report/purchase_report.py
addons/purchase_double_validation/__init__.py [new file with mode: 0644]
addons/purchase_double_validation/__openerp__.py [new file with mode: 0644]
addons/purchase_double_validation/purchase_double_validation_installer.py [new file with mode: 0644]
addons/purchase_double_validation/purchase_double_validation_installer.xml [new file with mode: 0644]
addons/purchase_double_validation/purchase_double_validation_view.xml [new file with mode: 0644]
addons/purchase_double_validation/purchase_double_validation_workflow.xml [new file with mode: 0644]
addons/stock/stock.py
addons/stock/wizard/stock_change_product_qty.py
addons/stock/wizard/stock_change_product_qty_view.xml
addons/stock_planning/stock_planning_view.xml
addons/stock_planning/wizard/stock_planning_create_periods.py

index 28228b4..663df95 100644 (file)
@@ -193,16 +193,17 @@ class report_creator(osv.osv):
         if context is None:
             context = {}
         data = context.get('report_id', False)
+        res = super(report_creator, self).read(cr, user, ids, fields, context, load)
         if (not context) or 'report_id' not in context:
-            return super(report_creator, self).read(cr, user, ids, fields, context, load)
+            return res
         ctx = context or {}
         wp = ''
-        if data:
+        for data in res:
+            if not data.get('sql_query'):
+                return res
             if self.model_set_id:
                 wp = [self._id_get(cr, user, data, context) + (' in (%s)' % (','.join(map(lambda x: "'" + str(x) + "'", ids))))]
-            report = self._sql_query_get(cr, user, [data], 'sql_query', None, ctx, where_plus = wp)
-            sql_query = report[data]
-            cr.execute(sql_query)
+            cr.execute(data['sql_query'])
             res = cr.dictfetchall()
             fields_get = self.fields_get(cr, user, None, context)
             for r in res:
@@ -216,7 +217,7 @@ class report_creator(osv.osv):
                         related_name = self.pool.get(field_dict.get('relation')).name_get(cr, user, [r[k]], context)[0]
                         r[k] = related_name
 
-            return res
+        return res
 
     def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
         """
@@ -253,9 +254,8 @@ class report_creator(osv.osv):
                     newargs += [("count(*) " + a[1] +" " + str(a[2]))]
             ctx = context or {}
             ctx['getid'] = True
-            report = self._sql_query_get(cr, user, [context_id], 'sql_query', None, ctx, where_plus = newargs, limit=limit, offset=offset)
-            query = report[context_id]
-            cr.execute(query, newargs2)
+            sql_query = report.sql_query
+            cr.execute(sql_query, newargs2)
             result = cr.fetchall()
             return map(lambda x: x[0], result)
 
index e17c337..e0e65d3 100644 (file)
                                         string="Consume Products" type="action"
                                         icon="gtk-go-forward" context="{'consume': True}"
                                         states="draft,waiting,confirmed,assigned" />
+                                    <button
+                                           name="%(stock.track_line)d"
+                                           string="Split in production lots"
+                                           type="action" icon="gtk-justify-fill"
+                                           states="draft,waiting,confirmed,assigned" />
                                     <button name="%(stock.move_scrap)d"
                                         string="Scrap Products" type="action"
                                         icon="gtk-convert" context="{'scrap': True}"
                                        <field name="state" invisible="1"/>
                                        <field name="scrapped" invisible="1"/>
                                        <button
-                                           name="%(stock.track_line)d"
-                                           string="Split in production lots"
-                                           type="action" icon="gtk-justify-fill"
-                                           states="done,cancel" />
-                                       <button
                                            name="%(stock.move_scrap)d"
                                            string="Scrap Products" type="action"
                                            icon="gtk-convert"
             <field name="arch" type="xml">
                 <search string="Search Production">
                    <group col='9' colspan='4'>
-                       <filter icon="terp-camera_test" string="Ready"
+                          <filter icon="terp-gtk-media-pause" string="Pending" name="pending"
+                           domain="[('state','=','confirmed')]"
+                           help="Manufacturing Orders which are waiting for raw materials."/>
+                                          <filter icon="terp-check" string="In Production" name="inprogress"
+                           domain="[('state','=','in_production')]"
+                           help="Manufacturing Orders which are currently in production."/>
+                       <filter icon="terp-camera_test" string="Ready" name="ready"
                            domain="[('state','=','ready')]"
-                           help="Non confirmed manufacturing orders"/>
-                       <filter icon="terp-check" string="Current" name="current"
-                           domain="[('state','in',('confirmed','ready','exception','in_production'))]"
-                           help="Manufacturing Orders which are waiting for raw materials, confirmed, ready to start or currently in production."/>
+                           help="Manufacturing Orders which are ready to start production."/>
                        <separator orientation="vertical"/>
                        <filter icon="terp-gnome-cpu-frequency-applet+" string="Late"
                            domain="['&amp;', ('date_planned::date','&lt;', current_date), ('state', 'in', ('draft', 'confirmed', 'ready'))]"
             <field name="view_mode">tree,form,calendar,graph,gantt</field>
             <field name="view_id" eval="False"/>
             <field name="search_view_id" ref="view_mrp_production_filter"/>
-            <field name="context">{'search_default_current':1}</field>
+            <field name="context">{'search_default_ready':1}</field>
             <field name="help">Manufacturing Orders are usually proposed automatically by OpenERP based on the bill of materials and the procurement rules, but you can also create manufacturing orders manually. OpenERP will handle the consumation of the raw materials (stock decrease) and the production of the finished products (stock increase) when the order is processed.</field>
         </record>
         <menuitem action="mrp_production_action" id="menu_mrp_production_action" parent="menu_mrp_manufacturing" groups="mrp.group_mrp_user,mrp.group_mrp_manager" sequence="1"/>
index 4fd723e..ad172f3 100644 (file)
@@ -35,6 +35,7 @@
                     <field name="product_id"/>
                     <field name="product_qty"/>
                     <field name="product_uom" string="UOM"/>
+                    <field name="state" invisible = "1"/>
                     <field name="message"/>
                 </tree>
             </field>
index c2c764b..6a5aa1d 100644 (file)
@@ -53,7 +53,7 @@ def check_ean(eancode):
             evensum += int(finalean[i])
     total=(oddsum * 3) + evensum
 
-    check = int(10 - math.ceil(total % 10.0))
+    check = int(10 - math.ceil(total % 10.0)) %10
 
     if check != int(eancode[-1]):
         return False
index 029f432..30e0fd9 100644 (file)
                                 <field name="state" readonly="1"/>
                                 <button name="purchase_cancel" states="draft,confirmed,wait_auth" string="Cancel" icon="gtk-cancel"/>
                                 <button name="action_cancel_draft" states="cancel" string="Set to Draft" type="object" icon="gtk-convert"/>
-                                <button name="action_cancel" states="approved,except_picking,except_invoice" string="Cancel Purchase Order" type="object" icon="gtk-cancel"/>
+                                <button name="action_cancel" states="approved,except_picking,except_invoice,wait" string="Cancel Purchase Order" type="object" icon="gtk-cancel"/>
                                 <button name="picking_ok" states="except_picking" string="Manually Corrected" icon="gtk-convert"/>
                                 <button name="invoice_ok" states="except_invoice" string="Manually Corrected" icon="gtk-convert"/>
                                 <button name="purchase_confirm" states="draft" string="Convert to Purchase Order" icon="gtk-go-forward"/>
                  <group col='10' colspan='4'>
                     <filter icon="terp-document-new" name="draft" string="Quotations" domain="[('state','=','draft')]" separator="1" help="Purchase order which are in draft state"/>
                     <filter icon="terp-camera_test" name="confirmed" string="To Approve" domain="[('state','in',('wait','confirmed'))]" separator="1" help="Purchase order to be approved"/>
-                    <filter icon="terp-check" name="approved" string="Approved" domain="[('state','in',('approved','done'))]" separator="1" help="Approved purchase order"/>
+                    <filter icon="terp-check" name="approved" string="Approved" domain="[('state','=','approved')]" separator="1" help="Approved purchase order"/>
                     <separator orientation="vertical"/>
                     <filter icon="terp-emblem-important" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" separator="1" help="Purchase order which are in the exception state"/>
                     <separator orientation="vertical"/>
index f30d65d..cd19722 100644 (file)
@@ -99,7 +99,10 @@ class purchase_report(osv.osv):
                     extract(epoch from age(l.date_planned,s.date_order))/(24*60*60)::decimal(16,2) as delay_pass,
                     count(*) as nbr,
                     (l.price_unit*l.product_qty*u.factor)::decimal(16,2) as price_total,
-                    avg(100.0 * (l.price_unit*l.product_qty*u.factor) / (t.standard_price*l.product_qty*u.factor))::decimal(16,2) as negociation,
+                    avg(case when t.standard_price <= 0 then (l.price_unit*l.product_qty*u.factor)
+                    else
+                    (100.0 * (l.price_unit*l.product_qty*u.factor) / (t.standard_price*l.product_qty*u.factor))
+                    end) as negociation,
                     sum(t.standard_price*l.product_qty*u.factor)::decimal(16,2) as price_standard,
                     (sum(l.product_qty*l.price_unit)/sum(l.product_qty*u.factor))::decimal(16,2) as price_average
                 from purchase_order s
diff --git a/addons/purchase_double_validation/__init__.py b/addons/purchase_double_validation/__init__.py
new file mode 100644 (file)
index 0000000..9898505
--- /dev/null
@@ -0,0 +1,24 @@
+# -*- 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/>.
+#
+##############################################################################
+
+import purchase_double_validation_installer
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/purchase_double_validation/__openerp__.py b/addons/purchase_double_validation/__openerp__.py
new file mode 100644 (file)
index 0000000..55327b6
--- /dev/null
@@ -0,0 +1,42 @@
+# -*- 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/>.
+#
+##############################################################################
+
+{
+    "name" : "purchase_double_validation",
+    "version" : "1.1",
+    "category": 'Generic Modules/Sales & Purchases',
+    "depends" : ["base","purchase"],
+    "author" : 'OpenERP SA',
+    "description": """
+               This module modifies purchase workflow in order to validate purchases that exceeds minimum amount set by configuration wizard
+    """,
+    'website': 'http://www.openerp.com',
+    'init_xml': [],
+    'update_xml': [
+                   'purchase_double_validation_view.xml',
+                   'purchase_double_validation_workflow.xml',
+                   'purchase_double_validation_installer.xml'
+                    ],
+    'demo_xml': [],
+    'installable': True,
+    'active': False,
+
+}
diff --git a/addons/purchase_double_validation/purchase_double_validation_installer.py b/addons/purchase_double_validation/purchase_double_validation_installer.py
new file mode 100644 (file)
index 0000000..3d4c2d8
--- /dev/null
@@ -0,0 +1,57 @@
+# -*- 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/>.
+#
+##############################################################################
+
+import time
+from osv import fields, osv
+
+class purchase_double_validation_installer(osv.osv_memory):
+    _name = 'purchase.double.validation.installer'
+    _inherit = 'res.config'
+
+    _columns = {
+        'limit_amount': fields.integer('Limit Amount', required=True, help="Minimum amount after which validation of purchase is required."),
+    }
+
+    _defaults = {
+        'limit_amount': 1000,
+    }
+
+    def execute(self, cr, uid, ids, context=None):
+        data = self.read(cr, uid, ids, context=context)
+        if not data:
+            return {}
+        amt = data[0]['limit_amount']
+        data_pool = self.pool.get('ir.model.data')
+        transition_obj = self.pool.get('workflow.transition')
+        waiting = data_pool._get_id(cr, uid, 'purchase_double_validation', 'trans_router1_waiting')
+        waiting_id = data_pool.browse(cr, uid, waiting, context=context).res_id
+        confirm = data_pool._get_id(cr, uid, 'purchase', 'trans_draft_confirmed')
+        confirm_id = data_pool.browse(cr, uid, confirm, context=context).res_id
+        transition_obj.write(cr, uid, waiting_id, {'condition': 'amount_total>%s' % (amt), 'signal': False})
+        transition_obj.write(cr, uid, confirm_id, {'condition': 'amount_total<=%s' % (amt), 'signal': False})
+        return {}
+
+purchase_double_validation_installer()
+
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/purchase_double_validation/purchase_double_validation_installer.xml b/addons/purchase_double_validation/purchase_double_validation_installer.xml
new file mode 100644 (file)
index 0000000..1ee4420
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+        <!-- configartion view -->
+
+        <record id="view_config_purchase_limit_amount" model="ir.ui.view">
+            <field name="name">Configure Limit Amount for Purchase</field>
+            <field name="model">purchase.double.validation.installer</field>
+            <field name="type">form</field>
+            <field name="inherit_id" ref="base.res_config_view_base"/>
+            <field name="arch" type="xml">
+              <data>
+                <form position="attributes">
+                  <attribute name="string">Purchase Application Configuration</attribute>
+                </form>
+                <separator string="title" position="attributes">
+                <attribute name="string">Configure Limit Amount for Purchase</attribute>
+                  </separator>
+                  <xpath expr="//label[@string='description']" position="attributes">
+                    <attribute name="string">Define minimum amount after which puchase is needed to be validated.</attribute>
+                  </xpath>
+                <xpath expr='//separator[@string="vsep"]' position='attributes'>
+                      <attribute name='rowspan'>15</attribute>
+                      <attribute name='string'></attribute>
+                  </xpath>
+                <group string="res_config_contents" position="replace">
+                  <field name="limit_amount"/>
+                  <newline/>
+                </group>
+              </data>
+            </field>
+        </record>
+
+        <record id="action_config_purchase_limit_amount" model="ir.actions.act_window">
+            <field name="name">Configure Limit Amount for Purchase</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">purchase.double.validation.installer</field>
+            <field name="view_id" ref="view_config_purchase_limit_amount"/>
+            <field name="view_type">form</field>
+            <field name="view_mode">form</field>
+            <field name="target">new</field>
+        </record>
+
+        <!-- register configuration wizard -->
+        <record id="config_wizard_step_purchase_limit_amount" model="ir.actions.todo">
+            <field name="action_id" ref="action_config_purchase_limit_amount"/>
+            <field name="restart">onskip</field>
+            <field name="groups_id" eval="[(6,0,[ref('base.group_extended')])]"/>
+        </record>
+        
+    </data>
+</openerp>
diff --git a/addons/purchase_double_validation/purchase_double_validation_view.xml b/addons/purchase_double_validation/purchase_double_validation_view.xml
new file mode 100644 (file)
index 0000000..5136ffe
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+        <record id="view_purchase_form_inherit" model="ir.ui.view">
+            <field name="name">purchase.order.form.inherit</field>
+            <field name="model">purchase.order</field>
+            <field name="inherit_id" ref="purchase.purchase_order_form"/>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <xpath expr="//button[@string='Convert to Purchase Order']" position="replace">
+                    <button name="draft_router1" states="draft" string="Confirm" icon="gtk-go-forward"/>
+                </xpath>
+                <xpath expr="//button[@string='Approve Purchase']" position="replace">
+                    <button name="waiting_confirmed" states="wait" string="Convert to Purchase Order" icon="gtk-go-forward"/>
+                </xpath>
+            </field>
+        </record>
+
+
+    </data>
+</openerp>
+
diff --git a/addons/purchase_double_validation/purchase_double_validation_workflow.xml b/addons/purchase_double_validation/purchase_double_validation_workflow.xml
new file mode 100644 (file)
index 0000000..ea61341
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+         <record id="act_waiting" model="workflow.activity">
+            <field name="wkf_id" ref="purchase.purchase_order"/>
+            <field name="name">waiting</field>
+            <field name="kind">function</field>
+            <field name="action">write({'state':'wait'})</field>
+        </record>
+
+         <record id="act_router1" model="workflow.activity">
+            <field name="wkf_id" ref="purchase.purchase_order"/>
+            <field name="name">router1</field>
+            <field name="split_mode">OR</field>
+            <field name="kind">dummy</field>
+         </record>
+
+        <record id="trans_draft_router1" model="workflow.transition">
+            <field name="act_from" ref="purchase.act_draft"/>
+            <field name="act_to" ref="act_router1"/>
+            <field name="condition">True</field>
+            <field name="signal">draft_router1</field>
+        </record>
+
+        <record id="trans_router1_waiting" model="workflow.transition">
+            <field name="act_from" ref="act_router1"/>
+            <field name="act_to" ref="act_waiting"/>
+            <field name="condition">True</field>
+        </record>
+
+
+         <record id="purchase.trans_draft_confirmed" model="workflow.transition">
+            <field name="act_from" ref="act_router1"/>
+            <field name="act_to" ref="purchase.act_confirmed"/>
+            <field name="condition">True</field>
+            <field name="signal">waiting_confirmed</field>
+        </record>
+
+        <record id="trans_waiting_confirmed" model="workflow.transition">
+            <field name="act_from" ref="act_waiting"/>
+            <field name="act_to" ref="purchase.act_confirmed"/>
+            <field name="condition">True</field>
+            <field name="signal">waiting_confirmed</field>
+        </record>
+
+    </data>
+</openerp>
index f2f4285..ec281ca 100644 (file)
@@ -2299,14 +2299,12 @@ class stock_move(osv.osv):
             context = {}
         if quantity <= 0:
             raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
-
         res = []
         for move in self.browse(cr, uid, ids, context=context):
             move_qty = move.product_qty
             if move_qty <= 0:
                 raise osv.except_osv(_('Error!'), _('Can not consume a move with negative or zero quantity !'))
             quantity_rest = move.product_qty
-
             quantity_rest -= quantity
             uos_qty_rest = quantity_rest / move_qty * move.product_uos_qty
             if quantity_rest <= 0:
@@ -2323,7 +2321,7 @@ class stock_move(osv.osv):
                     'product_uos_qty': uos_qty,
                     'location_id': location_id or move.location_id.id,
                 }
-                if move.product_id.track_production and location_id:
+                if (not move.prodlot_id.id) and (move.product_id.track_production and location_id):
                     # IF product has checked track for production lot, move lines will be split by 1
                     res += self.action_split(cr, uid, [move.id], quantity, split_by_qty=1, context=context)
                 else:
@@ -2337,7 +2335,7 @@ class stock_move(osv.osv):
             else:
                 quantity_rest = quantity
                 uos_qty_rest =  uos_qty
-                if move.product_id.track_production and location_id:
+                if (not move.prodlot_id.id) and (move.product_id.track_production and location_id):
                     res += self.action_split(cr, uid, [move.id], quantity_rest, split_by_qty=1, context=context)
                 else:
                     res += [move.id]
@@ -2486,7 +2484,8 @@ class stock_inventory(osv.osv):
         'inventory_line_id': fields.one2many('stock.inventory.line', 'inventory_id', 'Inventories', states={'done': [('readonly', True)]}),
         'move_ids': fields.many2many('stock.move', 'stock_inventory_move_rel', 'inventory_id', 'move_id', 'Created Moves'),
         'state': fields.selection( (('draft', 'Draft'), ('done', 'Done'), ('confirm','Confirmed'),('cancel','Cancelled')), 'State', readonly=True, select=True),
-        'company_id': fields.many2one('res.company','Company',required=True,select=True),
+        'company_id': fields.many2one('res.company', 'Company', required=True, select=True, readonly=True, states={'draft':[('readonly',False)]}),
+
     }
     _defaults = {
         'date': time.strftime('%Y-%m-%d %H:%M:%S'),
index 4e437ee..56a6252 100644 (file)
@@ -27,8 +27,10 @@ class stock_change_product_qty(osv.osv_memory):
     _name = "stock.change.product.qty"
     _description = "Change Product Quantity"
     _columns = {
-        'new_quantity': fields.float('Quantity', required=True, help='This quantity is expressed in the Default UoM of the product.'), 
-        'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade", domain="[('usage', '=', 'internal')]"), 
+        'product_id' : fields.many2one('product.product', 'Product'),
+        'new_quantity': fields.float('Quantity', required=True, help='This quantity is expressed in the Default UoM of the product.'),
+        'prodlot_id': fields.many2one('stock.production.lot', 'Production Lot', domain="[('product_id','=',product_id)]"),
+        'location_id': fields.many2one('stock.location', 'Location', required=True, domain="[('usage', '=', 'internal')]"),
     }
 
     def default_get(self, cr, uid, fields, context):
@@ -40,10 +42,14 @@ class stock_change_product_qty(osv.osv_memory):
          @param context: A standard dictionary
          @return: A dictionary which of fields with values.
         """
+        product_id = context and context.get('active_id', False) or False
+        prod_obj =self.pool.get('product.product')
         res = super(stock_change_product_qty, self).default_get(cr, uid, fields, context=context)
 
         if 'new_quantity' in fields:
             res.update({'new_quantity': 1})
+        if 'product_id' in fields:
+            res.update({'product_id': product_id})
         return res
 
     def change_product_qty(self, cr, uid, ids, context=None):
@@ -70,18 +76,27 @@ class stock_change_product_qty(osv.osv_memory):
         for data in self.browse(cr, uid, ids, context=context):
             inventory_id = inventry_obj.create(cr , uid, {'name': _('INV: ') + str(res_original.name)}, context=context)
             line_data ={
-                'inventory_id' : inventory_id, 
-                'product_qty' : data.new_quantity, 
-                'location_id' : data.location_id.id, 
-                'product_id' : rec_id, 
-                'product_uom' : res_original.uom_id.id, 
+                'inventory_id' : inventory_id,
+                'product_qty' : data.new_quantity,
+                'location_id' : data.location_id.id,
+                'product_id' : rec_id,
+                'product_uom' : res_original.uom_id.id,
+                'prod_lot_id' : data.prodlot_id.id
             }
             line_id = inventry_line_obj.create(cr , uid, line_data, context=context)
-    
+
             inventry_obj.action_confirm(cr, uid, [inventory_id], context=context)
             inventry_obj.action_done(cr, uid, [inventory_id], context=context)
-            
-        return {}
+
+        return {
+            'domain': "[('id','=', %s)]" % (inventory_id),
+            'name' : _('Physical Inventories'),
+            'view_type': 'form',
+            'view_mode': 'tree,form',
+            'res_model': 'stock.inventory',
+            'context': context,
+            'type': 'ir.actions.act_window',
+        }
 
 stock_change_product_qty()
 
index 927f3e9..6bedd76 100644 (file)
                     <separator string="Select Quantity" colspan="4"/>
                     <newline/>
                     <field name="new_quantity" />
+                    <newline/>
+                    <field name="product_id" invisible="1"/>
                     <field name="location_id" />
+                    <field name="prodlot_id" />
                     <separator string="" colspan="4" />
                     <label string="" colspan="2"/>
                     <group col="2" colspan="2">
index aaf7e77..9995752 100644 (file)
@@ -40,7 +40,7 @@
                 </tree>
             </field>
         </record>
-        
+
         <record id="view_stock_period_search" model="ir.ui.view">
             <field name="name">stock.period.search</field>
             <field name="model">stock.period</field>
                 </graph>
             </field>
         </record>
-        
+
         <!-- Forecast section -->
-        
-        <menuitem id="menu_stock_sale_forecast" name="Sales Forecasts" 
+
+        <menuitem id="menu_stock_sale_forecast" name="Sales Forecasts"
                 parent="base.menu_base_partner" sequence="6" groups="base.group_extended"/>
 
         <record id="view_stock_sale_forecast_filter" model="ir.ui.view">
                   action="action_view_stock_sale_forecast_form"/>
 
         <!-- Planning section -->
-        
+
         <menuitem id="menu_stock_planning_main" name="Stock Planning" parent="stock.menu_stock_root" sequence="2"/>
 
         <record id="view_stock_planning_form" model="ir.ui.view">
             <field name="arch" type="xml">
                 <tree string="Master Procurement Schedule" colors ="blue:line_time=='Past';black:line_time=='Future'">
                     <field name="period_id"/>
+                    <field name="company_id" invisible="1"/>
                     <field name="product_id" on_change="product_id_change(product_id)" />
                     <field name="product_uom"/>
                     <field name="warehouse_forecast" string="Forecast"/>
index 13a822e..47e19d1 100644 (file)
@@ -21,7 +21,7 @@
 
 import time
 from datetime import datetime
-from dateutil.relativedelta import relativedelta 
+from dateutil.relativedelta import relativedelta
 
 from osv import osv, fields
 
@@ -35,7 +35,7 @@ class stock_period_createlines(osv.osv_memory):
         result = cr.fetchone()
         last_date = result and result[0] or False
         if last_date:
-            period_start = datetime(last_date,"%Y-%m-%d %H:%M:%S")+ relativedelta(days=1)
+            period_start = datetime.strptime(last_date,"%Y-%m-%d %H:%M:%S")+ relativedelta(days=1)
             period_start = period_start - relativedelta(hours=period_start.hour, minutes=period_start.minute, seconds=period_start.second)
         else:
             period_start = datetime.today()
@@ -51,7 +51,7 @@ class stock_period_createlines(osv.osv_memory):
     _defaults={
         'date_start': _get_new_period_start,
     }
-    
+
     def create_stock_periods(self, cr, uid, ids, context=None):
         if context is None:
             context = {}
@@ -60,37 +60,50 @@ class stock_period_createlines(osv.osv_memory):
         period_obj = self.pool.get('stock.period')
         lines = []
         for p in self.browse(cr, uid, ids, context=context):
-            dt = p.date_start
+            dt_stp = datetime.strptime(p.date_stop, '%Y-%m-%d')
             ds = datetime.strptime(p.date_start, '%Y-%m-%d')
-            while ds.strftime('%Y-%m-%d') < p.date_stop:
+
+            while ds <= dt_stp:
                 if name =='Daily':
-                    de = ds + relativedelta(days=interval, minutes =-1)
-                    new_name = de.strftime('%Y-%m-%d')
+                    de = ds + relativedelta(days=(interval + 1), seconds =-1)
                     new_id = period_obj.create(cr, uid, {
-                    'name': new_name,
-                    'date_start': ds.strftime('%Y-%m-%d'),
+                    'name': de.strftime('%Y-%m-%d'),
+                    'date_start': ds.strftime('%Y-%m-%d %H:%M:%S'),
                     'date_stop': de.strftime('%Y-%m-%d %H:%M:%S'),
                     })
-                    ds = ds + relativedelta(days=interval) + 1
+                    ds = ds + relativedelta(days=(interval + 1))
                 if name =="Weekly":
-                    de = ds + relativedelta(days=interval, minutes =-1)
-                    new_name = de.strftime('%Y, week %W')
+                    de = ds + relativedelta(days=(interval + 1), seconds =-1)
+                    if dt_stp < de:
+                        de = dt_stp + relativedelta(days=1, seconds =-1)
+                    else:
+                        de = ds + relativedelta(days=(interval + 1), seconds =-1)
+                    new_name = ds.strftime('Week %W-%Y')
+                    if ds.strftime('%Y') != de.strftime('%Y'):
+                        new_name = ds.strftime('Week %W-%Y') + ', ' + de.strftime('Week %W-%Y')
                     new_id = period_obj.create(cr, uid, {
                     'name': new_name,
-                    'date_start': ds.strftime('%Y-%m-%d'),
+                    'date_start': ds.strftime('%Y-%m-%d %H:%M:%S'),
                     'date_stop': de.strftime('%Y-%m-%d %H:%M:%S'),
                     })
-                    ds = ds + relativedelta(days=interval) + 1
+                    ds = ds + relativedelta(days=(interval + 1))
                 if name == "Monthly":
-                    de = ds + relativedelta(months=interval, minutes=-1)
+                    de = ds + relativedelta(months=interval, seconds=-1)
+                    if dt_stp < de:
+                        de = dt_stp + relativedelta(days=1, seconds =-1)
+                    else:
+                        de = ds + relativedelta(months=interval, seconds=-1)
                     new_name = ds.strftime('%Y/%m')
+                    if ds.strftime('%m') != de.strftime('%m'):
+                        new_name = ds.strftime('%Y/%m') + '-' + de.strftime('%Y/%m')
                     new_id =period_obj.create(cr, uid, {
-                    'name': new_name,
-                    'date_start': ds.strftime('%Y-%m-%d'),
+                    'name': new_name, 
+                    'date_start': ds.strftime('%Y-%m-%d %H:%M:%S'),
                     'date_stop': de.strftime('%Y-%m-%d %H:%M:%S'),
                     })
                     ds = ds + relativedelta(months=interval)
                 lines.append(new_id)
+
         return {
             'domain': "[('id','in', ["+','.join(map(str, lines))+"])]",
             'view_type': 'form',