[merge]
authorRaphaël Valyi <rvalyi@gmail.com>
Sat, 10 Jul 2010 17:51:57 +0000 (14:51 -0300)
committerRaphaël Valyi <rvalyi@gmail.com>
Sat, 10 Jul 2010 17:51:57 +0000 (14:51 -0300)
bzr revid: rvalyi@gmail.com-20100710175157-6fesw4ykbsyo2odn

65 files changed:
addons/account_report/i18n/bs.po
addons/base_action_rule/base_action_rule.py
addons/base_action_rule/base_action_rule_view.xml
addons/crm/__openerp__.py
addons/crm/board_crm_statistical_view.xml
addons/crm/board_crm_view.xml
addons/crm/crm.py
addons/crm/crm_view.xml
addons/crm/security/ir.model.access.csv
addons/crm/test/test_crm_lead.yml
addons/crm/test/test_crm_opportunity.yml
addons/crm/test/test_crm_phonecall.yml
addons/crm/wizard/__init__.py
addons/crm/wizard/crm_custom_create_menu.py [new file with mode: 0644]
addons/crm/wizard/crm_custom_create_menu_view.xml [new file with mode: 0644]
addons/crm/wizard/crm_forward_to_partner.py
addons/crm_claim/test/test_crm_claim.yml
addons/crm_helpdesk/test/test_crm_helpdesk.yml
addons/event/event.py
addons/procurement/procurement.py
addons/product/product.py
addons/project/__init__.py
addons/project/__openerp__.py
addons/project/board_project_demo.xml
addons/project/board_project_view.xml
addons/project/installer.py
addons/project/project.py
addons/project/project_data.xml
addons/project/project_demo.xml
addons/project/project_installer.xml
addons/project/project_mailgate.py
addons/project/project_resource.py
addons/project/project_view.xml
addons/project/project_wizard.xml [deleted file]
addons/project/report/__init__.py
addons/project/report/project_report.py
addons/project/report/project_report_view.xml
addons/project/res_partner.py
addons/project/res_partner_view.xml
addons/project/wizard/project_close_task.py
addons/project/wizard/project_close_task_view.xml
addons/project/wizard/project_task_delegate.py
addons/project_issue/__openerp__.py
addons/project_issue/project_issue.py
addons/project_issue_sheet/project_issue_sheet.py
addons/project_issue_sheet/project_issue_sheet_view.xml
addons/project_long_term/__openerp__.py
addons/project_long_term/project_long_term.py
addons/project_long_term/wizard/project_compute_phases.py
addons/project_long_term/wizard/project_schedule_tasks.py
addons/project_messages/__openerp__.py
addons/project_mrp/__init__.py
addons/project_mrp/mrp.py [deleted file]
addons/project_mrp/project_mrp.py
addons/project_mrp/project_mrp_view.xml
addons/project_mrp/project_procurement.py [new file with mode: 0644]
addons/project_planning/project_planning.py
addons/project_retro_planning/project_retro_planning.py
addons/project_retro_planning/test/deadline_change.yml
addons/project_timesheet/project_timesheet.py
addons/purchase/__openerp__.py
addons/purchase/purchase_workflow.xml
addons/purchase/test/procurement_buy.yml [new file with mode: 0644]
addons/sale/wizard/sale_make_invoice_advance.py
addons/wiki/__openerp__.py

index 3fd8984..bd0c147 100644 (file)
@@ -7,13 +7,13 @@ msgstr ""
 "Project-Id-Version: OpenERP Server 5.0.4\n"
 "Report-Msgid-Bugs-To: support@openerp.com\n"
 "POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2010-07-07 09:59+0000\n"
+"PO-Revision-Date: 2010-07-09 06:46+0000\n"
 "Last-Translator: Bojan Markovic <Unknown>\n"
 "Language-Team: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-07-08 03:50+0000\n"
+"X-Launchpad-Export-Date: 2010-07-10 04:02+0000\n"
 "X-Generator: Launchpad (build Unknown)\n"
 
 #. module: account_report
@@ -26,17 +26,17 @@ msgstr ""
 #. module: account_report
 #: wizard_field:print.indicators.pdf,init,file:0
 msgid "Select a PDF File"
-msgstr ""
+msgstr "Odaberi PDF datoteku"
 
 #. module: account_report
 #: constraint:ir.actions.act_window:0
 msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Neispravan naziv modela u definiciji zadatka."
 
 #. module: account_report
 #: view:account.report.report:0
 msgid "Operators:"
-msgstr ""
+msgstr "Operatori:"
 
 #. module: account_report
 #: field:account.report.report,parent_id:0
@@ -46,12 +46,12 @@ msgstr "Sintetika"
 #. module: account_report
 #: field:account.report.report,disp_graph:0
 msgid "Display As Graph"
-msgstr ""
+msgstr "Prikaži kao grafikon"
 
 #. module: account_report
 #: view:account.report.report:0
 msgid "Account Debit:"
-msgstr ""
+msgstr "Dugovanje konta:"
 
 #. module: account_report
 #: selection:account.report.report,type:0
@@ -66,12 +66,12 @@ msgstr ""
 #. module: account_report
 #: rml:print.indicators:0
 msgid "Tabular Summary"
-msgstr ""
+msgstr "Tablični sažetak"
 
 #. module: account_report
 #: view:account.report.report:0
 msgid "Notes"
-msgstr ""
+msgstr "Bilješke"
 
 #. module: account_report
 #: view:account.report.report:0
index 79b883c..b1ef4f5 100644 (file)
@@ -61,7 +61,6 @@ class base_action_rule(osv.osv):
 
     _columns = {
         'name': fields.many2one('ir.model', 'Object', required=True), 
-        'max_level': fields.integer('Max Level', help='Specifies maximum level.'), 
         '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."), 
@@ -111,19 +110,16 @@ the rule to mark CC(mail to any other person defined in actions)."),
 \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), 
-        'domain':fields.char('Domain', size=124, required=False, readonly=False),
     }
 
     _defaults = {
         'active': lambda *a: True, 
-        'max_level': lambda *a: 15, 
         '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, 
-        'domain': lambda *a: '[]'
     }
     
     _order = 'sequence'
