← Back to team overview

openerp-dev-web team mailing list archive

[Merge] lp:~openerp-dev/openobject-addons/ksa-addons2 into lp:~openerp-dev/openobject-addons/trunk-dev-addons2

 

ksa(OpenERP) has proposed merging lp:~openerp-dev/openobject-addons/ksa-addons2 into lp:~openerp-dev/openobject-addons/trunk-dev-addons2.

Requested reviews:
  OpenERP R&D Team (openerp-dev)


[1] Apply rights for purchase & procurement
[2] FIX : https://bugs.launchpad.net/openobject-addons/+bug/670905
[3] Task-1773 in periodical inventories apply missing features
[4] FIX :https://bugs.launchpad.net/openobject-addons/+bug/504353 

-- 
https://code.launchpad.net/~openerp-dev/openobject-addons/ksa-addons2/+merge/40620
Your team OpenERP R&D Team is requested to review the proposed merge of lp:~openerp-dev/openobject-addons/ksa-addons2 into lp:~openerp-dev/openobject-addons/trunk-dev-addons2.
=== modified file 'account/account_view.xml'
--- account/account_view.xml	2010-11-10 09:03:41 +0000
+++ account/account_view.xml	2010-11-11 12:44:58 +0000
@@ -405,7 +405,7 @@
             <field name="arch" type="xml">
                 <form string="Account Journal">
                     <group colspan="4" col="6">
-                        <field name="name" select="1"/>
+                        <field name="name" select="1" colspan="4"/>
                         <field name="code" select="1"/>
                         <field name="type" on_change="onchange_type(type, currency)"/>
                     </group>
@@ -465,7 +465,6 @@
             <field name="view_mode">tree,form</field>
         </record>
         <menuitem action="action_account_journal_form" id="menu_action_account_journal_form" parent="account_account_menu"/>
-
         <record id="view_account_bank_statement_filter" model="ir.ui.view">
             <field name="name">account.cash.statement.select</field>
             <field name="model">account.bank.statement</field>
@@ -490,7 +489,6 @@
                 </search>
             </field>
         </record>
-
         <record id="view_bank_statement_tree" model="ir.ui.view">
             <field name="name">account.bank.statement.tree</field>
             <field name="model">account.bank.statement</field>
@@ -950,7 +948,6 @@
             <field name="domain">[('parent_id','=',False)]</field>
         </record>
         <menuitem action="action_tax_form" id="menu_action_tax_form" parent="next_id_27"/>
-
         <record id="action_tax_code_tree" model="ir.actions.act_window">
             <field name="name">Chart of Taxes</field>
             <field name="res_model">account.tax.code</field>
@@ -1418,6 +1415,10 @@
                         <field name="period_id"/>
                     </group>
                     <newline/>
+                    <group col="10" colspan="4">
+                        <field name="journal_id" widget="selection" context="{'journal_id':self, 'visible_id':self or 0, 'normal_view':False}"/>
+                        <field name="period_id" widget="selection" context="{'period_id':self}"/>
+                    </group>
                     <group expand="0" string="Group By..." colspan="12" col="10">
                         <filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
                         <separator orientation="vertical"/>
@@ -2573,7 +2574,6 @@
                 </tree>
             </field>
         </record>
-
         <record id="view_bank_statement_form2" model="ir.ui.view">
             <field name="name">account.bank.statement.form</field>
             <field name="model">account.bank.statement</field>
@@ -2588,7 +2588,6 @@
                         <field name="period_id" select="1"/>
                         <field name="currency" invisible="1"/>
                     </group>
-
                     <notebook colspan="4">
                         <page string="Cash Transactions" attrs="{'invisible': [('state','=','draft')]}">
                             <field colspan="4" name="line_ids" nolabel="1">

=== modified file 'account_analytic_analysis/security/ir.model.access.csv'
--- account_analytic_analysis/security/ir.model.access.csv	2010-10-16 16:47:09 +0000
+++ account_analytic_analysis/security/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -1,3 +1,3 @@
-id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_account_analytic_analysis_summary_user,account_analytic_analysis.summary.user,model_account_analytic_analysis_summary_user,account.group_account_manager,1,0,0,0
-access_account_analytic_analysis_summary_month,account_analytic_analysis.summary.month,model_account_analytic_analysis_summary_month,account.group_account_manager,1,0,0,0
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_account_analytic_analysis_summary_user","account_analytic_analysis.summary.user","model_account_analytic_analysis_summary_user","account.group_account_manager",1,0,0,0
+"access_account_analytic_analysis_summary_month","account_analytic_analysis.summary.month","model_account_analytic_analysis_summary_month","account.group_account_manager",1,0,0,0

=== modified file 'base_action_rule/base_action_rule.py'
--- base_action_rule/base_action_rule.py	2010-09-30 15:29:42 +0000
+++ base_action_rule/base_action_rule.py	2010-11-11 12:44:58 +0000
@@ -24,7 +24,7 @@
 from datetime import datetime
 from datetime import timedelta
 from tools.safe_eval import safe_eval
-import pooler 
+import pooler
 import re
 import time
 import tools
@@ -34,7 +34,7 @@
 
     _name = 'base.action.rule'
     _description = 'Action Rules'
-    
+
     def _state_get(self, cr, uid, context={}):
         """ Get State
             @param self: The object pointer
@@ -50,7 +50,7 @@
             @param uid: the current user’s ID for security checks,
             @param context: A standard dictionary for contextual values """
         return [('', '')]
-  
+
     def priority_get(self, cr, uid, context={}):
         """ Get Priority
             @param self: The object pointer
@@ -60,57 +60,57 @@
         return [('', '')]
 
     _columns = {
-        'name':  fields.char('Rule Name', size=64, required=True), 
-        'model_id': fields.many2one('ir.model', 'Object', required=True), 
-        'create_date': fields.datetime('Create Date', readonly=1), 
+        'name':  fields.char('Rule Name', size=64, required=True),
+        'model_id': fields.many2one('ir.model', 'Object', required=True),
+        'create_date': fields.datetime('Create Date', readonly=1),
         'active': fields.boolean('Active', help="If the active field is set to False,\
- it will allow you to hide the rule without removing it."), 
+ it will allow you to hide the rule without removing it."),
         'sequence': fields.integer('Sequence', help="Gives the sequence order \
-when displaying a list of rules."), 
+when displaying a list of rules."),
         'trg_date_type':  fields.selection([
-            ('none', 'None'), 
-            ('create', 'Creation Date'), 
-            ('action_last', 'Last Action Date'), 
-            ('date', 'Date'), 
-            ('deadline', 'Deadline'), 
-            ], 'Trigger Date', size=16), 
+            ('none', 'None'),
+            ('create', 'Creation Date'),
+            ('action_last', 'Last Action Date'),
+            ('date', 'Date'),
+            ('deadline', 'Deadline'),
+            ], 'Trigger Date', size=16),
         'trg_date_range': fields.integer('Delay after trigger date', \
                                          help="Delay After Trigger Date,\
 specifies you can put a negative number. If you need a delay before the \
-trigger date, like sending a reminder 15 minutes before a meeting."), 
+trigger date, like sending a reminder 15 minutes before a meeting."),
         'trg_date_range_type': fields.selection([('minutes', 'Minutes'), ('hour', 'Hours'), \
-                                ('day', 'Days'), ('month', 'Months')], 'Delay type'), 
-        'trg_user_id':  fields.many2one('res.users', 'Responsible'), 
-        'trg_partner_id': fields.many2one('res.partner', 'Partner'), 
-        'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'), 
-        'trg_state_from': fields.selection(_state_get, 'State', size=16), 
-        'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16), 
+                                ('day', 'Days'), ('month', 'Months')], 'Delay type'),
+        'trg_user_id':  fields.many2one('res.users', 'Responsible'),
+        'trg_partner_id': fields.many2one('res.partner', 'Partner'),
+        'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'),
+        'trg_state_from': fields.selection(_state_get, 'State', size=16),
+        'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16),
 
-        'act_method': fields.char('Call Object Method', size=64), 
-        'act_user_id': fields.many2one('res.users', 'Set Responsible to'), 
-        'act_state': fields.selection(_state_get, 'Set State to', size=16), 
+        'act_method': fields.char('Call Object Method', size=64),
+        'act_user_id': fields.many2one('res.users', 'Set Responsible to'),
+        'act_state': fields.selection(_state_get, 'Set State to', size=16),
         'act_email_cc': fields.char('Add Watchers (Cc)', size=250, help="\
 These people will receive a copy of the future communication between partner \
-and users by email"), 
+and users by email"),
         'act_remind_partner': fields.boolean('Remind Partner', help="Check \
-this if you want the rule to send a reminder by email to the partner."), 
+this if you want the rule to send a reminder by email to the partner."),
         'act_remind_user': fields.boolean('Remind Responsible', help="Check \
-this if you want the rule to send a reminder by email to the user."), 
-        'act_reply_to': fields.char('Reply-To', size=64), 
-        'act_remind_attach': fields.boolean('Remind with Attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."), 
+this if you want the rule to send a reminder by email to the user."),
+        'act_reply_to': fields.char('Reply-To', size=64),
+        'act_remind_attach': fields.boolean('Remind with Attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."),
         'act_mail_to_user': fields.boolean('Mail to Responsible', help="Check\
- this if you want the rule to send an email to the responsible person."), 
-        'act_mail_to_watchers': fields.boolean('Mail to Watchers (CC)', 
+ this if you want the rule to send an email to the responsible person."),
+        'act_mail_to_watchers': fields.boolean('Mail to Watchers (CC)',
                                                 help="Check this if you want \
-the rule to mark CC(mail to any other person defined in actions)."), 
+the rule to mark CC(mail to any other person defined in actions)."),
         'act_mail_to_email': fields.char('Mail to these Emails', size=128, \
-        help="Email-id of the persons whom mail is to be sent"), 
-        'act_mail_body': fields.text('Mail body', help="Content of mail"), 
+        help="Email-id of the persons whom mail is to be sent"),
+        'act_mail_body': fields.text('Mail body', help="Content of mail"),
         'regex_name': fields.char('Regex on Resource Name', size=128, help="Regular expression for matching name of the resource\
 \ne.g.: 'urgent.*' will search for records having name starting with the string 'urgent'\
-\nNote: This is case sensitive search."), 
-        'server_action_id': fields.many2one('ir.actions.server', 'Server Action', help="Describes the action name.\neg:on which object which action to be taken on basis of which condition"), 
-        'filter_id':fields.many2one('ir.filters', 'Filter', required=False), 
+\nNote: This is case sensitive search."),
+        'server_action_id': fields.many2one('ir.actions.server', 'Server Action', help="Describes the action name.\neg:on which object which action to be taken on basis of which condition"),
+        'filter_id':fields.many2one('ir.filters', 'Filter', required=False),
         'act_email_from' : fields.char('Email From', size=64, required=False,
                 help="Use a python expression to specify the right field on which one than we will use for the 'From' field of the header"),
         'act_email_to' : fields.char('Email To', size=64, required=False,
@@ -118,17 +118,17 @@
     }
 
     _defaults = {
-        'active': lambda *a: True, 
-        'trg_date_type': lambda *a: 'none', 
-        'trg_date_range_type': lambda *a: 'day', 
-        'act_mail_to_user': lambda *a: 0, 
-        'act_remind_partner': lambda *a: 0, 
-        'act_remind_user': lambda *a: 0, 
-        'act_mail_to_watchers': lambda *a: 0, 
+        'active': lambda *a: True,
+        'trg_date_type': lambda *a: 'none',
+        'trg_date_range_type': lambda *a: 'day',
+        'act_mail_to_user': lambda *a: 0,
+        'act_remind_partner': lambda *a: 0,
+        'act_remind_user': lambda *a: 0,
+        'act_mail_to_watchers': lambda *a: 0,
     }
-    
+
     _order = 'sequence'
-    
+
     def onchange_model_id(self, cr, uid, ids, name):
         #This is not a good solution as it will affect the domain only on onchange
         res = {'domain':{'filter_id':[]}}
@@ -165,7 +165,7 @@
                 self.pre_action(cr, uid, [new_id], model, context=context)
             return new_id
         return make_call_old
-    
+
     def _write(self, old_write, model, context=None):
         if not context:
             context  = {}
@@ -191,9 +191,9 @@
         return True
     def create(self, cr, uid, vals, context=None):
         res_id = super(base_action_rule, self).create(cr, uid, vals, context)
-        self._register_hook(cr, uid, [res_id], context=context)        
+        self._register_hook(cr, uid, [res_id], context=context)
         return res_id
-    
+
     def write(self, cr, uid, ids, vals, context=None):
         res = super(base_action_rule, self).write(cr, uid, ids, vals, context)
         self._register_hook(cr, uid, ids, context=context)
@@ -207,7 +207,7 @@
         rule_pool = self.pool.get('base.action.rule')
         rule_ids = rule_pool.search(cr, uid, [], context=context)
         return self._register_hook(cr, uid, rule_ids, context=context)
-        
+
 
     def format_body(self, body):
         """ Foramat Action rule's body
