Improved CRM module:
authorFabien Pinckaers <fp@tinyerp.com>
Mon, 17 Dec 2007 20:16:01 +0000 (20:16 +0000)
committerFabien Pinckaers <fp@tinyerp.com>
Mon, 17 Dec 2007 20:16:01 +0000 (20:16 +0000)
* Better Wizard
* Added some views: calendar
* Changed Date_Deadline to datetime (for calendar purpose)

bzr revid: fp@tinyerp.com-76c641d9d2267a0609c07876e0471ed7297c8ae9

addons/crm/crm.py
addons/crm/crm_view.xml
addons/crm/wizard/crm_wizard.py

index e420fd8..b59d482 100644 (file)
@@ -49,6 +49,12 @@ AVAILABLE_PRIORITIES = [
        ('1','Highest')
 ]
 
+icon_lst = {
+       'form':'STOCK_NEW',
+       'tree':'STOCK_JUSTIFY_FILL',
+       'calendar':'STOCK_SELECT_COLOR'
+}
+
 class crm_case_section(osv.osv):
        _name = "crm.case.section"
        _description = "Case Section"
@@ -81,6 +87,53 @@ class crm_case_section(osv.osv):
                (_check_recursion, 'Error ! You can not create recursive sections.', ['parent_id'])
        ]
 
+       # Mainly used by the wizard
+       def menu_create_data(self, cr, uid, data, menu_lst, context):
+               menus = {}
+               menus[0] = data['menu_parent_id']
+               section = self.browse(cr, uid, data['section_id'], context)
+               for (index, mname, mdomain, latest, view_mode) in menu_lst:
+                       if view_mode=='no':
+                               menus[index] = data['menu_parent_id']
+                               continue
+                       view_mode = data['menu'+str(index)+'_option']
+                       icon = icon_lst.get(view_mode.split(',')[0], 'STOCK_JUSTIFY_FILL')
+                       menu_id=self.pool.get('ir.ui.menu').create(cr, uid, {
+                               'name': data['menu'+str(index)],
+                               'parent_id': menus[latest],
+                               'icon': icon
+                       })
+                       menus[index] = menu_id
+                       action_id = self.pool.get('ir.actions.act_window').create(cr,uid, {
+                               'name': data['menu'+str(index)],
+                               'res_model': 'crm.case',
+                               'domain': mdomain.replace('SECTION_ID', str(data['section_id'])),
+                               'view_type': 'form',
+                               'view_mode': view_mode,
+                       })
+                       seq = 0
+                       for mode in view_mode.split(','):
+                               self.pool.get('ir.actions.act_window.view').create(cr, uid, {
+                                       'sequence': seq,
+                                       'view_id': data['view_'+mode],
+                                       'view_mode': mode,
+                                       'act_window_id': action_id,
+                                       'multi': True
+                               })
+                               seq+=1
+                       self.pool.get('ir.values').create(cr, uid, {
+                               'name': data['menu'+str(index)],
+                               'key2': 'tree_but_open',
+                               'model': 'ir.ui.menu',
+                               'res_id': menu_id,
+                               'value': 'ir.actions.act_window,%d'%action_id,
+                               'object': True
+                       })
+               return True
+
+       #
+       # Used when called from .XML file
+       #
        def menu_create(self, cr, uid, ids, name, menu_parent_id=False, context={}):
                menus = {}
                menus[-1] = menu_parent_id
@@ -273,7 +326,7 @@ class crm_case(osv.osv):
                'som': fields.many2one('res.partner.som', 'State of Mind'),
                'date': fields.datetime('Date'),
                'create_date': fields.datetime('Created' ,readonly=True),
-               'date_deadline': fields.date('Deadline'),
+               'date_deadline': fields.datetime('Deadline'),
                'date_closed': fields.datetime('Closed', readonly=True),
                'canal_id': fields.many2one('res.partner.canal', 'Channel'),
                'user_id': fields.many2one('res.users', 'User Responsible'),
@@ -688,8 +741,15 @@ class crm_case_history(osv.osv):
        _description = "Case history"
        _order = "id desc"
        _inherits = {'crm.case.log':"log_id"}
+       def _note_get(self, cursor, user, ids, name, arg, context=None):
+               res = {}
+               for hist in self.browse(cursor, user, ids, context or {}):
+                       res[hist.id] = (hist.email or '/') + ' (' + str(hist.date) + ')\n'
+                       res[hist.id] += (hist.description or '')
+               return res
        _columns = {
                'description': fields.text('Description'),
+               'note': fields.function(_note_get, method=True, string="Description", type="text"),
                'email': fields.char('Email', size=84),
                'log_id': fields.many2one('crm.case.log','Log'),
        }