@@ -249,9 +245,13 @@ the rule to mark CC(mail to any other person defined in actions)."),
             @param uid: the current user’s ID for security checks,
             @param context: A standard dictionary for contextual values """
         ok = True 
-        if eval(action.domain):
-            obj_ids = obj._table.search(cr, uid, eval(action.domain), context=context)
-            if not obj.id in obj_ids:
+        if action.filter_id:
+            if action.name.model == action.filter_id.model_id:
+                context.update(eval(action.filter_id.context))
+                obj_ids = obj._table.search(cr, uid, eval(action.filter_id.domain), context=context)
+                if not obj.id in obj_ids:
+                    ok = False
+            else:
                 ok = False
         if hasattr(obj, 'user_id'):
             ok = ok and (not action.trg_user_id.id or action.trg_user_id.id==obj.user_id.id)
@@ -344,9 +344,6 @@ the rule to mark CC(mail to any other person defined in actions)."),
         if not scrit:
             scrit = []
         for action in self.browse(cr, uid, ids):
-            level = action.max_level
-            if not level:
-                break
             model_obj = self.pool.get(action.name.model)
             for obj in objects:
                 ok = self.do_check(cr, uid, action, obj, context=context)
@@ -391,7 +388,6 @@ the rule to mark CC(mail to any other person defined in actions)."),
                 if ok:
                     self.do_action(cr, uid, action, model_obj, obj, context)
                     break
-            level -= 1
         context.update({'action': False})
         return True
 
index 36140e6..ef0b70e 100644 (file)
@@ -17,8 +17,6 @@
                     <field name="name" select="1"/>
                     <field name="active"/>
                     <field name="sequence"/>
-                    <field name="max_level" />
-                    <field name="domain"/>
                     <field name="filter_id"/>
                     <notebook colspan="4">
                         <page string="Conditions">
             <field name="type">tree</field>
             <field name="arch" type="xml">
                 <tree string="Action Rule">
-                    <field name="name" colspan="4"/>
                     <field name="sequence"/>
-                    <field name="max_level"/>
-                    <field name="domain"/>
+                    <field name="name" colspan="4"/>
+                    <field name="filter_id"/>
                 </tree>
             </field>
            </record>
index a490a80..f23b61d 100644 (file)
@@ -85,6 +85,8 @@ Create dashboard for CRM that includes:
 
         'wizard/crm_forward_to_partner_view.xml',
         'wizard/crm_send_email_view.xml',
+        'wizard/crm_custom_create_menu_view.xml',
+
         'crm_view.xml',
 
         'crm_action_rule_view.xml',
index b23fdea..01d0472 100644 (file)
@@ -36,7 +36,7 @@
             <field name="arch" type="xml">
                 <graph string="Opportunities By Stage" type="bar">
                     <field name="stage_id"/>
-                    <field name="nbr" operator="+"/>
+                    <field name="planned_revenue" operator="+"/>
                     <field name="user_id" group="True"/>
                 </graph>
             </field>
@@ -60,7 +60,7 @@
         </record>
 
         <record model="ir.actions.act_window" id="act_oppor_stage_user">
-            <field name="res_model">Number of Opportunities by stage</field>
+            <field name="res_model">Planned revenue by user and stage</field>
             <field name="res_model">crm.lead.report</field>
             <field name="view_type">form</field>
             <field name="view_mode">graph,tree,form</field>
@@ -93,7 +93,7 @@
                         <child2>
 
                             <action
-                                string="Number of Opportunities by Stage and User"
+                                string="Planned Revenue by Stage and User"
                                 name="%(act_oppor_stage_user)d"
                                 colspan="4"/>
 
index ed6044a..ccaf0f7 100644 (file)
@@ -51,7 +51,7 @@
                        <field name="view_type">form</field>
                        <field name="view_mode">graph,tree,form</field>
                        <field name="view_id" ref="view_report_crm_oppor_graph"/>
-            <field name="domain">['&amp;', ('user_id','=',uid), '!' , '&amp;', ('state', '=', 'done'), ('date_closed','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]</field>
+            <field name="domain">['&amp;', '&amp;', ('user_id','=',uid), ('type', '=', 'opportunity'), '!' , '&amp;', ('state', '=', 'done'),  ('date_closed','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]</field>
                </record>
 
                <record model="ir.actions.act_window" id="act_sales_pipeline">
                                                </child1>
                                                <child2>
                                                        <action
-                                string="Revenues by stage"
+                                string="Planned Revenues by Stage"
                                 name="%(act_my_oppor_stage)d"
                                 colspan="4"/>
                             <action
-                                string="Win/Lost Ratio for the last Year"
+                                string="Win/Lost Ratio for the Last Year"
                                 name="%(act_sales_pipeline)d"
                                 colspan="4"/>
                         </child2>
index 575c2a8..ba05269 100644 (file)
@@ -639,4 +639,86 @@ class res_partner(osv.osv):
     }
 res_partner()
 
+
+class crm_case_section_custom(osv.osv):
+    _name = "crm.case.section.custom"
+    _description = 'Custom CRM Case Section' 
+
+    _columns = {
+        'name': fields.char('Case Section',size=64, required=True, translate=True),
+        'code': fields.char('Section Code',size=8),
+        'active': fields.boolean('Active'),
+        'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
+        'sequence': fields.integer('Sequence'),
+        'user_id': fields.many2one('res.users', 'Responsible User'),
+        'reply_to': fields.char('Reply-To', size=64, help="The email address put in the 'Reply-To' of all emails sent by Open ERP about cases in this section"),
+        'parent_id': fields.many2one('crm.case.section.custom', 'Parent Section'), 
+        'note': fields.text('Notes'),
+    }
+
+    _defaults = {
+        'active': 1,
+        'allow_unlink': 1,
+    }
+
+    _sql_constraints = [
+        ('code_uniq', 'unique (code)', 'The code of the section must be unique !')
+    ]
+
+    def _check_recursion(self, cr, uid, ids):
+        level = 100
+        while len(ids):
+            cr.execute('SELECT DISTINCT parent_id FROM crm_case_section_custom '\
+                       'WHERE id IN %s',
+                       (tuple(ids),))
+            ids = filter(None, map(lambda x:x[0], cr.fetchall()))
+            if not level:
+                return False
+            level -= 1
+        return True
+    _constraints = [
+        (_check_recursion, 'Error ! You cannot create recursive sections.', ['parent_id'])
+    ]
+
+crm_case_section_custom()
+
+
+class crm_case_custom(osv.osv, crm_case):
+    _name = 'crm.case.custom'
+    _inherit = 'mailgate.thread'
+    _description = "Custom CRM Case"
+
+    _columns = {
+            'id': fields.integer('ID', readonly=True),
+            'name': fields.char('Name',size=64,required=True),
+            'priority': fields.selection(AVAILABLE_PRIORITIES, 'Priority'),
+            'active': fields.boolean('Active'),
+            'description': fields.text('Description'),
+            'section_id': fields.many2one('crm.case.section.custom', 'Section', required=True, select=True),
+            'probability': fields.float('Probability (%)'),
+            'email_from': fields.char('Partner Email', size=128),
+            'email_cc': fields.char('CC', size=252),
+            'partner_id': fields.many2one('res.partner', 'Partner'),
+            'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', domain="[('partner_id','=',partner_id)]"),
+            'date': fields.datetime('Date'),
+            'create_date': fields.datetime('Created' ,readonly=True),
+            'date_deadline': fields.datetime('Deadline'),
+            'date_closed': fields.datetime('Closed', readonly=True),
+            'user_id': fields.many2one('res.users', 'Responsible'),
+            'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True),
+            'ref' : fields.reference('Reference', selection=_links_get, size=128),
+            'date_action_last': fields.datetime('Last Action', readonly=1),
+            'date_action_next': fields.datetime('Next Action', readonly=1),
+        }
+
+    _defaults = {
+        'active': 1,
+        'state': 'draft',
+        'priority': AVAILABLE_PRIORITIES[2][0],
+        'date': time.strftime('%Y-%m-%d %H:%M:%S'),
+    }
+
+crm_case_custom()
+
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index 74786ad..61da1ab 100644 (file)
         <menuitem id="base.next_id_64" name="Reporting"
             parent="base.menu_base_partner" sequence="11" />
 
+        <menuitem action="crm_custom_create_menu_action"
+            id="crm_case_create_custom_menu"
+            parent="base.menu_crm_config_sales"
+            groups="base.group_extended"
+            name="Create Menu for Custom Cases" />
+
+
         <!-- Case Sections Form View -->
 
         <record id="crm_case_section_view_form" model="ir.ui.view">
                     </field>
                 </field>
         </record>
+        
+        
+        <!-- Custom Case Sections -->
+        <record id="crm_case_section_custom_view_form" model="ir.ui.view">
+            <field name="name">crm.case.section.custom.form</field>
+            <field name="model">crm.case.section.custom</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form string="Custom Case Section">
+                    <group col="6" colspan="4">
+                        <field name="name" select="1" colspan="2"/>
+                        <field name="parent_id" select="2" widget="selection"/>
+                        <field name="code" select="1"/>
+                        <newline/>
+                        <field name="user_id" select="2"/>
+                        <field name="active" select="2"/>
+                    </group>
+                    <notebook colspan="4">
+                        <page string="Information">
+                            <group col="2" colspan="1">
+                                <separator string="Mailgateway" colspan="2"/>
+                                <field name="reply_to" select="2"/>
+                            </group>
+                            <group col="2" colspan="1">
+                                <separator string="Configuration" colspan="2"/>
+                                <field name="allow_unlink" select="2"/>
+                            </group>
+                        </page>
+                        <page string="Notes">
+                            <field name="note" select="1" colspan="4" nolabel="1"/>
+                        </page>
+                    </notebook>
+                </form>
+            </field>
+        </record>
+        <record id="crm_case_section_custom_view_tree" model="ir.ui.view">
+            <field name="name">crm.case.section.custom.tree</field>
+            <field name="model">crm.case.section.custom</field>
+            <field name="type">tree</field>
+            <field name="arch" type="xml">
+                <tree string="Custom Case Section">
+                    <field name="name" select="1"/>
+                    <field name="code" select="1"/>
+                    <field name="user_id" select="1"/>
+                </tree>
+            </field>
+        </record>
+        
+        <!-- Custom crm case-->
+        
+        <record id="crm_case_custom_tree_view" model="ir.ui.view">
+            <field name="name">Custom Cases - Tree</field>
+            <field name="model">crm.case.custom</field>
+            <field name="type">tree</field>
+            <field name="arch" type="xml">
+                <tree colors="red:date_deadline&lt;current_date and state=='open'" string="Custom Cases">
+                    <field name="id"/>
+                    <field name="date"/>
+                    <field name="date_deadline"/>
+                    <field name="name"/>
+                    <field name="partner_id"/>
+                    <field name="user_id"/>
+                    <field name="priority"/>
+                    <field name="state"/>
+                    <field name="create_date" invisible="1"/>
+                </tree>
+            </field>
+        </record>
+
+        <record id="crm_case_custom_form_view" model="ir.ui.view">
+            <field name="name">Custom Cases - Form</field>
+            <field name="model">crm.case.custom</field>
+            <field name="type">form</field>
+            <field name="priority" eval="1"/>
+            <field name="arch" type="xml">
+                <form string="Custom Cases">
+                    <group colspan="4" col="6">
+                        <field name="name" select="1"/>
+                        <field name="section_id" widget="selection"/>
+                        <field name="user_id" select="1"/>
+                        <field name="priority"/>
+                        <field name="date" select="1"/>
+                        <field name="date_deadline" select="2"/>
+                    </group>
+                    <notebook colspan="4">
+                        <page string="General">
+                            <group col="4" colspan="4">
+                                <separator string="Communication" colspan="4"/>
+                                <field name="partner_id" on_change="onchange_partner_id(partner_id, email_from)" select="1"/>
+                                <field name="partner_address_id" on_change="onchange_partner_address_id(partner_address_id, email_from)" select="2"/>
+                                <newline/>
+                                <field name="email_from" select="2"/>
+                            </group>
+
+                            <separator string="Notes" colspan="4"/>
+                            <field colspan="4" name="description" nolabel="1" select="2"/>
+
+                            <separator colspan="4"/>
+                            <group col="8" colspan="4">
+                                <field name="state"/>
+                                <button name="case_open" string="Open"
+                                    states="draft,pending" type="object"
+                                    icon="gtk-go-forward" />
+                                <button name="case_close" string="Close"
+                                    states="open,draft,pending" type="object"
+                                    icon="gtk-close" />
+                                <button name="case_pending" string="Pending"
+                                    states="draft,open" type="object"
+                                    icon="gtk-media-pause" />
+                                <button name="case_cancel" string="Cancel"
+                                    states="draft,open,pending" type="object"
+                                    icon="gtk-cancel" />
+                                <button name="case_reset"
+                                    string="Reset to Draft" states="done,cancel"
+                                    type="object" icon="gtk-convert" />
+                            </group>
+                        </page>
+                        <page string="Extra Info">
+                            <separator colspan="4" string="Dates"/>
+                            <field name="create_date"/>
+                            <field name="date_closed"/>
+                            <field name="date_action_last"/>
+                            <field name="date_action_next"/>
+                            <separator colspan="4" string="Others"/>
+                            <field name="id" select="1"/>
+                            <field name="active" select="2"/>
+                            <separator colspan="4" string="References"/>
+                            <field colspan="4" name="ref"/>
+                            <field colspan="4" name="log_ids" nolabel="1">
+                                <tree string="Logs">
+                                    <field name="name" colspan="4"/>
+                                    <field name="date"/>
+                                    <field name="user_id"/>
+                                </tree>
+                                <form string="Logs">
+                                    <separator string="Action Information" colspan="4"/>
+                                    <field name="name" colspan="4"/>
+                                    <field name="date"/>
+                                    <field name="user_id"/>
+                                </form>
+                            </field>
+                        </page>
+                        <page string="Emails" groups="base.group_extended">
+                           <group colspan="4">
+                               <field colspan="4" name="email_cc" string="CC" widget="char" size="512"/>
+                           </group>
+                            <field name="message_ids" colspan="4" nolabel="1" mode="form,tree">
+                                <form string="Communication history">
+                                    <group col="4" colspan="4">
+                                        <field name="email_from"/>
+                                        <field name="date"/>
+                                        <field name="email_to" widget="char" size="512"/>
+                                        <field name="email_cc" widget="char" size="512"/>
+                                        <field name="name" colspan="4" widget="char" size="512"/>
+                                    </group>
+                                    <notebook colspan="4">
+                                        <page string="Details">
+                                            <field name="description" colspan="4" nolabel="1"/>
+                                        </page>
+                                        <page string="Attachments">
+                                            <field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/>
+                                        </page>
+                                    </notebook>
+                                    <button colspan="4"
+                                    string="Reply"
+                                    name="%(crm.action_crm_send_mail)d"
+                                    context="{'mail':'reply', 'model': 'crm.case.custom', 'include_original' : True}"
+                                    icon="gtk-undo" type="action" />
+                                </form>
+                                <tree string="Communication history">
+                                    <field name="date"/>
+                                    <field name="email_from" />
+                                    <field name="email_to"/>
+                                    <field name="description"/>
+                                </tree>
+                            </field>
+                            <button colspan="2" string="Send New Email"
+                                name="%(crm.action_crm_send_mail)d"
+                                context="{'mail':'new', 'model': 'crm.case.custom'}"
+                                icon="gtk-go-forward" type="action" />
+                            <button colspan="2" string="Forward to Partner"
+                                name="%(crm_lead_forward_to_partner_act)d"
+                                icon="gtk-go-forward" type="action" />
+                         </page>
+                    </notebook>
+                </form>
+            </field>
+        </record>
+        
+        <record model="ir.ui.view" id="crm_case_custom_calendar_view">
+            <field name="name">Custom Cases - Calendar</field>
+            <field name="model">crm.case.custom</field>
+            <field name="type">calendar</field>
+            <field name="priority" eval="2"/>
+            <field name="arch" type="xml">
+                <calendar string="Cases"
+                    date_start="date" color="user_id">
+                    <field name="name" />
+                    <field name="partner_id" />
+                </calendar>
+            </field>
+        </record>
+      
+      <!-- Custom Cases Search View -->
+
+    <record id="crm_case_custom_search_view" model="ir.ui.view">
+        <field name="name">Custom Cases - Search</field>
+        <field name="model">crm.case.custom</field>
+        <field name="type">search</field>
+        <field name="arch" type="xml">
+            <search string="Search Cases">
+                <filter icon="terp-check"
+                    string="Current"
+                    default="1" name="current"
+                    domain="[('state','in',('draft','open'))]"/>
+                <filter icon="terp-camera_test"
+                    string="Open"
+                    domain="[('state','=','open')]"/>
+                <filter icon="terp-gtk-media-pause"
+                    string="Pending"
+                    domain="[('state','=','pending')]"/>
+
+                <separator orientation="vertical"/>
+                <filter icon="terp-go-today" string="Today"
+                    domain="[('create_date','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')), ('create_date','&gt;=', time.strftime('%%Y-%%m-%%d 00:00:00'))]"
+                    help="Todays' Cases" />
+                <filter icon="terp-go-week" string="7 Days"
+                    help="Cases creating during last 7 days"
+                    domain="[('create_date','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')),('create_date','&gt;=',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d 00:00:00'))]"
+                />
+                <separator orientation="vertical"/>
+                <field name="name"/>
+                <field name="user_id">
+                    <filter icon="terp-personal-"
+                        domain="[('user_id','=', False)]"
+                        help="Unassigned Cases" />
+                </field>
+                <newline/>
+                <group  expand="0" string="Extended options..." groups="base.group_extended">
+                      <field name="create_date" string="Creation Date"/>
+                      <field name="date_closed"/>
+                </group>
+                <newline/>
+                <group expand="0" string="Group By...">
+                    <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+                    <filter string="Priority" icon="terp-rating-rated"
+                            domain="[]" context="{'group_by':'priority'}" />
+                    <separator orientation="vertical"/>
+                    <filter string="Salesman" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
+                    <filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
+                    <separator orientation="vertical"/>
+                    <filter string="Creation" icon="terp-go-month"
+                        domain="[]" context="{'group_by':'create_date'}" />
+                </group>
+           </search>
+        </field>
+    </record>
     </data>
 </openerp>
index bd88163..a849c04 100644 (file)
@@ -39,3 +39,7 @@
 "access_res_partner_category","res.partner.category.crm.user","base.model_res_partner_category","crm.group_crm_user",1,0,0,0
 "mail_gateway_mailgate_message","mail_gateway.mailgate.message","mail_gateway.model_mailgate_message","crm.group_crm_user",1,1,1,1
 "mail_gateway_mailgate_thread","mail_gateway.mailgate.thread","mail_gateway.model_mailgate_thread","crm.group_crm_user",1,1,1,1
+"access_crm_case_section_custom_user","crm.case.section.custom.user","model_crm_case_section_custom","crm.group_crm_user",1,0,0,0
+"access_crm_case_section_custom_manager","crm.case.section.custom.manager","model_crm_case_section_custom","crm.group_crm_manager",1,1,1,1
+"access_crm_case_custom_user","crm.case.custom.user","model_crm_case_custom","crm.group_crm_user",1,1,1,1
+"access_crm_case_custom_manager","crm.case.custom.manager","model_crm_case_custom","crm.group_crm_manager",1,1,1,1
index 97c54b5..f61021a 100644 (file)
   !python {model: crm.lead2opportunity}: |
      self.action_apply(cr, uid, [ref('crm_lead2opportunity_stonage_0')], {'active_id': ref('crm_lead_newcustomer0')})
 
--  |   
-   I can check that a lead and a business opportunity is now assigned to this
-   lead.
-#-
-#   !python {model: crm.lead, id: crm_lead_newcustomer0}: 
-#     - opportunity_id == False
-         
 -  |
-   I check that the partner associated to this lead as the same country, phone number
-   and name than the opportunity.
+   In order to check the opportunity is created or not, I check type.
 -  
   !python {model: crm.lead}: |
     lead = self.browse(cr, uid, ref("crm_lead_newcustomer0"))
-    obj_opportunity = self.pool.get('crm.lead')
-    ids = obj_opportunity.search(cr, uid, [('name', '=', lead.partner_name)])
-    opportunity = obj_opportunity.browse(cr, uid, ids)[0]
-    assert lead.partner_name == opportunity.partner_id.name
-    assert lead.phone == opportunity.phone
+    assert lead.type == 'opportunity'
 
 #-
 #  |
index 48a71de..cf62d05 100644 (file)
@@ -4,7 +4,7 @@
 -
    !record {model: crm.lead, id: crm_opportunity_abcfuelcounits0}:
     email_from: info@balmerinc.be
-    name: 'ABC FUEL CO 829264 - 10002 units '
+    name: 'ABC FUEL CO 829264 - 10002 units'
     partner_address_id: base.res_partner_address_1
     partner_id: base.res_partner_9
     probability: 1.0
    then I click on the date on which I want schedule meeting.
    I fill proper data for that meeting and save it
 -
-   !record {model: crm.meeting, id: crm_meeting_abcfuelcounits0}:
-    alarm_id: base_calendar.alarm3
+  !record {model: crm.meeting, id: crm_meeting_abcfuelcounits0}:
     date: '2010-04-16 00:00:00'
     date_deadline: '2010-04-16 08:00:00'
     duration: 8.0
     email_from: info@balmerinc.be
-    name: 'ABC FUEL CO 829264 - 10002 units '
+    name: 'ABC FUEL CO 829264 - 10002 units'
     opportunity_id: 'crm_opportunity_abcfuelcounits0'
     partner_address_id: base.res_partner_address_1
     partner_id: base.res_partner_9
-    rrule_type: weekly
     section_id: crm.section_sales_department
     state: open
 - |
@@ -54,7 +52,7 @@
 - 
   !record {model: crm.opportunity2phonecall, id: crm_opportunity2phonecall_abcfuelcounits0}:
     date: '2010-04-17 11:15:00'
-    name: 'ABC FUEL CO 829264 - 10002 units '
+    name: 'ABC FUEL CO 829264 - 10002 units'
     section_id: crm.section_sales_department
     user_id: base.user_demo
 - |    
@@ -66,8 +64,9 @@
   I  check that phonecall record is created for that opportunity.       
 -   
   !python {model: crm.phonecall}: |
-    ids = self.search(cr, uid, [('name', '=', 'ABC FUEL CO 829264 - 10002 units')])
-    assert len(ids) 
+    phone_obj = self.pool.get('crm.phonecall')
+    ids = phone_obj.search(cr, uid, [('name', '=', 'ABC FUEL CO 829264 - 10002 units')])
+    assert len(ids)
 - |    
   I can see phonecall record after click on "Schedule call" wizard.     
 -
@@ -78,4 +77,4 @@
     partner_address_id:  base.res_partner_address_1
     partner_id:  base.res_partner_9
     section_id: crm.section_sales_department
-    
\ No newline at end of file
+    
index f202065..af28c19 100644 (file)
 -    
   !python {model: crm.phonecall2opportunity}: |
      self.action_apply(cr, uid, [ref("crm_phonecall2opportunity_interviewcall0")], {"active_id": ref("crm_phonecall_interviewcall0")})
--
-  # This is not working, find a way to do that in YAML
-  
+
 - |
   I can see that a business opportunity is now assigned to this phonecall
 -
   !assert {model: crm.phonecall, id: crm_phonecall_interviewcall0}:
-      - opportunity_id == True
+     - opportunity_id != False
       
 - |
   And I check that the phonecall and the newly created business opportunity is linked
   to same  partner
 -
   !python {model:  crm.phonecall}: | 
-    xid= ref('crm_phonecall_interviewcall0')
-    obj_phonecall = self.browse(cr, uid, xid)
+    obj_phonecall = self.browse(cr, uid, ref('crm_phonecall_interviewcall0'))
     ids = self.pool.get('crm.lead').search(cr, uid, [('name', '=', obj_phonecall.opportunity_id.name)])
     obj_opp = self.pool.get('crm.lead').browse(cr, uid, ids)[0]
     assert obj_phonecall.partner_id == obj_opp.partner_id
     phonecall_id: 'crm_phonecall_interviewcall0'
     rrule_type: weekly
     state: open
-
--
-  #This is not working for yaml    
-- |
-  I can jump to this meeting by "Meetings" shortcut from my phonecall's form view
--
   
 - |
   In order to schedule other phonecall to the partner
index e4eb233..8c6a650 100644 (file)
@@ -30,5 +30,7 @@ import crm_phonecall_to_partner
 import crm_phonecall_to_opportunity
 import crm_partner_to_opportunity
 
+import crm_custom_create_menu
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 
diff --git a/addons/crm/wizard/crm_custom_create_menu.py b/addons/crm/wizard/crm_custom_create_menu.py
new file mode 100644 (file)
index 0000000..8cf8619
--- /dev/null
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from osv import fields,osv
+
+
+class crm_case_custom_create_menu(osv.osv_memory):
+    '''
+    Create menu for custom Cases
+    '''
+    _name = 'crm.custom.create.menu'
+    _description = 'Create menu for custom Cases'
+    
+    _columns = {
+        'name': fields.char('Menu Name', size=64, required=True),
+        'menu_parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', required=True),
+        'section_id': fields.many2one('crm.case.section.custom', 'Section', required=True),
+        'view_form': fields.many2one('ir.ui.view', 'Form View', domain=[('type','=','form'),('model','=','crm.case.custom')]),
+        'view_tree': fields.many2one('ir.ui.view', 'Tree View', domain=[('type','=','tree'),('model','=','crm.case.custom')]),
+        'view_calendar': fields.many2one('ir.ui.view', 'Calendar View', domain=[('type','=','calendar'),('model','=','crm.case.custom')]),
+        'view_search': fields.many2one('ir.ui.view', 'Search View', domain=[('type','=','search'),('model','=','crm.case.custom')]),
+    }
+    
+    def menu_create(self, cr, uid, ids, context=None):
+        """
+        Creates Menus for selected custom section
+        """
+        data_obj = self.pool.get('ir.model.data')
+        for this in self.browse(cr, uid, ids, context=context):
+            domain = [('section_id', '=', this.section_id.id)]
+            view_mode = [this.view_tree and 'tree', this.view_form and 'form', this.view_calendar and 'calendar']
+            view_mode = filter(None , view_mode)
+            action_id = self.pool.get('ir.actions.act_window').create(cr,uid, {
+                    'name': this.name,
+                    'res_model': 'crm.case.custom',
+                    'domain': domain,
+                    'view_type': 'form',
+                    'view_mode': ','.join(view_mode),
+                    'search_view_id': this.view_search.id or False, 
+                    'context': {'default_section_id': this.section_id.id, 'default_user_id': uid}
+                })
+            menu_id=self.pool.get('ir.ui.menu').create(cr, uid, {
+                'name': this.name,
+                'parent_id': this.menu_parent_id.id,
+                'icon': 'STOCK_JUSTIFY_FILL'
+            })
+            self.pool.get('ir.values').create(cr, uid, {
+                    'name': 'Custom Cases',
+                    'key2': 'tree_but_open',
+                    'model': 'ir.ui.menu',
+                    'res_id': menu_id,
+                    'value': 'ir.actions.act_window,%d'%action_id,
+                    'object': True
+                })
+        return {}
+
+crm_case_custom_create_menu()
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/crm_custom_create_menu_view.xml b/addons/crm/wizard/crm_custom_create_menu_view.xml
new file mode 100644 (file)
index 0000000..ddd4f23
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+    <data>
+        <record model="ir.ui.view" id="crm_custom_create_menu_form">
+            <field name="name">crm.custom.create.menu.form</field>
+            <field name="model">crm.custom.create.menu</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form string="Create Menu for Custom Cases">
+                    <separator string="Menu Information" colspan="4"/>
+                    <field name="name"/>
+                    <field name="menu_parent_id"/>
+                    <field name="section_id"/>
+                    <label string="This wizard will create all sub-menus, within the selected menu." align="0.0" colspan="4"/>
+                    <label string="You may want to create a new parent menu to put all the created menus in." align="0.0" colspan="4"/>
+                    <separator string="Select Views (Empty for default)" colspan="4"/>
+                    <field name="view_form"/>
+                    <field name="view_tree"/>
+                    <field name="view_calendar"/>
+                    <field name="view_search"/>
+                    <separator string="" colspan="4"/>
+                    <label string="" colspan="2"/>
+                    <button special="cancel" string="_Cancel" icon="gtk-cancel"/>
+                   <button name="menu_create" string="Create _Menu" type="object" icon='gtk-ok'/>
+                </form>
+            </field>
+        </record>
+
+        <record model="ir.actions.act_window" id="crm_custom_create_menu_action">
+            <field name="name">Create Menu</field>
+            <field name="res_model">crm.custom.create.menu</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">form</field>
+            <field name="target">new</field>
+        </record>
+        
+    </data>
+</openerp>
index fb607ee..1e323ed 100644 (file)
@@ -48,7 +48,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
 
     _defaults = {
         'name' : 'email',
-        'history': 'latest',
+        'history': 'info',
         'add_cc': True,
         'email_from': lambda self, cr, uid, *a: self.pool.get('res.users')._get_email_from(cr, uid, uid)[uid]
     }
index e800016..14551ad 100644 (file)
   !assert {model: crm.claim, id: crm_claim_damagedproduct0}:
     - state == 'draft'
 - |
-  Now I make sure that claim is at "Accepted" stage.
-- 
-  !assert {model: crm.claim, id: crm_claim.crm_claim_damagedproduct0}:
-    stage_id: crm_claim.stage_claim1
-- |
   I can change that stage by next button right on it
 -
   !python {model: crm.claim}: |
index 6d3beb4..6872a99 100644 (file)
   !python {model: crm.helpdesk}: |
     self.case_open(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')])  
 - |
-  I can see that "Send Reminder" button is visible, which is used to send reminder to partner from
-  responsible person  or send reminder to responsible person from partner.
--  
-   #this is not work for yaml.
--   
-#  !python {model: crm.helpdesk}: |
-#     self.remind_user(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')], context={}, attach=False, destination=True)  
-- |
   After a proper communication for the request via email I make sure that the request is fulfilled and
   I close this HelpDesk Request by clicking on "Close" button.
 - 
   !python {model: crm.helpdesk}: |
-    self.case_close(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')])    
--
+    self.case_close(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')])
index 73ff7f6..8efa132 100644 (file)
@@ -454,7 +454,7 @@ and users by email"),
 
         contact_id = self.pool.get('res.partner.contact').browse(cr, uid, contact)
         data['badge_name'] = contact_id.name
-        data['badge_title'] = contact_id.title
+        data['badge_title'] = contact_id.title.name
         if partner:
             partner_addresses = self.pool.get('res.partner.address').search(cr, uid, [('partner_id', '=', partner)])
             job_ids = self.pool.get('res.partner.job').search(cr, uid, [('contact_id', '=', contact), ('address_id', 'in', partner_addresses)])
@@ -471,7 +471,9 @@ and users by email"),
         data_event =  self.pool.get('event.event').browse(cr, uid, event_id)
         
         context['currency_id'] = data_event.currency_id.id
-        
+        if data_event.user_id.id:
+            return {'value': {'user_id':data_event.user_id.id}}
+
         if data_event.product_id:
             if not partner_invoice_id:
                 unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
@@ -516,6 +518,7 @@ and users by email"),
         data_event =  self.pool.get('event.event').browse(cr, uid, event_id)
 
         if data_event.product_id:
+            data['event_product']=data_event.product_id.name
             if not partner_invoice_id:
                 data['unit_price']=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
                 return {'value': data}
index b098d27..34a5c02 100644 (file)
@@ -228,7 +228,14 @@ class procurement_order(osv.osv):
         return False
 
     def check_produce_service(self, cr, uid, procurement, context=[]):
-        return True
+        """ Checks project_mrp install or not.
+         @return: True or False"""
+        obj_module = self.pool.get('ir.module.module')
+        module_id = obj_module.search(cr, uid, [('name', '=', 'project_mrp'),('state', '=', 'installed')])
+        if module_id:
+            return True
+        cr.execute('update procurement_order set message=%s where id=%s', (_('Project_mrp module not installed !'), procurement.id))
+        return False
 
     def check_produce_product(self, cr, uid, procurement, context=[]):
         """ Finds BoM of a product if not found writes exception message.