@@ -219,18 +219,18 @@
             @param self: The object pointer """
 
         data = {
-            'object_id': obj.id, 
-            'object_subject': hasattr(obj, 'name') and obj.name or False, 
-            'object_date': hasattr(obj, 'date') and obj.date or False, 
-            'object_description': hasattr(obj, 'description') and obj.description or False, 
-            'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/', 
+            'object_id': obj.id,
+            'object_subject': hasattr(obj, 'name') and obj.name or False,
+            'object_date': hasattr(obj, 'date') and obj.date or False,
+            'object_description': hasattr(obj, 'description') and obj.description or False,
+            'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/',
             'object_user_email': hasattr(obj, 'user_id') and (obj.user_id and \
-                                    obj.user_id.address_id and obj.user_id.address_id.email) or '/', 
+                                    obj.user_id.address_id and obj.user_id.address_id.email) or '/',
             'object_user_phone': hasattr(obj, 'user_id') and (obj.user_id and\
-                                     obj.user_id.address_id and obj.user_id.address_id.phone) or '/', 
-            'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/', 
+                                     obj.user_id.address_id and obj.user_id.address_id.phone) or '/',
+            'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/',
             'partner_email': hasattr(obj, 'partner_address_id') and (obj.partner_address_id and\
-                                         obj.partner_address_id.email) or '/', 
+                                         obj.partner_address_id.email) or '/',
         }
         return self.format_body(body % data)
 
@@ -259,7 +259,7 @@
         emailfrom = tools.ustr(emailfrom)
         reply_to = emailfrom
         if not emailfrom:
-            raise osv.except_osv(_('Error!'), 
+            raise osv.except_osv(_('Error!'),
                     _("No E-Mail ID Found for your Company address!"))
         return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id))
 
@@ -272,7 +272,7 @@
             @param context: A standard dictionary for contextual values """
         if context is None:
             context = {}
-        ok = True 
+        ok = True
         if action.filter_id:
             if action.model_id.model == action.filter_id.model_id:
                 context.update(eval(action.filter_id.context))
@@ -418,10 +418,10 @@
                     base = datetime.strptime(obj.date, '%Y-%m-%d %H:%M:%S')
                 if base:
                     fnct = {
-                        'minutes': lambda interval: timedelta(minutes=interval), 
-                        'day': lambda interval: timedelta(days=interval), 
-                        'hour': lambda interval: timedelta(hours=interval), 
-                        'month': lambda interval: timedelta(months=interval), 
+                        'minutes': lambda interval: timedelta(minutes=interval),
+                        'day': lambda interval: timedelta(days=interval),
+                        'hour': lambda interval: timedelta(hours=interval),
+                        'month': lambda interval: timedelta(months=interval),
                     }
                     d = base + fnct[action.trg_date_range_type](action.trg_date_range)
                     dt = d.strftime('%Y-%m-%d %H:%M:%S')
@@ -463,15 +463,15 @@
         return True
 
     _constraints = [
-        (_check_mail, 'Error: The mail is not well formated', ['act_mail_body']), 
+        (_check_mail, 'Error: The mail is not well formated', ['act_mail_body']),
     ]
 
 base_action_rule()
 
 
 class ir_cron(osv.osv):
-    _inherit = 'ir.cron' 
-    
+    _inherit = 'ir.cron'
+
     def _poolJobs(self, db_name, check=False):
         try:
             db = pooler.get_db(db_name)

=== modified file 'base_calendar/test/base_calendar_test.yml'
--- base_calendar/test/base_calendar_test.yml	2010-10-27 08:12:24 +0000
+++ base_calendar/test/base_calendar_test.yml	2010-11-11 12:44:58 +0000
@@ -42,8 +42,8 @@
         name: All day test event
         rrule_type: none
 -   |
-    In order to check reminder I will first create reminder 
-- 
+    In order to check reminder I will first create reminder
+-
   !record {model: res.alarm, id: res_alarm_daybeforeeventstarts0}:
     name: 1 Day before event starts
     trigger_duration: 1
@@ -57,7 +57,7 @@
      self.write(cr, uid, [ref("calendar_event_alldaytestevent0")], {'alarm_id': ref("res_alarm_daybeforeeventstarts0")})
 -   |
     In order to assign attendee I will invite Demo user
-- 
+-
   !record {model: base_calendar.invite.attendee, id: base_calendar_invite_attendee_0}:
     type: internal
     send_mail: False