index ef109b0..20b7259 100644 (file)
                </field>
        </record>
 
+       <record model="ir.ui.view" id="crm_case_calendar-view">
+               <field name="name">crm.case.calendar</field>
+               <field name="model">crm.case</field>
+               <field name="type">calendar</field>
+               <field name="arch" type="xml">
+                       <calendar string="Cases" color="user_id" date_start="date" date_stop="date_deadline" day_length="12">
+                               <field name="name"/>
+                               <field name="partner_id"/>
+                               <field name="state"/>
+                       </calendar>
+               </field>
+       </record>
+
+
        <record model="ir.ui.view" id="crm_case_tree-view">
                <field name="name">crm.case.tree</field>
                <field name="model">crm.case</field>
                                                        <field name="description" colspan="4" nolabel="1" select="2"/>
                                                </form>
                                                <tree string="Communication history">
-                                                       <field name="description"/>
-                                                       <field name="email"/>
-                                                       <field name="date"/>
+                                                       <field name="note"/>
                                                </tree>
                                        </field>
                                        <group col="2" colspan="2" expand="1">
                                                <field name="canal_id"/>
-                                               <field name="som" select="2"/>
                                                <button name="add_reply" string="Add Last Mail for Replying"
                                                        states="open" type="object" colspan="2"/>
                                                <field name="description" colspan="2" select="2" nolabel="1"/>
                                        <field name="active" select="2"/>
                                        <field name="email_cc" colspan="4"/>
                                        <field name="categ_id" select="2" on_change="onchange_categ_id(categ_id)"/>
+                                       <field name="som" select="2"/>
                                        <separator colspan="4" string="Dates"/>
                                        <field name="create_date"/>
                                        <field name="date_closed"/>
index 60b1fe4..c1c91cd 100644 (file)
@@ -32,28 +32,102 @@ import osv
 import pooler
 
 section_form = '''<?xml version="1.0"?>
-<form string="Create menus for cases">
+<form string="Create Menus For Cases">
+       <separator string="Base Information" colspan="4"/>
        <field name="menu_name"/>
        <field name="menu_parent_id"/>
        <field name="section_id"/>
+       <separator string="Select Views (empty for default)" colspan="4"/>
+       <field name="view_form"/>
+       <field name="view_tree"/>
+       <field name="view_calendar"/>
 </form>'''
 
 section_fields = {
-       'menu_name': {'string':'Menu base name', 'type':'char', 'required':True, 'size':64},
-       'menu_parent_id': {'string':'Parent menu', 'type':'many2one', 'relation':'ir.ui.menu'},
+       'menu_name': {'string':'Base Menu Name', 'type':'char', 'required':True, 'size':64},
+       'menu_parent_id': {'string':'Parent Menu', 'type':'many2one', 'relation':'ir.ui.menu', 'required':True},
        'section_id': {'string':'Case Section', 'type':'many2one', 'relation':'crm.case.section', 'required':True},
+       'view_form': {'string':'Form View', 'type':'many2one', 'relation':'ir.ui.view', 'domain':[('type','=','form'),('model','=','crm.case')] },
+       'view_tree': {'string':'Tree View', 'type':'many2one', 'relation':'ir.ui.view', 'domain':[('type','=','tree'),('model','=','crm.case')] },
+       'view_calendar': {'string':'Calendar View', 'type':'many2one', 'relation':'ir.ui.view', 'domain':[('type','=','calendar'),('model','=','crm.case')] }
 }
 