@@ -344,6 +351,10 @@ class procurement_order(osv.osv):
         return True
 
     def _check_make_to_stock_service(self, cr, uid, procurement, context={}):
+        """
+           This method may be overrided by objects that override procurement.order
+           for computing their own purpose
+        @return: True"""
         return True
 
     def _check_make_to_stock_product(self, cr, uid, procurement, context={}):
index b4dc56d..aa916fb 100644 (file)
@@ -227,7 +227,7 @@ class product_template(osv.osv):
 
     _columns = {
         'name': fields.char('Name', size=128, required=True, translate=True, select=True),
-        'product_manager': fields.many2one('res.users','Product Manager'),
+        'product_manager': fields.many2one('res.users','Product Manager',help="This is use as task responsible"),
         'description': fields.text('Description',translate=True),
         'description_purchase': fields.text('Purchase Description',translate=True),
         'description_sale': fields.text('Sale Description',translate=True),
index 44154c8..3f65abc 100644 (file)
@@ -27,5 +27,4 @@ import report
 import wizard
 import res_partner
 
-
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index c3784c4..726e87b 100644 (file)
@@ -26,8 +26,8 @@
     "author": "Tiny",
     "website": "http://www.openerp.com",
     "category": "Generic Modules/Projects & Services",
-    "depends": ["product", "analytic", "process", "mail_gateway","board"],
-    "description": """Project management module that track multi-level projects, tasks,
+    "depends": ["product", "analytic", "mail_gateway", "board"],
+    "description": """Project management module tracks multi-level projects, tasks,
 work done on tasks, eso. It is able to render planning, order tasks, eso.
  Dashboard for project members that includes:
     * List of my open tasks
@@ -41,7 +41,6 @@ work done on tasks, eso. It is able to render planning, order tasks, eso.
         "wizard/project_task_delegate_view.xml",
         "security/ir.model.access.csv",
         "project_data.xml",
-        "project_wizard.xml",
         "project_view.xml",
         "project_report.xml",
         "process/task_process.xml",
index 2a160b4..99c9c4a 100644 (file)
@@ -1,8 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <openerp>
     <data noupdate="1">
-        
-        
+             
         <!--
                 Administrator shortcut
                 Demo user startup menu
@@ -14,6 +13,7 @@
             <field name="sequence">3</field>
             <field name="res_id" ref="menu_board_project"/>
         </record-->
+        
         <record id="base.user_root" model="res.users">
             <field name="action_id" ref="open_board_project"/>
         </record>
index f9e2dc5..6258c85 100644 (file)
@@ -6,22 +6,6 @@
             <field name="name">Project</field>
         </record>
 
-        <record id="view_task_tree" model="ir.ui.view">
-            <field name="name">project.task.tree</field>
-            <field name="model">project.task</field>
-            <field name="type">tree</field>
-            <field eval="99" name="priority"/>
-            <field name="arch" type="xml">
-                <tree colors="red:date_deadline&lt;current_date;blue:date_deadline==current_date;black:date_deadline&gt;current_date" string="My Tasks">
-                    <field name="name"/>
-                    <field name="project_id"/>
-                    <field name="date_deadline"/>
-                    <field name="planned_hours"/>
-                    <field name="effective_hours"/>
-                    <field name="priority"/>
-                </tree>
-            </field>
-        </record>
         <!-- Editable My task -->
         <record id="view_task_tree" model="ir.ui.view">
             <field name="name">project.task.tree</field>
@@ -39,6 +23,7 @@
                 </tree>
             </field>
         </record>
+        
         <record id="action_view_task_tree" model="ir.actions.act_window">
             <field name="name">My Open Tasks</field>
             <field name="res_model">project.task</field>
@@ -47,6 +32,7 @@
             <field name="domain">[('user_id','=',uid),('state','=','open')]</field>
             <field name="view_id" ref="view_task_tree"/>
         </record>
+        
         <record id="action_view_pending_task_tree" model="ir.actions.act_window">
             <field name="name">My Pending Tasks</field>
             <field name="res_model">project.task</field>
@@ -55,6 +41,7 @@
             <field name="domain">[('user_id','=',uid),('state','=','pending')]</field>
             <field name="view_id" ref="view_task_tree"/>
         </record>
+        
         <record id="action_view_task_tree_deadline" model="ir.actions.act_window">
             <field name="name">My Task's Deadlines</field>
             <field name="res_model">project.task</field>
             <field name="usage">menu</field>
             <field name="view_id" ref="board_project_form"/>
         </record>
+        
         <menuitem
             id="next_id_86"
             name="Dashboard"
             icon="terp-graph"
             sequence="0"
             parent="base.menu_project_report"/>
+            
         <menuitem
             action="open_board_project"
             icon="terp-graph"
             id="menu_board_project"
             parent="next_id_86"
             sequence="1"/>
+            
     </data>
 </openerp>
index e35e1b7..23ab963 100644 (file)
@@ -18,6 +18,7 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
+
 from osv import fields, osv
 
 class project_installer(osv.osv_memory):
@@ -26,7 +27,8 @@ class project_installer(osv.osv_memory):
 
     _columns = {
         # Project Management
-        'project_long_term': fields.boolean('Long Term Planning',
+        'project_long_term': fields.boolean(
+        'Long Term Planning',
             help="Enables long-term projects tracking, including "
                  "multiple-phase projects and resource allocation handling."),
         'project_wiki': fields.boolean('Specifications in a Wiki',
@@ -35,7 +37,7 @@ class project_installer(osv.osv_memory):
             help="Tracks and helps employees encode and validate timesheets "
                  "and attendance."),
         'hr_timesheet_invoice': fields.boolean('Invoice Based on Hours',
-            help="Helps generate invoice based on based on human resources "
+            help="Helps generate invoice based on human resources "
                  "costs and general expenses."),
         'account_budget': fields.boolean('Budgets',
             help="Helps accountants manage analytic and crossover budgets."),
@@ -49,12 +51,14 @@ class project_installer(osv.osv_memory):
             help="Implements and tracks the concepts and task types defined "
                  "in the SCRUM methodology."),
         'project_gtd': fields.boolean('Getting Things Done',
-            help="Embeds the Getting Things Done concepts into OpenERP's "
+            help="Embeds the 'Getting Things Done concepts' into OpenERP's "
                  "project management."),
         }
+    
     _defaults={
-             'project_crm': True,
+                'project_crm': True,
                }
+    
 project_installer()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
index 0d62929..5ed5f96 100644 (file)
@@ -18,8 +18,8 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
+
 from lxml import etree
-import datetime
 import time
 
 from tools.translate import _
@@ -38,6 +38,7 @@ class project_task_type(osv.osv):
     _defaults = {
         'sequence': 1
     }
+    
 project_task_type()
 
 class project(osv.osv):
@@ -46,10 +47,8 @@ class project(osv.osv):
     _inherits = {'account.analytic.account':"category_id"}
 
     def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
-        if context is None:
-            context = {}
         if user == 1:
-                return super(project, self).search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
+            return super(project, self).search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
         if context and context.has_key('user_prefence') and context['user_prefence']:
                 cr.execute("""SELECT project.id FROM project_project project
                            LEFT JOIN account_analytic_account account ON account.id = project.category_id
@@ -61,8 +60,6 @@ class project(osv.osv):
             context=context, count=count)
 
     def _complete_name(self, cr, uid, ids, name, args, context=None):
-        if context is None:
-            context = {}
         res = {}
         for m in self.browse(cr, uid, ids, context=context):
             res[m.id] = (m.parent_id and (m.parent_id.name + '/') or '') + m.name
@@ -73,8 +70,6 @@ class project(osv.osv):
                 parent=parent)
 
     def onchange_partner_id(self, cr, uid, ids, part=False, context=None):
-        if context is None:
-            context = {}
         partner_obj = self.pool.get('res.partner')
         if not part:
             return {'value':{'contact_id': False, 'pricelist_id': False}}
@@ -84,8 +79,6 @@ class project(osv.osv):
         return {'value':{'contact_id': addr['contact'], 'pricelist_id': pricelist_id}}
 
     def _progress_rate(self, cr, uid, ids, names, arg, context=None):
-        if context is None:
-            context = {}
         res = {}.fromkeys(ids, 0.0)
         progress = {}
         if not ids:
@@ -143,13 +136,16 @@ class project(osv.osv):
         'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages'),
         'project_escalation_id': fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.'),
      }
+    
     _order = "sequence"
+    
     _defaults = {
         'active': True,
         'priority': 1,
         'sequence': 10,
         'warn_manager': True,
     }
+    
     def _check_dates(self, cr, uid, ids):
          leave = self.read(cr, uid, ids[0], ['date_start', 'date'])
          if leave['date_start'] and leave['date']:
@@ -168,6 +164,7 @@ class project(osv.osv):
         (_check_dates, 'Error! project start-date must be lower then project end-date.', ['date_start', 'date']),
         (_check_escalation, 'Error! You cannot assign escalation to the same project!', ['project_escalation_id'])
     ]
+    
     def set_template(self, cr, uid, ids, context=None):
         res = self.setActive(cr, uid, ids, value=False, context=context)
         return res
@@ -255,16 +252,11 @@ class project(osv.osv):
                 'search_view_id': search_view['res_id'],
                 'nodestroy': True
                 }
-#        return result
 
     # set active value for a project, its sub projects and its tasks
     def setActive(self, cr, uid, ids, value=True, context=None):
-        if context is None:
-            context = {}
         task_obj = self.pool.get('project.task')
         for proj in self.browse(cr, uid, ids, context=None):
-            if context is None:
-                context = {}
             self.write(cr, uid, [proj.id], {'state': value and 'open' or 'template'}, context)
             cr.execute('select id from project_task where project_id=%s', (proj.id,))
             tasks_id = [x[0] for x in cr.fetchall()]
@@ -273,9 +265,8 @@ class project(osv.osv):
             child_ids = self.search(cr, uid, [('parent_id','=', proj.id)])
             if child_ids:
                 self.setActive(cr, uid, child_ids, value, context=None)
-                if context is None:
-                    context = {}
         return True
+    
 project()
 
 class task(osv.osv):
@@ -285,16 +276,12 @@ class task(osv.osv):
     _date_name = "date_start"
 
     def _str_get(self, task, level=0, border='***', context=None):
-        if context is None:
-            context = {}
         return border+' '+(task.user_id and task.user_id.name.upper() or '')+(level and (': L'+str(level)) or '')+(' - %.1fh / %.1fh'%(task.effective_hours or 0.0,task.planned_hours))+' '+border+'\n'+ \
             border[0]+' '+(task.name or '')+'\n'+ \
             (task.description or '')+'\n\n'
 
     # Compute: effective_hours, total_hours, progress
     def _hours_get(self, cr, uid, ids, field_names, args, context=None):
-        if context is None:
-            context = {}
         res = {}
         cr.execute("SELECT task_id, COALESCE(SUM(hours),0) FROM project_task_work WHERE task_id IN %s GROUP BY task_id",(tuple(ids),))
         hours = dict(cr.fetchall())
@@ -314,6 +301,8 @@ class task(osv.osv):
         return {'value':{'remaining_hours': planned - effective}}
 
     def _default_project(self, cr, uid, context=None):
+        if context is None:
+            context = {}
         if 'project_id' in context and context['project_id']:
             return int(context['project_id'])
         return False
@@ -323,15 +312,11 @@ class task(osv.osv):
     #]
 
     def copy_data(self, cr, uid, id, default={}, context=None):
-        if context is None:
-            context = {}
         default = default or {}
         default['work_ids'] = []
         return super(task, self).copy_data(cr, uid, id, default, context)
 
     def _check_dates(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         task = self.read(cr, uid, ids[0], ['date_start', 'date_end'])
         if task['date_start'] and task['date_end']:
              if task['date_start'] > task['date_end']:
@@ -346,7 +331,7 @@ class task(osv.osv):
         'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of tasks."),
         'type': fields.many2one('project.task.type', 'Stage',),
         'state': fields.selection([('draft', 'Draft'),('open', 'In Progress'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
-                                  help='If the task is created the state \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\
+                                  help='If the task is created the state is \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\
                                   \n If the task is over, the states is set to \'Done\'.'),
         'date_start': fields.datetime('Starting Date'),
         'date_end': fields.datetime('Ending Date'),
@@ -370,6 +355,7 @@ class task(osv.osv):
         'manager_id': fields.related('project_id', 'category_id', 'user_id', type='many2one', relation='res.users', string='Project Manager'),
         'company_id': fields.many2one('res.company', 'Company'),
     }
+    
     _defaults = {
         'state': 'draft',
         'priority': '2',
@@ -380,6 +366,7 @@ class task(osv.osv):
         'project_id': _default_project,
         'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.task', context=c)
     }
+    
     _order = "sequence, priority, date_start, id"
 
     _constraints = [
@@ -388,10 +375,9 @@ class task(osv.osv):
     #
     # Override view according to the company definition
     #
+    
     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
         users_obj = self.pool.get('res.users')
-        if context is None:
-            context = {}
         obj_tm = users_obj.browse(cr, uid, uid, context).company_id.project_time_mode_id
         tm = obj_tm and obj_tm.name or 'Hours'
 
@@ -424,6 +410,10 @@ class task(osv.osv):
         mod_obj = self.pool.get('ir.model.data')
         request = self.pool.get('res.request')
         tasks = self.browse(cr, uid, ids)
+        task_id = ids[0]
+        cntx = {}
+        if len(args):
+            cntx = args[0]
         for task in tasks:
             project = task.project_id
             if project:
@@ -437,8 +427,7 @@ class task(osv.osv):
                         'ref_doc1': 'project.task,%d'% (task.id,),
                         'ref_doc2': 'project.project,%d'% (project.id,),
                     })
-                elif project.warn_manager:
-                    task_id = ids[0]
+                elif project.warn_manager and cntx.get('mail_send',False):
                     mail_send = True
             message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
             self.log(cr, uid, task.id, message)
@@ -454,11 +443,11 @@ class task(osv.osv):
         if mail_send:
             model_data_ids = mod_obj.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_project_close_task')])
             resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id']
-            args[0].update({'task_id': task_id})
+            cntx.update({'task_id': task_id})
             return {
                 'name': _('Email Send to Customer'),
                 'view_type': 'form',
-                'context': args[0], # improve me
+                'context': cntx, # improve me
                 'view_mode': 'tree,form',
                 'res_model': 'close.task',
                 'views': [(resource_id,'form')],
@@ -466,7 +455,9 @@ class task(osv.osv):
                 'target': 'new',
                 'nodestroy': True
                     }
-        return True
+        else:
+            self.write(cr, uid, [task_id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
+        return False
 
     def do_reopen(self, cr, uid, ids, *args):
         request = self.pool.get('res.request')
@@ -562,11 +553,14 @@ class project_work(osv.osv):
         'user_id': fields.many2one('res.users', 'Done by', required=True),
         'company_id': fields.related('task_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True)
     }
+    
     _defaults = {
         'user_id': lambda obj, cr, uid, context: uid,
         'date': time.strftime('%Y-%m-%d %H:%M:%S')
     }
+    
     _order = "date desc"
+    
     def create(self, cr, uid, vals, *args, **kwargs):
         if 'hours' in vals and (not vals['hours']):
             vals['hours'] = 0.00
@@ -588,10 +582,12 @@ class project_work(osv.osv):
         for work in self.browse(cr, uid, ids):
             cr.execute('update project_task set remaining_hours=remaining_hours + %s where id=%s', (work.hours, work.task_id.id))
         return super(project_work,self).unlink(cr, uid, ids, *args, **kwargs)
+    
 project_work()
 
 class config_compute_remaining(osv.osv_memory):
     _name='config.compute.remaining'
+    
     def _get_remaining(self,cr, uid, ctx):
         task_obj = self.pool.get('project.task')
         if 'active_id' in ctx:
@@ -638,6 +634,7 @@ config_compute_remaining()
 class message(osv.osv):
     _name = "project.message"
     _description = "Message"
+    
     _columns = {
         'subject': fields.char('Subject', size=128, required="True"),
         'project_id': fields.many2one('project.project', 'Project', ondelete='cascade'),
@@ -655,7 +652,7 @@ class message(osv.osv):
 
     _defaults = {
         'user_id': lambda self,cr,uid,ctx: uid,
-        'date': lambda self,cr,uid,ctx: time.strftime('%Y-%m-%d'),
+        'date': time.strftime('%Y-%m-%d'),
         'project_id': _default_project
     }
 
@@ -667,6 +664,7 @@ class users(osv.osv):
     _columns = {
         'context_project_id': fields.many2one('project.project', 'Project')
      }
+    
 users()
 
 class account_analytic_account(osv.osv):
index a931c96..7c5b40f 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <openerp>
     <data>
+    
         <!--
                Requests Links
                -->
index 973194e..43f01c2 100644 (file)
@@ -45,7 +45,7 @@
         <record id="project_project_22" model="project.project">
             <field name="priority">20</field>
             <field name="parent_id" ref="project_project_9"/>
-            <field name="name">Specific Developements</field>
+            <field name="name">Specific Developments</field>
             <field name="manager" ref="base.user_root"/>
             <field eval="[(6, 0, [ref('project_tt_specification'), ref('project_tt_development')])]" name="type_ids"/>
         </record>
@@ -64,7 +64,7 @@
             <field name="type" ref="project_tt_development"/>
             <field name="user_id" ref="base.user_root"/>
             <field name="project_id" ref="project_project_22"/>
-            <field name="description">BoM, After sales returns, interventions. Tracability.</field>
+            <field name="description">BoM, After sales returns, interventions. Traceability.</field>
             <field name="name">Specific adaptation to MRP</field>
         </record>
         <record id="project_task_130" model="project.task">
             <field name="remaining_hours">24.0</field>
             <field name="user_id" ref="base.user_root"/>
             <field name="project_id" ref="project_project_21"/>
-            <field name="name">MRP; functionnal layer</field>
+            <field name="name">MRP; functional layer</field>
             <field name="state">done</field>
             <field eval="time.strftime('%Y-%m-%d 12:12')" name="date_close"/>
         </record>
             <field name="remaining_hours">32.0</field>
             <field model="res.users" name="user_id" search="[('login','=','demo')]"/>
             <field name="project_id" ref="project_project_22"/>
-            <field name="name">Customer docs</field>
+            <field name="name">Customer doc</field>
         </record>
         <record id="project_task_197" model="project.task">
             <field name="sequence">30</field>
 - Create Users</field>
                        <field name="subject">Configuration steps</field>
                </record>
+               
     </data>
 </openerp>
index 12510f8..c989ab5 100644 (file)
@@ -1,12 +1,13 @@
 <openerp>
   <data>
+  
     <record id="view_project_installer" model="ir.ui.view">
       <field name="name">project.installer.view</field>
       <field name="model">project.installer</field>
       <field name="type">form</field>
       <field name="inherit_id" ref="base.res_config_installer"/>
       <field name="arch" type="xml">
-        <data>
+       <data>
           <form position="attributes">
             <attribute name="string">Project Modules Installation</attribute>
           </form>
            <xpath expr='//separator[@string="vsep"]' position='attributes'>
                  <attribute name='string'></attribute>
                </xpath>
-          <xpath expr="//label[@string='description']"
-                 position="attributes">
-            <attribute name="string">Various OpenERP applications are available to bring your project management to the next levels of control and flexibility.</attribute>
+          <xpath expr="//label[@string='description']" position="attributes">
+               <attribute name="string">Various OpenERP applications are available to bring your project management to the next levels of control and flexibility.</attribute>
           </xpath>
           <xpath expr="//button[@string='Install Modules']" position="attributes">
-                   <attribute name="string">Configure</attribute>
+               <attribute name="string">Configure</attribute>
           </xpath>
           <group colspan="8">
             <field name="project_crm"/>
@@ -65,5 +65,6 @@
                                </xpath>
                        </field>
        </record>
+       
   </data>
 </openerp>
index b057c98..8c1004b 100644 (file)
 #
 ##############################################################################
 
-import time
-import re
-import os
-
-import mx.DateTime
-import base64
-
-from tools.translate import _
-
-import tools
-from osv import fields,osv,orm
-from osv.orm import except_orm
+from osv import fields,osv
 
 class project_tasks(osv.osv):
     _name = "project.task"
     _inherit = "project.task"
 
-    def msg_new(self, cr, uid, msg):        
+    def msg_new(self, cr, uid, msg):
         mailgate_obj = self.pool.get('mail.gateway')
         msg_body = mailgate_obj.msg_body_get(msg)
         data = {      
@@ -72,14 +61,11 @@ class project_tasks(osv.osv):
             if msg_actions['priority'] in ('1','2','3','4','5'):
                 data['priority'] = msg_actions['priority']
         
-
         self.write(cr, uid, [id], data)
         getattr(self,act)(cr, uid, [id])
         return True
 
     def message_followers(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         res = []
         if isinstance(ids, (str, int, long)):
             select = [ids]
@@ -93,6 +79,8 @@ class project_tasks(osv.osv):
         return res
 
     def msg_send(self, cr, uid, id, *args, **argv):
-        return True 
+        return True
 
 project_tasks()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
index 8ff68c9..1295ea9 100644 (file)
@@ -1,10 +1,29 @@
+# -*- 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 pooler
 import datetime
 
-def timeformat_convert(cr, uid, time_string, context=None):
+def timeformat_convert(cr, uid, time_string):
 #    Function to convert input time string:: 8.5 to output time string 8:30
-        if context is None:
-            context = {}
         split_list = str(time_string).split('.')
         hour_part = split_list[0]
         mins_part = split_list[1]
@@ -12,7 +31,7 @@ def timeformat_convert(cr, uid, time_string, context=None):
         converted_string = hour_part + ':' + str(round_mins)[0:2]
         return converted_string
 
-def leaves_resource(cr,uid,calendar_id,resource_id=False,resource_calendar=False):
+def leaves_resource(cr, uid, calendar_id, resource_id=False, resource_calendar=False):
 #    To get the leaves for the resource_ids working on phase
 
         pool = pooler.get_pool(cr.dbname)
@@ -31,20 +50,20 @@ def leaves_resource(cr,uid,calendar_id,resource_id=False,resource_calendar=False
                 leaves.sort()
         return leaves
 
-def compute_working_calendar(cr,uid,calendar_id):
+def compute_working_calendar(cr, uid, calendar_id):
 #     To change the format of working calendar to bring it into 'faces' format
 
         pool = pooler.get_pool(cr.dbname)
         resource_week_pool = pool.get('resource.calendar.week')
         time_range = "8:00-8:00"
         non_working = ""
-        wk = {"0":"mon","1":"tue","2":"wed","3":"thu","4":"fri","5":"sat","6":"sun"}
+        wk = {"0":"mon", "1":"tue", "2":"wed", "3":"thu", "4":"fri", "5":"sat", "6":"sun"}
         wk_days = {}
         wk_time = {}
         wktime_list = []
         wktime_cal = []
         week_ids = resource_week_pool.search(cr, uid, [('calendar_id','=',calendar_id)])
-        week_obj = resource_week_pool.read(cr, uid, week_ids, ['dayofweek','hour_from','hour_to'])
+        week_obj = resource_week_pool.read(cr, uid, week_ids, ['dayofweek', 'hour_from', 'hour_to'])
 
 #     Converting time formats into appropriate format required
 #     and creating a list like [('mon', '8:00-12:00'), ('mon', '13:00-18:00')]
@@ -80,3 +99,5 @@ def compute_working_calendar(cr,uid,calendar_id):
             wktime_cal.append((non_working[:-1],time_range))
 
         return wktime_cal
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
index 990b093..0c9b2f6 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <openerp>
     <data>
+    
         <menuitem
             icon="terp-project" id="base.menu_main_pm"
             name="Project" sequence="10"
                     <field name="name" string="Project Name"/>
                     <field name="user_id" string="Project Manager"/>
                     <field name="partner_id" string="Partner"/>
+                    <field name="parent_id" invisible="1"/>
                     <field name="planned_hours" widget="float_time"/>
                     <field name="total_hours" widget="float_time"/>
                     <field name="effective_hours" widget="float_time"/>
         <act_window domain="[('user_id', '=', active_id),('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"/>
 
         <act_window domain="[('project_id', '=', active_id)]" id="act_project_messages" name="Messages" res_model="project.message" src_model="project.project"/>
+        
     </data>
 </openerp>
diff --git a/addons/project/project_wizard.xml b/addons/project/project_wizard.xml
deleted file mode 100644 (file)
index 2500160..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
-    <data>
-        <!--<wizard id="wizard_close_task" menu="False" model="project.task" name="project.task.close" string="Close Task"/>-->
-        <!--<wizard id="wizard_delegate_task" menu="False" model="project.task" name="project.task.delegate" string="Delegate Task"/>-->
-        <!--<wizard
-            id="wizard_duplicate_template"
-            menu="False"
-            model="project.project"
-            name="project.duplicate.template" string="Duplicate Template"/>
--->
-    </data>
-</openerp>
index 295b8c9..f35064b 100644 (file)
@@ -18,6 +18,7 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
+
 import project_report
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index fec1052..a3ecf0f 100644 (file)
@@ -118,6 +118,7 @@ class report_project_task_user(osv.osv):
                     t.type
 
         """)
+
 report_project_task_user()
 
 #This class is generated for project deshboard purpose
@@ -162,6 +163,7 @@ class project_vs_remaining_hours(osv.osv):
                  GROUP BY pur.uid,aaa.state,aaa.name
             )
         """)
+
 project_vs_remaining_hours()
 
 class task_by_days(osv.osv):
@@ -192,6 +194,7 @@ class task_by_days(osv.osv):
                     to_char(pt.create_date, 'YYYY-MM-DD'),pt.state,pt.project_id
             )
         """)