=== removed file 'base_module_quality/unit_test/__init__.py'
--- base_module_quality/unit_test/__init__.py	2010-01-12 09:18:39 +0000
+++ base_module_quality/unit_test/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU 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 General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== removed file 'base_module_quality/unit_test/unit_test.py'
--- base_module_quality/unit_test/unit_test.py	2010-10-26 13:22:54 +0000
+++ base_module_quality/unit_test/unit_test.py	1970-01-01 00:00:00 +0000
@@ -1,114 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU 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 General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-import os
-
-from osv import fields, osv
-from tools.translate import _
-import pooler
-import addons
-from base_module_quality import base_module_quality
-
-class quality_test(base_module_quality.abstract_quality_check):
-
-    def __init__(self):
-        super(quality_test, self).__init__()
-        self.bool_installed_only = True
-        self.name = _("Unit Test")
-        self.note = _("""
-This test checks the Unit Test(PyUnit) Cases of the module. Note that 'unit_test/test.py' is needed in module.
-
-""")
-        self.min_score = 0
-        self.message = 'This test does not calculate score'
-        self.bool_count_score = False
-        return None
-
-    def run_test(self, cr, uid, module_path):
-        pool = pooler.get_pool(cr.dbname)
-        module_name = module_path.split('/')[-1]
-        test_file = addons.get_module_resource(module_name) + '/unit_test/test.py'
-        if not os.path.isfile(test_file):
-            self.result += _("Module does not have 'unit_test/test.py' file")
-            return None
-        module_obj = pool.get('ir.module.module')
-        module_ids = module_obj.search(cr, uid, [('name', '=', module_name)])
-        module = module_obj.browse(cr, uid, module_ids)
-        if not len(module):
-            self.result += _("Error! Module is not properly loaded/installed")
-            return None
-        module = module[0]
-        test = module.name + '.' + 'unit_test.test'
-        test_module = __import__(test)
-        test_file = getattr(test_module, 'unit_test')
-        test_obj = getattr(test_file, 'test')
-
-        test_result = test_obj.runTest(cr,uid)
-        self.result = self.get_result(test_result)
-        self.result_details += self.get_result_details(test_result)
-        return None
-
-    def get_result(self, data_list):
-        header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-40s \n', [_('Summary'), _('Status')])
-        result_unit = {}
-        res_list = []
-        if data_list[0]:
-            res = data_list[1].split('\n')
-            res_list.append(res[-4:][0])
-            res_list.append(res[-4:][2])
-            result_unit['unit_test'] = res_list
-            return self.format_table(header, data_list=result_unit)
-        return "Unit Test Fail"
-
-    def get_result_details(self, data_list):
-        detail = '''<html><head>%s</head><body><table class="tablestyle">
-           <tr><th class="tdatastyle">Test Cases</th ><th class="tdatastyle">Result</th>'''%(self.get_style())
-        html = ''
-
-        if data_list[0] == True:
-            data = data_list[1].split('... ok')
-            for case in map(lambda x:x[0].replace('\n',''),map(lambda x: x.split(' ('),data)):
-                if case.find('Ran') != -1:
-                    case = case[case.index('Ran'):-2]
-                    html += '<tr><th class="tdatastyle">%s</th><th class="tdatastyle">OK</th></tr>'%(case)
-                else:
-                    html += '<tr><td class="tdatastyle">%s</td><td class="tdatastyle">OK</td></tr>'%(case)
-            res = detail + html + '</table></body></html>'
-            return res
-        else:
-            detail_dict = {}
-            detail += '''<th class="tdatastyle">Details</th></tr>'''
-            data = data_list[1].split("======================================================================")
-            test = data[0].split('\n')
-            for err in (data_list[0].failures,data_list[0].errors):
-                for value in err:
-                    detail_dict[value[0]._testMethodName] = value[1]
-            for case in map(lambda x:x.split('...'), test):
-                if len(case[0]) < 2:
-                    continue
-                test_name = case[0].split(' (')[0]
-                if not detail_dict.has_key(test_name):
-                    detail_dict[test_name] = ''
-                html += '<tr><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th><td class="tdatastyle">%s</td></tr>'%(test_name, case[1], detail_dict[test_name])
-            return detail + html +'</tr></table></body></html>'
-        return ''
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file

=== modified file 'crm/crm_lead.py'
--- crm/crm_lead.py	2010-10-17 18:28:33 +0000
+++ crm/crm_lead.py	2010-11-11 12:44:58 +0000
@@ -100,7 +100,7 @@
 
     _columns = {
         # Overridden from res.partner.address:
-        'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', 
+        'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null',
             select=True, help="Optional linked partner, usually after conversion of the lead"),
 
         # From crm.case
@@ -124,7 +124,7 @@
             domain="['|',('section_id','=',section_id),('section_id','=',False)]"),
         'channel_id': fields.many2one('res.partner.canal', 'Channel'),
 
-        'contact_name': fields.char('Contact Name', size=64), 
+        'contact_name': fields.char('Contact Name', size=64),
         'partner_name': fields.char("Customer Name", size=64),
         'optin': fields.boolean('Opt-In', help="If opt-in is checked, this contact has accepted to receive emails."),
         'optout': fields.boolean('Opt-Out', help="If opt-out is checked, this contact has refused to receive emails or unsubscribed to a campaign."),
@@ -147,7 +147,7 @@
                                   help='The state is set to \'Draft\', when a case is created.\
                                   \nIf the case is in progress the state is set to \'Open\'.\
                                   \nWhen the case is over, the state is set to \'Done\'.\
-                                  \nIf the case needs to be reviewed then the state is set to \'Pending\'.'), 
+                                  \nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
         'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
     }
 
@@ -341,7 +341,7 @@
         @param self: The object pointer
         @param cr: the current row, from the database cursor,
         @param uid: the current user’s ID for security checks,
-        @param ids: List of update mail’s IDs 
+        @param ids: List of update mail’s IDs
         """
 
         if isinstance(ids, (str, int, long)):

=== modified file 'crm/crm_meeting.py'
--- crm/crm_meeting.py	2010-10-18 07:00:37 +0000
+++ crm/crm_meeting.py	2010-11-11 12:44:58 +0000
@@ -45,12 +45,12 @@
     _inherit = ['mailgate.thread',"calendar.event"]
     _columns = {
         # From crm.case
-        'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}), 
-        'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}), 
+        'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}),
+        'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
         'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
-                                 domain="[('partner_id','=',partner_id)]", states={'done': [('readonly', True)]}), 
+                                 domain="[('partner_id','=',partner_id)]", states={'done': [('readonly', True)]}),
         'section_id': fields.many2one('crm.case.section', 'Sales Team', states={'done': [('readonly', True)]}, \
-                        select=True, help='Sales team to which Case belongs to.'), 
+                        select=True, help='Sales team to which Case belongs to.'),
         'email_from': fields.char('Email', size=128, states={'done': [('readonly', True)]}, help="These people will receive email."),
         'id': fields.integer('ID'),
         'create_date': fields.datetime('Creation Date' , readonly=True),
@@ -76,7 +76,7 @@
     }
 
     _defaults = {
-        'state': lambda *a: 'draft', 
+        'state': lambda *a: 'draft',
         'active': lambda *a: 1,
         'user_id': lambda self, cr, uid, ctx: uid,
     }

=== modified file 'crm/report/crm_lead_report.py'
--- crm/report/crm_lead_report.py	2010-10-05 13:13:07 +0000
+++ crm/report/crm_lead_report.py	2010-11-11 12:44:58 +0000
@@ -107,7 +107,7 @@
                     c.partner_id,
                     c.country_id,
                     c.planned_revenue,
-                    c.planned_revenue*(c.probability/100) as probable_revenue, 
+                    c.planned_revenue*(c.probability/100) as probable_revenue,
                     1 as nbr,
                     (SELECT count(id) FROM mailgate_message WHERE model='crm.lead' AND res_id=c.id AND history=True) AS email,
                     date_trunc('day',c.create_date) as create_date,

=== modified file 'crm/report/crm_phonecall_report.py'
--- crm/report/crm_phonecall_report.py	2010-10-12 05:58:58 +0000
+++ crm/report/crm_phonecall_report.py	2010-11-11 12:44:58 +0000
@@ -38,7 +38,6 @@
     _name = "crm.phonecall.report"
     _description = "Phone calls by user and section"
     _auto = False
-    
     _columns = {
         'name': fields.char('Year', size=64, required=False, readonly=True),
         'user_id':fields.many2one('res.users', 'User', readonly=True),
@@ -53,7 +52,7 @@
                                   ('09', 'September'), ('10', 'October'),\
                                   ('11', 'November'), ('12', 'December')], 'Month', readonly=True),
         'create_date': fields.datetime('Create Date', readonly=True),
-        'day': fields.char('Day', size=128, readonly=True), 
+        'day': fields.char('Day', size=128, readonly=True),
         'delay_close': fields.float('Delay to close', digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
         'duration': fields.float('Duration', digits=(16,2),readonly=True, group_operator="avg"),
         'delay_open': fields.float('Delay to open',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to open the case"),

=== modified file 'crm/security/crm_security.xml'
--- crm/security/crm_security.xml	2010-10-18 09:28:40 +0000
+++ crm/security/crm_security.xml	2010-11-11 12:44:58 +0000
@@ -20,6 +20,7 @@
         <field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field>
         <field name="groups" eval="[(4, ref('base.group_sale_salesman'))]"/>
     </record>
+
     <record id="crm_rule_all_lead" model="ir.rule">
         <field name="name">All Leads</field>
         <field ref="model_crm_lead" name="model_id"/>

=== modified file 'crm_claim/report/crm_claim_report.py'
--- crm_claim/report/crm_claim_report.py	2010-10-04 06:03:16 +0000
+++ crm_claim/report/crm_claim_report.py	2010-11-11 12:44:58 +0000
@@ -45,7 +45,6 @@
     _name = "crm.claim.report"
     _auto = False
     _description = "CRM Claim Report"
-
     _columns = {
         'name': fields.char('Year', size=64, required=False, readonly=True),
         'user_id':fields.many2one('res.users', 'User', readonly=True),
@@ -60,7 +59,7 @@
                                   ('11', 'November'), ('12', 'December')], 'Month', readonly=True),
         'company_id': fields.many2one('res.company', 'Company', readonly=True),
         'create_date': fields.datetime('Create Date', readonly=True),
-        'day': fields.char('Day', size=128, readonly=True), 
+        'day': fields.char('Day', size=128, readonly=True),
         'delay_close': fields.float('Delay to close', digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
         'stage_id': fields.many2one ('crm.case.stage', 'Stage', readonly=True),
         'categ_id': fields.many2one('crm.case.categ', 'Category',\

=== modified file 'crm_fundraising/report/crm_fundraising_report.py'
--- crm_fundraising/report/crm_fundraising_report.py	2010-09-20 13:59:10 +0000
+++ crm_fundraising/report/crm_fundraising_report.py	2010-11-11 12:44:58 +0000
@@ -36,7 +36,6 @@
     _name = "crm.fundraising.report"
     _auto = False
     _description = "CRM Fundraising Report"
-
     _columns = {
         'name': fields.char('Year', size=64, required=False, readonly=True),
         'user_id':fields.many2one('res.users', 'User', readonly=True),
@@ -51,7 +50,7 @@
                                   ('11', 'November'), ('12', 'December')], 'Month', readonly=True),
         'company_id': fields.many2one('res.company', 'Company', readonly=True),
         'create_date': fields.datetime('Create Date', readonly=True),
-        'day': fields.char('Day', size=128, readonly=True), 
+        'day': fields.char('Day', size=128, readonly=True),
         'categ_id': fields.many2one('crm.case.categ', 'Category', \
                     domain="[('section_id','=',section_id),\
                     ('object_id.model', '=', 'crm.fundraising')]"),

=== modified file 'document/document_storage.py'
--- document/document_storage.py	2010-08-10 12:29:57 +0000
+++ document/document_storage.py	2010-11-11 12:44:58 +0000
@@ -54,7 +54,7 @@
  Have (ir.attachment, context), we modify the file (save, update, rename etc).
  Have (directory, context), we create a file.
  Have (path, context), we create or modify a file.
- 
+
 Note that in all above cases, we don't explicitly choose the storage media,
 but always require a context to be present.
 
@@ -63,7 +63,7 @@
 media + directory.
 
 The algorithm says that in any of the above cases, our first goal is to locate
-the node for any combination of search criteria. It would be wise NOT to 
+the node for any combination of search criteria. It would be wise NOT to
 represent each node in the path (like node[/] + node[/dir1] + node[/dir1/dir2])
 but directly jump to the end node (like node[/dir1/dir2]) whenever possible.
 
@@ -100,7 +100,7 @@
         if mode.endswith('b'):
             mode = mode[:-1]
         self.mode = mode
-        
+
         for attr in ('closed', 'read', 'write', 'seek', 'tell'):
             setattr(self,attr, getattr(self.__file, attr))
 
@@ -117,7 +117,7 @@
             filename = par.path
             if isinstance(filename, (tuple, list)):
                 filename = '/'.join(filename)
-            
+
             try:
                 mime, icont = cntIndex.doIndex(None, filename=filename,
                         content_type=None, realfname=fname)
@@ -167,7 +167,7 @@
         nodes.node_descriptor.__init__(self, parent)
         if mode.endswith('b'):
             mode = mode[:-1]
-        
+
         if mode in ('r', 'r+'):
             cr = ira_browse._cr # reuse the cursor of the browse object, just now
             cr.execute('SELECT db_datas FROM ir_attachment WHERE id = %s',(ira_browse.id,))
@@ -198,7 +198,7 @@
                 filename = par.path
                 if isinstance(filename, (tuple, list)):
                     filename = '/'.join(filename)
-            
+
                 try:
                     mime, icont = cntIndex.doIndex(data, filename=filename,
                             content_type=None, realfname=None)
@@ -235,7 +235,7 @@
 
 class nodefd_db64(StringIO, nodes.node_descriptor):
     """ A descriptor to db data, base64 (the old way)
