[IMP]: Changes in CRM , Merged caldav features in CRM
bzr revid: rpa@tinyerp.com-20091204084021-ggb1i6da1vnwmble
This commit is contained in:
parent
8139658707
commit
9cc036ed86
|
@ -21,6 +21,7 @@
|
|||
|
||||
import crm
|
||||
import crm_segmentation
|
||||
import crm_calendar
|
||||
|
||||
import report
|
||||
import wizard
|
||||
|
|
|
@ -44,7 +44,9 @@ The CRM module has a email gateway for the synchronisation interface
|
|||
between mails and Open ERP.""",
|
||||
'author': 'Tiny',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base'],
|
||||
'depends': ['base',
|
||||
'caldav'
|
||||
],
|
||||
'init_xml': ['crm_data.xml'],
|
||||
'update_xml': [
|
||||
'crm_wizard.xml',
|
||||
|
|
|
@ -1099,5 +1099,46 @@ class crm_email_add_cc_wizard(osv.osv_memory):
|
|||
|
||||
crm_email_add_cc_wizard()
|
||||
|
||||
|
||||
class crm_calendar_config_wizard(osv.osv_memory):
|
||||
_name = 'crm.calendar.config_wizard'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64),
|
||||
'caldav': fields.boolean('Caldav Properties View', help="Manages the fields required for Caldav Properties.")
|
||||
}
|
||||
|
||||
def action_create(self, cr, uid, ids, context=None):
|
||||
res = self.read(cr, uid, ids)[0]
|
||||
idref = {}
|
||||
if res['caldav']:
|
||||
for fname in ('view', 'wizard'):
|
||||
try:
|
||||
fp = tools.file_open(os.path.join('crm', 'crm_caldav_' + fname + '.xml'))
|
||||
except IOError, e:
|
||||
fp = None
|
||||
if fp:
|
||||
tools.convert_xml_import(cr, 'crm', fp, idref, 'init', noupdate=True)
|
||||
cr.commit()
|
||||
|
||||
return {
|
||||
'view_type': 'form',
|
||||
"view_mode": 'form',
|
||||
'res_model': 'ir.actions.configuration.wizard',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
return {
|
||||
'view_type': 'form',
|
||||
"view_mode": 'form',
|
||||
'res_model': 'ir.actions.configuration.wizard',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
crm_calendar_config_wizard()
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="caldav_attendee_form_view" model="ir.ui.view">
|
||||
<field name="name">crm.case.caldav.attendee</field>
|
||||
<field name="model">caldav.attendee</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Atendee details">
|
||||
<field name="cutype" select="1"/>
|
||||
<field name="member"/>
|
||||
<field name="role" select="1"/>
|
||||
<field name="partstat"/>
|
||||
<field name="rsvp"/>
|
||||
<field name="delegated_to" select="1"/>
|
||||
<field name="delegated_from" select="1"/>
|
||||
<field name="sent_by"/>
|
||||
<field name="cn" select="1"/>
|
||||
<field name="dir"/>
|
||||
<field name="language"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="caldav_attendee_tree_view" model="ir.ui.view">
|
||||
<field name="name">crm.case.caldav.attendee</field>
|
||||
<field name="model">caldav.attendee</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Atendee details">
|
||||
<field name="cutype" select="1"/>
|
||||
<field name="member"/>
|
||||
<field name="role" select="1"/>
|
||||
<field name="partstat"/>
|
||||
<field name="rsvp"/>
|
||||
<field name="delegated_to" select="1"/>
|
||||
<field name="delegated_from" select="1"/>
|
||||
<field name="sent_by"/>
|
||||
<field name="cn" select="1"/>
|
||||
<field name="dir"/>
|
||||
<field name="language"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="caldav_crm_case_view" model="ir.ui.view">
|
||||
<field name="name">crm.case.caldav.form</field>
|
||||
<field name="model">crm.case</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="crm.crm_case-view"/>
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page string="CalDav Properties">
|
||||
<field name="class"/>
|
||||
<field name="transparent"/>
|
||||
<field name="caldav_url" widget="url"/>
|
||||
<newline/>
|
||||
<separator string="Event Location" colspan="4"/>
|
||||
<field name="location" colspan="4" nolabel="1"/>
|
||||
<separator string="Freebusy Value" colspan="4"/>
|
||||
<field name="freebusy" colspan="4" nolabel="1"/>
|
||||
<separator string="Attendee Details" colspan="4"/>
|
||||
<field name="attendee" colspan="4" nolabel="1"/>
|
||||
<separator string="RRule Details" colspan="4"/>
|
||||
<field name="rrule" colspan="4" nolabel="1"/>
|
||||
<separator string="Recurrenet Dates" colspan="4"/>
|
||||
<field name="rdates" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Attendee">
|
||||
<separator string="Attendee" colspan="4"/>
|
||||
<field name="attendees" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="caldav_crm_case_view1" model="ir.ui.view">
|
||||
<field name="name">crm.case.caldav.form1</field>
|
||||
<field name="model">crm.case</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="crm.crm_case-view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="categ_id" position="replace">
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="caldav_crm_case_view2" model="ir.ui.view">
|
||||
<field name="name">crm.case.caldav.tree1</field>
|
||||
<field name="model">crm.case</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="inherit_id" ref="crm.crm_case_tree-view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="id" position="replace">
|
||||
<field name="id" widget="char"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,12 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<wizard string="Import ICS File" model="crm.case"
|
||||
name="caldav.crm.import" id="wizard_crm_cal_import" multi="True"
|
||||
/>
|
||||
|
||||
<wizard string="Export ICS File" model="crm.case" name="caldav.crm.export"
|
||||
id="wizard_crm_cal_export" multi="True"
|
||||
/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,299 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields, osv
|
||||
from time import strftime
|
||||
import time
|
||||
import base64
|
||||
import vobject
|
||||
from dateutil.rrule import *
|
||||
from dateutil import parser
|
||||
from datetime import datetime
|
||||
from time import strftime
|
||||
from pytz import timezone
|
||||
import tools
|
||||
|
||||
class crm_section(osv.osv):
|
||||
_name = 'crm.case.section'
|
||||
_inherit = 'crm.case.section'
|
||||
_description = 'Cases Section'
|
||||
|
||||
def export_cal(self, cr, uid, ids, context={}):
|
||||
# Set all property of CalDAV
|
||||
self.export_ical()
|
||||
|
||||
def import_cal(self, cr, uid, ids, context={}):
|
||||
self.import_ical(cr, uid)
|
||||
# get all property of CalDAV
|
||||
crm_section()
|
||||
|
||||
class caldav_attendee(osv.osv):
|
||||
_name = 'caldav.attendee'
|
||||
_description = 'Attendee information'
|
||||
_rec_name = 'cutype'
|
||||
|
||||
__attribute__ = {
|
||||
'cutype' : {'field':'cutype', 'type':'text'}, # Use: 0-1 Specify the type of calendar user specified by the property like "INDIVIDUAL"/"GROUP"/"RESOURCE"/"ROOM"/"UNKNOWN".
|
||||
'member' : {'field':'member', 'type':'text'}, # Use: 0-1 Specify the group or list membership of the calendar user specified by the property.
|
||||
'role' : {'field':'role', 'type':'text'}, # Use: 0-1 Specify the participation role for the calendar user specified by the property like "CHAIR"/"REQ-PARTICIPANT"/"OPT-PARTICIPANT"/"NON-PARTICIPANT"
|
||||
'partstat' : {'field':'partstat', 'type':'text'}, # Use: 0-1 Specify the participation status for the calendar user specified by the property. like use for VEVENT :- "NEEDS-ACTION"/"ACCEPTED"/"DECLINED"/"TENTATIVE"/"DELEGATED", use for VTODO :-"NEEDS-ACTION"/"ACCEPTED"/"DECLINED"/"TENTATIVE"/"DELEGATED"/"COMPLETED"/"IN-PROCESS" and use for VJOURNAL :- "NEEDS-ACTION"/"ACCEPTED"/"DECLINED".
|
||||
'rsvp' : {'field':'rsvp', 'type':'boolean'}, # Use: 0-1 Specify whether there is an expectation of a favor of a reply from the calendar user specified by the property value like TRUE / FALSE.
|
||||
'delegated-to' : {'field':'delegated_to', 'type':'char'}, # Use: 0-1 Specify the calendar users to whom the calendar user specified by the property has delegated participation.
|
||||
'delegated-from' : {'field':'delegated_from', 'type':'char'}, # Use: 0-1 Specify the calendar users that have delegated their participation to the calendar user specified by the property.
|
||||
'sent-by' : {'field':'sent_by', 'type':'text'}, # Use: 0-1 Specify the calendar user that is acting on behalf of the calendar user specified by the property.
|
||||
'cn' : {'field':'cn', 'type':'text'}, # Use: 0-1 Specify the common name to be associated with the calendar user specified by the property.
|
||||
'dir' : {'field':'dir', 'type':'text'}, # Use: 0-1 Specify reference to a directory entry associated with the calendar user specified by the property.
|
||||
'language' : {'field':'language', 'type':'text'}, # Use: 0-1 Specify the language for text values in a property or property parameter.
|
||||
}
|
||||
|
||||
_columns = {
|
||||
'cutype' : fields.selection([('INDIVIDUAL', 'INDIVIDUAL'), ('GROUP', 'GROUP'), \
|
||||
('RESOURCE', 'RESOURCE'), ('ROOM', 'ROOM'), ('UNKNOWN', 'UNKNOWN') ], 'CUTYPE'),
|
||||
'member' : fields.char('Member', size=124),
|
||||
'role' : fields.selection([('CHAIR', 'CHAIR'), ('REQ-PARTICIPANT', 'REQ-PARTICIPANT'), \
|
||||
('OPT-PARTICIPANT', 'OPT-PARTICIPANT'), ('NON-PARTICIPANT', 'NON-PARTICIPANT')], 'ROLE'),
|
||||
'partstat' : fields.selection([('NEEDS-ACTION', 'NEEDS-ACTION'), ('ACCEPTED', 'ACCEPTED'), \
|
||||
('DECLINED', 'DECLINED'), ('TENTATIVE', 'TENTATIVE'), ('DELEGATED', 'DELEGATED')], 'PARTSTAT'),
|
||||
'rsvp' : fields.boolean('RSVP'),
|
||||
'delegated_to' : fields.char('DELEGATED-TO', size=124),
|
||||
'delegated_from' : fields.char('DELEGATED-FROM', size=124),
|
||||
'sent_by' : fields.char('SENT-BY', size=124),
|
||||
'cn' : fields.char('CN', size=124),
|
||||
'dir' : fields.char('DIR', size=124),
|
||||
'language' : fields.char('LANGUAGE', size=124),
|
||||
}
|
||||
|
||||
caldav_attendee()
|
||||
|
||||
class crm_case(osv.osv):
|
||||
_name = 'crm.case'
|
||||
_inherit = 'crm.case'
|
||||
_description = 'Cases'
|
||||
|
||||
__attribute__ = {
|
||||
'class' : {'field':'class', 'type':'text'},
|
||||
'created' : {'field':'create_date', 'type':'datetime'}, # keep none for now
|
||||
'description' : {'field':'description', 'type':'text'},
|
||||
'dtstart' : {'field':'date', 'type':'datetime'},
|
||||
#'last-mod' : {'field':'write_date', 'type':'datetime'},
|
||||
'location' : {'field':'location', 'type':'text'},
|
||||
'organizer' : {'field':'partner_id', 'sub-field':'name', 'type':'many2one'},
|
||||
'priority' : {'field':'priority', 'type':'int'},
|
||||
'dtstamp' : {'field':'date', 'type':'datetime'},
|
||||
'seq' : None,
|
||||
'status' : {'field':'state', 'type':'selection', 'mapping' : {'TENTATIVE' : 'draft', \
|
||||
'CONFIRMED' : 'open' , 'CANCELLED' : 'cancel'}},
|
||||
'summary' : {'field':'name', 'type':'text'},
|
||||
'transp' : {'field':'transparent', 'type':'text'},
|
||||
'uid' : {'field':'id', 'type':'text'},
|
||||
'url' : {'field':'caldav_url', 'type':'text'},
|
||||
'recurid' : None,
|
||||
# 'attach' : {'field':'attachment_ids', 'sub-field':'datas', 'type':'list'},
|
||||
'attendee' : {'field':'attendees', 'type':'text'},
|
||||
# 'categories' : {'field':'categ_id', 'sub-field':'name'},
|
||||
# 'categories' : {'field':None , 'sub-field':'name', 'type':'text'}, # keep none for now
|
||||
'comment' : None,
|
||||
'contact' : None,
|
||||
'exdate' : None,
|
||||
'exrule' : None,
|
||||
'rstatus' : None,
|
||||
'related' : None,
|
||||
'resources' : None,
|
||||
'rdate' : None,
|
||||
'rrule' : {'field':'rrule', 'type':'text'},
|
||||
'x-openobject-id' : {'field':'id', 'type':'text'},
|
||||
'x-openobject-model' : {'value':_name, 'type':'text'},
|
||||
# 'duration' : {'field':'duration'},
|
||||
'dtend' : {'field':'date_closed', 'type':'datetime'},
|
||||
}
|
||||
|
||||
def _get_location(self, cr, uid, ids, name, arg, context=None):
|
||||
res = {}
|
||||
for case in self.browse(cr, uid, ids):
|
||||
if case.partner_address_id:
|
||||
add = case.partner_address_id
|
||||
st = add.street and add.street+',\n' or ''
|
||||
st2 = add.street2 and add.street2+',\n' or ''
|
||||
ct = add.city and add.city+',\n' or ''
|
||||
zip = add.zip and add.zip or ''
|
||||
country = add.country_id and add.country_id.name+',\n' or ''
|
||||
res[case.id] = st + st2+ ct + country + zip
|
||||
else:
|
||||
res[case.id] = ''
|
||||
return res
|
||||
|
||||
def _get_rdates(self, cr, uid, ids, name, arg, context=None):
|
||||
res = {}
|
||||
context.update({'read':True})
|
||||
for case in self.read(cr, uid, ids, ['date', 'rrule'], context=context):
|
||||
if case['rrule']:
|
||||
rule = case['rrule'].split('\n')[0]
|
||||
exdate = case['rrule'].split('\n')[1:]
|
||||
event_obj = self.pool.get('caldav.event')
|
||||
res[case['id']] = str(event_obj.get_recurrent_dates(str(rule), exdate, case['date']))
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'categ_id': fields.many2many('crm.case.categ', 'crm_category_rel', 'case_id', 'category_id', 'Categories'),
|
||||
'class' : fields.selection([('PUBLIC', 'PUBLIC'), ('PRIVATE', 'PRIVATE'), \
|
||||
('CONFIDENTIAL', 'CONFIDENTIAL')], 'Class'),
|
||||
'location' : fields.function(_get_location, method=True, store = True, string='Location', type='text'),
|
||||
'freebusy' : fields.text('FreeBusy'),
|
||||
'transparent' : fields.selection([('OPAQUE', 'OPAQUE'), ('TRANSPARENT', 'TRANSPARENT')], 'Trensparent'),
|
||||
'caldav_url' : fields.char('Caldav URL', size=34),
|
||||
# 'attachment_ids' : function ("one2many from ir.attachemnt"),
|
||||
'attendee' : fields.text('Attendee'), #TODO : display dynamic view from text value
|
||||
'rrule' : fields.text('Recurrent Rule'),
|
||||
'rdates' : fields.function(_get_rdates, method=True, string='Recurrent Dates', \
|
||||
store=True, type='text'),
|
||||
'attendees': fields.many2many('caldav.attendee', 'crm_attendee_rel', 'case_id', 'attendee_id', 'Attendees'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'caldav_url': lambda *a: 'http://localhost:8080',
|
||||
'class': lambda *a: 'PUBLIC',
|
||||
'transparent': lambda *a: 'OPAQUE',
|
||||
}
|
||||
|
||||
def export_cal(self, cr, uid, ids, context={}):
|
||||
crm_data = self.read(cr, uid, ids, [])
|
||||
ical = vobject.iCalendar()
|
||||
event_obj = self.pool.get('caldav.event')
|
||||
for crm in crm_data:
|
||||
ical.add('vevent')
|
||||
vevent = ical.vevent
|
||||
for key, val in self.__attribute__.items():
|
||||
if val == None or key == 'rrule':
|
||||
continue
|
||||
if val.has_key('field') and val.has_key('sub-field') and crm[val['field']] and crm[val['field']]:
|
||||
vevent.add(key).value = crm[val['field']][1]
|
||||
elif val.has_key('field') and crm[val['field']]:
|
||||
if val['type'] == "text":
|
||||
vevent.add(key).value = str(crm[val['field']])
|
||||
elif val['type'] == 'datetime' and crm[val['field']]:
|
||||
vevent.add(key).value = datetime.strptime(crm[val['field']], "%Y-%m-%d %H:%M:%S")
|
||||
if crm[self.__attribute__['rrule']['field']]:
|
||||
startdate = datetime.strptime(crm['date'], "%Y-%m-%d %H:%M:%S")
|
||||
if not startdate:
|
||||
startdate = datetime.now()
|
||||
rset1 = rrulestr(str(crm[event_obj.__attribute__['rrule']['field']]), dtstart=startdate, forceset=True)
|
||||
vevent.rruleset = rset1
|
||||
|
||||
return ical.serialize().replace(vobject.icalendar.CRLF, vobject.icalendar.LF).strip()
|
||||
|
||||
def import_cal(self, cr, uid, ids, data, context={}):
|
||||
file_content = base64.decodestring(data['form']['file_path'])
|
||||
event_obj = self.pool.get('caldav.event')
|
||||
event_obj.__attribute__.update(self.__attribute__)
|
||||
event_obj.import_ical(cr, uid, file_content)
|
||||
vals = {}
|
||||
for map_dict in event_obj.__attribute__:
|
||||
map_val = event_obj.ical_get(map_dict, 'value')
|
||||
field = event_obj.ical_get(map_dict, 'field')
|
||||
field_type = event_obj.ical_get(map_dict, 'type')
|
||||
if field and map_val:
|
||||
if field_type == 'selection':
|
||||
mapping =event_obj.__attribute__[map_dict].get('mapping', False)
|
||||
if mapping:
|
||||
map_val = mapping[map_val]
|
||||
if field_type == 'many2one':
|
||||
# TODO: Map field value to many2one object
|
||||
continue # For now
|
||||
vals[field] = map_val
|
||||
# TODO: Select proper section
|
||||
section_id = self.pool.get('crm.case.section').search(cr, uid, [])[0]
|
||||
vals.update({'section_id' : section_id})
|
||||
vals.pop('id')
|
||||
vals.pop('create_date')
|
||||
case_id = self.create(cr, uid, vals)
|
||||
return
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False):
|
||||
res = super(crm_case, self).search(cr, uid, args, offset,
|
||||
limit, order, context, count)
|
||||
return res
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
res = super(crm_case, self).write(cr, uid, ids, vals, context=context)
|
||||
return res
|
||||
|
||||
def browse(self, cr, uid, select, context=None, list_class=None, fields_process={}):
|
||||
select = map(lambda x:int(str(x).split('-')[0]), select)
|
||||
return super(crm_case, self).browse(cr, uid, select, context, list_class, fields_process)
|
||||
|
||||
def read(self, cr, uid, ids, fields=None, context={},
|
||||
load='_classic_read'):
|
||||
""" logic for recurrent event
|
||||
example : 123-20091111170822"""
|
||||
if context and context.has_key('read'):
|
||||
return super(crm_case, self).read(cr, uid, ids, fields=fields, context=context, load=load)
|
||||
ids = map(lambda x:int(str(x).split('-')[0]), ids)
|
||||
res = super(crm_case, self).read(cr, uid, ids, fields=fields, context=context, load=load)
|
||||
result = res + []
|
||||
read_ids = ",".join([str(x) for x in ids])
|
||||
cr.execute('select id,rrule,rdates from crm_case where id in (%s)' % read_ids)
|
||||
rrules = filter(lambda x: not x['rrule']==None, cr.dictfetchall())
|
||||
rdates = []
|
||||
for data in rrules:
|
||||
if data['rrule'] and data['rdates']: # delete 2nd condition at last
|
||||
rdates = eval(data['rdates'])
|
||||
for res_temp in res:
|
||||
if res_temp['id'] == data['id']:
|
||||
val = res_temp
|
||||
if rdates:
|
||||
result.remove(val)
|
||||
|
||||
for rdate in rdates:
|
||||
import re
|
||||
idval = (re.compile('\d')).findall(rdate)
|
||||
val['date'] = rdate
|
||||
id = str(val['id']).split('-')[0]
|
||||
val['id'] = id + '-' + ''.join(idval)
|
||||
val1 = val.copy()
|
||||
result += [val1]
|
||||
return result
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
#TODO: Change RRULE
|
||||
for id in ids:
|
||||
if len(str(id).split('-')) > 1:
|
||||
date_new = time.strftime("%Y-%m-%d %H:%M:%S", time.strptime(str(str(id).split('-')[1]), "%Y%m%d%H%M%S"))
|
||||
for record in self.read(cr, uid, [str(id).split('-')[0]], ['date', 'rdates', 'rrule']):
|
||||
if record['date'] == date_new:
|
||||
self.write(cr, uid, [int(str(id).split('-')[0])], {'rrule' : record['rrule'] +"\n" + str(date_new)})
|
||||
else:
|
||||
return super(crm_case, self).unlink(cr, uid, ids)
|
||||
crm_case()
|
||||
|
||||
|
||||
class ir_attachment(osv.osv):
|
||||
_name = 'ir.attachment'
|
||||
_inherit = 'ir.attachment'
|
||||
|
||||
def search_count(self, cr, user, args, context=None):
|
||||
args1 = []
|
||||
for arg in args:
|
||||
args1.append(map(lambda x:str(x).split('-')[0], arg))
|
||||
return super(ir_attachment, self).search_count(cr, user, args1, context)
|
||||
|
||||
ir_attachment()
|
|
@ -36,7 +36,7 @@ class crm_segmentation(osv.osv):
|
|||
'description': fields.text('Description'),
|
||||
'categ_id': fields.many2one('res.partner.category', 'Partner Category', required=True, help='The partner category that will be added to partners that match the segmentation criterions after computation.'),
|
||||
'exclusif': fields.boolean('Exclusive', help='Check if the category is limited to partners that match the segmentation criterions. If checked, remove the category from partners that doesn\'t match segmentation criterions'),
|
||||
'state': fields.selection([('not running','Not Running'),('running','Running')], 'Execution State', readonly=True),
|
||||
'state': fields.selection([('not running','Not Running'),('running','Running')], 'Execution Status', readonly=True),
|
||||
'partner_id': fields.integer('Max Partner ID processed'),
|
||||
'segmentation_line': fields.one2many('crm.segmentation.line', 'segmentation_id', 'Criteria', required=True),
|
||||
'som_interval': fields.integer('Days per Periode', help="A period is the average number of days between two cycle of sale or purchase for this segmentation. It's mainly used to detect if a partner has not purchased or buy for a too long time, so we suppose that his state of mind has decreased because he probably bought goods to another supplier. Use this functionality for recurring businesses."),
|
||||
|
|
|
@ -706,5 +706,42 @@
|
|||
</record>
|
||||
<menuitem id="crm_email_gateway_server_menu" name="Email Gateway Server" parent="next_id_51" action="crm_email_gateway_server_act" />
|
||||
|
||||
<!-- Caldav configartion view -->
|
||||
|
||||
<record id="view_config_crm_caldav_menu" model="ir.ui.view">
|
||||
<field name="name">Configure Menu for Caldav Properites</field>
|
||||
<field name="model">crm.calendar.config_wizard</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Configure view for Caldav Properites">
|
||||
<separator colspan="4" string=""/>
|
||||
<label colspan="4" align="0.0" string="This will provide a detailed view for caldav properties configuration"/>
|
||||
<newline/>
|
||||
<field name="caldav"/>
|
||||
<separator colspan="4" string=""/>
|
||||
<group col="4" colspan="4">
|
||||
<button icon="gtk-cancel" name="action_cancel" type="object" special="cancel" string="Cancel"/>
|
||||
<button icon="gtk-go-forward" name="action_create" string="Next" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_config_crm_caldav_menu" model="ir.actions.act_window">
|
||||
<field name="name">Configure Menu for Caldav Properites</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">crm.calendar.config_wizard</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<!-- register configuration wizard -->
|
||||
<record id="config_wizard_step_cam_caldav_menu" model="ir.actions.todo">
|
||||
<field name="name">Configure Menu for Caldav Properites</field>
|
||||
<field name="note">This Configuration step use to provide a detailed view for caldav properties configuration</field>
|
||||
<field name="action_id" ref="action_view_config_crm_caldav_menu"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -23,6 +23,8 @@ import crm_wizard
|
|||
import wizard_crm_send_email
|
||||
import wizard_crm_new_send_email
|
||||
import wizard_fetch_mail
|
||||
import wizard_cal_export
|
||||
import wizard_cal_import
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import time
|
||||
import tools
|
||||
import wizard
|
||||
import os
|
||||
import mx.DateTime
|
||||
import base64
|
||||
import pooler
|
||||
import vobject
|
||||
|
||||
|
||||
class crm_cal_export_wizard(wizard.interface):
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="Export ICS">
|
||||
<separator string="Save ICS file"/>
|
||||
<field name="file_path" colspan="4" width="300" nolabel="1"/>
|
||||
</form>'''
|
||||
|
||||
form1_fields = {
|
||||
'file_path': {
|
||||
'string': 'Select ICS file',
|
||||
'type': 'binary',
|
||||
'required' : True,
|
||||
'filters' : '*.ics'
|
||||
}
|
||||
}
|
||||
|
||||
def _process_export_ics(self, cr, uid, data, context):
|
||||
case_obj = pooler.get_pool(cr.dbname).get('crm.case')
|
||||
calendar = case_obj.export_cal(cr, uid, data['ids'], context)
|
||||
return {'file_path': base64.encodestring(calendar)}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_process_export_ics],
|
||||
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', '_Cancel', 'gtk-cancel'), ('end', 'Ok', 'gtk-ok')]}
|
||||
},
|
||||
}
|
||||
|
||||
crm_cal_export_wizard('caldav.crm.export')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,66 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import time
|
||||
import tools
|
||||
import wizard
|
||||
import os
|
||||
import mx.DateTime
|
||||
import base64
|
||||
import pooler
|
||||
import vobject
|
||||
|
||||
|
||||
class crm_cal_import_wizard(wizard.interface):
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="Import ICS">
|
||||
<separator string="Select ICS file"/>
|
||||
<field name="file_path" colspan="4" width="300" nolabel="1"/>
|
||||
</form>'''
|
||||
|
||||
form1_fields = {
|
||||
'file_path': {
|
||||
'string': 'Select ICS file',
|
||||
'type': 'binary',
|
||||
'required' : True,
|
||||
'filters' : '*.ics'
|
||||
}
|
||||
}
|
||||
|
||||
def _process_import_ics(self, cr, uid, data, context=None):
|
||||
case_obj = pooler.get_pool(cr.dbname).get('crm.case')
|
||||
case_obj.import_cal(cr, uid, data['ids'], data, context)
|
||||
return {}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', '_Cancel', 'gtk-cancel'), ('open', '_Import', 'gtk-ok')]}
|
||||
},
|
||||
'open': {
|
||||
'actions': [],
|
||||
'result': {'type': 'action', 'action':_process_import_ics, 'state':'end'}
|
||||
}
|
||||
}
|
||||
|
||||
crm_cal_import_wizard('caldav.crm.import')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
Loading…
Reference in New Issue