+
 task_by_days()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index 9df6bd1..f22875c 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <openerp>
     <data>
+    
         <menuitem id="base.menu_project_report" name="Reporting" parent="base.menu_main_pm" sequence="50"/>
 
         <record id="view_task_project_user_tree" model="ir.ui.view">
             <field name="model">report.project.task.user</field>
             <field name="type">graph</field>
             <field name="arch" type="xml">
-            <graph string="Tasks Analysis" type="bar">
-                 <field name="name"/>
-                 <field name="state" group="True"/>
-                 <field name="no_of_days" operator="+"/>
-             </graph>
-         </field>
-    </record>
+                   <graph string="Tasks Analysis" type="bar">
+                        <field name="name"/>
+                        <field name="state" group="True"/>
+                        <field name="no_of_days" operator="+"/>
+                    </graph>
+               </field>
+       </record>
 
         <record id="view_task_project_user_search" model="ir.ui.view">
             <field name="name">report.project.task.user.search</field>
          </field>
     </record>
 
-   <record id="action_project_vs_remaining_hours_graph" model="ir.actions.act_window">
+    <record id="action_project_vs_remaining_hours_graph" model="ir.actions.act_window">
         <field name="name">Project and remaining hours</field>
         <field name="res_model">project.vs.remaining.hours</field>
         <field name="view_type">form</field>
     </record>
 
     <!-- Views and action for project issue dashboard -->