+menu_lst = [
+       (1,'My ',"[('section_id','=',SECTION_ID),('user_id','=',uid)]", 0, 'form,tree'),
+       (2,'My Unclosed ',"[('section_id','=',SECTION_ID),('user_id','=',uid), ('state','<>','cancel'), ('state','<>','done')]", 1, 'tree,form'),
+       (5,'My Open ',"[('section_id','=',SECTION_ID),('user_id','=',uid), ('state','=','open')]", 2, 'tree,form'),
+       (6,'My Pending ',"[('section_id','=',SECTION_ID),('user_id','=',uid), ('state','=','pending')]", 2, 'tree,form'),
+       (7,'My Draft ',"[('section_id','=',SECTION_ID),('user_id','=',uid), ('state','=','draft')]", 2, 'tree,form'),
+       (3,'My Late ',"[('section_id','=',SECTION_ID),('user_id','=',uid), ('date_deadline','<=',time.strftime('%Y-%m-%d')), ('state','<>','cancel'), ('state','<>','done')]", 1, 'tree,form'),
+       (4,'My Canceled ',"[('section_id','=',SECTION_ID),('user_id','=',uid), ('state','=','cancel')]", 1, 'no'),
+       (8,'All ',"[('section_id','=',SECTION_ID),]", 0, 'tree,form'),
+       (9,'All Unassigned ',"[('section_id','=',SECTION_ID),('user_id','=',False)]", 8, 'no'),
+       (10,'All Late ',"[('section_id','=',SECTION_ID),('user_id','=',uid), ('date_deadline','<=',time.strftime('%Y-%m-%d')), ('state','<>','cancel'), ('state','<>','done')]", 8, 'no'),
+       (11,'All Canceled ',"[('section_id','=',SECTION_ID),('state','=','cancel')]", 8, 'no'),
+       (12,'All Unclosed ',"[('section_id','=',SECTION_ID),('state','<>','cancel'), ('state','<>','done')]", 8, 'tree,form'),
+       (13,'All Open ',"[('section_id','=',SECTION_ID),('state','=','open')]", 12, 'tree,form'),
+       (14,'All Pending ',"[('section_id','=',SECTION_ID),('state','=','pending')]", 12, 'tree,form'),
+       (15,'All Draft ',"[('section_id','=',SECTION_ID),('state','=','draft')]", 12, 'tree,form'),
+       (16,'All Unclosed and Unassigned ',"[('section_id','=',SECTION_ID),('user_id','=',False),('state','<>','cancel'),('state','<>','done')]", 12, 'no')
+]
+
+section_menu_form = '''<?xml version="1.0"?>
+<form string="Created Menus" width="800">
+       <separator string="Update The Proposed Menus To Be Created" colspan="4"/>
+''' + '\n'.join(map(lambda x: '\t<field name="menu%d" colspan="3"/> <field name="menu%d_option" nolabel="1"/>' % (x[0],x[0]), menu_lst)) + '''\n</form>'''
+
+section_menu_fields = { }
+for menu in menu_lst:
+       section_menu_fields['menu'+str(menu[0])] = {
+               'string': menu[1],
+               'type': 'char',
+               'size': 64,
+               'required': True
+       }
+       section_menu_fields['menu'+str(menu[0])+'_option'] = {
+               'string': menu[1],
+               'type': 'selection',
+               'selection': [
+                       ('no',"Don't Create"),
+                       ('form,tree','New Form'),
+                       ('form,tree,calendar','New With Calendar'),
+                       ('tree,form','List'),
+                       ('tree,form,calendar','List With Calendar'),
+                       ('calendar,tree,form','Calendar'),
+               ],
+               'size': 64,
+               'required': True,
+       }
+
 def case_menu_create(self, cr, uid, data, context):
        pool = pooler.get_pool(cr.dbname)
-       pool.get('crm.case.section').menu_create(cr, uid, [data['form']['section_id']], data['form']['menu_name'],  data['form']['menu_parent_id'], context)
+       pool.get('crm.case.section').menu_create_data(cr, uid, data['form'], menu_lst, context)
        return {}
 
+def _menu_default(self, cr, uid, data, context):
+       result = {}
+       for menu in menu_lst:
+               result['menu'+str(menu[0])] = menu[1] + data['form']['menu_name']
+               result['menu'+str(menu[0])+'_option'] = menu[4]
+       return result
+
 class wizard_section_menu_create(wizard.interface):
        states = {
                'init': {
                        'actions': [], 
-                       'result': {'type':'form', 'arch':section_form, 'fields':section_fields, 'state':[('end','Cancel'),('create','Create menu Entries')]}
+                       'result': {'type':'form', 'arch':section_form, 'fields':section_fields, 'state':[('end','Cancel'),('design_menu','Create menu Entries')]}
+               },
+               'design_menu': {
+                       'actions': [_menu_default], 
+                       'result': {
+                               'type':'form', 
+                               'arch':section_menu_form, 
+                               'fields':section_menu_fields, 
+                               'state':[
+                                       ('end','Cancel'),
+                                       ('create','Create menu Entries')
+                               ]
+                       }
                },
                'create': {
                        'actions': [case_menu_create],