-    
+
         It stores the data in base64 encoding at the db. Not optimal, but
         the transparent compression of Postgres will save the day.
     """
@@ -243,7 +243,7 @@
         nodes.node_descriptor.__init__(self, parent)
         if mode.endswith('b'):
             mode = mode[:-1]
-        
+
         if mode in ('r', 'r+'):
             StringIO.__init__(self, base64.decodestring(ira_browse.db_datas))
         elif mode in ('w', 'w+'):
@@ -271,7 +271,7 @@
                 filename = par.path
                 if isinstance(filename, (tuple, list)):
                     filename = '/'.join(filename)
-            
+
                 try:
                     mime, icont = cntIndex.doIndex(data, filename=filename,
                             content_type=None, realfname=None)
@@ -312,7 +312,7 @@
     media.
     The referring document.directory-ies will control the placement of data
     into the storage.
-    
+
     It is a bad idea to have multiple document.storage objects pointing to
     the same tree of filesystem storage.
     """
@@ -367,12 +367,12 @@
 
     def __prepare_realpath(self, cr, file_node, ira, store_path, do_create=True):
         """ Cleanup path for realstore, create dirs if needed
-        
+
             @param file_node  the node
             @param ira    ir.attachment browse of the file_node
             @param store_path the path of the parent storage object, list
             @param do_create  create the directories, if needed
-            
+
             @return tuple(path "/var/filestore/real/dir/", npath ['dir','fname.ext'] )
         """
         file_node.fix_ppath(cr, ira)
@@ -406,7 +406,7 @@
         boo = self.browse(cr, uid, id, context)
         if not boo.online:
             raise IOError(errno.EREMOTE, 'medium offline')
-        
+
         if fil_obj:
             ira = fil_obj
         else:
@@ -421,10 +421,10 @@
         boo = self.browse(cr, uid, id, context)
         if not boo.online:
             raise IOError(errno.EREMOTE, 'medium offline')
-        
+
         if boo.readonly and mode not in ('r', 'rb'):
             raise IOError(errno.EPERM, "Readonly medium")
-        
+
         ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context)
         if boo.type == 'filestore':
             if not ira.store_fname:
@@ -464,7 +464,7 @@
 
         elif boo.type == 'virtual':
             raise ValueError('Virtual storage does not support static files')
-        
+
         else:
             raise TypeError("No %s storage" % boo.type)
 
@@ -529,7 +529,7 @@
 
         if not boo.online:
             raise IOError(errno.EREMOTE, 'medium offline')
-        
+
         if boo.readonly:
             raise IOError(errno.EPERM, "Readonly medium")
 
@@ -546,7 +546,7 @@
                 fp.close()
                 self._doclog.debug( "Saved data to %s" % fname)
                 filesize = len(data) # os.stat(fname).st_size
-                
+
                 # TODO Here, an old file would be left hanging.
 
             except Exception, e:
@@ -623,7 +623,7 @@
 
         if not storage_bo.online:
             raise IOError(errno.EREMOTE, 'medium offline')
-        
+
         if storage_bo.readonly:
             raise IOError(errno.EPERM, "Readonly medium")
 
@@ -660,7 +660,7 @@
         """ A preparation for a file rename.
             It will not affect the database, but merely check and perhaps
             rename the realstore file.
-            
+
             @return the dict of values that can safely be be stored in the db.
         """
         sbro = self.browse(cr, uid, file_node.storage_id, context=context)
@@ -668,7 +668,7 @@
 
         if not sbro.online:
             raise IOError(errno.EREMOTE, 'medium offline')
-        
+
         if sbro.readonly:
             raise IOError(errno.EPERM, "Readonly medium")
 