-       <record id="view_task_by_days_tree" model="ir.ui.view">
+    <record id="view_task_by_days_tree" model="ir.ui.view">
         <field name="name">task.by.days.tree</field>
         <field name="model">task.by.days</field>
         <field name="type">tree</field>
index 351f28c..3e2ff83 100644 (file)
@@ -23,7 +23,7 @@ from osv import fields,osv
 
 class res_partner(osv.osv):
 
-    """ Inherits partner and adds CRM information in the partner form """
+    """ Inherits partner and adds Tasks information in the partner form """
     _inherit = 'res.partner'
     _columns = {
         'task_ids': fields.one2many('project.task', 'partner_id', 'Tasks'),
index 4778c0f..b130b05 100644 (file)
@@ -20,6 +20,7 @@
                 </page>
             </field>
        </record>
+       
    </data>
 </openerp>
 
index b1cd933..715e70e 100644 (file)
@@ -19,8 +19,9 @@
 #
 ##############################################################################
 
-from osv import fields, osv
+import time
 
+from osv import fields, osv
 from tools.translate import _
 from tools import email_send as email
 
@@ -42,7 +43,7 @@ class project_close_task(osv.osv_memory):
         if 'task_id' in context:
             task = self.pool.get('project.task').browse(cr, uid, context['task_id'])
             partner_id = task.partner_id or task.project_id.partner_id
-            if partner_id and partner_id.address[0].email:
+            if partner_id and len(partner_id.address) and partner_id.address[0].email:
                 email = partner_id.address[0].email
         return email
 
@@ -54,10 +55,15 @@ class project_close_task(osv.osv_memory):
             return task.description or task.name
         return ''
 
-    _defaults={
+    _defaults = {
        'email': _get_email,
        'description': _get_desc,
                }
+    
+    def close(self, cr, uid, ids, context=None):
+        if 'task_id' in context:
+            self.pool.get('project.task').write(cr, uid, [context['task_id']], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
+        return {}
 
     def confirm(self, cr, uid, ids, context=None):
         if context is None:
@@ -67,8 +73,10 @@ class project_close_task(osv.osv_memory):
         close_task = self.read(cr, uid, ids[0], [])
         to_adr = close_task['email']
         description = close_task['description']
+        
         if 'task_id' in context:
-            for task in self.pool.get('project.task').browse(cr, uid, [context['task_id']], context=context):
+            task_obj = self.pool.get('project.task')
+            for task in task_obj.browse(cr, uid, [context['task_id']], context=context):
                 project = task.project_id
                 subject = "Task '%s' closed" % task.name
                 if task.user_id and task.user_id.address_id and task.user_id.address_id.email:
@@ -89,9 +97,11 @@ class project_close_task(osv.osv_memory):
                     footer = (project.warn_footer or '') % val
                     body = u'%s\n%s\n%s\n\n-- \n%s' % (header, description, footer, signature)
                     email(from_adr, [to_adr], subject, body.encode('utf-8'), email_bcc=[from_adr])
+                    task_obj.write(cr, uid, [task.id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
                 else:
-                    raise osv.except_osv(_('Error'), _("Couldn't send mail because the contact for this task (%s) has no email address!") % contact.name)
+                    raise osv.except_osv(_('Error'), _("Please specify the email address of partner."))
         return {}
 
 project_close_task()
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index f920615..e46ddf7 100644 (file)
                              <newline/>
                              <field name="description" />
                              </group>
-                             <group colspan="4" col="6">
-                                       <button  icon="gtk-cancel" special="cancel" string="_Close"/>
-                                       <button icon="gtk-ok" name="confirm" string="Send Mail" type="object"/>
+                             <separator string="" colspan="6"/>
+                             <group colspan="6" col="6">
+                                       <button icon="gtk-ok" name="confirm" string="Send and Close" type="object"/>
+                                       <button  icon="gtk-ok" string="Close" name="close" type="object"/>
+                                       <button  icon="gtk-cancel" special="cancel" string="_Cancel"/>
                              </group>
                                </form>
             </field>
index 7799092..850f27b 100644 (file)
@@ -102,19 +102,20 @@ class project_task_delegate(osv.osv_memory):
             'description': delegate_data['new_task_description'] or '',
             'child_ids': [],
             'work_ids': []
-        })
+        }, context)
         task_obj.write(cr, uid, [task.id], {
             'remaining_hours': delegate_data['planned_hours_me'],
             'planned_hours': delegate_data['planned_hours_me'] + (task.effective_hours or 0.0),
             'name': newname,
-        })
+        }, context)
         if delegate_data['state'] == 'pending':
