@@ -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: 2009-02-03 11:15+0000\n"
|
||||
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
|
||||
"PO-Revision-Date: 2010-01-19 09:48+0000\n"
|
||||
"Last-Translator: lem0na <nickyk@gmx.net>\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: 2009-12-16 05:18+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-01-20 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: auction
|
||||
@@ -44,19 +44,19 @@ msgstr "продавач"
|
||||
#. module: auction
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr ""
|
||||
msgstr "Невалидно име на модел при задаване на действие"
|
||||
|
||||
#. module: auction
|
||||
#: selection:auction.lots.send.aie,date_ask,numerotation:0
|
||||
#: selection:auction.lots.send.aie,init,numerotation:0
|
||||
msgid "Provisoire"
|
||||
msgstr ""
|
||||
msgstr "Временен"
|
||||
|
||||
#. module: auction
|
||||
#: selection:auction.lots.send.aie,date_ask,numerotation:0
|
||||
#: selection:auction.lots.send.aie,init,numerotation:0
|
||||
msgid "Definitive (ordre catalogue)"
|
||||
msgstr ""
|
||||
msgstr "Зададен (за каталог)"
|
||||
|
||||
#. module: auction
|
||||
#: model:ir.ui.menu,name:auction.menu_report_auction_object_date_tree1_my
|
||||
@@ -71,7 +71,7 @@ msgstr "История на партида"
|
||||
#. module: auction
|
||||
#: field:report.seller.auction,avg_estimation:0
|
||||
msgid "Avg estimation"
|
||||
msgstr ""
|
||||
msgstr "Усреднена оценка"
|
||||
|
||||
#. module: auction
|
||||
#: field:report.auction.object.date,obj_num:0
|
||||
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2010-01-19 04:41+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-01-20 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: auction
|
||||
|
||||
@@ -7,13 +7,13 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.0\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2009-09-08 13:21+0000\n"
|
||||
"Last-Translator: Pedro_Maschio <pedro.bicudo@tgtconsult.com.br>\n"
|
||||
"PO-Revision-Date: 2010-01-20 01:10+0000\n"
|
||||
"Last-Translator: pedrobom <pedrobomlimeira@gmail.com>\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: 2009-12-16 05:24+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-01-20 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: audittrail
|
||||
@@ -32,32 +32,32 @@ msgstr ""
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log.line,log_id:0
|
||||
msgid "Log"
|
||||
msgstr ""
|
||||
msgstr "Registro (log)"
|
||||
|
||||
#. module: audittrail
|
||||
#: selection:audittrail.rule,state:0
|
||||
msgid "Subscribed"
|
||||
msgstr ""
|
||||
msgstr "Inscrito"
|
||||
|
||||
#. module: audittrail
|
||||
#: view:audittrail.log:0
|
||||
msgid "Old Value : "
|
||||
msgstr ""
|
||||
msgstr "Valor Anterior : "
|
||||
|
||||
#. module: audittrail
|
||||
#: selection:audittrail.log,method:0
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
msgstr "Criar"
|
||||
|
||||
#. module: audittrail
|
||||
#: wizard_view:audittrail.view.log,init:0
|
||||
msgid "Audit Logs"
|
||||
msgstr ""
|
||||
msgstr "Logs de auditoria"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.rule,state:0
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
msgstr "Status"
|
||||
|
||||
#. module: audittrail
|
||||
#: selection:audittrail.rule,state:0
|
||||
@@ -67,12 +67,12 @@ msgstr ""
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log.line,old_value:0
|
||||
msgid "Old Value"
|
||||
msgstr ""
|
||||
msgstr "Valor Anterior"
|
||||
|
||||
#. module: audittrail
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr ""
|
||||
msgstr "Nome de modelo inválido na definição da ação."
|
||||
|
||||
#. module: audittrail
|
||||
#: model:ir.actions.wizard,name:audittrail.wizard_audittrail_log
|
||||
@@ -87,7 +87,7 @@ msgstr ""
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log,method:0
|
||||
msgid "Method"
|
||||
msgstr ""
|
||||
msgstr "Método"
|
||||
|
||||
#. module: audittrail
|
||||
#: wizard_field:audittrail.view.log,init,from:0
|
||||
@@ -97,17 +97,17 @@ msgstr ""
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log.line,log:0
|
||||
msgid "Log ID"
|
||||
msgstr ""
|
||||
msgstr "Log ID"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log,res_id:0
|
||||
msgid "Resource Id"
|
||||
msgstr ""
|
||||
msgstr "ID Recurso"
|
||||
|
||||
#. module: audittrail
|
||||
#: selection:audittrail.log,method:0
|
||||
msgid "Write"
|
||||
msgstr ""
|
||||
msgstr "Escrever"
|
||||
|
||||
#. module: audittrail
|
||||
#: model:ir.ui.menu,name:audittrail.menu_action_audittrail
|
||||
@@ -117,23 +117,23 @@ msgstr ""
|
||||
#. module: audittrail
|
||||
#: view:audittrail.log:0
|
||||
msgid "Log Lines"
|
||||
msgstr ""
|
||||
msgstr "Linhas do Log"
|
||||
|
||||
#. module: audittrail
|
||||
#: view:audittrail.rule:0
|
||||
msgid "Subscribe"
|
||||
msgstr ""
|
||||
msgstr "Assinar"
|
||||
|
||||
#. module: audittrail
|
||||
#: selection:audittrail.log,method:0
|
||||
msgid "Read"
|
||||
msgstr ""
|
||||
msgstr "Ler"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log,object_id:0
|
||||
#: field:audittrail.rule,object_id:0
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
msgstr "Objeto"
|
||||
|
||||
#. module: audittrail
|
||||
#: view:audittrail.rule:0
|
||||
@@ -162,12 +162,12 @@ msgstr ""
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log,timestamp:0
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
msgstr "Data"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log,user_id:0
|
||||
msgid "User"
|
||||
msgstr ""
|
||||
msgstr "Usuário"
|
||||
|
||||
#. module: audittrail
|
||||
#: view:audittrail.log:0
|
||||
@@ -182,92 +182,92 @@ msgstr "Invalido XML para Arquitetura da View"
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log,name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
msgstr "Nome"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log,line_ids:0
|
||||
msgid "Log lines"
|
||||
msgstr ""
|
||||
msgstr "Linhas de Log"
|
||||
|
||||
#. module: audittrail
|
||||
#: model:ir.ui.menu,name:audittrail.menu_action_audittrail_rule_tree_sub
|
||||
msgid "Subscribed Rules"
|
||||
msgstr ""
|
||||
msgstr "Regras Inscritas"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log.line,field_id:0
|
||||
msgid "Fields"
|
||||
msgstr ""
|
||||
msgstr "Campos"
|
||||
|
||||
#. module: audittrail
|
||||
#: view:audittrail.rule:0
|
||||
msgid "AuditTrail Rules"
|
||||
msgstr ""
|
||||
msgstr "Regras de Auditoria"
|
||||
|
||||
#. module: audittrail
|
||||
#: model:ir.model,name:audittrail.model_audittrail_rule
|
||||
msgid "audittrail.rule"
|
||||
msgstr ""
|
||||
msgstr "audittrail.rule"
|
||||
|
||||
#. module: audittrail
|
||||
#: view:audittrail.rule:0
|
||||
msgid "UnSubscribe"
|
||||
msgstr ""
|
||||
msgstr "Remover Inscrição"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.rule,log_write:0
|
||||
msgid "Log writes"
|
||||
msgstr ""
|
||||
msgstr "Escritas de Log"
|
||||
|
||||
#. module: audittrail
|
||||
#: model:ir.model,name:audittrail.model_audittrail_log
|
||||
msgid "audittrail.log"
|
||||
msgstr ""
|
||||
msgstr "audittrail.log"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log.line,field_description:0
|
||||
msgid "Field Description"
|
||||
msgstr ""
|
||||
msgstr "Descrição do Campo"
|
||||
|
||||
#. module: audittrail
|
||||
#: selection:audittrail.log,method:0
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
msgstr "Apagar"
|
||||
|
||||
#. module: audittrail
|
||||
#: wizard_button:audittrail.view.log,init,open:0
|
||||
msgid "Open Logs"
|
||||
msgstr ""
|
||||
msgstr "Abrir Logs"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log.line,new_value_text:0
|
||||
msgid "New value Text"
|
||||
msgstr ""
|
||||
msgstr "Texto do novo valor"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.rule,name:0
|
||||
msgid "Rule Name"
|
||||
msgstr ""
|
||||
msgstr "Nome da Regra"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.rule,log_read:0
|
||||
msgid "Log reads"
|
||||
msgstr ""
|
||||
msgstr "Leituras de Log"
|
||||
|
||||
#. module: audittrail
|
||||
#: model:ir.ui.menu,name:audittrail.menu_action_audittrail_log_tree
|
||||
msgid "Logs"
|
||||
msgstr ""
|
||||
msgstr "Logs"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log.line,new_value:0
|
||||
msgid "New Value"
|
||||
msgstr ""
|
||||
msgstr "Novo Valor"
|
||||
|
||||
#. module: audittrail
|
||||
#: model:ir.ui.menu,name:audittrail.menu_action_log_tree2
|
||||
msgid "View Logs"
|
||||
msgstr ""
|
||||
msgstr "Ver Logs"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.rule,log_create:0
|
||||
@@ -277,7 +277,7 @@ msgstr ""
|
||||
#. module: audittrail
|
||||
#: view:audittrail.log:0
|
||||
msgid "AuditTrail Logs"
|
||||
msgstr ""
|
||||
msgstr "Logs de Auditoria"
|
||||
|
||||
#. module: audittrail
|
||||
#: model:ir.ui.menu,name:audittrail.menu_action_audittrail_rule_tree
|
||||
@@ -287,22 +287,22 @@ msgstr "Regras"
|
||||
#. module: audittrail
|
||||
#: view:audittrail.log:0
|
||||
msgid "New Value : "
|
||||
msgstr ""
|
||||
msgstr "Novo Valor: "
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.rule,user_id:0
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
msgstr "Usuários"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.log.line,old_value_text:0
|
||||
msgid "Old value Text"
|
||||
msgstr ""
|
||||
msgstr "Texto do Valor Antigo"
|
||||
|
||||
#. module: audittrail
|
||||
#: wizard_button:audittrail.view.log,init,end:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. module: audittrail
|
||||
#: field:audittrail.rule,log_unlink:0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
@@ -15,7 +15,7 @@
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
@@ -25,6 +25,7 @@ import cStringIO
|
||||
import wizard
|
||||
from osv import osv
|
||||
import pooler
|
||||
from tools.translate import _
|
||||
|
||||
form_rep = '''<?xml version="1.0"?>
|
||||
<form string="Standard entries">
|
||||
@@ -35,7 +36,7 @@ form_rep = '''<?xml version="1.0"?>
|
||||
|
||||
|
||||
fields_rep = {
|
||||
'name': {'string': 'File name', 'type': 'char', 'required': True, 'help': 'Save report as .html format'},
|
||||
'name': {'string': 'File name', 'type': 'char', 'required': True, 'help': 'Save report as .html format', 'size':64},
|
||||
'module_file': {'string': 'Save report', 'type': 'binary', 'required': True},
|
||||
}
|
||||
|
||||
|
||||
@@ -21,5 +21,6 @@
|
||||
|
||||
import calendar
|
||||
import common
|
||||
import wizard
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
"demo_xml" : [],
|
||||
"update_xml" : [
|
||||
'security/ir.model.access.csv',
|
||||
'caldav_view.xml'
|
||||
'caldav_view.xml',
|
||||
'caldav_wizard.xml',
|
||||
],
|
||||
"installable" : True,
|
||||
"active" : False,
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
<record model="res.alarm" id="alarm9">
|
||||
<field name="name">3 hours before</field>
|
||||
|
||||
|
||||
<field name="active" eval="1" />
|
||||
<field name="trigger_duration" eval="3" />
|
||||
<field name="trigger_interval">hours</field>
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
<record model="res.alarm" id="alarm10">
|
||||
<field name="name">4 hours before</field>
|
||||
|
||||
|
||||
<field name="active" eval="1" />
|
||||
<field name="trigger_duration" eval="4" />
|
||||
<field name="trigger_interval">hours</field>
|
||||
@@ -96,7 +96,7 @@
|
||||
|
||||
<record model="res.alarm" id="alarm11">
|
||||
<field name="name">5 hours before</field>
|
||||
|
||||
|
||||
<field name="active" eval="1" />
|
||||
<field name="trigger_duration" eval="5" />
|
||||
<field name="trigger_interval">hours</field>
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
<record model="res.alarm" id="alarm12">
|
||||
<field name="name">18 hours before</field>
|
||||
|
||||
|
||||
<field name="active" eval="1" />
|
||||
<field name="trigger_duration" eval="18" />
|
||||
<field name="trigger_interval">hours</field>
|
||||
@@ -115,9 +115,9 @@
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Scheduler for Event Alarm-->
|
||||
<record forcecreate="True" id="ir_cron_scheduler_alarm"
|
||||
model="ir.cron">
|
||||
<!-- Scheduler for Event Alarm-->
|
||||
<record forcecreate="True" id="ir_cron_scheduler_alarm"
|
||||
model="ir.cron">
|
||||
<field name="name">Run Event Reminder</field>
|
||||
<field eval="True" name="active" />
|
||||
<field name="user_id" ref="base.user_root" />
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<wizard string="Import .ics File" model="calendar.event"
|
||||
name="caldav.event.import" id="wizard_cal_event_import" multi="True" />
|
||||
|
||||
<wizard string="Subscribe to a Remote calendar"
|
||||
model="calendar.event" name="caldav.event.subscribe"
|
||||
id="wizard_cal_event_subscribe" multi="True" />
|
||||
|
||||
<wizard string="Export .ics File" model="calendar.event"
|
||||
name="caldav.event.export" id="wizard_cal_event_export" multi="True" />
|
||||
|
||||
<wizard string="Edit this event" model="calendar.event"
|
||||
name="calendar.event.edit.this" id="wizard_edit_this_event"
|
||||
menu="False" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -42,7 +42,7 @@ def map_data(cr, uid, obj):
|
||||
if field_type == 'selection':
|
||||
if not map_val:
|
||||
continue
|
||||
mapping =obj.__attribute__[map_dict].get('mapping', False)
|
||||
mapping = obj.__attribute__[map_dict].get('mapping', False)
|
||||
if mapping:
|
||||
map_val = mapping[map_val.lower()]
|
||||
else:
|
||||
@@ -97,12 +97,12 @@ class CalDAV(object):
|
||||
val = self.__attribute__.get(name).get(type, None)
|
||||
valtype = self.__attribute__.get(name).get('type', None)
|
||||
if type == 'value':
|
||||
if valtype and valtype=='datetime' and val:
|
||||
if valtype and valtype == 'datetime' and val:
|
||||
if isinstance(val, list):
|
||||
val = ','.join(map(lambda x: x.strftime('%Y-%m-%d %H:%M:%S'), val))
|
||||
else:
|
||||
val = val.strftime('%Y-%m-%d %H:%M:%S')
|
||||
if valtype and valtype=='integer' and val:
|
||||
if valtype and valtype == 'integer' and val:
|
||||
val = int(val)
|
||||
return val
|
||||
else:
|
||||
@@ -122,7 +122,7 @@ class CalDAV(object):
|
||||
map_field = self.ical_get(field, 'field')
|
||||
map_type = self.ical_get(field, 'type')
|
||||
if map_field in data.keys():
|
||||
if field == 'uid' :
|
||||
if field == 'uid':
|
||||
model = context.get('model', None)
|
||||
if not model:
|
||||
continue
|
||||
@@ -155,7 +155,7 @@ class CalDAV(object):
|
||||
elif map_type == "timedelta":
|
||||
vevent.add(field).value = timedelta(hours=data[map_field])
|
||||
elif map_type == "many2one":
|
||||
vevent.add(field).value = [data.get(map_field)[1]]
|
||||
vevent.add(field).value = [data.get(map_field)[1]]
|
||||
if self.__attribute__.get(field).has_key('mapping'):
|
||||
for key1, val1 in self.ical_get(field, 'mapping').items():
|
||||
if val1 == data[map_field]:
|
||||
@@ -377,15 +377,15 @@ class Alarm(CalDAV, osv.osv_memory):
|
||||
related = 'before'
|
||||
if not seconds:
|
||||
duration = abs(days)
|
||||
related = days>0 and 'after' or 'before'
|
||||
related = days > 0 and 'after' or 'before'
|
||||
elif (abs(diff) / 3600) == 0:
|
||||
duration = abs(diff / 60)
|
||||
interval = 'minutes'
|
||||
related = days>=0 and 'after' or 'before'
|
||||
related = days >= 0 and 'after' or 'before'
|
||||
else:
|
||||
duration = abs(diff / 3600)
|
||||
interval = 'hours'
|
||||
related = days>=0 and 'after' or 'before'
|
||||
related = days >= 0 and 'after' or 'before'
|
||||
self.ical_set('trigger_interval', interval, 'value')
|
||||
self.ical_set('trigger_duration', duration, 'value')
|
||||
self.ical_set('trigger_occurs', related.lower(), 'value')
|
||||
@@ -439,7 +439,7 @@ class Attendee(CalDAV, osv.osv_memory):
|
||||
attendee_add.params[a_key] = [str(attendee[a_val['field']])]
|
||||
if a_val['field'] == 'cn':
|
||||
cn_val = [str(attendee[a_val['field']])]
|
||||
attendee_add.params['CN']= cn_val
|
||||
attendee_add.params['CN'] = cn_val
|
||||
return vevent
|
||||
|
||||
Attendee()
|
||||
|
||||
+489
-24
@@ -21,9 +21,12 @@
|
||||
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta
|
||||
from dateutil import parser
|
||||
from osv import fields, osv
|
||||
from service import web_services
|
||||
from tools.translate import _
|
||||
import base64
|
||||
import re
|
||||
import time
|
||||
|
||||
@@ -48,7 +51,7 @@ def real_id2caldav_id(real_id, recurrent_date):
|
||||
if real_id and recurrent_date:
|
||||
recurrent_date = time.strftime("%Y%m%d%H%M%S", \
|
||||
time.strptime(recurrent_date, "%Y-%m-%d %H:%M:%S"))
|
||||
return '%d-%s'%(real_id, recurrent_date)
|
||||
return '%d-%s' % (real_id, recurrent_date)
|
||||
return real_id
|
||||
|
||||
def uid2openobjectid(cr, uidval, oomodel, rdate):
|
||||
@@ -221,8 +224,8 @@ request was delegated to"),
|
||||
'partner_address_id': fields.many2one('res.partner.address', 'Contact'),
|
||||
'partner_id':fields.related('partner_address_id', 'partner_id', type='many2one', relation='res.partner', string='Partner'),
|
||||
'email': fields.char('Email', size=124),
|
||||
'event_date' : fields.function(_compute_data, method=True, string='Event Date', type="datetime", multi='event_date'),
|
||||
'event_end_date' : fields.function(_compute_data, method=True, string='Event End Date', type="datetime", multi='event_end_date'),
|
||||
'event_date': fields.function(_compute_data, method=True, string='Event Date', type="datetime", multi='event_date'),
|
||||
'event_end_date': fields.function(_compute_data, method=True, string='Event End Date', type="datetime", multi='event_end_date'),
|
||||
'ref': fields.reference('Document Ref', selection=_links_get, size=128),
|
||||
'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"),
|
||||
}
|
||||
@@ -318,8 +321,8 @@ are both optional, but if one occurs, so MUST the other"""),
|
||||
alarm_ids = alarm_obj.search(cr, uid, [('model_id', '=', model_id), ('res_id', '=', datas.id)])
|
||||
if alarm_ids and len(alarm_ids):
|
||||
alarm_obj.unlink(cr, uid, alarm_ids)
|
||||
cr.execute('Update crm_meeting set caldav_alarm_id=NULL, \
|
||||
alarm_id=NULL where id=%s' % (datas.id))
|
||||
cr.execute('Update %s set caldav_alarm_id=NULL, \
|
||||
alarm_id=NULL where id=%s' % (self._table, datas.id))
|
||||
cr.commit()
|
||||
return True
|
||||
|
||||
@@ -356,12 +359,12 @@ or contains the text to be used for display"""),
|
||||
'attach': fields.binary('Attachment', help="""* Points to a sound resource, which is rendered when the alarm is triggered for audio,
|
||||
* File which is intended to be sent as message attachments for email,
|
||||
* Points to a procedure resource, which is invoked when the alarm is triggered for procedure."""),
|
||||
'res_id' : fields.integer('Resource ID'),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'model_id': fields.many2one('ir.model', 'Model'),
|
||||
'user_id': fields.many2one('res.users', 'Owner'),
|
||||
'event_date' : fields.datetime('Event Date'),
|
||||
'event_end_date' : fields.datetime('Event End Date'),
|
||||
'trigger_date' : fields.datetime('Trigger Date', readonly="True"),
|
||||
'event_date': fields.datetime('Event Date'),
|
||||
'event_end_date': fields.datetime('Event End Date'),
|
||||
'trigger_date': fields.datetime('Trigger Date', readonly="True"),
|
||||
'state':fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('run', 'Run'),
|
||||
@@ -372,7 +375,7 @@ or contains the text to be used for display"""),
|
||||
|
||||
_defaults = {
|
||||
'action': lambda *x: 'email',
|
||||
'state' : lambda *x: 'run',
|
||||
'state': lambda *x: 'run',
|
||||
}
|
||||
|
||||
def create(self, cr, uid, vals, context={}):
|
||||
@@ -411,7 +414,7 @@ or contains the text to be used for display"""),
|
||||
'act_to': alarm.user_id.id,
|
||||
'body': alarm.description,
|
||||
'trigger_date': alarm.trigger_date,
|
||||
'ref_doc1' : '%s,%s' %(alarm.model_id.model, alarm.res_id)
|
||||
'ref_doc1': '%s,%s' % (alarm.model_id.model, alarm.res_id)
|
||||
}
|
||||
request_id = request_obj.create(cr, uid, value)
|
||||
request_ids = [request_id]
|
||||
@@ -422,17 +425,17 @@ or contains the text to be used for display"""),
|
||||
request_obj.request_send(cr, uid, request_ids)
|
||||
|
||||
if alarm.action == 'email':
|
||||
sub = '[Openobject Remainder] %s' %(alarm.name)
|
||||
sub = '[Openobject Remainder] %s' % (alarm.name)
|
||||
body = """
|
||||
Name : %s
|
||||
Date : %s
|
||||
Description : %s
|
||||
Name: %s
|
||||
Date: %s
|
||||
Description: %s
|
||||
|
||||
From :
|
||||
From:
|
||||
%s
|
||||
%s
|
||||
|
||||
""" %(alarm.name, alarm.trigger_date, alarm.description, \
|
||||
""" % (alarm.name, alarm.trigger_date, alarm.description, \
|
||||
alarm.user_id.name, alarm.user_id.sign)
|
||||
mail_to = [alarm.user_id.address_id.email]
|
||||
for att in alarm.attendee_ids:
|
||||
@@ -449,6 +452,469 @@ or contains the text to be used for display"""),
|
||||
|
||||
calendar_alarm()
|
||||
|
||||
|
||||
class calendar_event(osv.osv):
|
||||
_name = "calendar.event"
|
||||
_description = "Calendar Event"
|
||||
|
||||
#kept it until fields mapping implemented
|
||||
__attribute__ = {
|
||||
'class': {'field': 'class', 'type': 'selection'},
|
||||
'created': {'field': 'create_date', 'type': 'datetime'},
|
||||
'description': {'field': 'description', 'type': 'text'},
|
||||
'dtstart': {'field': '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'},
|
||||
'recurrence-id': {'field': 'recurrent_id', 'type': 'datetime'},
|
||||
'attendee': {'field': 'attendee_ids', 'type': 'many2many', 'object': 'calendar.attendee'},
|
||||
'categories': {'field': 'categ_id', 'type': 'many2one', 'object': 'crm.meeting.categ'},
|
||||
'comment': None,
|
||||
'contact': None,
|
||||
'exdate': {'field': 'exdate', 'type': 'datetime'},
|
||||
'exrule': {'field': 'exrule', 'type': 'text'},
|
||||
'rstatus': None,
|
||||
'related': None,
|
||||
'resources': None,
|
||||
'rdate': None,
|
||||
'rrule': {'field': 'rrule', 'type': 'text'},
|
||||
'x-openobject-model': {'value': _name, 'type': 'text'},
|
||||
'dtend': {'field': 'date_deadline', 'type': 'datetime'},
|
||||
'valarm': {'field': 'caldav_alarm_id', 'type': 'many2one', 'object': 'calendar.alarm'},
|
||||
}
|
||||
|
||||
def onchange_rrule_type(self, cr, uid, ids, rtype, *args, **argv):
|
||||
if rtype == 'none' or not rtype:
|
||||
return {'value': {'rrule': ''}}
|
||||
if rtype == 'custom':
|
||||
return {}
|
||||
rrule = self.pool.get('calendar.custom.rrule')
|
||||
rrulestr = rrule.compute_rule_string(cr, uid, {'freq': rtype.upper(), \
|
||||
'interval': 1})
|
||||
return {'value': {'rrule': rrulestr}}
|
||||
|
||||
def _get_duration(self, cr, uid, ids, name, arg, context):
|
||||
res = {}
|
||||
for event in self.browse(cr, uid, ids, context=context):
|
||||
start = datetime.strptime(event.date, "%Y-%m-%d %H:%M:%S")
|
||||
res[event.id] = 0
|
||||
if event.date_deadline:
|
||||
end = datetime.strptime(event.date_deadline[:19], "%Y-%m-%d %H:%M:%S")
|
||||
diff = end - start
|
||||
duration = float(diff.days)* 24 + (float(diff.seconds) / 3600)
|
||||
res[event.id] = round(duration, 2)
|
||||
return res
|
||||
|
||||
def _set_duration(self, cr, uid, id, name, value, arg, context):
|
||||
event = self.browse(cr, uid, id, context=context)
|
||||
start = datetime.strptime(event.date, "%Y-%m-%d %H:%M:%S")
|
||||
end = start + timedelta(hours=value)
|
||||
cr.execute("UPDATE %s set date_deadline='%s' \
|
||||
where id=%s"% (self._table, end.strftime("%Y-%m-%d %H:%M:%S"), id))
|
||||
return True
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Description', size=64, required=True),
|
||||
'date': fields.datetime('Date'),
|
||||
'date_deadline': fields.datetime('Deadline'),
|
||||
'duration': fields.function(_get_duration, method=True, \
|
||||
fnct_inv=_set_duration, string='Duration'),
|
||||
'description': fields.text('Your action'),
|
||||
'class': fields.selection([('public', 'Public'), ('private', 'Private'), \
|
||||
('confidential', 'Confidential')], 'Mark as'),
|
||||
'location': fields.char('Location', size=264, help="Location of Event"),
|
||||
'show_as': fields.selection([('free', 'Free'), \
|
||||
('busy', 'Busy')],
|
||||
'Show as'),
|
||||
'caldav_url': fields.char('Caldav URL', size=264),
|
||||
'exdate': fields.text('Exception Date/Times', help="This property \
|
||||
defines the list of date/time exceptions for arecurring calendar component."),
|
||||
'exrule': fields.char('Exception Rule', size=352, help="defines a \
|
||||
rule or repeating pattern for anexception to a recurrence set"),
|
||||
'rrule': fields.char('Recurrent Rule', size=124),
|
||||
'rrule_type': fields.selection([('none', 'None'), ('daily', 'Daily'), \
|
||||
('weekly', 'Weekly'), ('monthly', 'Monthly'), \
|
||||
('yearly', 'Yearly'), ('custom', 'Custom')], 'Recurrency'),
|
||||
'alarm_id': fields.many2one('res.alarm', 'Alarm'),
|
||||
'caldav_alarm_id': fields.many2one('calendar.alarm', 'Alarm'),
|
||||
'recurrent_uid': fields.integer('Recurrent ID'),
|
||||
'recurrent_id': fields.datetime('Recurrent ID date'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'class': lambda *a: 'public',
|
||||
'show_as': lambda *a: 'busy',
|
||||
}
|
||||
|
||||
def export_cal(self, cr, uid, ids, context={}):
|
||||
ids = map(lambda x: caldav_id2real_id(x), ids)
|
||||
event_data = self.read(cr, uid, ids)
|
||||
event_obj = self.pool.get('basic.calendar.event')
|
||||
event = self.pool.get('calendar.event')
|
||||
event_obj.__attribute__.update(event.__attribute__)
|
||||
ical = event_obj.export_ical(cr, uid, event_data, context={'model': self._name})
|
||||
cal_val = ical.serialize()
|
||||
cal_val = cal_val.replace('"', '').strip()
|
||||
return cal_val
|
||||
|
||||
def import_cal(self, cr, uid, data, context={}):
|
||||
file_content = base64.decodestring(data)
|
||||
event_obj = self.pool.get('basic.calendar.event')
|
||||
event = self.pool.get('calendar.event')
|
||||
event_obj.__attribute__.update(event.__attribute__)
|
||||
|
||||
attendee_obj = self.pool.get('basic.calendar.attendee')
|
||||
attendee = self.pool.get('calendar.attendee')
|
||||
attendee_obj.__attribute__.update(attendee.__attribute__)
|
||||
|
||||
alarm_obj = self.pool.get('basic.calendar.alarm')
|
||||
alarm = self.pool.get('calendar.alarm')
|
||||
alarm_obj.__attribute__.update(alarm.__attribute__)
|
||||
|
||||
vals = event_obj.import_ical(cr, uid, file_content)
|
||||
ids = []
|
||||
for val in vals:
|
||||
exists, r_id = uid2openobjectid(cr, val['id'], self._name, \
|
||||
val.get('recurrent_id'))
|
||||
if val.has_key('create_date'): val.pop('create_date')
|
||||
val['caldav_url'] = context.get('url') or ''
|
||||
val.pop('id')
|
||||
if exists and r_id:
|
||||
val.update({'recurrent_uid': exists})
|
||||
self.write(cr, uid, [r_id], val)
|
||||
ids.append(r_id)
|
||||
elif exists:
|
||||
self.write(cr, uid, [exists], val)
|
||||
ids.append(exists)
|
||||
else:
|
||||
event_id = self.create(cr, uid, val)
|
||||
ids.append(event_id)
|
||||
return ids
|
||||
|
||||
def modify_this(self, cr, uid, ids, defaults, context=None, *args):
|
||||
datas = self.read(cr, uid, ids[0], context=context)
|
||||
date = datas.get('date')
|
||||
defaults.update({
|
||||
'recurrent_uid': caldav_id2real_id(datas['id']),
|
||||
'recurrent_id': defaults.get('date'),
|
||||
'rrule_type': 'none',
|
||||
'rrule': ''
|
||||
})
|
||||
new_id = self.copy(cr, uid, ids[0], default=defaults, context=context)
|
||||
return new_id
|
||||
|
||||
def get_recurrent_ids(self, cr, uid, select, base_start_date, base_until_date, limit=100):
|
||||
if not limit:
|
||||
limit = 100
|
||||
if isinstance(select, (str, int, long)):
|
||||
ids = [select]
|
||||
else:
|
||||
ids = select
|
||||
result = []
|
||||
if ids and (base_start_date or base_until_date):
|
||||
cr.execute("select m.id, m.rrule, m.date, m.exdate \
|
||||
from " + self._table + " m where m.id in ("\
|
||||
+ ','.join(map(lambda x: str(x), ids))+")")
|
||||
|
||||
count = 0
|
||||
for data in cr.dictfetchall():
|
||||
start_date = base_start_date and datetime.strptime(base_start_date, "%Y-%m-%d") or False
|
||||
until_date = base_until_date and datetime.strptime(base_until_date, "%Y-%m-%d") or False
|
||||
if count > limit:
|
||||
break
|
||||
event_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
|
||||
if start_date and start_date <= event_date:
|
||||
start_date = event_date
|
||||
if not data['rrule']:
|
||||
if start_date and event_date < start_date:
|
||||
continue
|
||||
if until_date and event_date > until_date:
|
||||
continue
|
||||
idval = real_id2caldav_id(data['id'], data['date'])
|
||||
result.append(idval)
|
||||
count += 1
|
||||
else:
|
||||
exdate = data['exdate'] and data['exdate'].split(',') or []
|
||||
event_obj = self.pool.get('basic.calendar.event')
|
||||
rrule_str = data['rrule']
|
||||
new_rrule_str = []
|
||||
rrule_until_date = False
|
||||
is_until = False
|
||||
for rule in rrule_str.split(';'):
|
||||
name, value = rule.split('=')
|
||||
if name == "UNTIL":
|
||||
is_until = True
|
||||
value = parser.parse(value)
|
||||
rrule_until_date = parser.parse(value.strftime("%Y-%m-%d"))
|
||||
if until_date and until_date >= rrule_until_date:
|
||||
until_date = rrule_until_date
|
||||
if until_date:
|
||||
value = until_date.strftime("%Y%m%d%H%M%S")
|
||||
new_rule = '%s=%s' % (name, value)
|
||||
new_rrule_str.append(new_rule)
|
||||
if not is_until and until_date:
|
||||
value = until_date.strftime("%Y%m%d%H%M%S")
|
||||
name = "UNTIL"
|
||||
new_rule = '%s=%s' % (name, value)
|
||||
new_rrule_str.append(new_rule)
|
||||
new_rrule_str = ';'.join(new_rrule_str)
|
||||
start_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
|
||||
rdates = event_obj.get_recurrent_dates(str(new_rrule_str), exdate, start_date)
|
||||
for rdate in rdates:
|
||||
r_date = datetime.strptime(rdate, "%Y-%m-%d %H:%M:%S")
|
||||
if start_date and r_date < start_date:
|
||||
continue
|
||||
if until_date and r_date > until_date:
|
||||
continue
|
||||
idval = real_id2caldav_id(data['id'], rdate)
|
||||
result.append(idval)
|
||||
count += 1
|
||||
if result:
|
||||
ids = result
|
||||
if isinstance(select, (str, int, long)):
|
||||
return ids and ids[0] or False
|
||||
return ids
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=100, order=None,
|
||||
context=None, count=False):
|
||||
args_without_date = []
|
||||
start_date = False
|
||||
until_date = False
|
||||
for arg in args:
|
||||
if arg[0] not in ('date', unicode('date')):
|
||||
args_without_date.append(arg)
|
||||
else:
|
||||
if arg[1] in ('>', '>='):
|
||||
start_date = arg[2]
|
||||
elif arg[1] in ('<', '<='):
|
||||
until_date = arg[2]
|
||||
res = super(calendar_event, self).search(cr, uid, args_without_date, offset,
|
||||
limit, order, context, count)
|
||||
return self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit)
|
||||
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
new_ids = []
|
||||
for id in select:
|
||||
id = caldav_id2real_id(id)
|
||||
if not id in new_ids:
|
||||
new_ids.append(id)
|
||||
res = super(calendar_event, self).write(cr, uid, new_ids, vals, context=context)
|
||||
if vals.get('alarm_id'):
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, new_ids, self._name, 'date')
|
||||
return res
|
||||
|
||||
def browse(self, cr, uid, ids, context=None, list_class=None, fields_process={}):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
select = map(lambda x: caldav_id2real_id(x), select)
|
||||
res = super(calendar_event, self).browse(cr, uid, select, context, list_class, fields_process)
|
||||
if isinstance(ids, (str, int, long)):
|
||||
return res and res[0] or False
|
||||
return res
|
||||
|
||||
def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
select = map(lambda x: (x, caldav_id2real_id(x)), select)
|
||||
result = []
|
||||
if fields and 'date' not in fields:
|
||||
fields.append('date')
|
||||
for caldav_id, real_id in select:
|
||||
res = super(calendar_event, self).read(cr, uid, real_id, fields=fields, context=context, \
|
||||
load=load)
|
||||
ls = caldav_id2real_id(caldav_id, with_date=True)
|
||||
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
|
||||
res['date'] = ls[1]
|
||||
res['id'] = caldav_id
|
||||
|
||||
result.append(res)
|
||||
if isinstance(ids, (str, int, long)):
|
||||
return result and result[0] or False
|
||||
return result
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
res = super(calendar_event, self).copy(cr, uid, caldav_id2real_id(id), default, context)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date')
|
||||
return res
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
res = False
|
||||
for id in ids:
|
||||
ls = caldav_id2real_id(id)
|
||||
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
|
||||
date_new = ls[1]
|
||||
for record in self.read(cr, uid, [caldav_id2real_id(id)], \
|
||||
['date', 'rrule', 'exdate']):
|
||||
if record['rrule']:
|
||||
exdate = (record['exdate'] and (record['exdate'] + ',') or '') + \
|
||||
''.join((re.compile('\d')).findall(date_new)) + 'Z'
|
||||
if record['date'] == date_new:
|
||||
res = self.write(cr, uid, [caldav_id2real_id(id)], {'exdate': exdate})
|
||||
else:
|
||||
ids = map(lambda x: caldav_id2real_id(x), ids)
|
||||
res = super(calendar_event, self).unlink(cr, uid, caldav_id2real_id(ids))
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_unlink(cr, uid, ids, self._name)
|
||||
else:
|
||||
ids = map(lambda x: caldav_id2real_id(x), ids)
|
||||
res = super(calendar_event, self).unlink(cr, uid, ids)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_unlink(cr, uid, ids, self._name)
|
||||
return res
|
||||
|
||||
def create(self, cr, uid, vals, context={}):
|
||||
res = super(calendar_event, self).create(cr, uid, vals, context)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date')
|
||||
return res
|
||||
|
||||
calendar_event()
|
||||
|
||||
class calendar_todo(osv.osv):
|
||||
_name = "calendar.todo"
|
||||
_inherit = "calendar.event"
|
||||
_description = "Calendar Task"
|
||||
|
||||
def _get_date(self, cr, uid, ids, name, arg, context):
|
||||
res = {}
|
||||
for event in self.browse(cr, uid, ids, context=context):
|
||||
res[event.id] = event.date_start
|
||||
return res
|
||||
|
||||
def _set_date(self, cr, uid, id, name, value, arg, context):
|
||||
event = self.browse(cr, uid, id, context=context)
|
||||
cr.execute("UPDATE %s set date_start='%s' where id=%s" \
|
||||
% (self._table, value, id))
|
||||
return True
|
||||
|
||||
_columns = {
|
||||
'date': fields.function(_get_date, method=True, fnct_inv=_set_date, \
|
||||
string='Duration', store=True, type='datetime'),
|
||||
'duration': fields.integer('Duration'),
|
||||
}
|
||||
|
||||
#kept it until fields mapping implemented
|
||||
__attribute__ = {
|
||||
'class': {'field': 'class', 'type': 'text'},
|
||||
'completed': {'field': 'date_close', 'type': 'datetime'},
|
||||
# 'created': {'field': 'field', 'type': 'text'},
|
||||
'description': {'field': 'description', 'type': 'text'},
|
||||
# 'dtstamp': {'field': 'field', 'type': 'text'},
|
||||
'dtstart': {'field': 'date_start', 'type': 'datetime'},
|
||||
'duration': {'field': 'planned_hours', 'type': 'timedelta'},
|
||||
'due': {'field': 'date_deadline', 'type': 'datetime'},
|
||||
# 'geo': {'field': 'field', 'type': 'text'},
|
||||
# 'last-mod ': {'field': 'field', 'type': 'text'},
|
||||
'location': {'field': 'location', 'type': 'text'},
|
||||
'organizer': {'field': 'partner_id', 'type': 'many2one', 'object': 'res.partner'},
|
||||
'percent': {'field': 'progress_rate', 'type': 'int'},
|
||||
'priority': {'field': 'priority', 'type': 'text'},
|
||||
# 'recurid': {'field': 'field', 'type': 'text'},
|
||||
'seq': {'field': 'sequence', 'type': 'text'},
|
||||
'status': {'field': 'state', 'type': 'selection', \
|
||||
'mapping': {'needs-action': 'draft', \
|
||||
'completed': 'done', 'in-process': 'open', \
|
||||
'cancelled': 'cancelled'}},
|
||||
'summary': {'field': 'name', 'type': 'text'},
|
||||
'uid': {'field': 'id', 'type': 'int'},
|
||||
'url': {'field': 'caldav_url', 'type': 'text'},
|
||||
# 'attach': {'field': 'field', 'type': 'text'},
|
||||
'attendee': {'field': 'attendee_ids', 'type': 'many2many', 'object': 'calendar.attendee'},
|
||||
'comment': {'field': 'notes', 'type': 'text'},
|
||||
# 'contact': {'field': 'field', 'type': 'text'},
|
||||
'exdate': {'field':'exdate', 'type':'datetime'},
|
||||
'exrule': {'field':'exrule', 'type':'text'},
|
||||
# 'rstatus': {'field': 'field', 'type': 'text'},
|
||||
# 'related': {'field': 'field', 'type': 'text'},
|
||||
# 'resources': {'field': 'field', 'type': 'text'},
|
||||
# 'rdate': {'field': 'field', 'type': 'text'},
|
||||
'rrule': {'field': 'rrule', 'type': 'text'},
|
||||
'valarm': {'field':'caldav_alarm_id', 'type':'many2one', 'object': 'calendar.alarm'},
|
||||
}
|
||||
|
||||
def import_cal(self, cr, uid, data, context={}):
|
||||
file_content = base64.decodestring(data)
|
||||
todo_obj = self.pool.get('basic.calendar.todo')
|
||||
todo = self.pool.get('calendar.todo')
|
||||
todo_obj.__attribute__.update(todo.__attribute__)
|
||||
|
||||
attendee_obj = self.pool.get('basic.calendar.attendee')
|
||||
crm_attendee = self.pool.get('calendar.attendee')
|
||||
attendee_obj.__attribute__.update(crm_attendee.__attribute__)
|
||||
|
||||
alarm_obj = self.pool.get('basic.calendar.alarm')
|
||||
crm_alarm = self.pool.get('calendar.alarm')
|
||||
alarm_obj.__attribute__.update(crm_alarm.__attribute__)
|
||||
|
||||
vals = todo_obj.import_ical(cr, uid, file_content)
|
||||
for val in vals:
|
||||
obj_tm = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.project_time_mode_id
|
||||
if not val.has_key('planned_hours'):
|
||||
# 'Computes duration' in days
|
||||
start = datetime.strptime(val['date_start'], '%Y-%m-%d %H:%M:%S')
|
||||
end = datetime.strptime(val['date_deadline'], '%Y-%m-%d %H:%M:%S')
|
||||
diff = end - start
|
||||
plan = (diff.seconds/float(86400) + diff.days) * obj_tm.factor
|
||||
val['planned_hours'] = plan
|
||||
else:
|
||||
# Converts timedelta into hours
|
||||
hours = (val['planned_hours'].seconds / float(3600)) + \
|
||||
(val['planned_hours'].days * 24)
|
||||
val['planned_hours'] = hours
|
||||
exists, r_id = uid2openobjectid(cr, val['id'], self._name, val.get('recurrent_id'))
|
||||
val.pop('id')
|
||||
if exists:
|
||||
self.write(cr, uid, [exists], val)
|
||||
else:
|
||||
task_id = self.create(cr, uid, val)
|
||||
return {'count': len(vals)}
|
||||
|
||||
def export_cal(self, cr, uid, ids, context={}):
|
||||
task_datas = self.read(cr, uid, ids, [], context ={'read': True})
|
||||
tasks = []
|
||||
for task in task_datas:
|
||||
if task.get('planned_hours', None) and task.get('date_deadline', None):
|
||||
task.pop('planned_hours')
|
||||
tasks.append(task)
|
||||
todo_obj = self.pool.get('basic.calendar.todo')
|
||||
todo = self.pool.get('calendar.todo')
|
||||
todo_obj.__attribute__.update(todo.__attribute__)
|
||||
|
||||
attendee_obj = self.pool.get('basic.calendar.attendee')
|
||||
attendee = self.pool.get('calendar.attendee')
|
||||
attendee_obj.__attribute__.update(attendee.__attribute__)
|
||||
|
||||
alarm_obj = self.pool.get('basic.calendar.alarm')
|
||||
alarm = self.pool.get('calendar.alarm')
|
||||
alarm_obj.__attribute__.update(alarm.__attribute__)
|
||||
|
||||
ical = todo_obj.export_ical(cr, uid, tasks, {'model': 'project.task'})
|
||||
calendar_val = ical.serialize()
|
||||
calendar_val = calendar_val.replace('"', '').strip()
|
||||
return calendar_val
|
||||
|
||||
calendar_todo()
|
||||
|
||||
class ir_attachment(osv.osv):
|
||||
_name = 'ir.attachment'
|
||||
_inherit = 'ir.attachment'
|
||||
@@ -481,10 +947,10 @@ class ir_values(osv.osv):
|
||||
new_model.append((data[0], caldav_id2real_id(data[1])))
|
||||
else:
|
||||
new_model.append(data)
|
||||
return super(ir_values, self).set(cr, uid, key, key2, name, new_model,\
|
||||
return super(ir_values, self).set(cr, uid, key, key2, name, new_model, \
|
||||
value, replace, isobject, meta, preserve_user, company)
|
||||
|
||||
def get(self, cr, uid, key, key2, models, meta=False, context={},\
|
||||
def get(self, cr, uid, key, key2, models, meta=False, context={}, \
|
||||
res_id_req=False, without_user=True, key2_req=True):
|
||||
new_model = []
|
||||
for data in models:
|
||||
@@ -579,7 +1045,7 @@ class calendar_custom_rrule(osv.osv):
|
||||
|
||||
freq = datas.get('freq')
|
||||
if freq == 'None':
|
||||
obj.write(cr, uid, [res_obj.id], {'rrule' : ''})
|
||||
obj.write(cr, uid, [res_obj.id], {'rrule': ''})
|
||||
return {}
|
||||
|
||||
if freq == 'weekly':
|
||||
@@ -630,7 +1096,7 @@ class calendar_custom_rrule(osv.osv):
|
||||
res_obj = obj.browse(cr, uid, context['active_id'])
|
||||
|
||||
rrule_string = self.compute_rule_string(cr, uid, datas)
|
||||
obj.write(cr, uid, [res_obj.id], {'rrule' : rrule_string})
|
||||
obj.write(cr, uid, [res_obj.id], {'rrule': rrule_string})
|
||||
return {}
|
||||
|
||||
calendar_custom_rrule()
|
||||
@@ -653,7 +1119,7 @@ class res_users(osv.osv):
|
||||
status = 'busy'
|
||||
res.update({user_id:status})
|
||||
|
||||
#TOCHECK : Delegrated Event
|
||||
#TOCHECK: Delegrated Event
|
||||
#cr.execute("SELECT user_id,'busy' FROM att_del_to_user_rel where user_id = ANY(%s)", (ids,))
|
||||
#res.update(cr.dictfetchall())
|
||||
for user_id in ids:
|
||||
@@ -698,7 +1164,7 @@ class invite_attendee_wizard(osv.osv_memory):
|
||||
res_obj = obj.browse(cr, uid, context['active_id'])
|
||||
type = datas.get('type')
|
||||
att_obj = self.pool.get('calendar.attendee')
|
||||
vals = {'ref': '%s,%s'%(model, caldav_id2real_id(context['active_id']))}
|
||||
vals = {'ref': '%s,%s' % (model, caldav_id2real_id(context['active_id']))}
|
||||
if type == 'internal':
|
||||
user_obj = self.pool.get('res.users')
|
||||
for user_id in datas.get('user_ids', []):
|
||||
@@ -715,7 +1181,6 @@ class invite_attendee_wizard(osv.osv_memory):
|
||||
vals.update({'email': datas['email']})
|
||||
att_id = att_obj.create(cr, uid, vals)
|
||||
obj.write(cr, uid, res_obj.id, {'attendee_ids': [(4, att_id)]})
|
||||
|
||||
elif type == 'partner':
|
||||
add_obj = self.pool.get('res.partner.address')
|
||||
for contact in add_obj.browse(cr, uid, datas['contact_ids']):
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"basic_calendar_all","basic.calendar","model_basic_calendar",,1,1,1,1
|
||||
"basic_calendar_event_all","basic.calendar.event","model_basic_calendar_event",,1,1,1,1
|
||||
"basic_calendar_attendee_all","basic.calendar.attendee","model_basic_calendar_attendee",,1,1,1,1
|
||||
"access_basic_calendar_attendee","calendar.attendee","model_basic_calendar_attendee",,1,1,1,1
|
||||
"access_basic_calendar_alarm","calendar.alarm","model_basic_calendar_alarm",,1,1,1,1
|
||||
"access_basic_calendar_all","basic.calendar","model_basic_calendar",,1,1,1,1
|
||||
"access_basic_calendar_event_all","basic.calendar.event","model_basic_calendar_event",,1,1,1,1
|
||||
"access_basic_calendar_attendee_all","basic.calendar.attendee","model_basic_calendar_attendee",,1,1,1,1
|
||||
"access_calendar_todo_all","basic.calendar.todo","model_basic_calendar_todo",,1,1,1,1
|
||||
"access_calendar_todo_all","basic.calendar.todo","model_basic_calendar_todo",,1,1,1,1
|
||||
"access_calendar_attendee","calendar.attendee","model_calendar_attendee",,1,1,1,1
|
||||
"access_calendar_alarm","calendar.alarm","model_calendar_alarm",,1,1,1,1
|
||||
"access_res_alarm","res.alarm","model_res_alarm",,1,1,1,1
|
||||
"access_calendar_event_all","calendar.event","model_calendar_event",,1,1,1,1
|
||||
|
||||
|
Regular → Executable
+4
-2
@@ -2,7 +2,7 @@
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# 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
|
||||
@@ -22,5 +22,7 @@
|
||||
import wizard_cal_export
|
||||
import wizard_cal_import
|
||||
import wizard_cal_subscribe
|
||||
import wizard_cal_edit_event
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
+15
-16
@@ -22,46 +22,45 @@
|
||||
import wizard
|
||||
import pooler
|
||||
|
||||
class meeting_edit_this(wizard.interface):
|
||||
case_form = """<?xml version="1.0"?>
|
||||
<form string="Edit Meeting">
|
||||
class event_edit_this(wizard.interface):
|
||||
event_form = """<?xml version="1.0"?>
|
||||
<form string="Edit Event">
|
||||
<separator string="" colspan="4" />
|
||||
<newline />
|
||||
<field name='name' colspan="4" />
|
||||
<newline />
|
||||
<field name='location' colspan="4" />
|
||||
<newline />
|
||||
<field name='categ_id'/>
|
||||
<newline />
|
||||
<field name='date' />
|
||||
<field name='date_deadline' />
|
||||
<newline />
|
||||
<field name='alarm_id'/>
|
||||
</form>"""
|
||||
|
||||
case_fields = {
|
||||
event_fields = {
|
||||
'name': {'string': 'Title', 'type': 'char', 'size': 64},
|
||||
'date': {'string': 'Start Date', 'type': 'datetime'},
|
||||
'date_deadline': {'string': 'End Date', 'type': 'datetime'},
|
||||
'location': {'string': 'Location', 'type': 'char', 'size': 124},
|
||||
'categ_id': {'string': 'Category', 'type': 'many2one', 'relation': 'crm.meeting.categ'},
|
||||
'alarm_id': {'string': 'Reminder', 'type': 'many2one', 'relation': 'res.alarm'},
|
||||
}
|
||||
|
||||
def _default_values(self, cr, uid, data, context):
|
||||
case_obj = pooler.get_pool(cr.dbname).get('crm.meeting')
|
||||
case = case_obj.read(cr, uid, data['id'], ['name', 'location', 'date',\
|
||||
'date_deadline', 'categ_id', 'alarm_id'])
|
||||
return case
|
||||
model = data.get('model')
|
||||
model_obj = pooler.get_pool(cr.dbname).get(model)
|
||||
event = model_obj.read(cr, uid, data['id'], ['name', 'location', 'date',\
|
||||
'date_deadline', 'alarm_id'])
|
||||
return event
|
||||
|
||||
def _modify_this(self, cr, uid, datas, *args):
|
||||
case_obj = pooler.get_pool(cr.dbname).get('crm.meeting')
|
||||
new_id = case_obj.modify_this(cr, uid, [datas['id']], datas['form'])
|
||||
model = datas.get('model')
|
||||
model_obj = pooler.get_pool(cr.dbname).get(model)
|
||||
new_id = model_obj.modify_this(cr, uid, [datas['id']], datas['form'])
|
||||
value = {
|
||||
'name': 'New event',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form,tree',
|
||||
'res_model': 'crm.meeting',
|
||||
'res_model': model,
|
||||
'res_id': new_id,
|
||||
'view_id': False,
|
||||
'type': 'ir.actions.act_window',
|
||||
@@ -71,7 +70,7 @@ class meeting_edit_this(wizard.interface):
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_default_values],
|
||||
'result': {'type': 'form', 'arch': case_form, 'fields': case_fields,
|
||||
'result': {'type': 'form', 'arch': event_form, 'fields': event_fields,
|
||||
'state': [('end', 'Cancel', 'gtk-cancel'), ('edit', '_Save', 'gtk-save')]}
|
||||
},
|
||||
'edit': {
|
||||
@@ -80,6 +79,6 @@ class meeting_edit_this(wizard.interface):
|
||||
}
|
||||
}
|
||||
|
||||
meeting_edit_this('crm.meeting.edit.this')
|
||||
event_edit_this('calendar.event.edit.this')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -24,7 +24,7 @@ import base64
|
||||
import pooler
|
||||
|
||||
|
||||
class crm_cal_export_wizard(wizard.interface):
|
||||
class cal_event_export_wizard(wizard.interface):
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="Export ICS">
|
||||
<field name="name"/>
|
||||
@@ -35,8 +35,8 @@ class crm_cal_export_wizard(wizard.interface):
|
||||
'file_path': {
|
||||
'string': 'Save ICS file',
|
||||
'type': 'binary',
|
||||
'required' : True,
|
||||
'filters' : '*.ics'
|
||||
'required': True,
|
||||
'filters': '*.ics'
|
||||
},
|
||||
'name': {
|
||||
'string': 'File name',
|
||||
@@ -47,8 +47,9 @@ class crm_cal_export_wizard(wizard.interface):
|
||||
}
|
||||
|
||||
def _process_export_ics(self, cr, uid, data, context):
|
||||
case_obj = pooler.get_pool(cr.dbname).get('crm.meeting')
|
||||
calendar = case_obj.export_cal(cr, uid, data['ids'], context)
|
||||
model = data.get('model')
|
||||
model_obj = pooler.get_pool(cr.dbname).get(model)
|
||||
calendar = model_obj.export_cal(cr, uid, data['ids'], context)
|
||||
return {'file_path': base64.encodestring(calendar), \
|
||||
'name': 'OpenERP Events.ics'}
|
||||
|
||||
@@ -59,6 +60,6 @@ class crm_cal_export_wizard(wizard.interface):
|
||||
'state': [('end', '_Cancel', 'gtk-cancel'), ('end', 'Ok', 'gtk-ok')]}},
|
||||
}
|
||||
|
||||
crm_cal_export_wizard('caldav.crm.export')
|
||||
cal_event_export_wizard('caldav.event.export')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -23,7 +23,7 @@ import wizard
|
||||
import pooler
|
||||
|
||||
|
||||
class crm_cal_import_wizard(wizard.interface):
|
||||
class cal_event_import_wizard(wizard.interface):
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="Import ICS">
|
||||
<separator string="Select ICS file"/>
|
||||
@@ -52,8 +52,9 @@ class crm_cal_import_wizard(wizard.interface):
|
||||
}
|
||||
|
||||
def _process_imp_ics(self, cr, uid, data, context=None):
|
||||
case_obj = pooler.get_pool(cr.dbname).get('crm.meeting')
|
||||
vals = case_obj.import_cal(cr, uid, data['form']['file_path'], context)
|
||||
model = data.get('model')
|
||||
model_obj = pooler.get_pool(cr.dbname).get(model)
|
||||
vals = model_obj.import_cal(cr, uid, data['form']['file_path'], context)
|
||||
global cnt
|
||||
cnt = 0
|
||||
if vals:
|
||||
@@ -72,7 +73,7 @@ class crm_cal_import_wizard(wizard.interface):
|
||||
'open': {
|
||||
'actions': [],
|
||||
'result': {'type': 'action', 'action': _process_imp_ics, 'state': 'display'}
|
||||
},
|
||||
},
|
||||
'display': {
|
||||
'actions': [_result_set],
|
||||
'result': {'type': 'form', 'arch': display, 'fields': display_fields, \
|
||||
@@ -80,6 +81,6 @@ class crm_cal_import_wizard(wizard.interface):
|
||||
},
|
||||
}
|
||||
|
||||
crm_cal_import_wizard('caldav.crm.import')
|
||||
cal_event_import_wizard('caldav.event.import')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
+6
-5
@@ -25,7 +25,7 @@ import pooler
|
||||
import urllib
|
||||
import wizard
|
||||
|
||||
class crm_cal_subscribe_wizard(wizard.interface):
|
||||
class cal_event_subscribe_wizard(wizard.interface):
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="Subscribe to Remote ICS">
|
||||
<separator string="Provide path for Remote Calendar"/>
|
||||
@@ -58,13 +58,14 @@ class crm_cal_subscribe_wizard(wizard.interface):
|
||||
cnt = 0
|
||||
try:
|
||||
f = urllib.urlopen(data['form']['url_path'])
|
||||
caldata= f.fp.read()
|
||||
caldata = f.fp.read()
|
||||
f.close()
|
||||
except Exception,e:
|
||||
raise wizard.except_wizard(_('Error!'), _('Please provide Proper URL !'))
|
||||
case_obj = pooler.get_pool(cr.dbname).get('crm.meeting')
|
||||
model = data.get('model')
|
||||
model_obj = pooler.get_pool(cr.dbname).get(model)
|
||||
context.update({'url': data['form']['url_path']})
|
||||
vals = case_obj.import_cal(cr, uid, base64.encodestring(caldata), context)
|
||||
vals = model_obj.import_cal(cr, uid, base64.encodestring(caldata), context)
|
||||
if vals:
|
||||
cnt = vals['count']
|
||||
return {}
|
||||
@@ -89,6 +90,6 @@ class crm_cal_subscribe_wizard(wizard.interface):
|
||||
},
|
||||
}
|
||||
|
||||
crm_cal_subscribe_wizard('caldav.crm.subscribe')
|
||||
cal_event_subscribe_wizard('caldav.event.subscribe')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<!-- <menuitem id="menu_aftersale" name="After-Sale Services" parent="crm.menu_crm"/>-->
|
||||
<menuitem id="base.menu_aftersale" name="After-Sale Services" parent="base.menu_base_partner" sequence="6"/>
|
||||
|
||||
######################## CLAIMS (menu) ###########################
|
||||
<record model="ir.actions.act_window" id="crm_case_categ_claim0">
|
||||
<field name="name">All Claims</field>
|
||||
<field name="name">Claims</field>
|
||||
<field name="res_model">crm.claim</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,calendar,form,graph</field>
|
||||
@@ -38,7 +38,7 @@
|
||||
<field name="act_window_id" ref="crm_case_categ_claim0"/>
|
||||
</record>
|
||||
|
||||
<menuitem name="Claims" id="menu_crm_case_claims" parent="base.menu_sales" action="crm_case_categ_claim0"/>
|
||||
<menuitem name="Claims" id="menu_crm_case_claims" parent="base.menu_aftersale" action="crm_case_categ_claim0"/>
|
||||
|
||||
|
||||
</data>
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<!-- MENU -->
|
||||
<menuitem id="base.menu_fundrising" name="Fund Raising" parent="base.menu_base_partner" sequence="7"/>
|
||||
<record model="ir.actions.act_window" id="crm_case_category_act_fund_all1">
|
||||
<field name="name">All Funds</field>
|
||||
<field name="name">Funds</field>
|
||||
<field name="res_model">crm.fundraising</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="view_id" ref="crm.crm_case_tree_view_fund"/>
|
||||
@@ -28,7 +29,7 @@
|
||||
<field name="view_id" ref="crm.crm_case_graph_view_fund"/>
|
||||
<field name="act_window_id" ref="crm_case_category_act_fund_all1"/>
|
||||
</record>
|
||||
<menuitem name="Fund Raising" id="menu_crm_case_fund_raise" parent="base.menu_sales" action="crm_case_category_act_fund_all1" sequence="1"/>
|
||||
<menuitem name="Fund Raising" id="menu_crm_case_fund_raise" parent="base.menu_fundrising" action="crm_case_category_act_fund_all1" sequence="1"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<!-- <menuitem id="menu_aftersale" name="After-Sale Services" parent="crm.menu_crm"/>-->
|
||||
<menuitem id="base.menu_aftersale" name="After-Sale Services" parent="base.menu_base_partner" sequence="6"/>
|
||||
|
||||
######################## Help Desk (menu) ###########################
|
||||
<record model="ir.actions.act_window" id="crm_case_helpdesk_act111">
|
||||
<field name="name">All Helpdesk Requests</field>
|
||||
<field name="name">Helpdesk Requests</field>
|
||||
<field name="res_model">crm.helpdesk</field>
|
||||
<field name="view_mode">tree,calendar,form</field>
|
||||
<field name="view_id" ref="crm_case_tree_view_helpdesk"/>
|
||||
<field name="domain" eval="'[(\'section_id\',\'=\','+str(ref('section_support_help'))+')]'"/>
|
||||
<field name="view_id" ref="crm_case_tree_view_helpdesk"/>
|
||||
<field name="context" eval="{'default_state':'open'}"/>
|
||||
<field name="search_view_id" ref="crm.view_crm_case_filter"/>
|
||||
</record>
|
||||
@@ -31,7 +30,7 @@
|
||||
<field name="view_id" ref="crm_case_form_view_helpdesk"/>
|
||||
<field name="act_window_id" ref="crm_case_helpdesk_act111"/>
|
||||
</record>
|
||||
<menuitem name="Helpdesk and Support" id="menu_help_support_main" parent="base.menu_sales" action="crm_case_helpdesk_act111"/>
|
||||
<menuitem name="Helpdesk and Support" id="menu_help_support_main" parent="base.menu_aftersale" action="crm_case_helpdesk_act111"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
+9
-371
@@ -19,392 +19,30 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from caldav import common
|
||||
from datetime import datetime, timedelta
|
||||
from dateutil import parser
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import base64
|
||||
import re
|
||||
|
||||
|
||||
class crm_meeting(osv.osv):
|
||||
_name = 'crm.meeting'
|
||||
_description = "Meeting Cases"
|
||||
_order = "id desc"
|
||||
_inherit = "crm.case"
|
||||
|
||||
__attribute__ = {
|
||||
'class': {'field': 'class', 'type': 'selection'},
|
||||
'created': {'field': 'create_date', 'type': 'datetime'},
|
||||
'description': {'field': 'description', 'type': 'text'},
|
||||
'dtstart': {'field': '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'},
|
||||
'recurrence-id': {'field': 'recurrent_id', 'type': 'datetime'},
|
||||
'attendee': {'field': 'attendee_ids', 'type': 'many2many', 'object': 'calendar.attendee'},
|
||||
'categories': {'field': 'categ_id', 'type': 'many2one', 'object': 'crm.case.categ'},
|
||||
'comment': None,
|
||||
'contact': None,
|
||||
'exdate': {'field': 'exdate', 'type': 'datetime'},
|
||||
'exrule': {'field': 'exrule', 'type': 'text'},
|
||||
'rstatus': None,
|
||||
'related': None,
|
||||
'resources': None,
|
||||
'rdate': None,
|
||||
'rrule': {'field': 'rrule', 'type': 'text'},
|
||||
'x-openobject-model': {'value': _name, 'type': 'text'},
|
||||
'dtend': {'field': 'date_deadline', 'type': 'datetime'},
|
||||
'valarm': {'field': 'caldav_alarm_id', 'type': 'many2one', 'object': 'calendar.alarm'},
|
||||
}
|
||||
|
||||
def _get_duration(self, cr, uid, ids, name, arg, context):
|
||||
res = {}
|
||||
for meeting in self.browse(cr, uid, ids, context=context):
|
||||
start = datetime.strptime(meeting.date, "%Y-%m-%d %H:%M:%S")
|
||||
if meeting.date_deadline:
|
||||
end = datetime.strptime(meeting.date_deadline[:19], "%Y-%m-%d %H:%M:%S")
|
||||
diff = end - start
|
||||
duration = float(diff.days)* 24 + (float(diff.seconds) / 3600)
|
||||
res[meeting.id] = round(duration, 2)
|
||||
return res
|
||||
|
||||
def _set_duration(self, cr, uid, id, name, value, arg, context):
|
||||
meeting = self.browse(cr, uid, id, context=context)
|
||||
start = datetime.strptime(meeting.date, "%Y-%m-%d %H:%M:%S")
|
||||
end = start + timedelta(hours=value)
|
||||
cr.execute("UPDATE crm_meeting set date_deadline='%s' \
|
||||
where id=%s"% (end.strftime("%Y-%m-%d %H:%M:%S"), id))
|
||||
return True
|
||||
|
||||
def onchange_rrule_type(self, cr, uid, ids, rtype, *args, **argv):
|
||||
if rtype == 'none' or not rtype:
|
||||
return {'value': {'rrule': ''}}
|
||||
if rtype == 'custom':
|
||||
return {}
|
||||
rrule = self.pool.get('calendar.custom.rrule')
|
||||
rrulestr = rrule.compute_rule_string(cr, uid, {'freq': rtype.upper(), \
|
||||
'interval': 1})
|
||||
return {'value': {'rrule': rrulestr}}
|
||||
_inherit = ["crm.case", "calendar.event"]
|
||||
|
||||
_columns = {
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
'name': fields.char('Description', size=64, required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Section', select=True, help='Section to which Case belongs to. Define Responsible user and Email \
|
||||
account for mail gateway.'),
|
||||
'priority': fields.selection([('5','Lowest'),
|
||||
('4','Low'),
|
||||
('3','Normal'),
|
||||
('2','High'),
|
||||
('1','Highest')
|
||||
], 'Priority'),
|
||||
'date': fields.datetime('Date'),
|
||||
'date_deadline': fields.datetime('Deadline'),
|
||||
'duration': fields.function(_get_duration, method=True, \
|
||||
fnct_inv=_set_duration, string='Duration'),
|
||||
('4','Low'),
|
||||
('3','Normal'),
|
||||
('2','High'),
|
||||
('1','Highest')
|
||||
], 'Priority'),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.meeting')]", \
|
||||
domain="[('section_id','=',section_id),\
|
||||
('object_id.model', '=', 'crm.meeting')]", \
|
||||
help='Category related to the section.Subdivide the CRM cases \
|
||||
independently or section-wise.'),
|
||||
'description': fields.text('Your action'),
|
||||
'class': fields.selection([('public', 'Public'), ('private', 'Private'), \
|
||||
('confidential', 'Confidential')], 'Mark as'),
|
||||
'location': fields.char('Location', size=264, help="Location of Meeting"),
|
||||
'show_as': fields.selection([('free', 'Free'), \
|
||||
('busy', 'Busy')],
|
||||
'Show as'),
|
||||
'caldav_url': fields.char('Caldav URL', size=264),
|
||||
'exdate': fields.text('Exception Date/Times', help="This property \
|
||||
defines the list of date/time exceptions for arecurring calendar component."),
|
||||
'exrule': fields.char('Exception Rule', size=352, help="defines a \
|
||||
rule or repeating pattern for anexception to a recurrence set"),
|
||||
'rrule': fields.char('Recurrent Rule', size=124),
|
||||
'rrule_type': fields.selection([('none', 'None'), ('daily', 'Daily'), \
|
||||
('weekly', 'Weekly'), ('monthly', 'Monthly'), \
|
||||
('yearly', 'Yearly'), ('custom', 'Custom')], 'Recurrency'),
|
||||
'attendee_ids': fields.many2many('calendar.attendee', 'crm_attendee_rel', 'case_id', 'attendee_id', 'Attendees'),
|
||||
'alarm_id': fields.many2one('res.alarm', 'Alarm'),
|
||||
'caldav_alarm_id': fields.many2one('calendar.alarm', 'Alarm'),
|
||||
'recurrent_uid': fields.integer('Recurrent ID'),
|
||||
'recurrent_id': fields.datetime('Recurrent ID date'),
|
||||
'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', 'event_id', 'attendee_id', 'Attendees'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'class': lambda *a: 'public',
|
||||
'show_as': lambda *a: 'busy',
|
||||
}
|
||||
|
||||
def on_change_duration(self, cr, uid, id, date, duration):
|
||||
if not date:
|
||||
return {}
|
||||
start_date = datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
|
||||
if duration >= 0:
|
||||
end = start_date + datetime.timedelta(hours=duration)
|
||||
if duration < 0:
|
||||
raise osv.except_osv(_('Warning !'),
|
||||
_('You can not set negative Duration.'))
|
||||
res = {'value': {'date_deadline': end.strftime('%Y-%m-%d %H:%M:%S')}}
|
||||
return res
|
||||
|
||||
def export_cal(self, cr, uid, ids, context={}):
|
||||
ids = map(lambda x: common.caldav_id2real_id(x), ids)
|
||||
crm_data = self.read(cr, uid, ids)
|
||||
event_obj = self.pool.get('basic.calendar.event')
|
||||
event_obj.__attribute__.update(self.__attribute__)
|
||||
ical = event_obj.export_ical(cr, uid, crm_data, context={'model': self._name})
|
||||
cal_val = ical.serialize()
|
||||
cal_val = cal_val.replace('"', '').strip()
|
||||
return cal_val
|
||||
|
||||
def import_cal(self, cr, uid, data, context={}):
|
||||
file_content = base64.decodestring(data)
|
||||
event_obj = self.pool.get('basic.calendar.event')
|
||||
event_obj.__attribute__.update(self.__attribute__)
|
||||
|
||||
attendee_obj = self.pool.get('basic.calendar.attendee')
|
||||
attendee = self.pool.get('calendar.attendee')
|
||||
attendee_obj.__attribute__.update(attendee.__attribute__)
|
||||
|
||||
alarm_obj = self.pool.get('basic.calendar.alarm')
|
||||
alarm = self.pool.get('calendar.alarm')
|
||||
alarm_obj.__attribute__.update(alarm.__attribute__)
|
||||
|
||||
vals = event_obj.import_ical(cr, uid, file_content)
|
||||
ids = []
|
||||
for val in vals:
|
||||
exists, r_id = common.uid2openobjectid(cr, val['id'], self._name, \
|
||||
val.get('recurrent_id'))
|
||||
if val.has_key('create_date'): val.pop('create_date')
|
||||
val['caldav_url'] = context.get('url') or ''
|
||||
val.pop('id')
|
||||
if exists and r_id:
|
||||
val.update({'recurrent_uid': exists})
|
||||
self.write(cr, uid, [r_id], val)
|
||||
ids.append(r_id)
|
||||
elif exists:
|
||||
self.write(cr, uid, [exists], val)
|
||||
ids.append(exists)
|
||||
else:
|
||||
case_id = self.create(cr, uid, val)
|
||||
ids.append(case_id)
|
||||
return ids
|
||||
|
||||
def get_recurrent_ids(self, cr, uid, select, base_start_date, base_until_date, limit=100):
|
||||
if not limit:
|
||||
limit = 100
|
||||
if isinstance(select, (str, int, long)):
|
||||
ids = [select]
|
||||
else:
|
||||
ids = select
|
||||
result = []
|
||||
if ids and (base_start_date or base_until_date):
|
||||
cr.execute("select m.id, m.rrule, m.date, m.exdate \
|
||||
from crm_meeting m\
|
||||
where m.id in ("+ ','.join(map(lambda x: str(x), ids))+")")
|
||||
|
||||
count = 0
|
||||
for data in cr.dictfetchall():
|
||||
start_date = base_start_date and datetime.strptime(base_start_date, "%Y-%m-%d") or False
|
||||
until_date = base_until_date and datetime.strptime(base_until_date, "%Y-%m-%d") or False
|
||||
if count > limit:
|
||||
break
|
||||
event_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
|
||||
if start_date and start_date <= event_date:
|
||||
start_date = event_date
|
||||
if not data['rrule']:
|
||||
if start_date and event_date < start_date:
|
||||
continue
|
||||
if until_date and event_date > until_date:
|
||||
continue
|
||||
idval = common.real_id2caldav_id(data['id'], data['date'])
|
||||
result.append(idval)
|
||||
count += 1
|
||||
else:
|
||||
exdate = data['exdate'] and data['exdate'].split(',') or []
|
||||
event_obj = self.pool.get('basic.calendar.event')
|
||||
rrule_str = data['rrule']
|
||||
new_rrule_str = []
|
||||
rrule_until_date = False
|
||||
is_until = False
|
||||
for rule in rrule_str.split(';'):
|
||||
name, value = rule.split('=')
|
||||
if name == "UNTIL":
|
||||
is_until = True
|
||||
value = parser.parse(value)
|
||||
rrule_until_date = parser.parse(value.strftime("%Y-%m-%d"))
|
||||
if until_date and until_date >= rrule_until_date:
|
||||
until_date = rrule_until_date
|
||||
if until_date:
|
||||
value = until_date.strftime("%Y%m%d%H%M%S")
|
||||
new_rule = '%s=%s' % (name, value)
|
||||
new_rrule_str.append(new_rule)
|
||||
if not is_until and until_date:
|
||||
value = until_date.strftime("%Y%m%d%H%M%S")
|
||||
name = "UNTIL"
|
||||
new_rule = '%s=%s' % (name, value)
|
||||
new_rrule_str.append(new_rule)
|
||||
new_rrule_str = ';'.join(new_rrule_str)
|
||||
start_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
|
||||
rdates = event_obj.get_recurrent_dates(str(new_rrule_str), exdate, start_date)
|
||||
for rdate in rdates:
|
||||
r_date = datetime.strptime(rdate, "%Y-%m-%d %H:%M:%S")
|
||||
if start_date and r_date < start_date:
|
||||
continue
|
||||
if until_date and r_date > until_date:
|
||||
continue
|
||||
idval = common.real_id2caldav_id(data['id'], rdate)
|
||||
result.append(idval)
|
||||
count += 1
|
||||
if result:
|
||||
ids = result
|
||||
if isinstance(select, (str, int, long)):
|
||||
return ids and ids[0] or False
|
||||
return ids
|
||||
|
||||
def modify_this(self, cr, uid, ids, defaults, context=None, *args):
|
||||
datas = self.read(cr, uid, ids[0], context=context)
|
||||
date = datas.get('date')
|
||||
defaults.update({
|
||||
'recurrent_uid': common.caldav_id2real_id(datas['id']),
|
||||
'recurrent_id': defaults.get('date'),
|
||||
'rrule_type': 'none',
|
||||
'rrule': ''
|
||||
})
|
||||
new_id = self.copy(cr, uid, ids[0], default=defaults, context=context)
|
||||
return new_id
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=100, order=None,
|
||||
context=None, count=False):
|
||||
args_without_date = []
|
||||
start_date = False
|
||||
until_date = False
|
||||
for arg in args:
|
||||
if arg[0] not in ('date', unicode('date')):
|
||||
args_without_date.append(arg)
|
||||
else:
|
||||
if arg[1] in ('>', '>='):
|
||||
start_date = arg[2]
|
||||
elif arg[1] in ('<', '<='):
|
||||
until_date = arg[2]
|
||||
res = super(crm_meeting, self).search(cr, uid, args_without_date, offset,
|
||||
limit, order, context, count)
|
||||
return self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit)
|
||||
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
new_ids = []
|
||||
for id in select:
|
||||
id = common.caldav_id2real_id(id)
|
||||
if not id in new_ids:
|
||||
new_ids.append(id)
|
||||
res = super(crm_meeting, self).write(cr, uid, new_ids, vals, context=context)
|
||||
if vals.get('alarm_id'):
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, new_ids, self._name, 'date')
|
||||
return res
|
||||
|
||||
def browse(self, cr, uid, ids, context=None, list_class=None, fields_process={}):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
select = map(lambda x: common.caldav_id2real_id(x), select)
|
||||
res = super(crm_meeting, self).browse(cr, uid, select, context, list_class, fields_process)
|
||||
if isinstance(ids, (str, int, long)):
|
||||
return res and res[0] or False
|
||||
return res
|
||||
|
||||
def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
select = map(lambda x: (x, common.caldav_id2real_id(x)), select)
|
||||
result = []
|
||||
if fields and 'date' not in fields:
|
||||
fields.append('date')
|
||||
for caldav_id, real_id in select:
|
||||
res = super(crm_meeting, self).read(cr, uid, real_id, fields=fields, context=context, \
|
||||
load=load)
|
||||
ls = common.caldav_id2real_id(caldav_id, with_date=True)
|
||||
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
|
||||
res['date'] = ls[1]
|
||||
res['id'] = caldav_id
|
||||
|
||||
result.append(res)
|
||||
if isinstance(ids, (str, int, long)):
|
||||
return result and result[0] or False
|
||||
return result
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
res = super(crm_meeting, self).copy(cr, uid, common.caldav_id2real_id(id), default, context)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date')
|
||||
return res
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
res = False
|
||||
for id in ids:
|
||||
ls = common.caldav_id2real_id(id)
|
||||
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
|
||||
date_new = ls[1]
|
||||
for record in self.read(cr, uid, [common.caldav_id2real_id(id)], \
|
||||
['date', 'rrule', 'exdate']):
|
||||
if record['rrule']:
|
||||
exdate = (record['exdate'] and (record['exdate'] + ',') or '') + \
|
||||
''.join((re.compile('\d')).findall(date_new)) + 'Z'
|
||||
if record['date'] == date_new:
|
||||
res = self.write(cr, uid, [common.caldav_id2real_id(id)], {'exdate': exdate})
|
||||
else:
|
||||
ids = map(lambda x: common.caldav_id2real_id(x), ids)
|
||||
res = super(crm_meeting, self).unlink(cr, uid, common.caldav_id2real_id(ids))
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_unlink(cr, uid, ids, self._name)
|
||||
else:
|
||||
ids = map(lambda x: common.caldav_id2real_id(x), ids)
|
||||
res = super(crm_meeting, self).unlink(cr, uid, ids)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_unlink(cr, uid, ids, self._name)
|
||||
return res
|
||||
|
||||
def create(self, cr, uid, vals, context={}):
|
||||
res = super(crm_meeting, self).create(cr, uid, vals, context)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date')
|
||||
return res
|
||||
|
||||
crm_meeting()
|
||||
|
||||
class res_users(osv.osv):
|
||||
_inherit = 'res.users'
|
||||
def _get_user_avail(self, cr, uid, ids, context=None):
|
||||
current_datetime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
res = super(res_users, self)._get_user_avail(cr, uid, ids, context)
|
||||
cr.execute("SELECT m.user_id, 'busy' as status \
|
||||
FROM crm_meeting m\
|
||||
where m.date <= %s and m.date_deadline >= %s \
|
||||
and m.user_id = ANY(%s) and m.show_as = %s",
|
||||
(current_datetime, current_datetime, ids, 'busy'))
|
||||
result = cr.dictfetchall()
|
||||
for user_data in result:
|
||||
user_id = user_data['user_id']
|
||||
status = user_data['status']
|
||||
res.update({user_id:status})
|
||||
return res
|
||||
res_users()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<group col="3" colspan="4" attrs="{'invisible':[('rrule_type','in', ('none', False))]}">
|
||||
<label string="" />
|
||||
<button string="Modify this Occurrence"
|
||||
name="%(crm.wizard_meeting_edit_this)d" icon="gtk-save"
|
||||
name="%(caldav.wizard_edit_this_event)d" icon="gtk-save"
|
||||
type="action" context="{'model' : 'crm.meeting'}" />
|
||||
</group>
|
||||
</form>
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<wizard string="Import ICS File" model="crm.meeting"
|
||||
name="caldav.crm.import" id="wizard_crm_cal_import" multi="True"
|
||||
/>
|
||||
|
||||
<wizard string="Subscribe to a Remote calendar" model="crm.meeting"
|
||||
name="caldav.crm.subscribe" id="wizard_crm_cal_subscribe" multi="True"
|
||||
/>
|
||||
|
||||
<wizard string="Export ICS File" model="crm.meeting"
|
||||
name="caldav.crm.export" id="wizard_crm_cal_export" multi="True" />
|
||||
<wizard string="Import .ics File" model="crm.meeting"
|
||||
name="caldav.event.import" id="caldav.wizard_cal_event_import" multi="True" />
|
||||
|
||||
<wizard string="Edit this meeting" model="crm.meeting"
|
||||
name="crm.meeting.edit.this" id="wizard_meeting_edit_this"
|
||||
<wizard string="Subscribe to a Remote calendar"
|
||||
model="crm.meeting" name="caldav.event.subscribe"
|
||||
id="caldav.wizard_cal_event_subscribe" multi="True" />
|
||||
|
||||
<wizard string="Export .ics File" model="crm.meeting"
|
||||
name="caldav.event.export" id="caldav.wizard_cal_event_export" multi="True" />
|
||||
|
||||
<wizard string="Edit this event" model="crm.meeting"
|
||||
name="calendar.event.edit.this" id="caldav.wizard_edit_this_event"
|
||||
menu="False" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
+443
-200
File diff suppressed because it is too large
Load Diff
@@ -22,14 +22,9 @@
|
||||
import crm_opportunity_wizard
|
||||
import crm_lead_wizard
|
||||
import crm_phonecall_wizard
|
||||
import crm_meeting_edit_wizard
|
||||
|
||||
|
||||
import wizard_crm_send_email
|
||||
import wizard_crm_new_send_email
|
||||
import wizard_cal_export
|
||||
import wizard_cal_import
|
||||
import wizard_cal_subscribe
|
||||
import wizard_history_event
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
# Brazilian Portuguese translation for openobject-addons
|
||||
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-12-08 11:46+0000\n"
|
||||
"PO-Revision-Date: 2010-01-20 00:41+0000\n"
|
||||
"Last-Translator: pedrobom <pedrobomlimeira@gmail.com>\n"
|
||||
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2010-01-20 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: multi_company
|
||||
#: help:multi_company.default,object_id:0
|
||||
msgid "Object affect by this rules"
|
||||
msgstr "Objeto afetado por esta regra"
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"O nome do Objeto deve iniciar com x_ e não conter nenhum caracter especial!"
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:product.template:0
|
||||
msgid ""
|
||||
"Error: The default UOM and the purchase UOM must be in the same category."
|
||||
msgstr ""
|
||||
"Erro: A unidade padrão e a unidade de compra devem ser da mesma categoria."
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:res.partner:0
|
||||
msgid "The VAT doesn't seem to be correct."
|
||||
msgstr "O imposto não parece estar correto."
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "Nome de modelo inválido na definição da ação"
|
||||
|
||||
#. module: multi_company
|
||||
#: model:res.company,overdue_msg:multi_company.res_company_odoo
|
||||
#: model:res.company,overdue_msg:multi_company.res_company_oerp_be
|
||||
#: model:res.company,overdue_msg:multi_company.res_company_oerp_editor
|
||||
#: model:res.company,overdue_msg:multi_company.res_company_oerp_in
|
||||
#: model:res.company,overdue_msg:multi_company.res_company_oerp_us
|
||||
msgid ""
|
||||
"Would your payment have been carried out after this mail was sent, please "
|
||||
"consider the present one as void. Do not hesitate to contact our accounting "
|
||||
"department"
|
||||
msgstr ""
|
||||
|
||||
#. module: multi_company
|
||||
#: field:multi_company.default,company_dest_id:0
|
||||
msgid "Default Company"
|
||||
msgstr "Empresa Padrão"
|
||||
|
||||
#. module: multi_company
|
||||
#: field:multi_company.default,object_id:0
|
||||
msgid "Object"
|
||||
msgstr "Objeto"
|
||||
|
||||
#. module: multi_company
|
||||
#: model:ir.module.module,shortdesc:multi_company.module_meta_information
|
||||
#: view:multi_company.default:0
|
||||
msgid "Multi Company"
|
||||
msgstr "Multi Empresa"
|
||||
|
||||
#. module: multi_company
|
||||
#: model:ir.module.module,description:multi_company.module_meta_information
|
||||
msgid ""
|
||||
"This module add the possibility to easily manage \n"
|
||||
" the default value for each object\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Este módulo acrescenta a possibilidade de gerenciar facilmente \n"
|
||||
" o valor padrão para cada objeto\n"
|
||||
" "
|
||||
|
||||
#. module: multi_company
|
||||
#: field:multi_company.default,company_id:0
|
||||
msgid "Main Company"
|
||||
msgstr "Empresa principal"
|
||||
|
||||
#. module: multi_company
|
||||
#: view:multi_company.default:0
|
||||
msgid "Condition"
|
||||
msgstr "Condição"
|
||||
|
||||
#. module: multi_company
|
||||
#: help:multi_company.default,company_dest_id:0
|
||||
msgid "Company to store the current record"
|
||||
msgstr "Empresa para guardar o registro atual"
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "XML inválido para Arquitetura da View"
|
||||
|
||||
#. module: multi_company
|
||||
#: field:multi_company.default,name:0
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:product.template:0
|
||||
msgid "Error: UOS must be in a different category than the UOM"
|
||||
msgstr ""
|
||||
"Erro: Unidade de venda deve ser de categoria diferente da unidade de medida"
|
||||
|
||||
#. module: multi_company
|
||||
#: model:product.category,name:multi_company.Odoo1
|
||||
msgid "Odoo Offers"
|
||||
msgstr ""
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:res.company:0
|
||||
msgid "Error! You can not create recursive companies."
|
||||
msgstr "Erro! Você não pode criar empresas recursivas."
|
||||
|
||||
#. module: multi_company
|
||||
#: help:multi_company.default,name:0
|
||||
msgid "Name it to easily find a record"
|
||||
msgstr ""
|
||||
|
||||
#. module: multi_company
|
||||
#: model:ir.ui.menu,name:multi_company.menu_custom_multicompany
|
||||
msgid "Multi company"
|
||||
msgstr "Multi empresa"
|
||||
|
||||
#. module: multi_company
|
||||
#: model:ir.model,name:multi_company.model_multi_company_default
|
||||
msgid "multi_company.default"
|
||||
msgstr ""
|
||||
|
||||
#. module: multi_company
|
||||
#: help:multi_company.default,company_id:0
|
||||
msgid "Company where the user is connected"
|
||||
msgstr "Empresa onde o usuário está conectado"
|
||||
|
||||
#. module: multi_company
|
||||
#: model:ir.actions.act_window,name:multi_company.action_inventory_form
|
||||
msgid "Default Company per Object"
|
||||
msgstr "Empresa Padrão por Objeto"
|
||||
|
||||
#. module: multi_company
|
||||
#: field:multi_company.default,expression:0
|
||||
msgid "Expression"
|
||||
msgstr "Expressão"
|
||||
|
||||
#. module: multi_company
|
||||
#: model:product.template,name:multi_company.product_product_odoo1_product_template
|
||||
msgid "Odoo Offer"
|
||||
msgstr ""
|
||||
|
||||
#. module: multi_company
|
||||
#: field:multi_company.default,sequence:0
|
||||
msgid "Sequence"
|
||||
msgstr "Seqüência"
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:product.category:0
|
||||
msgid "Error ! You can not create recursive categories."
|
||||
msgstr "Erro! Você não pode criar categorias recursivas."
|
||||
|
||||
#. module: multi_company
|
||||
#: constraint:product.product:0
|
||||
msgid "Error: Invalid ean code"
|
||||
msgstr "Erro: Código EAN inválido"
|
||||
|
||||
#. module: multi_company
|
||||
#: help:multi_company.default,expression:0
|
||||
msgid "Expression, must be True to match"
|
||||
msgstr ""
|
||||
|
||||
#. module: multi_company
|
||||
#: model:ir.ui.menu,name:multi_company.menu_action_inventory_form
|
||||
msgid "Default company per Object"
|
||||
msgstr "Empresa padrão por Objeto"
|
||||
|
||||
#. module: multi_company
|
||||
#: code:addons/multi_company/multi_company.py:0
|
||||
#, python-format
|
||||
msgid " (copy)"
|
||||
msgstr " (cópia)"
|
||||
|
||||
#. module: multi_company
|
||||
#: view:multi_company.default:0
|
||||
msgid "Matching"
|
||||
msgstr ""
|
||||
@@ -7,13 +7,13 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.0\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2009-09-08 13:19+0000\n"
|
||||
"Last-Translator: Pedro_Maschio <pedro.bicudo@tgtconsult.com.br>\n"
|
||||
"PO-Revision-Date: 2010-01-19 23:15+0000\n"
|
||||
"Last-Translator: pedrobom <pedrobomlimeira@gmail.com>\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: 2009-12-16 05:02+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-01-20 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: profile_accounting
|
||||
@@ -104,7 +104,7 @@ msgstr ""
|
||||
#. module: profile_accounting
|
||||
#: field:profile.accounting.config.install_modules_wizard,account_budget:0
|
||||
msgid "Budgets"
|
||||
msgstr ""
|
||||
msgstr "Orçamentos"
|
||||
|
||||
#. module: profile_accounting
|
||||
#: view:profile.accounting.config.install_modules_wizard:0
|
||||
@@ -119,7 +119,7 @@ msgstr ""
|
||||
#. module: profile_accounting
|
||||
#: model:ir.module.module,shortdesc:profile_accounting.module_meta_information
|
||||
msgid "Accounting only profile"
|
||||
msgstr ""
|
||||
msgstr "Perfil apenas contábil"
|
||||
|
||||
#. module: profile_accounting
|
||||
#: field:profile.accounting.config.install_modules_wizard,account_analytic_analysis:0
|
||||
@@ -129,7 +129,7 @@ msgstr ""
|
||||
#. module: profile_accounting
|
||||
#: field:profile.accounting.config.install_modules_wizard,board_document:0
|
||||
msgid "Document Management"
|
||||
msgstr ""
|
||||
msgstr "Gestão de Documentos"
|
||||
|
||||
#. module: profile_accounting
|
||||
#: model:ir.model,name:profile_accounting.model_profile_accounting_config_install_modules_wizard
|
||||
|
||||
@@ -41,8 +41,8 @@ works done on tasks, eso. It is able to render planning, order tasks, eso.
|
||||
"process/task_process.xml",
|
||||
"project_installer.xml",
|
||||
],
|
||||
'demo_xml': ['project_demo.xml'
|
||||
|
||||
'demo_xml': [
|
||||
'project_demo.xml'
|
||||
],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
|
||||
@@ -132,7 +132,7 @@ class project(osv.osv):
|
||||
# \n If it is to be reviewed then the state is \'Pending\'.\n When the project is completed the state is set to \'Done\'.'),
|
||||
# 'company_id': fields.many2one('res.company', 'Company'),
|
||||
# 'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="Timetable working hours to adjust the gantt diagram report"),
|
||||
'allowed_task_type': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Allowed Task Types'),
|
||||
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Allowed Task Types'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
@@ -489,35 +489,23 @@ class task(osv.osv):
|
||||
return True
|
||||
|
||||
def next_type(self, cr, uid, ids, *args):
|
||||
type_obj = self.pool.get('project.task.type')
|
||||
types = []
|
||||
for typ in self.browse(cr, uid, ids):
|
||||
typeid = typ.type.id
|
||||
types = map(lambda x:x.id, typ.project_id.allowed_task_type)
|
||||
types = map(lambda x:x.id, typ.project_id.type_ids)
|
||||
if types:
|
||||
if typeid and typeid in types and types.index(typeid) != len(types)-1 :
|
||||
index = types.index(typeid)
|
||||
else:
|
||||
index = -1
|
||||
self.write(cr, uid, typ.id, {'type': types[index+1]})
|
||||
else:
|
||||
self.write(cr, uid, typ.id, {'type': ''})
|
||||
self.write(cr, uid, typ.id, {'type': types[index+1]})
|
||||
return True
|
||||
|
||||
def prev_type(self, cr, uid, ids, *args):
|
||||
type_obj = self.pool.get('project.task.type')
|
||||
types = []
|
||||
for typ in self.browse(cr, uid, ids):
|
||||
typeid = typ.type.id
|
||||
types = map(lambda x:x.id, typ.project_id.allowed_task_type)
|
||||
types = map(lambda x:x.id, typ.project_id.type_ids)
|
||||
if types:
|
||||
if typeid and typeid in types and types.index(typeid) != 0 :
|
||||
index = types.index(typeid)
|
||||
else:
|
||||
index = len(types)
|
||||
self.write(cr, uid, typ.id, {'type': types[index-1]})
|
||||
else:
|
||||
self.write(cr, uid, typ.id, {'type': ''})
|
||||
self.write(cr, uid, typ.id, {'type': types[index-1]})
|
||||
return True
|
||||
|
||||
task()
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<field name="warn_manager">1</field>
|
||||
<field name="name">Open ERP Integration</field>
|
||||
<field name="manager" ref="base.user_root"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_specification'),ref('project_tt_development'),ref('project_tt_testing'),ref('project_tt_merge')])]" name="allowed_task_type"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_specification'),ref('project_tt_development'),ref('project_tt_testing'),ref('project_tt_merge')])]" name="type_ids"/>
|
||||
</record>
|
||||
<record id="project_project_21" model="project.project">
|
||||
<field name="warn_manager">1</field>
|
||||
@@ -41,7 +41,7 @@
|
||||
<field name="name">Study + Prototype</field>
|
||||
<field model="account.analytic.account" name="category_id" search="[('name','=', 'Seagate P1')]"/>
|
||||
<field name="manager" ref="base.user_root"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_specification'),ref('project_tt_development')])]" name="allowed_task_type"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_specification'),ref('project_tt_development')])]" name="type_ids"/>
|
||||
</record>
|
||||
<record id="project_project_22" model="project.project">
|
||||
<field name="priority">20</field>
|
||||
@@ -49,7 +49,7 @@
|
||||
<field name="name">Specific Developements</field>
|
||||
<field model="account.analytic.account" name="category_id" search="[('name','=', 'Seagate P1')]"/>
|
||||
<field name="manager" ref="base.user_root"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_specification'), ref('project_tt_development')])]" name="allowed_task_type"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_specification'), ref('project_tt_development')])]" name="type_ids"/>
|
||||
</record>
|
||||
<record id="project_project_23" model="project.project">
|
||||
<field name="priority">30</field>
|
||||
@@ -57,7 +57,7 @@
|
||||
<field name="name">Install, data import, configuration</field>
|
||||
<field model="account.analytic.account" name="category_id" search="[('name','=', 'Seagate P1')]"/>
|
||||
<field name="manager" ref="base.user_root"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_development')])]" name="allowed_task_type"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_development')])]" name="type_ids"/>
|
||||
</record>
|
||||
|
||||
<!-- Tasks -->
|
||||
|
||||
@@ -83,24 +83,9 @@
|
||||
<label string="Date Stop: %%(date_stop)s"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Tasks">
|
||||
<field name="tasks" nolabel="1" attrs="{'readonly':[('state','in',['cancelled','done'])]}" colspan="4">
|
||||
<tree colors="grey:state in ('cancelled','done');blue:remaining_hours<0;red:bool(date_deadline) and (date_deadline<current_date) and (state in ('draft','open'));black:state not in ('cancelled','done')" string="Tasks">
|
||||
<!-- <tree string="Tasks">-->
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="user_id" string="Project Manager"/>
|
||||
<field name="date_deadline"/>
|
||||
<field name="planned_hours" sum="Planned" widget="float_time"/>
|
||||
<field name="delay_hours" sum="Delay" widget="float_time"/>
|
||||
<field name="progress" widget="progressbar"/>
|
||||
<field name="priority"/>
|
||||
<field name="state"/>
|
||||
<field name="remaining_hours" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
<separator string="Allowed Task Types"/>
|
||||
<field nolabel="1" name="allowed_task_type" colspan="4" groups="base.group_extended"/>
|
||||
<page string="Tasks" groups="base.group_extended">
|
||||
<separator string="Task Types"/>
|
||||
<field nolabel="1" name="type_ids" colspan="4"/>
|
||||
</page>
|
||||
<page string="Notes">
|
||||
<field colspan="4" name="description" nolabel="1"/>
|
||||
@@ -353,7 +338,6 @@
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Dates" colspan="2"/>
|
||||
<field name="date_start" select="2"/>
|
||||
<field name="date_close" select="2"/>
|
||||
</group>
|
||||
<separator string="Miscelleanous" colspan="4"/>
|
||||
@@ -379,7 +363,7 @@
|
||||
<field eval="2" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="grey:state in ('cancelled','done');blue:remaining_hours<0;red:bool(date_deadline) and (date_deadline<current_date) and (state in ('draft','open'));black:state not in ('cancelled','done')" string="Tasks">
|
||||
<field name="sequence" string="Seq."/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="project_id" icon="gtk-indent"/>
|
||||
<field name="user_id"/>
|
||||
@@ -486,21 +470,19 @@
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Task Edition">
|
||||
<group col="8" colspan="4">
|
||||
<group col="20" colspan="4">
|
||||
<filter string="By Users" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="By Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>
|
||||
<filter string="By Type" icon="terp-project" domain="[]" context="{'group_by':'type'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Tasks" icon="terp-project"/>
|
||||
<filter string="In Progress" domain="[('state','=','open')]" help="Open Tasks" icon="terp-project"/>
|
||||
<filter string="Pending" domain="[('state','=','pending')]" help="Pending Tasks" icon="terp-project"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="type" select="1" widget="selection"/>
|
||||
<field name="project_id" select="1" widget="selection">
|
||||
<filter domain="[('manager_id','=',False)]" help="Unassigned Project" icon="terp-project"/>
|
||||
</field>
|
||||
<filter string="By Users" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="By Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>
|
||||
<filter string="By Type" icon="terp-project" domain="[]" context="{'group_by':'type'}"/>
|
||||
</group>
|
||||
<group col="4" colspan="1">
|
||||
<field name="user_id" select="1" widget="selection">
|
||||
<filter domain="[('user_id','=',uid)]" help="My Tasks" icon="gtk-execute" default="1"/>
|
||||
<filter domain="[('user_id','=',False)]" help="Unassigned Tasks" icon="gtk-execute" separator="1"/>
|
||||
|
||||
@@ -20,6 +20,5 @@
|
||||
##############################################################################
|
||||
|
||||
import project_calendar
|
||||
import wizard
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -19,301 +19,14 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from caldav import common
|
||||
from datetime import datetime
|
||||
from osv import fields, osv
|
||||
from service import web_services
|
||||
import base64
|
||||
import re
|
||||
import time
|
||||
|
||||
class project_task(osv.osv):
|
||||
_inherit = "project.task"
|
||||
|
||||
_name = "project.task"
|
||||
_inherit = ["calendar.todo", "project.task"]
|
||||
_columns = {
|
||||
'class': fields.selection([('public', 'Public'), ('private', 'Private'), \
|
||||
('confidential', 'Confidential')], 'Mark as'),
|
||||
'location': fields.char('Location', size=264, help="Location of Task"),
|
||||
'exdate': fields.text('Exception Date/Times', help="This property \
|
||||
defines the list of date/time exceptions for arecurring calendar component."),
|
||||
'exrule': fields.char('Exception Rule', size=352, help="defines a rule\
|
||||
or repeating pattern for anexception to a recurrence set"),
|
||||
'attendee_ids': fields.many2many('calendar.attendee', 'task_attendee_rel', 'task_id', 'attendee_id', 'Attendees'),
|
||||
'caldav_url': fields.char('Calendar URL', size=34),
|
||||
'rrule': fields.char('Recurrent Rule', size=124),
|
||||
'rrule_type': fields.selection([('none', 'None'), ('daily', 'Daily'), \
|
||||
('weekly', 'Weekly'), ('monthly', 'Monthly'), \
|
||||
('yearly', 'Yearly'), ('custom', 'Custom')], 'Recurrency'),
|
||||
'alarm_id': fields.many2one('res.alarm', 'Alarm'),
|
||||
'caldav_alarm_id': fields.many2one('calendar.alarm', 'Alarm'),
|
||||
}
|
||||
|
||||
__attribute__ = {
|
||||
'class': {'field': 'class', 'type': 'text'},
|
||||
'completed': {'field': 'date_close', 'type': 'datetime'},
|
||||
# 'created': {'field': 'field', 'type': 'text'},
|
||||
'description': {'field': 'description', 'type': 'text'},
|
||||
# 'dtstamp': {'field': 'field', 'type': 'text'},
|
||||
'dtstart': {'field': 'date_start', 'type': 'datetime'},
|
||||
'duration': {'field': 'planned_hours', 'type': 'timedelta'},
|
||||
'due': {'field': 'date_deadline', 'type': 'datetime'},
|
||||
# 'geo': {'field': 'field', 'type': 'text'},
|
||||
# 'last-mod ': {'field': 'field', 'type': 'text'},
|
||||
'location': {'field': 'location', 'type': 'text'},
|
||||
'organizer': {'field': 'partner_id', 'type': 'many2one', 'object': 'res.partner'},
|
||||
'percent': {'field': 'progress_rate', 'type': 'int'},
|
||||
'priority': {'field': 'priority', 'type': 'text'},
|
||||
# 'recurid': {'field': 'field', 'type': 'text'},
|
||||
'seq': {'field': 'sequence', 'type': 'text'},
|
||||
'status': {'field': 'state', 'type': 'selection', \
|
||||
'mapping': {'needs-action': 'draft', \
|
||||
'completed': 'done', 'in-process': 'open', \
|
||||
'cancelled': 'cancelled'}},
|
||||
'summary': {'field': 'name', 'type': 'text'},
|
||||
'uid': {'field': 'id', 'type': 'int'},
|
||||
'url': {'field': 'caldav_url', 'type': 'text'},
|
||||
# 'attach': {'field': 'field', 'type': 'text'},
|
||||
'attendee': {'field': 'attendee_ids', 'type': 'many2many', 'object': 'calendar.attendee'},
|
||||
'comment': {'field': 'notes', 'type': 'text'},
|
||||
# 'contact': {'field': 'field', 'type': 'text'},
|
||||
'exdate': {'field':'exdate', 'type':'datetime'},
|
||||
'exrule': {'field':'exrule', 'type':'text'},
|
||||
# 'rstatus': {'field': 'field', 'type': 'text'},
|
||||
# 'related': {'field': 'field', 'type': 'text'},
|
||||
# 'resources': {'field': 'field', 'type': 'text'},
|
||||
# 'rdate': {'field': 'field', 'type': 'text'},
|
||||
'rrule': {'field': 'rrule', 'type': 'text'},
|
||||
'valarm': {'field':'caldav_alarm_id', 'type':'many2one', 'object': 'calendar.alarm'},
|
||||
}
|
||||
def onchange_rrule_type(self, cr, uid, ids, type, *args, **argv):
|
||||
if type == 'none':
|
||||
return {'value': {'rrule': ''}}
|
||||
if type == 'custom':
|
||||
return {}
|
||||
rrule = self.pool.get('calendar.custom.rrule')
|
||||
rrulestr = rrule.compute_rule_string(cr, uid, {'freq': type.upper(), \
|
||||
'interval': 1})
|
||||
return {'value': {'rrule': rrulestr}}
|
||||
|
||||
def import_cal(self, cr, uid, data, context={}):
|
||||
file_content = base64.decodestring(data)
|
||||
todo_obj = self.pool.get('basic.calendar.todo')
|
||||
todo_obj.__attribute__.update(self.__attribute__)
|
||||
|
||||
attendee_obj = self.pool.get('basic.calendar.attendee')
|
||||
crm_attendee = self.pool.get('calendar.attendee')
|
||||
attendee_obj.__attribute__.update(crm_attendee.__attribute__)
|
||||
|
||||
alarm_obj = self.pool.get('basic.calendar.alarm')
|
||||
crm_alarm = self.pool.get('calendar.alarm')
|
||||
alarm_obj.__attribute__.update(crm_alarm.__attribute__)
|
||||
|
||||
vals = todo_obj.import_ical(cr, uid, file_content)
|
||||
for val in vals:
|
||||
obj_tm = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.project_time_mode_id
|
||||
if not val.has_key('planned_hours'):
|
||||
# 'Computes duration' in days
|
||||
start = datetime.strptime(val['date_start'], '%Y-%m-%d %H:%M:%S')
|
||||
end = datetime.strptime(val['date_deadline'], '%Y-%m-%d %H:%M:%S')
|
||||
diff = end - start
|
||||
plan = (diff.seconds/float(86400) + diff.days) * obj_tm.factor
|
||||
val['planned_hours'] = plan
|
||||
else:
|
||||
# Converts timedelta into hours
|
||||
hours = (val['planned_hours'].seconds / float(3600)) + \
|
||||
(val['planned_hours'].days * 24)
|
||||
val['planned_hours'] = hours
|
||||
is_exists = common.uid2openobjectid(cr, val['id'], self._name)
|
||||
val.pop('id')
|
||||
if is_exists:
|
||||
self.write(cr, uid, [is_exists], val)
|
||||
else:
|
||||
task_id = self.create(cr, uid, val)
|
||||
return {'count': len(vals)}
|
||||
|
||||
def export_cal(self, cr, uid, ids, context={}):
|
||||
task_datas = self.read(cr, uid, ids, [], context ={'read': True})
|
||||
tasks = []
|
||||
for task in task_datas:
|
||||
if task.get('planned_hours', None) and task.get('date_deadline', None):
|
||||
task.pop('planned_hours')
|
||||
tasks.append(task)
|
||||
todo_obj = self.pool.get('basic.calendar.todo')
|
||||
todo_obj.__attribute__.update(self.__attribute__)
|
||||
|
||||
attendee_obj = self.pool.get('basic.calendar.attendee')
|
||||
attendee = self.pool.get('calendar.attendee')
|
||||
attendee_obj.__attribute__.update(attendee.__attribute__)
|
||||
|
||||
alarm_obj = self.pool.get('basic.calendar.alarm')
|
||||
alarm = self.pool.get('calendar.alarm')
|
||||
alarm_obj.__attribute__.update(alarm.__attribute__)
|
||||
|
||||
ical = todo_obj.export_ical(cr, uid, tasks, {'model': 'project.task'})
|
||||
caendar_val = ical.serialize()
|
||||
caendar_val = caendar_val.replace('"', '').strip()
|
||||
return caendar_val
|
||||
|
||||
def get_recurrent_ids(self, cr, uid, select, base_start_date, base_until_date, limit=100):
|
||||
if not limit:
|
||||
limit = 100
|
||||
if isinstance(select, (str, int, long)):
|
||||
ids = [select]
|
||||
else:
|
||||
ids = select
|
||||
result = []
|
||||
if ids and (base_start_date or base_until_date):
|
||||
cr.execute("select t.id, t.rrule, t.date_start, t.exdate \
|
||||
from project_task t\
|
||||
where t.id in ("+ ','.join(map(lambda x: str(x), ids))+")")
|
||||
|
||||
count = 0
|
||||
for data in cr.dictfetchall():
|
||||
start_date = base_start_date and datetime.strptime(base_start_date, "%Y-%m-%d") or False
|
||||
until_date = base_until_date and datetime.strptime(base_until_date, "%Y-%m-%d") or False
|
||||
if count > limit:
|
||||
break
|
||||
event_date = datetime.strptime(data['date_start'], "%Y-%m-%d %H:%M:%S")
|
||||
if start_date and start_date <= event_date:
|
||||
start_date = event_date
|
||||
if not data['rrule']:
|
||||
if start_date and event_date < start_date:
|
||||
continue
|
||||
if until_date and event_date > until_date:
|
||||
continue
|
||||
idval = common.real_id2caldav_id(data['id'], data['date_start'])
|
||||
result.append(idval)
|
||||
count += 1
|
||||
else:
|
||||
exdate = data['exdate'] and data['exdate'].split(',') or []
|
||||
event_obj = self.pool.get('basic.calendar.event')
|
||||
rrule_str = data['rrule']
|
||||
new_rrule_str = []
|
||||
rrule_until_date = False
|
||||
is_until = False
|
||||
for rule in rrule_str.split(';'):
|
||||
name, value = rule.split('=')
|
||||
if name == "UNTIL":
|
||||
is_until = True
|
||||
value = parser.parse(value)
|
||||
rrule_until_date = parser.parse(value.strftime("%Y-%m-%d"))
|
||||
if until_date and until_date >= rrule_until_date:
|
||||
until_date = rrule_until_date
|
||||
if until_date:
|
||||
value = until_date.strftime("%Y%m%d%H%M%S")
|
||||
new_rule = '%s=%s' % (name, value)
|
||||
new_rrule_str.append(new_rule)
|
||||
if not is_until and until_date:
|
||||
value = until_date.strftime("%Y%m%d%H%M%S")
|
||||
name = "UNTIL"
|
||||
new_rule = '%s=%s' % (name, value)
|
||||
new_rrule_str.append(new_rule)
|
||||
new_rrule_str = ';'.join(new_rrule_str)
|
||||
start_date = datetime.strptime(data['date_start'], "%Y-%m-%d %H:%M:%S")
|
||||
rdates = event_obj.get_recurrent_dates(str(new_rrule_str), exdate, start_date)
|
||||
for rdate in rdates:
|
||||
r_date = datetime.strptime(rdate, "%Y-%m-%d %H:%M:%S")
|
||||
if start_date and r_date < start_date:
|
||||
continue
|
||||
if until_date and r_date > until_date:
|
||||
continue
|
||||
idval = common.real_id2caldav_id(data['id'], rdate)
|
||||
result.append(idval)
|
||||
count += 1
|
||||
if result:
|
||||
ids = result
|
||||
if isinstance(select, (str, int, long)):
|
||||
return ids and ids[0] or False
|
||||
return ids
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=100, order=None,
|
||||
context=None, count=False):
|
||||
args_without_date = []
|
||||
start_date = False
|
||||
until_date = False
|
||||
for arg in args:
|
||||
if arg[0] not in ('date_start', unicode('date_start')):
|
||||
args_without_date.append(arg)
|
||||
else:
|
||||
if arg[1] in ('>', '>='):
|
||||
start_date = arg[2]
|
||||
elif arg[1] in ('<', '<='):
|
||||
until_date = arg[2]
|
||||
res = super(project_task, self).search(cr, uid, args_without_date, offset,
|
||||
limit, order, context, count)
|
||||
return self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit)
|
||||
|
||||
def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
select = map(lambda x: (x, common.caldav_id2real_id(x)), select)
|
||||
result = []
|
||||
if fields and 'date_start' not in fields:
|
||||
fields.append('date_start')
|
||||
for caldav_id, real_id in select:
|
||||
res = super(project_task, self).read(cr, uid, real_id, fields=fields, context=context, load=load)
|
||||
ls = common.caldav_id2real_id(caldav_id, with_date=True)
|
||||
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
|
||||
res['date_start'] = ls[1]
|
||||
res['id'] = caldav_id
|
||||
|
||||
result.append(res)
|
||||
if isinstance(ids, (str, int, long)):
|
||||
return result and result[0] or False
|
||||
return result
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
new_ids = []
|
||||
for id in select:
|
||||
id = common.caldav_id2real_id(id)
|
||||
if not id in new_ids:
|
||||
new_ids.append(id)
|
||||
res = super(project_task, self).write(cr, uid, new_ids, vals, context=context)
|
||||
if vals.get('alarm_id'):
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, new_ids, self._name, 'date_start')
|
||||
return res
|
||||
|
||||
def browse(self, cr, uid, ids, context=None, list_class=None, fields_process={}):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
select = map(lambda x:common.caldav_id2real_id(x), select)
|
||||
res = super(project_task, self).browse(cr, uid, select, context, list_class, fields_process)
|
||||
if isinstance(ids, (str, int, long)):
|
||||
return res and res[0] or False
|
||||
return res
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
res = super(project_task, self).copy(cr, uid, common.caldav_id2real_id(id), default, context)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date_start')
|
||||
return res
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
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, [common.caldav_id2real_id(id)], \
|
||||
['date_start', 'rrule', 'exdate']):
|
||||
if record['rrule']:
|
||||
exdate = (record['exdate'] and (record['exdate'] + ',') or '') + \
|
||||
''.join((re.compile('\d')).findall(date_new)) + 'Z'
|
||||
if record['date_start'] == date_new:
|
||||
self.write(cr, uid, [common.caldav_id2real_id(id)], {'exdate': exdate})
|
||||
else:
|
||||
ids = map(lambda x:common.caldav_id2real_id(x), ids)
|
||||
return super(project_task, self).unlink(cr, uid, ids)
|
||||
else:
|
||||
return super(project_task, self).unlink(cr, uid, ids)
|
||||
'attendee_ids': fields.many2many('calendar.attendee', 'task_attendee_rel', 'task_id', 'attendee_id', 'Attendees'),
|
||||
}
|
||||
|
||||
project_task()
|
||||
|
||||
|
||||
@@ -2,18 +2,6 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="caldav_project_task_view" model="ir.ui.view">
|
||||
<field name="name">project.task.caldav.tree</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="inherit_id" ref="project.view_task_tree2"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="sequence" position="before">
|
||||
<field name="id" widget="char"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_caldav_task_form" model="ir.ui.view">
|
||||
<field name="name">project.task.caldav.form</field>
|
||||
<field name="model">project.task</field>
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
<openerp>
|
||||
<data>
|
||||
<wizard string="Import ICS File" model="project.task"
|
||||
name="caldav.project.import" id="wizard_project_cal_import"
|
||||
multi="True"
|
||||
/>
|
||||
<wizard string="Export ICS File" model="project.task"
|
||||
name="caldav.project.export" id="wizard_project_cal_export"
|
||||
multi="True"
|
||||
/>
|
||||
|
||||
<wizard string="Subscribe to a Remote calendar" model="project.task"
|
||||
name="caldav.project.subscribe" id="wizard_project_cal_subscribe" multi="True"
|
||||
/>
|
||||
|
||||
<wizard string="Set RRULE" model="crm.case"
|
||||
name="caldav.set.rrule" id="wizard_crm_set_rrule" menu="False"
|
||||
/>
|
||||
<wizard string="Import .ics File" model="project.task"
|
||||
name="caldav.event.import" id="caldav.wizard_cal_event_import" multi="True" />
|
||||
|
||||
<wizard string="Subscribe to a Remote calendar"
|
||||
model="project.task" name="caldav.event.subscribe"
|
||||
id="caldav.wizard_cal_event_subscribe" multi="True" />
|
||||
|
||||
<wizard string="Export .ics File" model="project.task"
|
||||
name="caldav.event.export" id="caldav.wizard_cal_event_export" multi="True" />
|
||||
|
||||
<wizard string="Edit this event" model="project.task"
|
||||
name="calendar.event.edit.this" id="caldav.wizard_edit_this_event"
|
||||
menu="False" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -1,65 +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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import base64
|
||||
import pooler
|
||||
|
||||
|
||||
class project_cal_export_wizard(wizard.interface):
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="Export ICS">
|
||||
<field name="name"/>
|
||||
<field name="file_path" colspan="4" width="300"/>
|
||||
</form>'''
|
||||
|
||||
form1_fields = {
|
||||
'file_path': {
|
||||
'string': 'Save ICS file',
|
||||
'type': 'binary',
|
||||
'required' : True,
|
||||
'filters' : '*.ics'
|
||||
},
|
||||
'name': {
|
||||
'string': 'File name',
|
||||
'type': 'char',
|
||||
'size': 34,
|
||||
'required': True,
|
||||
'help': 'Save in .ics format'},
|
||||
}
|
||||
|
||||
def _process_export_ics(self, cr, uid, data, context):
|
||||
task_obj = pooler.get_pool(cr.dbname).get('project.task')
|
||||
calendar = task_obj.export_cal(cr, uid, data['ids'], context)
|
||||
return {'file_path': base64.encodestring(calendar), \
|
||||
'name': 'OpenERP Tasks.ics'}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_process_export_ics],
|
||||
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, \
|
||||
'state': [('end', '_Cancel', 'gtk-cancel'), ('end', 'Ok', 'gtk-ok')]}
|
||||
},
|
||||
}
|
||||
|
||||
project_cal_export_wizard('caldav.project.export')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -1,85 +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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import pooler
|
||||
|
||||
class project_cal_imp_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'
|
||||
}
|
||||
}
|
||||
display = '''<?xml version="1.0"?>
|
||||
<form string="Import Message">
|
||||
<field name="msg" colspan="4" width="300" nolabel="1"/>
|
||||
</form>'''
|
||||
|
||||
display_fields = {
|
||||
'msg': {
|
||||
'string': '',
|
||||
'type': 'text',
|
||||
'readonly': True,
|
||||
'default': 'Imported %s Tasks'
|
||||
}
|
||||
}
|
||||
|
||||
def _process_imp_ics(self, cr, uid, data, context=None):
|
||||
task_obj = pooler.get_pool(cr.dbname).get('project.task')
|
||||
vals = task_obj.import_cal(cr, uid, data['form']['file_path'], context)
|
||||
global cnt
|
||||
cnt = 0
|
||||
if vals:
|
||||
cnt = vals['count']
|
||||
return {}
|
||||
|
||||
def _result_set(self, cr, uid, data, context=None):
|
||||
return {'msg': 'Imported %s Task(s)' % cnt}
|
||||
|
||||
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_imp_ics, 'state': 'display'}
|
||||
},
|
||||
'display': {
|
||||
'actions': [_result_set],
|
||||
'result': {'type': 'form', 'arch': display, 'fields': display_fields, \
|
||||
'state': [('end', 'Ok', 'gtk-ok')]}
|
||||
},
|
||||
}
|
||||
|
||||
project_cal_imp_wizard('caldav.project.import')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -1,95 +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 tools.translate import _
|
||||
import base64
|
||||
import pooler
|
||||
import urllib
|
||||
import wizard
|
||||
|
||||
class project_cal_subscribe_wizard(wizard.interface):
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="Subscribe to Remote ICS">
|
||||
<separator string="Provide path for Remote Calendar"/>
|
||||
<field name="url_path" colspan="4" width="300" nolabel="1" widget="url"/>
|
||||
</form>'''
|
||||
|
||||
form1_fields = {
|
||||
'url_path': {
|
||||
'string': 'Provide path for remote calendar',
|
||||
'type': 'char',
|
||||
'required': True,
|
||||
'size': 124
|
||||
}
|
||||
}
|
||||
display = '''<?xml version="1.0"?>
|
||||
<form string="Message...">
|
||||
<field name="msg" colspan="4" width="300" nolabel="1"/>
|
||||
</form>'''
|
||||
|
||||
display_fields = {
|
||||
'msg': {
|
||||
'string': '',
|
||||
'type': 'text',
|
||||
'readonly': True,
|
||||
}
|
||||
}
|
||||
|
||||
def _process_imp_ics(self, cr, uid, data, context=None):
|
||||
global cnt
|
||||
cnt = 0
|
||||
try:
|
||||
f = urllib.urlopen(data['form']['url_path'])
|
||||
caldata= f.fp.read()
|
||||
f.close()
|
||||
except Exception,e:
|
||||
raise wizard.except_wizard(_('Error!'), _('Please provide Proper URL !'))
|
||||
|
||||
task_obj = pooler.get_pool(cr.dbname).get('project.task')
|
||||
context.update({'url': data['form']['url_path']})
|
||||
vals = task_obj.import_cal(cr, uid, base64.encodestring(caldata), context)
|
||||
if vals:
|
||||
cnt = vals['count']
|
||||
return {}
|
||||
|
||||
def _result_set(self, cr, uid, data, context=None):
|
||||
return {'msg': 'Subscribed %s Task(s)' % cnt}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type': 'form', 'arch': form1, 'fields': form1_fields, \
|
||||
'state': [('end', '_Cancel', 'gtk-cancel'), ('open', '_Subscribe', 'gtk-ok')]}
|
||||
},
|
||||
'open': {
|
||||
'actions': [],
|
||||
'result': {'type': 'action', 'action': _process_imp_ics, 'state': 'display'}
|
||||
},
|
||||
'display': {
|
||||
'actions': [_result_set],
|
||||
'result': {'type': 'form', 'arch': display, 'fields': display_fields, \
|
||||
'state': [('end', 'Ok', 'gtk-ok')]}
|
||||
},
|
||||
}
|
||||
|
||||
project_cal_subscribe_wizard('caldav.project.subscribe')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
Reference in New Issue
Block a user