@@ -700,7 +700,7 @@
         """ A preparation for a file move.
             It will not affect the database, but merely check and perhaps
             move the realstore file.
-            
+
             @param ndir_bro a browse object of document.directory, where this
                     file should move to.
             @return the dict of values that can safely be be stored in the db.
@@ -710,7 +710,7 @@
 
         if not sbro.online:
             raise IOError(errno.EREMOTE, 'medium offline')
-        
+
         if sbro.readonly:
             raise IOError(errno.EPERM, "Readonly medium")
 
@@ -735,11 +735,11 @@
                 return ValueError("Tried to rename a non-stored file")
             path = sbro.path
             oldpath = os.path.join(path, fname)
-            
+
             for ch in ('*', '|', "\\", '/', ':', '"', '<', '>', '?', '..'):
                 if ch in new_name:
                     raise ValueError("Invalid char %s in name %s" %(ch, new_name))
-                
+
             file_node.fix_ppath(cr, ira)
             npath = file_node.full_path() or []
             dpath = [path,]

=== modified file 'document_ftp/wizard/ftp_configuration.py'
--- document_ftp/wizard/ftp_configuration.py	2010-10-12 06:26:08 +0000
+++ document_ftp/wizard/ftp_configuration.py	2010-11-11 12:44:58 +0000
@@ -18,7 +18,6 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>
 #
 ##############################################################################
-
 from osv import osv, fields
 from tools import config
 
@@ -27,7 +26,7 @@
     _name='document.ftp.configuration'
     _description = 'Auto Directory Configuration'
     _inherit = 'res.config'
-    _rec_name = 'host'
+
     _columns = {
         'host': fields.char('Address', size=64,
                             help="Server address or IP and port to which users should connect to for DMS access",

=== modified file 'document_webdav/webdav_server.py'
--- document_webdav/webdav_server.py	2010-10-15 09:27:58 +0000
+++ document_webdav/webdav_server.py	2010-11-11 12:44:58 +0000
@@ -262,6 +262,17 @@
             return True
         return OpenERPAuthProvider.authenticate(self, db, user, passwd, client_address)
 
+from service.http_server import reg_http_service,OpenERPAuthProvider
+
+class DAVAuthProvider(OpenERPAuthProvider):
+    def authenticate(self, db, user, passwd, client_address):
+        """ authenticate, but also allow the False db, meaning to skip
+            authentication when no db is specified.
+        """
+        if db is False:
+            return True
+        return OpenERPAuthProvider.authenticate(self, db, user, passwd, client_address)
+
 try:
 
     if (config.get_misc('webdav','enable',True)):

=== modified file 'event/test/test_event.yml'
--- event/test/test_event.yml	2010-09-27 14:48:08 +0000
+++ event/test/test_event.yml	2010-11-11 12:44:58 +0000
@@ -1,17 +1,17 @@
 - |
-  In order to test the "Event Organisation" in Association system.  
+  In order to test the "Event Organisation" in Association system.
 - |
   I want to organize one conference event on "OpenERP Business".
 - |
   I'm creating new product "Ticket for Conference" to specify registration Cost of conference.
-- 
+-
   !record {model: product.product, id: product_product_ticketforconcert0}:
     categ_id: product.cat1
     list_price: 68.0
-    name: Ticket for Conference  
+    name: Ticket for Conference
 - |
   I'm creating Event type "Conference".
--   
+-
   !record {model: event.type, id: event_type_conference0}:
      name: Conferences
 - |
@@ -26,31 +26,31 @@
     reply_to: 'info@xxxxxxxxxxxx'
 - |
   Check that the new conference event is "Draft" or not.
-- 
+-
   !assert {model: event.event, id: event_event_conference0}:
      - state == 'draft', "Event should be in draft by default when first time created"
 - |
   Need Minimum 10 Registrations to confirm/start this Conference Event and does not allowed more than 100 Registrations.
 - |
   So I set Minimum and Maximum Registrations limit.
--   
+-
   !python {model: event.event}: |
     self.write(cr, uid, [ref('event_event_conference0')], {'register_max': 100, 'register_min': 10})
 - |
   I'm doing to confirm that conference event.
--  
+-
   !python {model: event.event}: |
     self.button_confirm(cr, uid, [ref("event_event_conference0")])
 - |
-  But this conference event need minimum 10 Confirmed Registrations. so Check that Event is not "confirmed". 
--   
+  But this conference event need minimum 10 Confirmed Registrations. so Check that Event is not "confirmed".
+-
   !assert {model: event.event, id: event_event_conference0}:
      - state != 'confirm', "Event should not confirmed if minimum registrations does not reached"
 - |
   "Mark Johnson" want to subscribe/join into "Conference on OpenERP Business" with 10 tickets.
-- | 
+- |
   I'm creating new partner "Mark Johnson" with his email "info@xxxxxxxxxxxxxx".
-- 
+-
   !record {model: res.partner, id: res_partner_markjohnson0}:
     address:
       - city: Bruxelles
@@ -66,10 +66,10 @@
         zip: '1000'
         email: 'info@xxxxxxxxxxxxxx'
     name: Mark Johnson
-    
+
 - |
-  I'm creating Registration for "Mark Johnson" on "Conference on OpenERP Business" with 10 tickets. 
-- 
+  I'm creating Registration for "Mark Johnson" on "Conference on OpenERP Business" with 10 tickets.
+-
   !record {model: event.registration, id: event_registration_registrationjacot0}:
     contact_id: base_contact.res_partner_contact_jacot0
     event_id: event.event_event_conference0
@@ -79,28 +79,28 @@
     unit_price: 68.0
     nb_register: 10
 - |
-  I'm going to Open that Registration.     
-- 
+  I'm going to Open that Registration.
+-
   !python {model: event.registration}: |
     self.check_confirm(cr, uid, [ref("event_registration_registrationjacot0")])
 - |
   Check that Registration is in "Open" state or not.
-- 
-  !assert {model: event.registration, id: event_registration_registrationjacot0}: 
+-
+  !assert {model: event.registration, id: event_registration_registrationjacot0}:
      - state == 'open', "Registration should be open here."
 
 - |
   I'm again trying to confirm that conference event.
--  
+-
   !python {model: event.event}: |
     self.button_confirm(cr, uid, [ref("event_event_conference0")])
-    
+
 - |
-  Now Minimum requirement of Registration is fulfil. so Check that Event is "confirmed" or not. 
--   
+  Now Minimum requirement of Registration is fulfil. so Check that Event is "confirmed" or not.
+-
   !assert {model: event.event, id: event_event_conference0}:
      - state == 'confirm', "Event should be confirmed here."
-  
+
 - |
   I'm creating invoice of Registration of "Mark Johnson" on "Conference on OpenERP Business".
 -
@@ -108,22 +108,22 @@
     self.action_invoice_create(cr, uid, [ref("event_registration_registrationjacot0")])
 
 - |
-  Check Invoice of Registration of "Mark Johnson" is created or not.     
-- 
+  Check Invoice of Registration of "Mark Johnson" is created or not.
+-
   !assert {model: event.registration, id: event_registration_registrationjacot0}:
      - invoice_id != False, "Invoice should be generated"
 
 - |
-  Check Registration of "Mark Johnson" is closed or not after invoice generated.     
-- 
+  Check Registration of "Mark Johnson" is closed or not after invoice generated.
+-
   !assert {model: event.registration, id: event_registration_registrationjacot0}:
      - state != 'done',  "Registration should be closed after invoice generated"
-  
+
 - |
   Now "Mark Johnson" want to another registration on "Conference on OpenERP Business" with 120 tickets.
 - |
   I'm creating new registration for "Mark Johnson" with 100 tickets.
-- 
+-
   !record {model: event.registration, id: event_registration_registrationzen0}:
     event_id: event.event_event_conference0
     partner_id: event.res_partner_markjohnson0
@@ -131,42 +131,42 @@
     event_product: Ticket for Conference
     unit_price: 68.0
     nb_register: 100
-    
+
 - |
-  I'm going to open "Mark Johnson" registration.     
-- 
+  I'm going to open "Mark Johnson" registration.
+-
   !python {model: event.registration}: |
     self.check_confirm(cr, uid, [ref("event_registration_registrationzen0")])
 
 - |
-  But conference event does not allow more than 100 Registrations. so Check that registration is not in "open" state. 
--   
+  But conference event does not allow more than 100 Registrations. so Check that registration is not in "open" state.
+-
   !assert {model: event.registration, id: event_registration_registrationzen0}:
      - state == 'draft', "Registration should be in draft by default."
 - |
-  Now I'm modifying number of tickets of "Mark Johnson"'s registration with 90 tickets. 
-- 
+  Now I'm modifying number of tickets of "Mark Johnson"'s registration with 90 tickets.
+-
   !python {model: event.registration}: |
     self.write(cr, uid, [ref("event_registration_registrationzen0")], {'nb_register': 90})
 - |
-  I'm again try to open "Mark Johnson" registration.     
-- 
+  I'm again try to open "Mark Johnson" registration.
+-
   !python {model: event.registration}: |
     self.check_confirm(cr, uid, [ref("event_registration_registrationzen0")])
 
 - |
-  Check that registration "open" or not. 
--   
+  Check that registration "open" or not.
+-
   !assert {model: event.registration, id: event_registration_registrationzen0}:
      - state == 'open', "Registration should be open here."
 - |
   I'm closing "Conference on OpenERP Business" Conference event
-- 
+-
   !python {model: event.event}: |
     self.button_done(cr, uid, [ref("event_event_conference0")])
 - |
-  Check that conference is in "close" state or not. 
--   
+  Check that conference is in "close" state or not.
+-
   !assert {model: event.event, id: event_event_conference0}:
      - state == 'done', "Registration should be Closed here."
-  
+

=== modified file 'hr_attendance/hr_attendance_view.xml'
--- hr_attendance/hr_attendance_view.xml	2010-10-16 09:19:07 +0000
+++ hr_attendance/hr_attendance_view.xml	2010-11-11 12:44:58 +0000
@@ -116,7 +116,7 @@
             <field name="view_id" ref="view_attendance_reason"/>
         </record>
 
-        <menuitem 
+        <menuitem
             sequence="2" id="hr.menu_open_view_attendance_reason_new_config" parent="hr.menu_hr_configuration" name="Attendances"
             groups="base.group_extended"/>
         <menuitem action="open_view_attendance_reason" id="menu_open_view_attendance_reason" parent="hr.menu_open_view_attendance_reason_new_config"/>

=== modified file 'hr_timesheet/security/ir.model.access.csv'
--- hr_timesheet/security/ir.model.access.csv	2010-10-09 05:27:04 +0000
+++ hr_timesheet/security/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -6,3 +6,4 @@
 "access_product_template_hr_timesheet","product.template.hr.timesheet","product.model_product_template","base.group_hr_user",1,1,1,1
 "access_product_uom_hr_timesheet","product.uom.hr.timesheet","product.model_product_uom","base.group_hr_user",1,1,1,1
 "access_account_fiscalyear_hr_user","account.account.fiscalyear.user","account.model_account_fiscalyear","base.group_hr_user",1,1,1,1
+"access_hr_analytic_timesheet","hr.analytic.timesheet","model_hr_analytic_timesheet","project.group_project_finance_user",1,0,0,0

=== modified file 'hr_timesheet_invoice/security/ir.model.access.csv'
--- hr_timesheet_invoice/security/ir.model.access.csv	2010-10-09 05:27:04 +0000
+++ hr_timesheet_invoice/security/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -14,3 +14,4 @@
 "access_account_invoice_hr_user","account.invoice.hr.user","account.model_account_invoice","base.group_hr_user",1,1,1,1
 "access_account_invoice_tax_hr_manager","account.invoice.tax.hr.manager","account.model_account_invoice_tax","base.group_hr_manager",1,1,1,1
 "access_report_timesheet_line_employee","report.timesheet.line.employee","model_report_timesheet_line","base.group_hr_user",1,1,1,1
+"access_hr_timesheet_invoice_factor","hr_timesheet_invoice.factor","model_hr_timesheet_invoice_factor","project.group_project_finance_user",1,1,0,0

=== modified file 'hr_timesheet_sheet/hr_timesheet_sheet_view.xml'
--- hr_timesheet_sheet/hr_timesheet_sheet_view.xml	2010-11-01 12:24:37 +0000
+++ hr_timesheet_sheet/hr_timesheet_sheet_view.xml	2010-11-11 12:44:58 +0000
@@ -182,8 +182,9 @@
         <menuitem
              id="base.menu_project_management_time_tracking"
              name="Time Tracking"
-             parent="base.menu_main_pm" sequence="5"/>
-
+             parent="base.menu_main_pm" sequence="5" groups="project.group_project_finance_user"/>
+        <menuitem action="hr_timesheet_sheet.act_hr_timesheet_sheet_form" id="menu_act_project_management_timesheet_sheet_form" parent="base.menu_project_management_time_tracking"
+              sequence="5"/>
         <menuitem action="act_hr_timesheet_sheet_form" id="menu_act_hr_timesheet_sheet_form" parent="hr_attendance.menu_hr_time_tracking"
              sequence="2"/>
 

=== modified file 'hr_timesheet_sheet/security/ir.model.access.csv'
--- hr_timesheet_sheet/security/ir.model.access.csv	2010-10-15 16:53:15 +0000
+++ hr_timesheet_sheet/security/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -1,4 +1,5 @@
 "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_hr_timesheet_report","hr.timesheet.report","model_hr_timesheet_report","base.group_hr_manager",1,0,0,0
 "access_hr_timesheet_sheet_sheet_user","hr_timesheet_sheet.sheet.user","model_hr_timesheet_sheet_sheet","base.group_hr_user",1,1,1,1
 "access_hr_timesheet_sheet_sheet_system_user","hr_timesheet_sheet.sheet.system.user","model_hr_timesheet_sheet_sheet","base.group_user",1,0,0,0
 "access_hr_timesheet_sheet_sheet_day","hr_timesheet_sheet.sheet.day","model_hr_timesheet_sheet_sheet_day","base.group_hr_user",1,1,1,1

=== modified file 'idea/idea.py'
--- idea/idea.py	2010-09-16 12:51:36 +0000
+++ idea/idea.py	2010-11-11 12:44:58 +0000
@@ -33,6 +33,7 @@
 
     _name = "idea.category"
     _description = "Idea Category"
+    _log_create=True
 
     _columns = {
         'name': fields.char('Category', size=64, required=True),
@@ -303,6 +304,7 @@
     _name = 'idea.vote'
     _description = 'Idea Vote'
     _rec_name = 'score'
+    _log_create = True
 
     _columns = {
         'user_id': fields.many2one('res.users', 'User', readonly="True"),

=== modified file 'idea/wizard/idea_post_vote.py'
--- idea/wizard/idea_post_vote.py	2010-09-06 05:05:43 +0000
+++ idea/wizard/idea_post_vote.py	2010-11-11 12:44:58 +0000
@@ -109,6 +109,7 @@
         for do_vote_obj in self.read(cr, uid, ids):
             score = str(do_vote_obj['vote'])
             comment = do_vote_obj.get('note', False)
+        for vote_id in vote_ids:
             vote = {
                 'idea_id': vote_id,
                 'user_id': uid,

=== modified file 'mail_gateway/mail_gateway.py'
--- mail_gateway/mail_gateway.py	2010-10-27 12:59:05 +0000
+++ mail_gateway/mail_gateway.py	2010-11-11 12:44:58 +0000
@@ -396,7 +396,6 @@
 
         model_pool = self.pool.get(model)
         res_id = False
-
         # Create New Record into particular model
         def create_record(msg):
             att_ids = []
@@ -551,7 +550,6 @@
         if not len(res_ids):
             new_res_id, attachment_ids = create_record(msg)
             res_ids = [new_res_id]
-
         # Store messages
         context.update({'model' : model})
         if hasattr(model_pool, 'history'):

=== modified file 'mrp/mrp.py'
--- mrp/mrp.py	2010-10-27 12:59:05 +0000
+++ mrp/mrp.py	2010-11-11 12:44:58 +0000
@@ -446,18 +446,18 @@
         'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.production', context=c),
     }
     _order = 'priority desc, date_planned asc';
-    
+
     def _check_qty(self, cr, uid, ids):
         orders = self.browse(cr, uid, ids)
         for order in orders:
             if order.product_qty <= 0:
                 return False
         return True
-    
+
     _constraints = [
         (_check_qty, 'Order quantity cannot be negative or zero !', ['product_qty']),
     ]
-    
+
     def unlink(self, cr, uid, ids, context=None):
         productions = self.read(cr, uid, ids, ['state'])
         unlink_ids = []
@@ -639,16 +639,16 @@
         @param production_mode: specify production mode (consume/consume&produce).
         @return: True
         """