-            task_obj.do_pending(cr, uid, [task.id])
+            task_obj.do_pending(cr, uid, [task.id], context)
         else:
-            task_obj.do_close(cr, uid, [task.id])
-        delegrate_user = user_obj.browse(cr, uid, delegate_data['user_id'], context=context)
-        message = _('Task ') + " '" + delegate_data['name'] + "' "+ _("is Delegated to User:") +" '"+ delegrate_user.name +"' "
-        self.log(cr, uid, task.id, message)
+            context.update({'mail_send': False} )
+            task_obj.do_close(cr, uid, [task.id], context)
+            delegrate_user = user_obj.browse(cr, uid, delegate_data['user_id'], context=context)
+            message = _('Task ') + " '" + delegate_data['name'] + "' "+ _("is Delegated to User:") +" '"+ delegrate_user.name +"' "
+            self.log(cr, uid, task.id, message)
         return {}
 
 project_task_delegate()
index ff90c5c..84414cf 100644 (file)
@@ -34,7 +34,6 @@
         'crm',
         'project',
         'hr_timesheet_sheet',
-        'resource'
     ],
     'init_xml': [
         'project_issue_data.xml'
index 802ef47..ed648fb 100644 (file)
@@ -144,7 +144,6 @@ class project_issue(osv.osv, crm.crm_case):
         'create_date': fields.datetime('Creation Date', readonly=True),
         'write_date': fields.datetime('Update Date', readonly=True),
         'date_deadline': fields.date('Deadline'),
-        'date_closed': fields.datetime('Closed', readonly=True),
         'section_id': fields.many2one('crm.case.section', 'Sales Team', \
                         select=True, help='Sales team to which Case belongs to.\
                              Define Responsible user and Email account for mail gateway.'),
@@ -391,7 +390,6 @@ class project_issue(osv.osv, crm.crm_case):
         res = self.write(cr, uid, ids, vals)
         return res
 
-
     def msg_send(self, cr, uid, id, *args, **argv):
 
         """ Send The Message
index 99d08c5..132fa50 100644 (file)
@@ -29,6 +29,7 @@ class project_issue(osv.osv):
         'timesheet_ids': fields.one2many('hr.analytic.timesheet', 'issue_id', 'Timesheets'),
         'analytic_account_id': fields.related('project_id', 'category_id', string='Analytic Account')
     }
+    
 project_issue()
 
 class account_analytic_line(osv.osv):
index fbc1dcc..0ff6413 100644 (file)
@@ -29,4 +29,4 @@
             </field>
         </record>
     </data>
-</openerp>
+</openerp>
\ No newline at end of file
index dfcddb7..ae391eb 100644 (file)
@@ -25,7 +25,7 @@
     "author": "Tiny",
     "website": "http://www.openerp.com",
     "category": "Generic Modules/Projects & Services",
-    "depends": ["project", "resource"],
+    "depends": ["resource", "project"],
     "description": """
 
         Long Term Project management module that tracks planning, scheduling, resources allocation.
index 8eaf9c6..2e86426 100644 (file)
@@ -114,7 +114,7 @@ class project_phase(osv.osv):
         'responsible_id': lambda obj,cr,uid,context: uid,
         'state': 'draft',
         'sequence': 10,
-        'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', 'Day')], context=c)[0]
+        'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', 'day')], context=c)[0]
     }
     _order = "name"
     _constraints = [
index f4c5fba..bc377a5 100644 (file)
@@ -61,7 +61,6 @@ class project_compute_phases(osv.osv_memory):
        resource_obj = self.pool.get('resource.resource')
        uom_obj = self.pool.get('product.uom')
        phase_resource_obj = False
-
        if context is None:
            context = {}
        if phase:
@@ -134,14 +133,13 @@ class project_compute_phases(osv.osv_memory):
 
         if context is None:
             context = {}
-        project_obj = self.pool.get('project.project')
         phase_obj = self.pool.get('project.phase')
         data = self.read(cr, uid, ids, [], context=context)[0]
         if not data['project_id'] and data['target_project'] == 'one':
             raise osv.except_osv(_('Error!'), _('Please Specify Project to be schedule'))
         if data['project_id']:        # If project mentioned find its phases
-            project_id = project_obj.browse(cr, uid, data['project_id'], context=context)
-            phase_ids = phase_obj.search(cr, uid, [('project_id', '=', project_id.id),
+            project_id = data['project_id']
+            phase_ids = phase_obj.search(cr, uid, [('project_id', '=', project_id),
                                                   ('state', 'in', ['draft', 'open', 'pending']),
                                                   ('previous_phase_ids', '=', False)
                                                   ])
index f0ad7c5..d3c42a9 100644 (file)
@@ -160,4 +160,5 @@ class project_schedule_task(osv.osv_memory):
         return {}
 
 project_schedule_task()
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index eb2bc24..6127533 100644 (file)
@@ -26,8 +26,8 @@
     "depends": ["project"],
     "author": "Tiny",
     "description": """
-    This module provides the functionality to send messages within a project.'
-    A user can send messages individually to other user also he can broadcast
+    This module provides the functionality to send messages within a project.
+    A user can send messages individually to other user. He can even broadcast
     it to all the users.
     """,
     'website': 'http://www.openerp.com',
index 766b70f..c2ef40b 100644 (file)
@@ -18,6 +18,6 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
-import mrp
+import project_procurement
 import project_mrp
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_mrp/mrp.py b/addons/project_mrp/mrp.py
deleted file mode 100644 (file)
index b8eff3c..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from osv import fields, osv, orm
-
-import tools
-
-class procurement_order(osv.osv):
-    _name = "procurement.order"
-    _inherit = "procurement.order"
-    _columns = {
-        'task_id': fields.many2one('project.task', 'Task')
-    }
-
-    def action_produce_assign_service(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
-        for procurement in self.browse(cr, uid, ids):
-            sline = self.pool.get('sale.order.line')
-            product_obj=self.pool.get('product.product')
-            content = ''
-            sale_order = self.pool.get('sale.order')
-            so_ref =  procurement.name.split(':')[0]
-            order_ids = sale_order.search(cr, uid, [('name', '=', so_ref)], context)
-
-            if order_ids:
-                sale_ids = sale_order.read(cr, uid, order_ids[0], ['order_line'], context=context)['order_line']
-            else:
-                so_ref =  procurement.origin.split(':')[0]
-                sale_ids = sline.search(cr, uid, [('procurement_id', '=',procurement.id)], context)
-            l = None
-            project_id = None
-            analytic_account_id = False
-            partner_id = False
-
-            for line in sline.browse(cr, uid, sale_ids, context=context):
-                content += (line.notes or '')
-                l = line
-                partner_id = line.order_id.partner_id.id
-                if line.order_id.project_id:
-                    analytic_account_id = line.order_id.project_id.id
-                    partner_id = line.order_id.partner_id.id
-                    content+="\n\n"+line.order_id.project_id.complete_name
-                    break
-
-            # Creating a project for task.Project is created from Procurement.
-            project_obj = self.pool.get('project.project')
-            proj_name = tools.ustr(so_ref)
-            proj_exist_id = project_obj.search(cr, uid, [('name', '=', proj_name)], context=context)
-            if  not proj_exist_id:
-                project_id = project_obj.create(cr, uid, {'name': proj_name, 'partner_id': partner_id})
-            else:
-                project_id = proj_exist_id[0]
-
-            self.write(cr, uid, [procurement.id], {'state': 'running'})
-
-            name_task = ('','')
-            planned_hours=0.0
-            if procurement.product_id.type == 'service':
-                proc_name = procurement.name
-                if procurement.origin == proc_name:
-                    proc_name = procurement.product_id.name
-
-                name_task = (procurement.origin, proc_name or '')
-            else:
-                name_task = (procurement.product_id.name or procurement.origin, procurement.name or '')
-            planned_hours= procurement.product_id.sale_delay +procurement.product_id. produce_delay   
-            task_id = self.pool.get('project.task').create(cr, uid, {
-                'name': '%s:%s' % name_task,
-                'date_deadline': procurement.date_planned,
-                'planned_hours':planned_hours,
-                'remaining_hours': planned_hours,
-                'user_id': procurement.product_id.product_manager.id,
-                'notes': "b"+(l and l.order_id.note or ''),
-                'procurement_id': procurement.id,
-                'description': content,
-                'date_deadline': procurement.date_planned,
-                'state': 'draft',
-                'partner_id': l and l.order_id.partner_id.id or False,
-                'company_id': procurement.company_id.id,
-                'project_id': project_id,
-            },context=context)
-            self.write(cr, uid, [procurement.id],{'task_id':task_id}) 
-            product_obj.write(cr,uid,[procurement.product_id.id],{'user_id':uid,'project_id':project_id})
-        return task_id
-
-procurement_order()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
index d946e2c..d5a7681 100644 (file)
@@ -51,7 +51,6 @@ project_task()
 class product_product(osv.osv):
     _inherit = "product.product"
     _columns = {
-        'user_id': fields.many2one('res.users', 'Responsible', ondelete='set null',help='Project Manager'),
         'project_id': fields.many2one('project.project', 'Project', ondelete='set null',)
     }
 product_product()    
index 5d0c1d7..726e95d 100644 (file)
@@ -20,7 +20,6 @@
             <field name="inherit_id" ref="product.product_normal_form_view"/>
             <field name="arch" type="xml">
                 <field name="company_id" position="after">
-                    <field name="user_id" attrs="{'readonly':[('type','!=','service')]}"/>
                     <field name="project_id" attrs="{'readonly':[('type','!=','service')]}" />
                 </field>
             </field>
diff --git a/addons/project_mrp/project_procurement.py b/addons/project_mrp/project_procurement.py
new file mode 100644 (file)
index 0000000..d4f703b
--- /dev/null
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from osv import fields, osv, orm
+
+import tools
+
+class procurement_order(osv.osv):
+    _name = "procurement.order"
+    _inherit = "procurement.order"
+    _columns = {
+        'task_id': fields.many2one('project.task', 'Task')
+    }
+
+    def action_produce_assign_service(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+        for procurement in self.browse(cr, uid, ids):
+            sline = self.pool.get('sale.order.line')
+            product_obj=self.pool.get('product.product')
+            content = ''
+            sale_order = self.pool.get('sale.order')
+            so_ref =  procurement.name.split(':')[0]
+            order_ids = sale_order.search(cr, uid, [('name', '=', so_ref)], context)
+
+            if order_ids:
+                sale_ids = sale_order.read(cr, uid, order_ids[0], ['order_line'], context=context)['order_line']
+            else:
+                so_ref =  procurement.origin.split(':')[0]
+                sale_ids = sline.search(cr, uid, [('procurement_id', '=',procurement.id)], context)
+            l = None
+            project_id = None
+            analytic_account_id = False
+            partner_id = False
+
+            for line in sline.browse(cr, uid, sale_ids, context=context):
+                content += (line.notes or '')
+                l = line
+                partner_id = line.order_id.partner_id.id
+                if line.order_id.project_id:
+                    analytic_account_id = line.order_id.project_id.id
+                    partner_id = line.order_id.partner_id.id
+                    content+="\n\n"+line.order_id.project_id.complete_name
+                    break
+
+            # Creating a project for task.Project is created from Procurement.
+            project_obj = self.pool.get('project.project')
+            proj_name = tools.ustr(so_ref)
+            product_project_id =procurement.product_id.project_id and procurement.product_id.project_id.id or False
+            proj_exist_id = project_obj.search(cr, uid, [('name', '=', proj_name)], context=context)
+            if  not proj_exist_id:
+                project_id = project_obj.create(cr, uid, {'name': proj_name, 'partner_id': partner_id,'parent_id':product_project_id})
+            else:
+                project_id = proj_exist_id[0]
+
+            self.write(cr, uid, [procurement.id], {'state': 'running'})
+
+            name_task = ('','')
+            planned_hours=0.0
+            if procurement.product_id.type == 'service':
+                proc_name = procurement.name
+                if procurement.origin == proc_name:
+                    proc_name = procurement.product_id.name
+
+                name_task = (procurement.origin, proc_name or '')
+            else:
+                name_task = (procurement.product_id.name or procurement.origin, procurement.name or '')
+            planned_hours= procurement.product_id.sale_delay +procurement.product_id. produce_delay   
+            task_id = self.pool.get('project.task').create(cr, uid, {
+                'name': '%s:%s' % name_task,
+                'date_deadline': procurement.date_planned,
+                'planned_hours':planned_hours,
+                'remaining_hours': planned_hours,
+                'user_id': procurement.product_id.product_manager.id,
+                'notes': "b"+(l and l.order_id.note or ''),
+                'procurement_id': procurement.id,
+                'description': content,
+                'date_deadline': procurement.date_planned,
+                'state': 'draft',
+                'partner_id': l and l.order_id.partner_id.id or False,
+                'company_id': procurement.company_id.id,
+                'project_id': project_id,
+            },context=context)
+            self.write(cr, uid, [procurement.id],{'task_id':task_id}) 
+            product_obj.write(cr,uid,[procurement.product_id.id],{'project_id':project_id})
+        return task_id
+
+procurement_order()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
index 2601130..69dfde4 100644 (file)
@@ -498,7 +498,10 @@ class report_account_analytic_planning_stat(osv.osv):
 WHERE user_id=%s and account_id=%s and date>=%s and date<=%s''', (line.user_id.id, line.account_id.id, line.planning_id.date_from, line.planning_id.date_to))
             else:
                 cr.execute('SELECT sum(unit_amount) FROM account_analytic_line WHERE account_id=%s AND date>=%s AND date<=%s', (line.account_id.id, line.planning_id.date_from, line.planning_id.date_to))
-            result[line.id] = cr.fetchone()[0] * div2
+                
+        sum = cr.fetchone()
+        if sum and sum[0]:
+            result[line.id] = sum[0] * div2
         return result
 
     def _sum_amount_tasks(self, cr, uid, ids, name, args, context=None):
@@ -527,13 +530,15 @@ WHERE user_id=%s and account_id=%s and date>=%s and date<=%s''', (line.user_id.i
                 WHERE
                 ''' + where + '''
                     project_id IN (select id from project_project where category_id=%s) AND
-                    date_close>=%s AND
-                    date_close<=%s''', (
+                    date_end>=%s AND
+                    date_end<=%s''', (
                 line.account_id.id,
                 line.planning_id.date_from,
                 line.planning_id.date_to)
             )
-            result[line.id] = cr.fetchone()[0] /div * div2
+            sum = cr.fetchone()
+            if sum and sum[0]:
+                result[line.id] = sum[0] /div * div2
         return result
 
     _columns = {
index 48244b4..ead6915 100644 (file)
@@ -37,11 +37,12 @@ class project_project(osv.osv):
                     for task in prj.tasks:
                         start_dt = (datetime(*time.strptime(task.date_start,'%Y-%m-%d  %H:%M:%S')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d %H:%M:%S')
                         if task.date_deadline:
-                            deadline_dt = (datetime(*time.strptime(task.date_deadline,'%Y-%m-%d  %H:%M:%S')[:6])+(c-d)).strftime('%Y-%m-%d %H:%M:%S')
+                            deadline_dt = (datetime(*time.strptime(task.date_deadline,'%Y-%m-%d')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d %H:%M:%S')
                             self.pool.get('project.task').write(cr, uid, task.id, {'date_start':start_dt, 'date_deadline':deadline_dt})
                         else:
                             self.pool.get('project.task').write(cr, uid, task.id, {'date_start':start_dt})
         return super(project_project,self).write(cr, uid, ids, vals, *args, **kwargs)
 
 project_project()
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index 0778c5c..8b1f316 100644 (file)
@@ -3,10 +3,9 @@
 - 
   !record {model: project.project, id: project_project_retroplanning0}:
     company_id: base.main_company
-    date: '2010-06-11'
+    date: !eval time.strftime('%Y-%m-%d')
     name: Retro Planning
     
-    
 - 
   Create task 'Plan all projects'
 - 
     project_id: project_project_retroplanning0
     remaining_hours: 24.0
     state: draft
-  
 -
   Check if task deadline_date and start_date changes upon changing its project's end_date 
 -
   !python {model: project.project}: |
-    from datetime import datetime, date
+    from datetime import datetime, date, timedelta
     import time
     data_project = self.browse(cr,uid,[ref("project_project_retroplanning0")])
     prj = data_project[0]
     if prj.date:
        old_end_date = date(*time.strptime(prj.date,'%Y-%m-%d')[:3])
     if old_end_date:
-       new_end_date = date(*time.strptime('2010-06-10','%Y-%m-%d')[:3])
+       new_end_date = date.today()+timedelta(1)
        res={}
        for task in prj.tasks:
                start_dt = (datetime(*time.strptime(task.date_start,'%Y-%m-%d  %H:%M:%S')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d %H:%M:%S')
                deadline_dt=''
             if task.date_deadline:
-                       deadline_dt = (datetime(*time.strptime(task.date_deadline,'%Y-%m-%d')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d')
+                   deadline_dt = (datetime(*time.strptime(task.date_deadline,'%Y-%m-%d')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d')
                res[task.id]=[start_dt,deadline_dt]
-    self.write(cr, uid, [ref("project_project_retroplanning0")], {'date':'2010-06-10'})
+    self.write(cr, uid, [ref("project_project_retroplanning0")], {'date' : (datetime.now()+timedelta(1)).strftime('%Y-%m-%d')})
     data_project = self.browse(cr,uid,[ref("project_project_retroplanning0")])
     prj = data_project[0]
+    
     for task in prj.tasks:
         assert task.date_start == res[task.id][0], "task start date differs, expected %s, got %s"%(res[task.id][0], task.date_start)
         assert task.date_deadline == res[task.id][1], "task deadline date differs, expected %s, got %s"%(res[task.id][1], task.date_deadline)
\ No newline at end of file
index e125ccb..6fd2beb 100644 (file)
@@ -84,10 +84,10 @@ class project_work(osv.osv):
         timeline_id = obj_timesheet.create(cr, uid, vals=vals_line, context=kwargs['context'])
 
         # Compute based on pricetype
-        amount_unit=obj_timesheet.on_change_unit_amount(cr, uid, timeline_id,
+        amount_unit = obj_timesheet.on_change_unit_amount(cr, uid, timeline_id,
             prod_id, amount, unit, context=kwargs['context'])
-
-        vals_line['amount'] = (-1) * vals['hours']* (amount_unit['value']['amount'] or 0.0)
+        if amount_unit:
+            vals_line['amount'] = (-1) * vals['hours']* (amount_unit.get('value',{}).get('amount',0.0) or 0.0)
         obj_timesheet.write(cr, uid, [timeline_id], vals_line, {})
         vals['hr_analytic_timesheet_id'] = timeline_id
         return super(project_work,self).create(cr, uid, vals, *args, **kwargs)
@@ -120,8 +120,10 @@ class project_work(osv.osv):
                 unit = False
                 amount_unit=obj.on_change_unit_amount(cr, uid, line_id,
                     vals_line['product_id'], vals_line['unit_amount'], unit, context=context)
-
-                vals_line['amount'] = (-1) * vals['hours'] * (amount_unit['value']['amount'] or 0.0)
+                
+                if amount_unit:
+                     vals_line['amount'] = (-1) * vals['hours'] * (amount_unit.get('value',{}).get('amount',0.0) or 0.0)
+                     
             obj.write(cr, uid, [line_id], vals_line, context=context)
 
         return super(project_work,self).write(cr, uid, ids, vals, context)
index 471f521..479155f 100644 (file)
@@ -58,7 +58,8 @@
              'test/purchase_from_order.yml',
              'test/purchase_from_manual.yml',
 #             'test/purchase_from_picking.yml',
-             'purchase_unit_test.xml'
+             'purchase_unit_test.xml',
+             'test/procurement_buy.yml',
     ],
     'demo': ['purchase_demo.xml'],
     'installable': True,
index a194cd1..d14530e 100644 (file)
         <record id="trans_confirmed_router" model="workflow.transition">
             <field name="act_from" ref="act_confirmed"/>
             <field name="act_to" ref="act_router"/>
+            <field name="signal">purchase_approve</field>
         </record>
         <record id="trans_router_picking" model="workflow.transition">
             <field name="act_from" ref="act_router"/>
diff --git a/addons/purchase/test/procurement_buy.yml b/addons/purchase/test/procurement_buy.yml
new file mode 100644 (file)
index 0000000..011e70d
--- /dev/null
@@ -0,0 +1,109 @@
+-
+  In order to test the procurement with product type buy in OpenERP, I will create product 
+  and then I will create procurement for this product.
+-        
+  I create  product.
+- 
+  !record {model: product.product, id: product_product_cddrive0}:
+    categ_id: product.product_category_3
+    cost_method: standard
+    mes_type: fixed
+    name: CD drive
+    procure_method: make_to_order
+    supply_method: buy
+    type: product
+    uom_id: product.product_uom_unit
+    uom_po_id: product.product_uom_unit
+    valuation: manual_periodic
+    volume: 0.0
+    warranty: 0.0
+    weight: 0.0
+    weight_net: 0.0
+    seller_ids:
+      - delay: 1
+        name: base.res_partner_asus
+        qty: 5.0
+-  
+  I create  procurement order.
+- 
+  !record {model: procurement.order, id: procurement_order_testcase0}:
+    company_id: base.main_company
+    date_planned: '2010-07-07 15:38:53'
+    location_id: stock.stock_location_stock
+    name: Test Case
+    priority: '1'
+    procure_method: make_to_order
+    product_id: product_product_cddrive0
+    product_qty: 5.0
+    product_uom: product.product_uom_unit
+    product_uos: product.product_uom_unit
+    product_uos_qty: 0.0
+    state: draft
+- 
+  I confirm on procurement order.
+- 
+  !workflow {model: procurement.order, action: button_confirm, ref: procurement_order_testcase0}
+- 
+  I run the scheduler.
+- 
+  !workflow {model: procurement.order, action: button_check, ref: procurement_order_testcase0}
+-
+  I check that  purchase order is generated.
+-
+  !python {model: procurement.order}: |
+    from tools.translate import _
+    proc_ids = self.browse(cr, uid, [ref('procurement_order_testcase0')])[0]
+    assert(proc_ids.purchase_id), _('Purchase Order is not Created!')
+-
+  I check the state is running.
+-
+  !python {model: procurement.order}: |
+    from tools.translate import _
+    proc_ids = self.browse(cr, uid, [ref('procurement_order_testcase0')])[0]
+    assert(proc_ids.state == 'running'), _('Exception') 
+- 
+  I confirm  and Approve the purchase order.
+- 
+  !python {model: purchase.order}: |
+    procurement_obj = self.pool.get('procurement.order')
+    proc_ids = procurement_obj.browse(cr, uid, [ref('procurement_order_testcase0')])[0]
+    import netsvc
+    wf_service = netsvc.LocalService("workflow")
+    wf_service.trg_validate(uid, 'purchase.order',proc_ids.purchase_id.id,'purchase_confirm', cr)  
+    wf_service.trg_validate(uid, 'purchase.order',proc_ids.purchase_id.id,'purchase_approve', cr)  
+-   
+  I receive the order of the supplier ASUStek from the Incoming Shipments menu.
+-   
+  !python {model: stock.picking }: |
+   import time
+   procurement_obj = self.pool.get('procurement.order')
+   proc_ids = procurement_obj.browse(cr, uid, [ref('procurement_order_testcase0')])[0] 
+   picking_id = self.search(cr, uid, [('origin', '=', proc_ids.purchase_id.name)])
+   if picking_id:
+      pick=self.browse(cr,uid,picking_id[0])
+      move =pick.move_lines[0]
+      partial_datas = {
+           'partner_id':pick.address_id.partner_id.id,
+            'address_id': pick.address_id.id,
+            'delivery_date' : time.strftime('%Y-%m-%d')
+           }
+      partial_datas['move%s'%(move.id)]= {
+          'product_id': move.product_id,
+          'product_qty': move.product_qty,
+          'product_uom': move.product_uom.id,
+      } 
+      self.do_partial(cr, uid, picking_id,partial_datas)
+-
+  I confirm the Reservation.
+-
+  !python {model: stock.move }: |
+   procurement_obj = self.pool.get('procurement.order')
+   proc_ids = procurement_obj.browse(cr, uid, [ref('procurement_order_testcase0')])[0]
+   self.action_done(cr,uid,[proc_ids.move_id.id])
+-
+  I check the state is Done.
+-
+  !python {model: procurement.order}: |
+    from tools.translate import _
+    proc_ids = self.browse(cr, uid, [ref('procurement_order_testcase0')])[0]
+    assert(proc_ids.state == 'done'), _('Order is not in done state') 
index 82a5f1c..19c23ec 100644 (file)
@@ -64,7 +64,7 @@ class sale_advance_payment_inv(osv.osv_memory):
                         _("You cannot make an advance on a sale order \
                              that is defined as 'Automatic Invoice after delivery'."))
                 val = obj_lines.product_id_change(cr, uid, [], sale_adv_obj.product_id.id,
-                        uom = False, partner_id = sale.partner_id.id, fiscal_position = sale.fiscal_position.id)
+                        uom = False, partner_id = sale.partner_id.id, fposition_id = sale.fiscal_position.id)
                 line_id =obj_lines.create(cr, uid, {
                     'name': val['value']['name'],
                     'account_id': val['value']['account_id'],
index 1b65dd4..d5c5cc1 100644 (file)
@@ -31,6 +31,7 @@ keep track for the wiki groups, pages, and history
     'author': 'Tiny & Axelor',
     'website': 'http://openerp.com',
     'depends': ['knowledge'],
+    'web_depends': ['widget_wiki'],
     'init_xml': [],
     'update_xml': [
         'wizard/wiki_wiki_page_open_view.xml',