-       
+
         stock_mov_obj = self.pool.get('stock.move')
         production = self.browse(cr, uid, production_id)
-        
+
         final_product_todo = []
 
         produced_qty = 0
         if production_mode == 'consume_produce':
             produced_qty = production_qty
-            
+
         for produced_product in production.move_created_ids2:
             if (produced_product.scrapped) or (produced_product.product_id.id<>production.product_id.id):
                 continue
@@ -658,7 +658,7 @@
             consumed_products = {}
             check = {}
             scrapped = map(lambda x:x.scrapped,production.move_lines2).count(True)
-            
+
             for consumed_product in production.move_lines2:
                 consumed = consumed_product.product_qty
                 if consumed_product.scrapped:
@@ -671,9 +671,9 @@
                         if (len(production.move_lines2) - scrapped) > len(production.product_lines):
                             check[consumed_product.product_id.id] += consumed_product.product_qty
                             consumed = check[consumed_product.product_id.id]
-                        rest_consumed = produced_qty * f.product_qty / production.product_qty - consumed 
+                        rest_consumed = produced_qty * f.product_qty / production.product_qty - consumed
                         consumed_products[consumed_product.product_id.id] = rest_consumed
-            
+
             for raw_product in production.move_lines:
                 for f in production.product_lines:
                     if f.product_id.id == raw_product.product_id.id:
@@ -712,7 +712,7 @@
                     new_parent_ids.append(final_product.id)
             for new_parent_id in new_parent_ids:
                 stock_mov_obj.write(cr, uid, [raw_product.id], {'move_history_ids': [(4,new_parent_id)]})
-        
+
         wf_service = netsvc.LocalService("workflow")
         wf_service.trg_validate(uid, 'mrp.production', production_id, 'button_produce_done', cr)
         return True
@@ -827,7 +827,7 @@
                 'company_id': production.company_id.id,
             }
             res_final_id = move_obj.create(cr, uid, data)
-             
+
             self.write(cr, uid, [production.id], {'move_created_ids': [(6, 0, [res_final_id])]})
             moves = []
             for line in production.product_lines:
@@ -879,7 +879,7 @@
                     'company_id': production.company_id.id,
                 })
                 wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
-                proc_ids.append(proc_id)                
+                proc_ids.append(proc_id)
             wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
             self.write(cr, uid, [production.id], {'picking_id': picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'})
             message = _("Manufacturing order '%s' is scheduled for the %s.") % (

=== modified file 'mrp/security/ir.model.access.csv'
--- mrp/security/ir.model.access.csv	2010-10-16 16:47:09 +0000
+++ mrp/security/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -67,3 +67,4 @@
 "access_stock_picking_mrp_manager","stock.picking mrp_manager","stock.model_stock_picking","mrp.group_mrp_manager",1,0,0,0
 "access_report_mrp_inout_user","report.mrp.inout user","model_report_mrp_inout","mrp.group_mrp_user",1,0,0,0
 "access_report_workcenter_load_user","report.workcenter.load.user","model_report_workcenter_load","mrp.group_mrp_user",1,0,0,0
+"access_mrp_production","mrp.production user","model_mrp_production","purchase.group_purchase_user",1,0,0,0

=== modified file 'product/product.py'
--- product/product.py	2010-10-27 12:59:05 +0000
+++ product/product.py	2010-11-11 12:44:58 +0000
@@ -24,7 +24,7 @@
 
 import math
 from _common import rounding
-import re  
+import re
 from tools.translate import _
 
 def is_pair(x):
@@ -106,9 +106,14 @@
             from_unit, to_unit = uoms[-1], uoms[0]
         return self._compute_qty_obj(cr, uid, from_unit, qty, to_unit)
 
-    def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context={}):
+    def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context=None):
+        if context is None:
+            context = {}
         if from_unit.category_id.id <> to_unit.category_id.id:
-            return qty
+            if context.get('raise-exception', True):
+                raise osv.except_osv(_('Error !'), _('Conversion from Product UoM m to Default UoM PCE is not possible as they both belong to different Category!.'))
+            else:
+                return qty
         amount = qty / from_unit.factor
         if to_unit:
             amount = rounding(amount * to_unit.factor, to_unit.rounding)

=== modified file 'project/project_view.xml'
--- project/project_view.xml	2010-10-27 05:51:19 +0000
+++ project/project_view.xml	2010-11-11 12:44:58 +0000
@@ -546,6 +546,7 @@
             </page>
        </field>
     </record>
+
     <act_window context="{'search_default_user_id': [active_id]}" domain="[('state', '&lt;&gt;', 'cancelled'),('state', '&lt;&gt;', 'done')]" id="act_res_users_2_project_task_opened" name="Assigned tasks" res_model="project.task" src_model="res.users" view_mode="tree,form,gantt,calendar,graph" view_type="form"/>
     <act_window context="{'search_default_user_id': [active_id]}" domain="[('date', '&gt;=', time.strftime('%Y-%m-01'))]" id="act_res_users_2_project_task_work_month" name="Month works" res_model="project.task.work" src_model="res.users" view_mode="tree,form" view_type="form"/>
     </data>

=== modified file 'project_issue/report/project_issue_report.py'
--- project_issue/report/project_issue_report.py	2010-10-12 14:21:09 +0000
+++ project_issue/report/project_issue_report.py	2010-11-11 12:44:58 +0000
@@ -1,7 +1,7 @@
 
 # -*- coding: utf-8 -*-
 ##############################################################################
-#    
+#
 #    OpenERP, Open Source Management Solution
 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
@@ -16,7 +16,7 @@
 #    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/>.     
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 

=== modified file 'project_issue/security/project_issue_security.xml'
--- project_issue/security/project_issue_security.xml	2010-10-15 14:51:56 +0000
+++ project_issue/security/project_issue_security.xml	2010-11-11 12:44:58 +0000
@@ -4,5 +4,15 @@
 	     <record id="group_project_supporter" model="res.groups">
 	        <field name="name">Project / Support Manager</field>
 	    </record>
+
+	    <record model="ir.rule" id="project_issue_rule">
+        <field name="name" >Issues according to Users or Members</field>
+        <field name="model_id" ref="model_project_issue"/>
+         <field eval="1" name="perm_read"/>
+         <field eval="1" name="perm_create"/>
+         <field eval="1" name="perm_write"/>
+        <field name="groups" eval="[(6, 0, [ref('project.group_project_user')])]"/>
+        <field name="domain_force">['|',('members','in',[user.id]),('user_id','=',user.id)]</field>
+    </record>
  	</data>
 </openerp>

=== added directory 'project_mailgate/security.moved'
=== added file 'project_mailgate/security.moved/ir.model.access.csv'
--- project_mailgate/security.moved/ir.model.access.csv	1970-01-01 00:00:00 +0000
+++ project_mailgate/security.moved/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -0,0 +1,3 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_mailgate_message_project_manager","project.mailgate.message.manager","mail_gateway.model_mailgate_message","project.group_project_manager",1,1,1,0
+"access_mailgate_message_project_user","project.mailgate.message.user","mail_gateway.model_mailgate_message","project.group_project_user",1,1,1,0

=== modified file 'purchase/purchase.py'
--- purchase/purchase.py	2010-11-04 12:53:29 +0000
+++ purchase/purchase.py	2010-11-11 12:44:58 +0000
@@ -282,6 +282,8 @@
             self.log(cr, uid, po.id, message)
 #        current_name = self.name_get(cr, uid, ids)[0][1]
         self.pool.get('purchase.order.line').action_confirm(cr, uid, todo, context)
+        message = _('confirm Order') + " ' " + po.name
+        self.log(cr,uid,po,message)
         for id in ids:
             self.write(cr, uid, [id], {'state' : 'confirmed', 'validator' : uid})
         return True

=== modified file 'purchase/security/ir.model.access.csv'
--- purchase/security/ir.model.access.csv	2010-10-17 21:30:29 +0000
+++ purchase/security/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -7,8 +7,8 @@
 "access_stock_warehouse_purchase_user","stock.warehouse","stock.model_stock_warehouse","group_purchase_user",1,0,0,0
 "access_stock_picking_purchase_user","stock.picking","stock.model_stock_picking","group_purchase_user",1,1,1,1
 "access_stock_move_purchase_user","stock.move","stock.model_stock_move","group_purchase_user",1,1,1,1
-"access_purchase_order_stock_worker","purchase.order","model_purchase_order","stock.group_stock_user",1,0,0,0
-"access_purchase_order_line_stock_worker","purchase.order.line","model_purchase_order_line","stock.group_stock_user",1,0,0,0
+"access_purchase_order_stock_worker","purchase.order","model_purchase_order","stock.group_stock_user",1,1,1,0
+"access_purchase_order_line_stock_worker","purchase.order.line","model_purchase_order_line","stock.group_stock_user",1,0,1,0
 "access_account_tax_purchase_user","account.tax","account.model_account_tax","group_purchase_user",1,0,0,0
 "access_report_purchase_order","purchase.report","model_purchase_report","group_purchase_manager",1,1,1,1
 "access_report_purchase_order_user","purchase.report user","model_purchase_report","group_purchase_user",1,0,0,0
@@ -42,3 +42,5 @@
 "access_account_move_reconcile","account.move.reconcile","account.model_account_move_reconcile","group_purchase_user",1,1,1,1
 "access_report_stock_move","report.stock.move.manager","stock.model_report_stock_move","group_purchase_manager",1,1,1,1
 "access_report_stock_move_user","report.stock.move.user","stock.model_report_stock_move","group_purchase_user",1,0,0,0
+"access_stock_production_lot_user","stock.production.lot user","stock.model_stock_production_lot","group_purchase_user",1,0,1,0
+"access_stock_production_lot_revision","stock.production.lot.revision","stock.model_stock_production_lot_revision","group_purchase_user",1,0,1,0

=== modified file 'purchase/stock.py'
--- purchase/stock.py	2010-10-14 00:37:29 +0000
+++ purchase/stock.py	2010-11-11 12:44:58 +0000
@@ -37,7 +37,7 @@
         """
         reference_amount, reference_currency_id = super(stock_move, self)._get_reference_accounting_values_for_valuation(cr, uid, move, context=context)
         if move.product_id.cost_method != 'average' or not move.price_unit:
-            # no average price costing or cost not specified during picking validation, we will 
+            # no average price costing or cost not specified during picking validation, we will
             # plug the purchase line values if they are found.
             if move.purchase_line_id and move.picking_id.purchase_id.pricelist_id:
                 reference_amount, reference_currency_id = move.purchase_line_id.price_unit, move.picking_id.purchase_id.pricelist_id.currency_id.id
@@ -123,6 +123,8 @@
         for pick in pick_obj.browse(cr, uid, context.get('active_ids', [])):
             has_product_cost = (pick.type == 'in' and pick.purchase_id)
             for m in pick.move_lines:
+                if m.state in ('done','cancel') :
+                    continue
                 if has_product_cost and m.product_id.cost_method == 'average' and m.purchase_line_id:
                     # We use the original PO unit purchase price as the basis for the cost, expressed
                     # in the currency of the PO (i.e the PO's pricelist currency)

=== modified file 'purchase_requisition/security/ir.model.access.csv'
--- purchase_requisition/security/ir.model.access.csv	2010-08-07 06:34:14 +0000
+++ purchase_requisition/security/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -3,3 +3,5 @@
 "access_purchase_requisition_line","purchase.requisition.line","model_purchase_requisition_line","purchase.group_purchase_user",1,1,1,1
 "access_purchase_requisition_manager","purchase.requisition manager","model_purchase_requisition","purchase.group_purchase_manager",1,0,0,0
 "access_purchase_requisition_line_manager","purchase.requisition.line manager","model_purchase_requisition_line","purchase.group_purchase_manager",1,0,0,0
+"access_purchase_requisition","purchase.requisition","model_purchase_requisition","stock.group_stock_manager",1,0,1,0
+"access_purchase_requisition_line","purchase.requisition.line","model_purchase_requisition_line","stock.group_stock_manager",1,0,1,0

=== modified file 'sale/sale.py'
--- sale/sale.py	2010-11-10 09:42:43 +0000
+++ sale/sale.py	2010-11-11 12:44:58 +0000
@@ -1062,7 +1062,7 @@
                     'title': _('Picking Information !'),
                     'message': warn_msg
                     }
-            result['product_uom_qty'] = qty
+            result['product_uom_qty'] = pack.qty
 
         uom2 = False
         if uom:

=== modified file 'sale_crm/wizard/crm_make_sale.py'
--- sale_crm/wizard/crm_make_sale.py	2010-10-22 07:23:46 +0000
+++ sale_crm/wizard/crm_make_sale.py	2010-11-11 12:44:58 +0000
@@ -154,5 +154,4 @@
          'close': True, 
          'partner_id': _selectPartner, 
     }
-
 crm_make_sale()

=== modified file 'stock/product.py'
--- stock/product.py	2010-10-27 12:59:05 +0000
+++ stock/product.py	2010-11-11 12:44:58 +0000
@@ -241,12 +241,12 @@
             where.append(tuple([to_date]))
         elif from_date:
             date_str = "date>=%s"
-            date_values = [from_date] 
+            date_values = [from_date]
         elif to_date:
             date_str = "date<=%s"
             date_values = [to_date]
 
-       
+
 	# TODO: perhaps merge in one query.
         if date_values:
             where.append(tuple(date_values))
@@ -282,13 +282,14 @@
             uoms = uom_obj.browse(cr, uid, list(set(uoms)), context=context)
         for o in uoms:
             uoms_o[o.id] = o
+        ctx = {'raise-exception': False} #TOCHECK: before change uom of product, stock move line are in old uom.
         for amount, prod_id, prod_uom in results:
             amount = uom_obj._compute_qty_obj(cr, uid, uoms_o[prod_uom], amount,
-                    uoms_o[context.get('uom', False) or product2uom[prod_id]])
+                     uoms_o[context.get('uom', False) or product2uom[prod_id]], context=ctx)
             res[prod_id] += amount
         for amount, prod_id, prod_uom in results2:
             amount = uom_obj._compute_qty_obj(cr, uid, uoms_o[prod_uom], amount,
-                    uoms_o[context.get('uom', False) or product2uom[prod_id]])
+                    uoms_o[context.get('uom', False) or product2uom[prod_id]], context=ctx)
             res[prod_id] -= amount
         return res
 
@@ -328,7 +329,7 @@
         'track_outgoing': fields.boolean('Track Outgoing Lots', help="Forces to specify a Production Lot for all moves containing this product and going to a Customer Location"),
         'location_id': fields.dummy(string='Stock Location', relation='stock.location', type='many2one'),
         'valuation':fields.selection([('manual_periodic', 'Periodical (manual)'),
-                                        ('real_time','Real Time (automated)'),], 'Inventory Valuation', 
+                                        ('real_time','Real Time (automated)'),], 'Inventory Valuation',
                                         help="If real-time valuation is enabled for a product, the system will automatically write journal entries corresponding to stock moves." \
                                              "The inventory variation account set on the product category will represent the current inventory value, and the stock input and stock output account will hold the counterpart moves for incoming and outgoing products."
                                         , required=True),

=== modified file 'stock/security/ir.model.access.csv'
--- stock/security/ir.model.access.csv	2010-10-16 16:47:09 +0000
+++ stock/security/ir.model.access.csv	2010-11-11 12:44:58 +0000
@@ -10,11 +10,11 @@
 "access_stock_tracking_user","stock.tracking user","model_stock_tracking","stock.group_stock_user",1,1,1,1
 "access_stock_tracking_manager","stock.tracking manager","model_stock_tracking","stock.group_stock_manager",1,0,0,0
 "access_stock_picking_user","stock.picking user","model_stock_picking","stock.group_stock_user",1,1,1,1
-"access_stock_picking_manager","stock.picking manager","model_stock_picking","stock.group_stock_manager",1,0,0,0
+"access_stock_picking_manager","stock.picking manager","model_stock_picking","stock.group_stock_manager",1,1,0,0
 "access_stock_production_lot_manager","stock.production.lot manager","model_stock_production_lot","stock.group_stock_manager",1,0,0,0
 "access_stock_production_lot_user","stock.production.lot user","model_stock_production_lot","stock.group_stock_user",1,1,1,1
 "access_stock_production_lot_revision","stock.production.lot.revision","model_stock_production_lot_revision","stock.group_stock_user",1,1,1,1
-"access_stock_move_manager","stock.move manager","model_stock_move","stock.group_stock_manager",1,0,0,0
+"access_stock_move_manager","stock.move manager","model_stock_move","stock.group_stock_manager",1,1,0,0
 "access_stock_move_user","stock.move user","model_stock_move","stock.group_stock_user",1,1,1,1
 "access_stock_inventory_user","stock.inventory user","model_stock_inventory","stock.group_stock_user",1,1,1,1
 "access_stock_inventory_manager","stock.inventory manager","model_stock_inventory","stock.group_stock_manager",1,0,0,0

=== modified file 'stock/stock.py'
--- stock/stock.py	2010-11-10 05:42:41 +0000
+++ stock/stock.py	2010-11-11 12:44:58 +0000
@@ -2376,7 +2376,7 @@
         'date_done': fields.datetime('Date done'),
         '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'), ('cancel','Cancelled')), 'State', readonly=True, select=True),
+        '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),
     }
     _defaults = {
@@ -2394,6 +2394,10 @@
         return self.pool.get('stock.move').create(cr, uid, move_vals)
 
     def action_done(self, cr, uid, ids, context=None):
+        self.write(cr, uid, ids, {'state':'done'} ,context=context)
+        return True
+
+    def action_confirm(self, cr, uid, ids, context=None):
         """ Finishes the inventory and writes its finished date
         @return: True
         """
@@ -2444,7 +2448,7 @@
                     move_ids.append(self._inventory_line_hook(cr, uid, line, value))
             message = _('Inventory') + " '" + inv.name + "' "+ _("is done.")
             self.log(cr, uid, inv.id, message)
-            self.write(cr, uid, [inv.id], {'state': 'done', 'date_done': time.strftime('%Y-%m-%d %H:%M:%S'), 'move_ids': [(6, 0, move_ids)]})
+            self.write(cr, uid, [inv.id], {'state': 'confirm', 'date_done': time.strftime('%Y-%m-%d %H:%M:%S'), 'move_ids': [(6, 0, move_ids)]})
         return True
 
     def action_cancel(self, cr, uid, ids, context=None):

=== modified file 'stock/stock_view.xml'
--- stock/stock_view.xml	2010-10-29 05:22:01 +0000
+++ stock/stock_view.xml	2010-11-11 12:44:58 +0000
@@ -118,12 +118,27 @@
                             </form>
                         </field>
                     </page><page string="Posted Inventory" groups="base.group_extended">
-                             <field colspan="2" name="move_ids" nolabel="1"  readonly="1" widget="one2many_list">
+                             <field colspan="2" name="move_ids" nolabel="1" widget="one2many_list">
                                 <tree string="Stock Moves">
                                     <field name="product_id"/>
                                     <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
                                     <field name="product_uom" string="UoM"/>
                                     <field name="prodlot_id" groups="base.group_extended"/>
+                                     <button name="%(track_line)d" string="Split in production lots" type="action"
+                                        icon="terp-stock_effects-object-colorize"
+                                        attrs="{'invisible': [('prodlot_id','&lt;&gt;',False)]}"
+                                        context="{'default_use_exist': picking_id.type=='in'}"
+                                        states="draft,done,cancel"
+                                        groups="base.group_extended"/>
+                                    <field groups="base.group_extended" name="tracking_id"/>
+                                    <button name="setlast_tracking" string="Put in current pack" type="object"
+                                        groups="base.group_extended"
+                                        icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
+                                        states="draft,done,cancel"/>
+                                     <button name="%(split_into)d" string="Put in a new pack" type="action"
+                                        groups="base.group_extended"
+                                        icon="terp-stock_effects-object-colorize"
+                                        states="draft,done,cancel"/>
                                     <field name="location_id"/>
                                     <field name="location_dest_id"/>
                                     <field name="date" string="Date"/>
@@ -135,7 +150,8 @@
                     <field name="state"/>
                     <group col="4" colspan="2">
                         <button name="action_cancel_inventary" states="draft" string="Cancel Inventory" type="object" icon="gtk-cancel"/>
-                        <button name="action_done" states="draft" string="Confirm Inventory" type="object" icon="gtk-apply"/>
+                        <button name="action_confirm" states="draft" string="Confirm Inventory" type="object" icon="gtk-apply"/>
+                        <button name="action_done" states="confirm" string="Done" type="object" icon="gtk-jump-to"/>
                         <button name="action_cancel" states="cancel" string="Set to Draft" type="object" icon="gtk-convert"/>
                     </group>
 
@@ -304,7 +320,7 @@
                         <page string="Stock Moves">
                             <field colspan="2" name="move_ids" nolabel="1" widget="one2many_list">
                                 <tree  string="Stock Moves">
- 									<field name="picking_id" string="Reference"/>                                
+ 									<field name="picking_id" string="Reference"/>
 									<field name="origin"/>
 									<field name="partner_id"/>
                                     <field name="product_id"/>
@@ -317,7 +333,7 @@
                                     <field name="location_dest_id"/>
                                     <field name="state"/>
                                 </tree>
-                             </field>                            
+                             </field>
                         </page>
                     </notebook>
                 </form>
@@ -658,6 +674,10 @@
                                         groups="base.group_extended"
                                         icon="terp-stock_effects-object-colorize"
                                         states="draft,assigned,confirmed,done"/>
+                                    <button name="%(split_into)d" string="Put in a new pack" type="action"
+                                        groups="base.group_extended"
+                                        icon="terp-stock_effects-object-colorize"
+                                        states="draft,assigned,confirmed,done"/>
                                     <field name="location_id"/>
                                     <field name="location_dest_id"/>
                                     <field name="date_expected" string="Date Expected"/>
@@ -1461,9 +1481,9 @@
         Reception Picking (By Stock Move)
         ====================================
 			<!--  from stock_partial_move_view -->
-	
-	
-            
+
+
+
         <record id="view_move_tree_reception_picking" model="ir.ui.view">
             <field name="name">stock.move.tree2</field>
             <field name="model">stock.move</field>
@@ -1523,7 +1543,7 @@
                 </tree>
             </field>
         </record>
-	
+
 
         <record id="view_move_form_reception_picking" model="ir.ui.view">
             <field name="name">stock.move.form2</field>


Follow ups