Merge with trunk addons
bzr revid: vir@tinyerp.com-20100120065611-inrbplhiwq2p5tg5
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
|
||||
|
||||
{
|
||||
"name" : "Accounting and financial management",
|
||||
"name" : "Accounting and Financial Management",
|
||||
"version" : "1.1",
|
||||
"depends" : ["product", "base", "process"],
|
||||
"author" : "Tiny",
|
||||
|
||||
+11
-11
@@ -29,17 +29,17 @@ from mx.DateTime import RelativeDateTime
|
||||
from tools import config
|
||||
from tools.translate import _
|
||||
|
||||
class fiscalyear_seq(osv.osv):
|
||||
_name = "fiscalyear.seq"
|
||||
_description = "Maintains Invoice sequences with Fiscal Year"
|
||||
_rec_name = 'fiscalyear_id'
|
||||
_columns = {
|
||||
'journal_id': fields.many2one('account.journal', 'Journal'),
|
||||
'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year',required=True),
|
||||
'sequence_id':fields.many2one('ir.sequence', 'Sequence',required=True),
|
||||
}
|
||||
|
||||
fiscalyear_seq()
|
||||
#class fiscalyear_seq(osv.osv):
|
||||
# _name = "fiscalyear.seq"
|
||||
# _description = "Maintains Invoice sequences with Fiscal Year"
|
||||
# _rec_name = 'fiscalyear_id'
|
||||
# _columns = {
|
||||
# 'journal_id': fields.many2one('account.journal', 'Journal'),
|
||||
# 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year',required=True),
|
||||
# 'sequence_id':fields.many2one('ir.sequence', 'Sequence',required=True),
|
||||
# }
|
||||
#
|
||||
#fiscalyear_seq()
|
||||
|
||||
class account_invoice(osv.osv):
|
||||
def _amount_all(self, cr, uid, ids, name, args, context=None):
|
||||
|
||||
@@ -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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
@@ -41,7 +41,7 @@ class account_analytic_account(osv.osv):
|
||||
where_date += " AND l.date >= '" + context['from_date'] + "'"
|
||||
if context.get('to_date',False):
|
||||
where_date += " AND l.date <= '" + context['to_date'] + "'"
|
||||
|
||||
|
||||
cr.execute("SELECT a.id, COALESCE(SUM(l.amount),0) FROM account_analytic_account a LEFT JOIN account_analytic_line l ON (a.id=l.account_id %s) WHERE l.amount<0 and a.id IN (%s) GROUP BY a.id" % (where_date,acc_set))
|
||||
r = dict(cr.fetchall())
|
||||
for i in ids:
|
||||
@@ -51,13 +51,13 @@ class account_analytic_account(osv.osv):
|
||||
def _debit_calc(self, cr, uid, ids, name, arg, context={}):
|
||||
|
||||
acc_set = ",".join(map(str, ids))
|
||||
|
||||
|
||||
where_date = ''
|
||||
if context.get('from_date',False):
|
||||
where_date += " AND l.date >= '" + context['from_date'] + "'"
|
||||
if context.get('to_date',False):
|
||||
where_date += " AND l.date <= '" + context['to_date'] + "'"
|
||||
|
||||
|
||||
cr.execute("SELECT a.id, COALESCE(SUM(l.amount),0) FROM account_analytic_account a LEFT JOIN account_analytic_line l ON (a.id=l.account_id %s) WHERE l.amount>0 and a.id IN (%s) GROUP BY a.id" % (where_date,acc_set))
|
||||
r= dict(cr.fetchall())
|
||||
for i in ids:
|
||||
@@ -68,21 +68,21 @@ class account_analytic_account(osv.osv):
|
||||
res = {}
|
||||
ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)])
|
||||
acc_set = ",".join(map(str, ids2))
|
||||
|
||||
|
||||
for i in ids:
|
||||
res.setdefault(i,0.0)
|
||||
|
||||
|
||||
if not acc_set:
|
||||
return res
|
||||
|
||||
|
||||
where_date = ''
|
||||
if context.get('from_date',False):
|
||||
where_date += " AND l.date >= '" + context['from_date'] + "'"
|
||||
if context.get('to_date',False):
|
||||
where_date += " AND l.date <= '" + context['to_date'] + "'"
|
||||
|
||||
|
||||
cr.execute("SELECT a.id, COALESCE(SUM(l.amount),0) FROM account_analytic_account a LEFT JOIN account_analytic_line l ON (a.id=l.account_id %s) WHERE a.id IN (%s) GROUP BY a.id" % (where_date,acc_set))
|
||||
|
||||
|
||||
for account_id, sum in cr.fetchall():
|
||||
res[account_id] = sum
|
||||
|
||||
@@ -115,19 +115,19 @@ class account_analytic_account(osv.osv):
|
||||
res = {}
|
||||
ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)])
|
||||
acc_set = ",".join(map(str, ids2))
|
||||
|
||||
|
||||
for i in ids:
|
||||
res.setdefault(i,0.0)
|
||||
|
||||
|
||||
if not acc_set:
|
||||
return res
|
||||
|
||||
|
||||
where_date = ''
|
||||
if context.get('from_date',False):
|
||||
where_date += " AND l.date >= '" + context['from_date'] + "'"
|
||||
if context.get('to_date',False):
|
||||
where_date += " AND l.date <= '" + context['to_date'] + "'"
|
||||
|
||||
|
||||
cr.execute('SELECT a.id, COALESCE(SUM(l.unit_amount), 0) \
|
||||
FROM account_analytic_account a \
|
||||
LEFT JOIN account_analytic_line l ON (a.id = l.account_id ' + where_date + ') \
|
||||
@@ -168,10 +168,10 @@ class account_analytic_account(osv.osv):
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'name' : fields.char('Account Name', size=64, required=True),
|
||||
'name' : fields.char('Account Name', size=128, required=True),
|
||||
'complete_name': fields.function(_complete_name_calc, method=True, type='char', string='Full Account Name'),
|
||||
'code' : fields.char('Account Code', size=24),
|
||||
'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the analytic account without removing it."),
|
||||
# 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the analytic account without removing it."),
|
||||
'type': fields.selection([('view','View'), ('normal','Normal')], 'Account Type'),
|
||||
'description' : fields.text('Description'),
|
||||
'parent_id': fields.many2one('account.analytic.account', 'Parent Analytic Account', select=2),
|
||||
@@ -189,11 +189,13 @@ class account_analytic_account(osv.osv):
|
||||
'date': fields.date('Date End'),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True),
|
||||
'company_currency_id': fields.function(_get_company_currency, method=True, type='many2one', relation='res.currency', string='Currency'),
|
||||
'state': fields.selection([('draft','Draft'), ('open','Open'), ('pending','Pending'), ('close','Close'),], 'State', required=True,
|
||||
'state': fields.selection([('draft','Draft'),('open','Open'), ('pending','Pending'),('cancelled', 'Cancelled'),('close','Close'),('template', 'Template')], 'State', required=True,readonly=True,
|
||||
help='* When an account is created its in \'Draft\' state.\
|
||||
\n* If any associated partner is there, it can be in \'Open\' state.\
|
||||
\n* If any pending balance is there it can be in \'Pending\'. \
|
||||
\n* And finally when all the transactions are over, it can be in \'Close\' state.'),
|
||||
\n* And finally when all the transactions are over, it can be in \'Close\' state. \
|
||||
\n* The project can be in either if the states \'Template\' and \'Running\'.\n If it is template then we can make projects based on the template projects. If its in \'Running\' state it is a normal project.\
|
||||
\n If it is to be reviewed then the state is \'Pending\'.\n When the project is completed the state is set to \'Done\'.'),
|
||||
}
|
||||
|
||||
def _default_company(self, cr, uid, context={}):
|
||||
@@ -202,13 +204,14 @@ class account_analytic_account(osv.osv):
|
||||
return user.company_id.id
|
||||
return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
|
||||
_defaults = {
|
||||
'active' : lambda *a : True,
|
||||
# 'active' : lambda *a : True,
|
||||
'type' : lambda *a : 'normal',
|
||||
'company_id': _default_company,
|
||||
'state' : lambda *a : 'draft',
|
||||
'state' : lambda *a : 'open',
|
||||
'user_id' : lambda self,cr,uid,ctx : uid,
|
||||
'partner_id': lambda self,cr, uid, ctx: ctx.get('partner_id', False),
|
||||
'contact_id': lambda self,cr, uid, ctx: ctx.get('contact_id', False),
|
||||
'date_start': lambda *a: time.strftime('%Y-%m-%d')
|
||||
}
|
||||
|
||||
def check_recursion(self, cr, uid, ids, parent=None):
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<newline/>
|
||||
<field name="date_start"/>
|
||||
<field name="date" select="2"/>
|
||||
<field name="active" select="2"/>
|
||||
|
||||
<newline/>
|
||||
<field name="quantity_max"/>
|
||||
<field name="user_id"/>
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
"access_account_fiscal_position","account.fiscal.position all","model_account_fiscal_position","base.group_user",1,0,0,0
|
||||
"access_account_fiscal_position_tax","account.fiscal.position.tax all","model_account_fiscal_position_tax","base.group_user",1,0,0,0
|
||||
"access_account_fiscal_position_account","account.fiscal.position all","model_account_fiscal_position_account","base.group_user",1,0,0,0
|
||||
"access_fiscalyear_seq","fiscalyear.seq","model_fiscalyear_seq","account.group_account_invoice",1,1,1,1
|
||||
"access_account_fiscal_position_template","account.fiscal.position.template","model_account_fiscal_position_template","account.group_account_manager",1,1,1,1
|
||||
"access_account_fiscal_position_tax_template","account.fiscal.position.tax.template","model_account_fiscal_position_tax_template","account.group_account_manager",1,1,1,1
|
||||
"access_account_fiscal_position_account_template","account.fiscal.position.account.template","model_account_fiscal_position_account_template","account.group_account_manager",1,1,1,1
|
||||
|
||||
|
@@ -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
|
||||
|
||||
@@ -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-11-17 09:09+0000\n"
|
||||
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
|
||||
"PO-Revision-Date: 2010-01-18 23:06+0000\n"
|
||||
"Last-Translator: Holverat <holverat@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:19+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-01-20 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: auction
|
||||
@@ -50,7 +50,7 @@ msgstr ""
|
||||
#: selection:auction.lots.send.aie,date_ask,numerotation:0
|
||||
#: selection:auction.lots.send.aie,init,numerotation:0
|
||||
msgid "Provisoire"
|
||||
msgstr ""
|
||||
msgstr "Provisório"
|
||||
|
||||
#. module: auction
|
||||
#: selection:auction.lots.send.aie,date_ask,numerotation:0
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -312,6 +312,7 @@
|
||||
</record>
|
||||
|
||||
|
||||
<!--
|
||||
<record id='view_partner_address_form_inherited5' model='ir.ui.view'>
|
||||
<field name='name'>res.partner.address.form.inherited5</field>
|
||||
<field name='model'>res.partner.address</field>
|
||||
@@ -319,7 +320,7 @@
|
||||
<field name='type'>form</field>
|
||||
<field name='arch' type='xml'>
|
||||
<group string="Communication" colspan="2" col="2" position="after">
|
||||
<newline/>
|
||||
<newline/>
|
||||
<field name="job_ids" mode="tree,form" colspan="4">
|
||||
<tree string="Contacts" editable="top">
|
||||
<field name="contact_id"/>
|
||||
@@ -341,17 +342,18 @@
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<record id="view_res_partner_address_filter" model="ir.ui.view">
|
||||
<field name="name">res.partner.address.select</field>
|
||||
<field name="model">res.partner.address</field>
|
||||
<field name="type">search</field>
|
||||
<field name="inherit_id" ref="base.view_res_partner_address_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Contact">
|
||||
<field name="job_ids" select='1'/>
|
||||
</search>
|
||||
</field>
|
||||
<record id="view_res_partner_address_filter" model="ir.ui.view">
|
||||
<field name="name">res.partner.address.select</field>
|
||||
<field name="model">res.partner.address</field>
|
||||
<field name="type">search</field>
|
||||
<field name="inherit_id" ref="base.view_res_partner_address_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Contact">
|
||||
<field name="job_ids" select='1'/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Views for res.partner.job -->
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ This module implements a dashboard for CRM that includes:
|
||||
'depends': ['board', 'crm', 'report_crm'],
|
||||
'update_xml': ['board_crm_statistical_view.xml', 'board_crm_view.xml'],
|
||||
'demo_xml': ['board_crm_demo.xml'],
|
||||
'installable': True,
|
||||
'installable': False,
|
||||
'active': False,
|
||||
'certificate': '0071599098909',
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
+21
-11
@@ -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,11 +122,21 @@ 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
|
||||
uidval = common.openobjectid2uid(cr, data[map_field], model)
|
||||
cr.execute('select id from %s where recurrent_uid=%s'
|
||||
% (model.replace('.', '_'), data[map_field]))
|
||||
r_ids = map(lambda x: x[0], cr.fetchall())
|
||||
if r_ids:
|
||||
rdata = self.pool.get(model).read(cr, uid, r_ids)
|
||||
rcal = self.export_ical(cr, uid, rdata, context=context)
|
||||
for revents in rcal.contents['vevent']:
|
||||
ical.contents['vevent'].append(revents)
|
||||
if data.get('recurrent_uid', None):
|
||||
uidval = common.openobjectid2uid(cr, data['recurrent_uid'], model)
|
||||
vevent.add('uid').value = uidval
|
||||
elif field == 'attendee' and data[map_field]:
|
||||
attendee_obj = self.pool.get('basic.calendar.attendee')
|
||||
@@ -145,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]:
|
||||
@@ -236,7 +246,7 @@ class Event(CalDAV, osv.osv_memory):
|
||||
'duration': None, # Use: O-1, Type: DURATION, Specifies a positive duration of time.
|
||||
'dtend': None, # Use: O-1, Type: DATE-TIME, Specifies the date and time that a calendar component ends.
|
||||
}
|
||||
def export_ical(self, cr, uid, datas, context={}):
|
||||
def export_ical(self, cr, uid, datas, vobj='vevent', context={}):
|
||||
return super(Event, self).export_ical(cr, uid, datas, 'vevent', context=context)
|
||||
|
||||
Event()
|
||||
@@ -279,7 +289,7 @@ class ToDo(CalDAV, osv.osv_memory):
|
||||
'rrule': None,
|
||||
}
|
||||
|
||||
def export_ical(self, cr, uid, datas, context={}):
|
||||
def export_ical(self, cr, uid, datas, vobj='vevent', context={}):
|
||||
return super(ToDo, self).export_ical(cr, uid, datas, 'vtodo', context=context)
|
||||
|
||||
ToDo()
|
||||
@@ -367,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')
|
||||
@@ -429,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()
|
||||
|
||||
+506
-30
@@ -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
|
||||
|
||||
@@ -40,7 +43,9 @@ def caldav_id2real_id(caldav_id=None, with_date=False):
|
||||
if with_date:
|
||||
real_date = time.strftime("%Y-%m-%d %H:%M:%S", \
|
||||
time.strptime(res[1], "%Y%m%d%H%M%S"))
|
||||
return (int(real_id), real_date)
|
||||
start = datetime.strptime(real_date, "%Y-%m-%d %H:%M:%S")
|
||||
end = start + timedelta(hours=with_date)
|
||||
return (int(real_id), real_date, end.strftime("%Y-%m-%d %H:%M:%S"))
|
||||
return int(real_id)
|
||||
return caldav_id and int(caldav_id) or caldav_id
|
||||
|
||||
@@ -48,22 +53,29 @@ 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):
|
||||
def uid2openobjectid(cr, uidval, oomodel, rdate):
|
||||
__rege = re.compile(r'OpenObject-([\w|\.]+)_([0-9]+)@(\w+)$')
|
||||
wematch = __rege.match(uidval.encode('utf8'))
|
||||
if not wematch:
|
||||
return False
|
||||
return (False, None)
|
||||
else:
|
||||
model, id, dbname = wematch.groups()
|
||||
if (not model == oomodel) or (not dbname == cr.dbname):
|
||||
return False
|
||||
cr.execute('select distinct(id) from %s' % model.replace('.', '_'))
|
||||
return (False, None)
|
||||
qry = 'select distinct(id) from %s' % model.replace('.', '_')
|
||||
if rdate:
|
||||
qry += " where recurrent_id='%s'" % (rdate)
|
||||
cr.execute(qry)
|
||||
r_id = cr.fetchone()
|
||||
if r_id:
|
||||
return (id, r_id[0])
|
||||
cr.execute(qry)
|
||||
ids = map(lambda x: str(x[0]), cr.fetchall())
|
||||
if id in ids:
|
||||
return id
|
||||
return (id, None)
|
||||
return False
|
||||
|
||||
def openobjectid2uid(cr, uidval, oomodel):
|
||||
@@ -214,8 +226,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"),
|
||||
}
|
||||
@@ -311,8 +323,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
|
||||
|
||||
@@ -349,12 +361,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'),
|
||||
@@ -365,7 +377,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={}):
|
||||
@@ -404,7 +416,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]
|
||||
@@ -415,17 +427,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:
|
||||
@@ -442,6 +454,471 @@ 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.date_deadline, \
|
||||
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=res.get('duration', 0))
|
||||
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
|
||||
res['date'] = ls[1]
|
||||
res['date_deadline'] = ls[2]
|
||||
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'
|
||||
@@ -474,10 +951,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:
|
||||
@@ -572,7 +1049,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':
|
||||
@@ -623,7 +1100,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()
|
||||
@@ -646,7 +1123,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:
|
||||
@@ -691,7 +1168,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', []):
|
||||
@@ -708,7 +1185,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:
|
||||
@@ -0,0 +1,84 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import pooler
|
||||
|
||||
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='date' />
|
||||
<field name='date_deadline' />
|
||||
<newline />
|
||||
<field name='alarm_id'/>
|
||||
</form>"""
|
||||
|
||||
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},
|
||||
'alarm_id': {'string': 'Reminder', 'type': 'many2one', 'relation': 'res.alarm'},
|
||||
}
|
||||
|
||||
def _default_values(self, cr, uid, data, context):
|
||||
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):
|
||||
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': model,
|
||||
'res_id': new_id,
|
||||
'view_id': False,
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
return value
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_default_values],
|
||||
'result': {'type': 'form', 'arch': event_form, 'fields': event_fields,
|
||||
'state': [('end', 'Cancel', 'gtk-cancel'), ('edit', '_Save', 'gtk-save')]}
|
||||
},
|
||||
'edit': {
|
||||
'actions': [],
|
||||
'result': {'type': 'action', 'action': _modify_this, 'state': 'end'}
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -81,8 +81,8 @@ between mails and Open ERP.""",
|
||||
'crm_claims_menu.xml',
|
||||
|
||||
# 'crm_report_view.xml',
|
||||
# 'crm_helpdesk_view.xml',
|
||||
# 'crm_helpdesk_menu.xml',
|
||||
'crm_helpdesk_view.xml',
|
||||
'crm_helpdesk_menu.xml',
|
||||
#'crm_report.xml',
|
||||
'security/crm_security.xml',
|
||||
#'security/ir.model.access.csv',
|
||||
|
||||
+62
-1
@@ -101,6 +101,67 @@ class crm_case_section(osv.osv):
|
||||
return res
|
||||
crm_case_section()
|
||||
|
||||
class crm_case_categ(osv.osv):
|
||||
_name = "crm.case.categ"
|
||||
_description = "Category of case"
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Case Category Name', size=64, required=True, translate=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'object_id': fields.many2one('ir.model','Object Name'),
|
||||
}
|
||||
def _find_object_id(self, cr, uid, context=None):
|
||||
object_id = context and context.get('object_id', False) or False
|
||||
ids =self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)])
|
||||
return ids and ids[0]
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0,
|
||||
'object_id' : _find_object_id
|
||||
}
|
||||
#
|
||||
crm_case_categ()
|
||||
|
||||
class crm_case_resource_type(osv.osv):
|
||||
_name = "crm.case.resource.type"
|
||||
_description = "Resource Type of case"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Case Resource Type', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'object_id': fields.many2one('ir.model','Object Name'),
|
||||
}
|
||||
def _find_object_id(self, cr, uid, context=None):
|
||||
object_id = context and context.get('object_id', False) or False
|
||||
ids =self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)])
|
||||
return ids and ids[0]
|
||||
_defaults = {
|
||||
'object_id' : _find_object_id
|
||||
}
|
||||
crm_case_resource_type()
|
||||
|
||||
|
||||
class crm_case_stage(osv.osv):
|
||||
_name = "crm.case.stage"
|
||||
_description = "Stage of case"
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Stage Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
|
||||
'object_id': fields.many2one('ir.model','Object Name'),
|
||||
}
|
||||
def _find_object_id(self, cr, uid, context=None):
|
||||
object_id = context and context.get('object_id', False) or False
|
||||
ids =self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)])
|
||||
return ids and ids[0]
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1,
|
||||
'object_id' : _find_object_id
|
||||
}
|
||||
|
||||
crm_case_stage()
|
||||
|
||||
|
||||
class crm_case_rule(osv.osv):
|
||||
@@ -327,7 +388,7 @@ class crm_case(osv.osv):
|
||||
|
||||
def stage_next(self, cr, uid, ids, context={}):
|
||||
ok = False
|
||||
sid = self.pool.get('crm.case.stage').search(cr, uid, [], context=context)
|
||||
sid = self.pool.get('crm.case.stage').search(cr, uid, [('object_id.model', '=', self._name)], context=context)
|
||||
s = {}
|
||||
previous = {}
|
||||
for stage in self.pool.get('crm.case.stage').browse(cr, uid, sid, context=context):
|
||||
|
||||
+5
-42
@@ -27,44 +27,7 @@ import netsvc
|
||||
from tools.translate import _
|
||||
import crm
|
||||
|
||||
class crm_claim_categ(osv.osv):
|
||||
_name = "crm.claim.categ"
|
||||
_description = "Claim Categories"
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', size=64, required=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_claim_categ()
|
||||
|
||||
class crm_claim_type(osv.osv):
|
||||
_name = "crm.claim.type"
|
||||
_description = "Claim Type"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Claim Type Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
|
||||
crm_claim_type()
|
||||
|
||||
class crm_claim_stage(osv.osv):
|
||||
_name = "crm.claim.stage"
|
||||
_description = "Stage of claim case"
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Stage Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
|
||||
}
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1
|
||||
}
|
||||
crm_claim_stage()
|
||||
|
||||
class crm_claim(osv.osv):
|
||||
_name = "crm.claim"
|
||||
@@ -82,23 +45,23 @@ class crm_claim(osv.osv):
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
|
||||
"the partner mentality in relation to our services.The scale has" \
|
||||
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
|
||||
'categ_id': fields.many2one('crm.claim.categ','Category', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]"),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'type_id': fields.many2one('crm.claim.type', 'Claim Type', domain="[('section_id','=',section_id)]"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Claim Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]"),
|
||||
|
||||
'partner_name': fields.char("Employee's Name", size=64),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'stage_id': fields.many2one ('crm.claim.stage', 'Stage', domain="[('section_id','=',section_id)]"),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'priority': lambda *a: AVAILABLE_PRIORITIES[2][0],
|
||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||
}
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.claim.categ').browse(cr, uid, categ, context).probability
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
crm_claim()
|
||||
|
||||
@@ -5,53 +5,63 @@
|
||||
<!--
|
||||
Claims Categories
|
||||
-->
|
||||
<record model="crm.claim.categ" id="categ_claim1">
|
||||
<record model="crm.case.categ" id="categ_claim1">
|
||||
<field name="name">Factual Claims</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.claim.categ" id="categ_claim2">
|
||||
<record model="crm.case.categ" id="categ_claim2">
|
||||
<field name="name">Value Claims</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.claim.categ" id="categ_claim3">
|
||||
<record model="crm.case.categ" id="categ_claim3">
|
||||
<field name="name">Policy Claims</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Case Category2
|
||||
-->
|
||||
<record model="crm.claim.type" id="type_claim1">
|
||||
<record model="crm.case.resource.type" id="type_claim1">
|
||||
<field name="name">Corrective</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.claim.type" id="type_claim2">
|
||||
<record model="crm.case.resource.type" id="type_claim2">
|
||||
<field name="name">Preventive</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Case Stage
|
||||
-->
|
||||
<record model="crm.claim.stage" id="stage_claim1">
|
||||
<record model="crm.case.stage" id="stage_claim1">
|
||||
<field name="name">Accepted as Claim</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.claim.stage" id="stage_claim2">
|
||||
<record model="crm.case.stage" id="stage_claim2">
|
||||
<field name="name">Fixed</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.claim.stage" id="stage_claim3">
|
||||
<record model="crm.case.stage" id="stage_claim3">
|
||||
<field name="name">Won't fix</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.claim.stage" id="stage_claim4">
|
||||
<record model="crm.case.stage" id="stage_claim4">
|
||||
<field name="name">Invalid</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.claim.stage" id="stage_claim5">
|
||||
<record model="crm.case.stage" id="stage_claim5">
|
||||
<field name="name">Awaiting Response</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -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="menu_aftersale" action="crm_case_categ_claim0"/>-->
|
||||
<menuitem name="Claims" id="menu_crm_case_claims" parent="base.menu_aftersale" action="crm_case_categ_claim0"/>
|
||||
|
||||
|
||||
</data>
|
||||
|
||||
@@ -4,73 +4,25 @@
|
||||
# ------------------------------------------------------
|
||||
# Claims
|
||||
# ------------------------------------------------------
|
||||
|
||||
|
||||
<!-- Claim Categories -->
|
||||
<record id="crm_claim_categ_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.claim.categ.form</field>
|
||||
<field name="model">crm.claim.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Claim Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_claim_categ_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.claim.categ.tree</field>
|
||||
<field name="model">crm.claim.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Claim Category">
|
||||
<field name="name"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_claim_categ_action" model="ir.actions.act_window">
|
||||
<field name="name">Claim Categories</field>
|
||||
<field name="res_model">crm.claim.categ</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_claim_categ_view_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.claim')]</field>
|
||||
<field name="context">{'object_id':'crm.claim'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_claim_categ_action" id="menu_crm_case_claim-act" parent="crm.menu_crm_case_categ"/>
|
||||
# ------------------------------------------------------
|
||||
# Stage
|
||||
# ------------------------------------------------------
|
||||
<record model="ir.ui.view" id="crm_claim_stage_tree">
|
||||
<field name="name">crm.claim.stage.tree</field>
|
||||
<field name="model">crm.claim.stage</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stages">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="crm_claim_stage_form">
|
||||
<field name="name">crm.claim.stage.form</field>
|
||||
<field name="model">crm.claim.stage</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stage">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
# ------------------------------------------------------
|
||||
# Stages
|
||||
# ------------------------------------------------------
|
||||
<record id="crm_claim_stage_act" model="ir.actions.act_window">
|
||||
<field name="name">Claim Stages</field>
|
||||
<field name="res_model">crm.claim.stage</field>
|
||||
<field name="res_model">crm.case.stage</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_claim_stage_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_stage_tree"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.claim')]</field>
|
||||
<field name="context">{'object_id':'crm.claim'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_claim_stage_act" id="menu_crm_claim_stage_act" parent="crm.menu_crm_case_stage"/>
|
||||
|
||||
|
||||
@@ -4,46 +4,54 @@
|
||||
|
||||
<!-- FUNDRAISING CATEGORY(categ_id) -->
|
||||
|
||||
<record model="crm.fundraising.categ" id="categ_fund1">
|
||||
<record model="crm.case.categ" id="categ_fund1">
|
||||
<field name="name">Social Rehabilitation And Rural Upliftment</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.fundraising.categ" id="categ_fund2">
|
||||
<record model="crm.case.categ" id="categ_fund2">
|
||||
<field name="name">Learning And Education</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.fundraising.categ" id="categ_fund3">
|
||||
<record model="crm.case.categ" id="categ_fund3">
|
||||
<field name="name">Healthcare</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.fundraising.categ" id="categ_fund4">
|
||||
<record model="crm.case.categ" id="categ_fund4">
|
||||
<field name="name">Arts And Culture</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!-- CASE CATEGORY2(category2_id) -->
|
||||
<!-- CASE Resource(type_id) -->
|
||||
|
||||
<record model="crm.fundraising.type" id="type_fund1">
|
||||
<record model="crm.case.resource.type" id="type_fund1">
|
||||
<field name="name">Cash</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.fundraising.type" id="type_fund2">
|
||||
<record model="crm.case.resource.type" id="type_fund2">
|
||||
<field name="name">Cheque</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.fundraising.type" id="type_fund3">
|
||||
<record model="crm.case.resource.type" id="type_fund3">
|
||||
<field name="name">Credit Card</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.fundraising.type" id="type_fund4">
|
||||
<record model="crm.case.resource.type" id="type_fund4">
|
||||
<field name="name">Demand Draft</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
</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,8 +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="crm.menu_crm" action="crm_case_category_act_fund_all1"/>-->
|
||||
<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>
|
||||
|
||||
@@ -5,70 +5,25 @@
|
||||
# ------------------------------------------------------
|
||||
# Fund Raising Categories
|
||||
# ------------------------------------------------------
|
||||
<record id="crm_fund_categ_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.fundraising.categ.form</field>
|
||||
<field name="model">crm.fundraising.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Fundraising Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_fund_categ_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.fundraising.categ.tree</field>
|
||||
<field name="model">crm.fundraising.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Fundraising Category">
|
||||
<field name="name"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_fund_categ_action" model="ir.actions.act_window">
|
||||
<field name="name">Fundraising Categories</field>
|
||||
<field name="res_model">crm.fundraising.categ</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_fund_categ_view_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.fundraising')]</field>
|
||||
<field name="context">{'object_id':'crm.fundraising'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_fund_categ_action" id="menu_crm_case_fundraising-act" parent="crm.menu_crm_case_categ"/>
|
||||
# ------------------------------------------------------
|
||||
# Fund Stage
|
||||
# ------------------------------------------------------
|
||||
<record model="ir.ui.view" id="crm_fundraising_stage_tree">
|
||||
<field name="name">crm.fundraising.stage.tree</field>
|
||||
<field name="model">crm.fundraising.stage</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stages">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="crm_fundraising_stage_form">
|
||||
<field name="name">crm.fundraising.stage.form</field>
|
||||
<field name="model">crm.fundraising.stage</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stage">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_fundraising_stage_act" model="ir.actions.act_window">
|
||||
<field name="name">Fundraising Stages</field>
|
||||
<field name="res_model">crm.claim.stage</field>
|
||||
<field name="res_model">crm.case.stage</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_fundraising_stage_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_stage_tree"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.fundraising')]</field>
|
||||
<field name="context">{'object_id':'crm.fundraising'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_fundraising_stage_act" id="menu_crm_fundraising_stage_act" parent="crm.menu_crm_case_stage"/>
|
||||
|
||||
|
||||
@@ -34,44 +34,6 @@ from osv.orm import except_orm
|
||||
|
||||
import crm
|
||||
|
||||
class crm_fundraising_categ(osv.osv):
|
||||
_name = "crm.fundraising.categ"
|
||||
_description = "Fundraising Categories"
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', size=64, required=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_fundraising_categ()
|
||||
|
||||
class crm_fundraising_type(osv.osv):
|
||||
_name = "crm.fundraising.type"
|
||||
_description = "Fundraising Type"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Fundraising Type Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
|
||||
crm_fundraising_type()
|
||||
|
||||
class crm_fundraising_stage(osv.osv):
|
||||
_name = "crm.fundraising.stage"
|
||||
_description = "Stage of fundraising case"
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Stage Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
|
||||
}
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1
|
||||
}
|
||||
crm_fundraising_stage()
|
||||
|
||||
|
||||
class crm_fundraising(osv.osv):
|
||||
@@ -82,7 +44,7 @@ class crm_fundraising(osv.osv):
|
||||
_columns = {
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'categ_id': fields.many2one('crm.fundraising.categ','Category', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.fundraising')]"),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'planned_cost': fields.float('Planned Costs'),
|
||||
'probability': fields.float('Probability (%)'),
|
||||
@@ -90,8 +52,8 @@ class crm_fundraising(osv.osv):
|
||||
'partner_name2': fields.char('Employee Email', size=64),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'stage_id': fields.many2one ('crm.fundraising.stage', 'Stage', domain="[('section_id','=',section_id)]"),
|
||||
'type_id': fields.many2one('crm.fundraising.type', 'Fundraising Type', domain="[('section_id','=',section_id)]"),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id)]"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Fundraising Type', domain="[('section_id','=',section_id)]"),
|
||||
'duration': fields.float('Duration'),
|
||||
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128),
|
||||
@@ -103,12 +65,12 @@ class crm_fundraising(osv.osv):
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'priority': lambda *a: AVAILABLE_PRIORITIES[2][0],
|
||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||
}
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.fundraising.categ').browse(cr, uid, categ, context).probability
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
|
||||
|
||||
@@ -34,18 +34,7 @@ from osv.orm import except_orm
|
||||
|
||||
import crm
|
||||
|
||||
class crm_helpdesk_categ(osv.osv):
|
||||
_name = "crm.helpdesk.categ"
|
||||
_description = "Helpdesk Categories"
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', size=64, required=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_helpdesk_categ()
|
||||
|
||||
|
||||
class crm_helpdesk(osv.osv):
|
||||
_name = "crm.helpdesk"
|
||||
@@ -65,13 +54,13 @@ class crm_helpdesk(osv.osv):
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
|
||||
"the partner mentality in relation to our services.The scale has" \
|
||||
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
|
||||
'categ_id': fields.many2one('crm.helpdesk.categ', 'Category', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.helpdesk')]"),
|
||||
'duration': fields.float('Duration'),
|
||||
}
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.helpdesk.categ').browse(cr, uid, categ, context).probability
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
crm_helpdesk()
|
||||
|
||||
@@ -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="menu_aftersale" 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>
|
||||
|
||||
@@ -5,36 +5,13 @@
|
||||
# ------------------------------------------------------
|
||||
# Helpdesk Support Categories
|
||||
# ------------------------------------------------------
|
||||
<record id="crm_helpdesk_categ_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.helpdesk.categ.form</field>
|
||||
<field name="model">crm.helpdesk.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Helpdesk Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_helpdesk_categ_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.helpdesk.categ.tree</field>
|
||||
<field name="model">crm.helpdesk.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Helpdesk Category">
|
||||
<field name="name"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_helpdesk_categ_action" model="ir.actions.act_window">
|
||||
<field name="name">Helpdesk Categories</field>
|
||||
<field name="res_model">crm.helpdesk.categ</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_helpdesk_categ_view_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.helpdesk')]</field>
|
||||
<field name="context">{'object_id':'crm.helpdesk'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_helpdesk_categ_action" id="menu_crm_case_helpdesk-act" parent="crm.menu_crm_case_categ"/>
|
||||
# ------------------------------------------------------
|
||||
|
||||
+5
-40
@@ -34,45 +34,10 @@ from osv.orm import except_orm
|
||||
|
||||
import crm
|
||||
|
||||
class crm_lead_categ(osv.osv):
|
||||
_name = "crm.lead.categ"
|
||||
_description = "Lead Categories"
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', size=64, required=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_lead_categ()
|
||||
|
||||
class crm_lead_type(osv.osv):
|
||||
_name = "crm.lead.type"
|
||||
_description = "Lead Type"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('lead Type Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
crm_lead_type()
|
||||
|
||||
class crm_lead_stage(osv.osv):
|
||||
_name = "crm.lead.stage"
|
||||
_description = "Stage of claim case"
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Stage Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
|
||||
}
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1
|
||||
}
|
||||
crm_lead_stage()
|
||||
class crm_opportunity(osv.osv):
|
||||
_name = "crm.opportunity"
|
||||
_description = "Opportunity Cases"
|
||||
crm_opportunity()
|
||||
|
||||
class crm_lead(osv.osv):
|
||||
@@ -81,8 +46,8 @@ class crm_lead(osv.osv):
|
||||
_order = "id desc"
|
||||
_inherit = 'crm.case'
|
||||
_columns = {
|
||||
'categ_id': fields.many2one('crm.lead.categ', 'Category', domain="[('section_id','=',section_id)]"),
|
||||
'type_id': fields.many2one('crm.lead.type', 'Lead Type Name', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Lead Type Name', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]"),
|
||||
'partner_name': fields.char("Employee's Name", size=64),
|
||||
'partner_name2': fields.char('Employee Email', size=64),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
@@ -96,7 +61,7 @@ class crm_lead(osv.osv):
|
||||
" With each commercial opportunity, you can indicate the canall which is this opportunity source."),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'planned_cost': fields.float('Planned Costs'),
|
||||
'stage_id': fields.many2one ('crm.lead.stage', 'Stage', domain="[('section_id','=',section_id)]"),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.lead')]"),
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
|
||||
"the partner mentality in relation to our services.The scale has" \
|
||||
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
|
||||
@@ -106,7 +71,7 @@ class crm_lead(osv.osv):
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.lead.categ').browse(cr, uid, categ, context).probability
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
crm_lead()
|
||||
|
||||
@@ -2,93 +2,114 @@
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="crm.lead.categ" id="categ_lead1">
|
||||
<record model="crm.case.categ" id="categ_lead1">
|
||||
<field name="name">Existing Customer</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.categ" id="categ_lead2">
|
||||
<record model="crm.case.categ" id="categ_lead2">
|
||||
<field name="name">Self Generated</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.categ" id="categ_lead3">
|
||||
<record model="crm.case.categ" id="categ_lead3">
|
||||
<field name="name">Employee</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.categ" id="categ_lead4">
|
||||
<record model="crm.case.categ" id="categ_lead4">
|
||||
<field name="name">Partner</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.categ" id="categ_lead6">
|
||||
<record model="crm.case.categ" id="categ_lead6">
|
||||
<field name="name">Website</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.categ" id="categ_lead7">
|
||||
<record model="crm.case.categ" id="categ_lead7">
|
||||
<field name="name">Word of mouth</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.categ" id="categ_lead8">
|
||||
<record model="crm.case.categ" id="categ_lead8">
|
||||
<field name="name">Other</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!-- CASE STATUS(stage_id) -->
|
||||
<record model="crm.lead.stage" id="stage_lead1">
|
||||
<record model="crm.case.stage" id="stage_lead1">
|
||||
<field name="name">New</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.stage" id="stage_lead2">
|
||||
<record model="crm.case.stage" id="stage_lead2">
|
||||
<field name="name">Assigned</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.stage" id="stage_lead3">
|
||||
<record model="crm.case.stage" id="stage_lead3">
|
||||
<field name="name">In Process</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.stage" id="stage_lead4">
|
||||
<record model="crm.case.stage" id="stage_lead4">
|
||||
<field name="name">Converted</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.stage" id="stage_lead5">
|
||||
<record model="crm.case.stage" id="stage_lead5">
|
||||
<field name="name">Recycled</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.stage" id="stage_lead6">
|
||||
<record model="crm.case.stage" id="stage_lead6">
|
||||
<field name="name">Dead</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!-- CASE CATEGORY2(category2_id) -->
|
||||
<record model="crm.lead.type" id="type_lead1">
|
||||
<record model="crm.case.resource.type" id="type_lead1">
|
||||
<field name="name">Telesales</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.type" id="type_lead2">
|
||||
<record model="crm.case.resource.type" id="type_lead2">
|
||||
<field name="name">Mail</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.type" id="type_lead3">
|
||||
<record model="crm.case.resource.type" id="type_lead3">
|
||||
<field name="name">Email</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.type" id="type_lead4">
|
||||
<record model="crm.case.resource.type" id="type_lead4">
|
||||
<field name="name">Print</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.type" id="type_lead5">
|
||||
<record model="crm.case.resource.type" id="type_lead5">
|
||||
<field name="name">Web</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.type" id="type_lead6">
|
||||
<record model="crm.case.resource.type" id="type_lead6">
|
||||
<field name="name">Radio</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.type" id="type_lead7">
|
||||
<record model="crm.case.resource.type" id="type_lead7">
|
||||
<field name="name">Television</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.lead.type" id="type_lead8">
|
||||
<record model="crm.case.resource.type" id="type_lead8">
|
||||
<field name="name">Newsletter</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -5,72 +5,27 @@
|
||||
# ------------------------------------------------------
|
||||
# Leads Categories
|
||||
# ------------------------------------------------------
|
||||
|
||||
<record id="crm_lead_categ_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.lead.categ.form</field>
|
||||
<field name="model">crm.lead.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Lead Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_lead_categ_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.lead.categ.tree</field>
|
||||
<field name="model">crm.lead.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Lead Category">
|
||||
<field name="name"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_lead_categ_action" model="ir.actions.act_window">
|
||||
<field name="name">Lead Categories</field>
|
||||
<field name="res_model">crm.lead.categ</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_lead_categ_view_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.lead')]</field>
|
||||
<field name="context">{'object_id':'crm.lead'}</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="crm_lead_categ_action" id="menu_crm_case_lead-act" parent="crm.menu_crm_case_categ"/>
|
||||
# ------------------------------------------------------
|
||||
# Stage
|
||||
# ------------------------------------------------------
|
||||
<record model="ir.ui.view" id="crm_lead_stage_tree">
|
||||
<field name="name">crm.lead.stage.tree</field>
|
||||
<field name="model">crm.lead.stage</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stages">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="crm_lead_stage_form">
|
||||
<field name="name">crm.lead.stage.form</field>
|
||||
<field name="model">crm.lead.stage</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stage">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_lead_stage_act" model="ir.actions.act_window">
|
||||
<field name="name">Lead Stages</field>
|
||||
<field name="res_model">crm.claim.stage</field>
|
||||
<field name="res_model">crm.case.stage</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_lead_stage_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_stage_tree"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.lead')]</field>
|
||||
<field name="context">{'object_id':'crm.lead'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_lead_stage_act" id="menu_crm_lead_stage_act" parent="crm.menu_crm_case_stage"/>
|
||||
# ------------------------------------------------------
|
||||
@@ -98,7 +53,7 @@
|
||||
</group>
|
||||
<group colspan="2" col="4">
|
||||
<field name="opportunity_id" string="Opportunity Case"/>
|
||||
<button string="Convert to Opportunity" name="%(wizard_crm_lead_opportunity_set)d" icon="gtk-index" type="action"/>
|
||||
<button string="Convert to Opportunity" name="%(wizard_crm_lead_opportunity_set)d" icon="gtk-index" type="action" attrs="{'invisible':[('opportunity_id','!=',False)]}"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Leads">
|
||||
|
||||
+10
-387
@@ -19,407 +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
|
||||
import time
|
||||
import tools
|
||||
|
||||
class crm_meeting_categ(osv.osv):
|
||||
_name = "crm.meeting.categ"
|
||||
_description = "Category of Meetings"
|
||||
_columns = {
|
||||
'name': fields.char('Meeting Category Name', size=64, required=True, \
|
||||
translate=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_meeting_categ()
|
||||
|
||||
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'},
|
||||
'recurid': None,
|
||||
# 'attach': {'field': 'attachment_ids', 'sub-field': 'datas', 'type': 'list'},
|
||||
'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 _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")
|
||||
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, 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}}
|
||||
_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'),
|
||||
'categ_id': fields.many2one('crm.meeting.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id)]", \
|
||||
('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')]", \
|
||||
help='Category related to the section.Subdivide the CRM cases \
|
||||
independently or section-wise.'),
|
||||
'description': fields.text('Your action'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'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'),
|
||||
'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, {'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:
|
||||
is_exists = common.uid2openobjectid(cr, val['id'], self._name)
|
||||
if val.has_key('create_date'): val.pop('create_date')
|
||||
val['caldav_url'] = context.get('url') or ''
|
||||
val.pop('id')
|
||||
if is_exists:
|
||||
self.write(cr, uid, [is_exists], val)
|
||||
ids.append(is_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 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
|
||||
|
||||
|
||||
def msg_new(self, cr, uid, msg):
|
||||
mailgate_obj = self.pool.get('mail.gateway')
|
||||
msg_body = mailgate_obj.msg_body_get(msg)
|
||||
data = {
|
||||
'name': msg['Subject'],
|
||||
'email_from': msg['From'],
|
||||
'email_cc': msg['Cc'],
|
||||
'user_id': False,
|
||||
'description': msg_body['body'],
|
||||
'history_line': [(0, 0, {'description': msg_body['body'], 'email': msg['From'] })],
|
||||
}
|
||||
res = mailgate_obj.partner_get(cr, uid, msg['From'])
|
||||
if res:
|
||||
data.update(res)
|
||||
res = self.create(cr, uid, data)
|
||||
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:
|
||||
|
||||
@@ -4,22 +4,26 @@
|
||||
|
||||
<!-- CASE CATEGORY(categ_id) -->
|
||||
|
||||
<record model="crm.meeting.categ" id="categ_meet1">
|
||||
<record model="crm.case.categ" id="categ_meet1">
|
||||
<field name="name">Customer Meeting</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.meeting.categ" id="categ_meet2">
|
||||
<record model="crm.case.categ" id="categ_meet2">
|
||||
<field name="name">Internal Meeting</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.fundraising')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.meeting.categ" id="categ_meet3">
|
||||
<record model="crm.case.categ" id="categ_meet3">
|
||||
<field name="name">Phone Call</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.meeting')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<record model="res.request.link" id="request_link_meeting">
|
||||
<field name="name">Case Meeting</field>
|
||||
<field name="object">crm.meeting</field>
|
||||
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<field name="date_deadline" string="End Date" required="1" />
|
||||
<field name="location" />
|
||||
<field name="categ_id" widget="selection" />
|
||||
<group colspan="2" col="3">
|
||||
<group colspan="2" col="3" attrs="{'readonly':[('recurrent_uid','!=',False)]}">
|
||||
<field name="rrule_type" string="Recurrency"
|
||||
on_change="onchange_rrule_type(rrule_type)"
|
||||
colspan="1" />
|
||||
@@ -46,8 +46,7 @@
|
||||
context="{'model' : 'crm.meeting'}" colspan="2"/>
|
||||
<field name="attendee_ids" colspan="4"
|
||||
nolabel="1" widget="one2many" mode="tree,form">
|
||||
<tree string="Atendee details"
|
||||
editable="top">
|
||||
<tree string="Atendee details" editable="top">
|
||||
<field name="email" />
|
||||
<field name="role" select="1" />
|
||||
<field name="state" />
|
||||
@@ -63,7 +62,7 @@
|
||||
<field name="state" />
|
||||
</page>
|
||||
<page string="Other">
|
||||
<field name="user_id" select="1" />
|
||||
<field name="user_id"/>
|
||||
<field name="partner_address_id" select="1" />
|
||||
<newline />
|
||||
</page>
|
||||
@@ -76,9 +75,17 @@
|
||||
<field name="show_as"/>
|
||||
<field name="class"/>
|
||||
<field name="user_id"/>
|
||||
<field name="rrule" invisible="1"/>
|
||||
<field name="recurrent_id" invisible="1" />
|
||||
<field name="recurrent_uid" invisible="1" />
|
||||
<field name="rrule" invisible="1" />
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="3" colspan="4" attrs="{'invisible':[('rrule_type','in', ('none', False))]}">
|
||||
<label string="" />
|
||||
<button string="Modify this Occurrence"
|
||||
name="%(caldav.wizard_edit_this_event)d" icon="gtk-save"
|
||||
type="action" context="{'model' : 'crm.meeting'}" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,17 +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="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>
|
||||
|
||||
@@ -34,43 +34,6 @@ from osv.orm import except_orm
|
||||
|
||||
import crm
|
||||
|
||||
class crm_opportunity_categ(osv.osv):
|
||||
_name = "crm.opportunity.categ"
|
||||
_description = "Opportunity Categories"
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', size=64, required=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_opportunity_categ()
|
||||
|
||||
class crm_opportunity_type(osv.osv):
|
||||
_name = "crm.opportunity.type"
|
||||
_description = "Opportunity Type"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('lead Type Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
crm_opportunity_type()
|
||||
|
||||
class crm_opportunity_stage(osv.osv):
|
||||
_name = "crm.opportunity.stage"
|
||||
_description = "Stage of opportunity case"
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Stage Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
|
||||
}
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1
|
||||
}
|
||||
crm_opportunity_stage()
|
||||
|
||||
class crm_opportunity(osv.osv):
|
||||
_name = "crm.opportunity"
|
||||
@@ -78,9 +41,9 @@ class crm_opportunity(osv.osv):
|
||||
_order = "id desc"
|
||||
_inherit = 'crm.case'
|
||||
_columns = {
|
||||
'stage_id': fields.many2one ('crm.opportunity.stage', 'Stage', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.opportunity.categ', 'Category', domain="[('section_id','=',section_id)]"),
|
||||
'type_id': fields.many2one('crm.opportunity.type', 'Opportunity Type', domain="[('section_id','=',section_id)]"),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]"),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Resource Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.opportunity')]"),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'probability': fields.float('Probability (%)'),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
@@ -98,7 +61,7 @@ class crm_opportunity(osv.osv):
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.opportunity.categ').browse(cr, uid, categ, context).probability
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
crm_opportunity()
|
||||
|
||||
@@ -1,77 +1,94 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<record model="crm.opportunity.categ" id="categ_oppor1">
|
||||
<record model="crm.case.categ" id="categ_oppor1">
|
||||
<field name="name">Existing Customer</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.categ" id="categ_oppor2">
|
||||
<record model="crm.case.categ" id="categ_oppor2">
|
||||
<field name="name">Self Generated</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.categ" id="categ_oppor3">
|
||||
<record model="crm.case.categ" id="categ_oppor3">
|
||||
<field name="name">Employee</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.categ" id="categ_oppor4">
|
||||
<record model="crm.case.categ" id="categ_oppor4">
|
||||
<field name="name">Partner</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.categ" id="categ_oppor5">
|
||||
<record model="crm.case.categ" id="categ_oppor5">
|
||||
<field name="name">Campaign</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.categ" id="categ_oppor6">
|
||||
<record model="crm.case.categ" id="categ_oppor6">
|
||||
<field name="name">Website</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.categ" id="categ_oppor7">
|
||||
<record model="crm.case.categ" id="categ_oppor7">
|
||||
<field name="name">Word of mouth</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.categ" id="categ_oppor8">
|
||||
<record model="crm.case.categ" id="categ_oppor8">
|
||||
<field name="name">Other</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!-- CASE STATUS(stage_id) -->
|
||||
<record model="crm.opportunity.stage" id="stage_oppor1">
|
||||
<record model="crm.case.stage" id="stage_oppor1">
|
||||
<field name="name">Prospecting</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.stage" id="stage_oppor2">
|
||||
<record model="crm.case.stage" id="stage_oppor2">
|
||||
<field name="name">Needs Analysis</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.stage" id="stage_oppor3">
|
||||
<record model="crm.case.stage" id="stage_oppor3">
|
||||
<field name="name">Value Proposition</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.stage" id="stage_oppor4">
|
||||
<record model="crm.case.stage" id="stage_oppor4">
|
||||
<field name="name">Proposal/Price Quote</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.stage" id="stage_oppor5">
|
||||
<record model="crm.case.stage" id="stage_oppor5">
|
||||
<field name="name">Negotiation/Review</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.stage" id="stage_oppor6">
|
||||
<record model="crm.case.stage" id="stage_oppor6">
|
||||
<field name="name">Closed Won</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.stage" id="stage_oppor7">
|
||||
<record model="crm.case.stage" id="stage_oppor7">
|
||||
<field name="name">Closed Lost</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!-- CASE CATEGORY2(category2_id) -->
|
||||
<record model="crm.opportunity.type" id="type_oppor1">
|
||||
<!-- Case Resource(type_id) -->
|
||||
<record model="crm.case.resource.type" id="type_oppor1">
|
||||
<field name="name">Existing Business</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.opportunity.type" id="type_oppor2">
|
||||
<record model="crm.case.resource.type" id="type_oppor2">
|
||||
<field name="name">New Business</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.opportunity')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -5,73 +5,26 @@
|
||||
# ------------------------------------------------------
|
||||
# Opportunity Categories
|
||||
# ------------------------------------------------------
|
||||
|
||||
<record id="crm_opportunity_categ_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.opportunity.categ.form</field>
|
||||
<field name="model">crm.opportunity.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Opportunity Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_opportunity_categ_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.opportunity.categ.tree</field>
|
||||
<field name="model">crm.opportunity.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Opportunity Category">
|
||||
<field name="name"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_opportunity_categ_action" model="ir.actions.act_window">
|
||||
<field name="name">Opportunity Categories</field>
|
||||
<field name="res_model">crm.opportunity.categ</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_opportunity_categ_view_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.opportunity')]</field>
|
||||
<field name="context">{'object_id':'crm.opportunity'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_opportunity_categ_action" id="menu_crm_case_opportunity-act" parent="crm.menu_crm_case_categ"/>
|
||||
# ------------------------------------------------------
|
||||
# Stage
|
||||
# ------------------------------------------------------
|
||||
<record model="ir.ui.view" id="crm_opportunity_stage_tree">
|
||||
<field name="name">crm.opportunity.stage.tree</field>
|
||||
<field name="model">crm.opportunity.stage</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stages">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="crm_opportunity_stage_form">
|
||||
<field name="name">crm.opportunity.stage.form</field>
|
||||
<field name="model">crm.opportunity.stage</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stage">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_opportunity_stage_act" model="ir.actions.act_window">
|
||||
<field name="name">Opportunity Stages</field>
|
||||
<field name="res_model">crm.claim.stage</field>
|
||||
<field name="res_model">crm.case.stage</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_opportunity_stage_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_stage_tree"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.opportunity')]</field>
|
||||
<field name="context">{'object_id':'crm.opportunity'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_opportunity_stage_act" id="menu_crm_opportunity_stage_act" parent="crm.menu_crm_case_stage"/>
|
||||
# ------------------------------------------------------
|
||||
@@ -103,7 +56,7 @@
|
||||
<field name="phonecall_id" select="1"/>
|
||||
</group>
|
||||
<button string="Schedule a Phone Call"
|
||||
name="%(wizard_crm_opportunity_reschedule_phone_call)d" icon="gtk-redo" type="action" />
|
||||
name="%(wizard_crm_opportunity_reschedule_phone_call)d" icon="gtk-redo" type="action" attrs="{'invisible':[('phonecall_id','!=',False)]}" />
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Description">
|
||||
|
||||
@@ -32,33 +32,6 @@ from tools.translate import _
|
||||
|
||||
import crm
|
||||
|
||||
class crm_phonecall_categ(osv.osv):
|
||||
_name = "crm.phonecall.categ"
|
||||
_description = "Phonecall Categories"
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', size=64, required=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_phonecall_categ()
|
||||
|
||||
class crm_phonecall_stage(osv.osv):
|
||||
_name = "crm.phonecall.stage"
|
||||
_description = "Stage of phonecal case"
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Stage Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
|
||||
}
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1
|
||||
}
|
||||
crm_phonecall_stage()
|
||||
|
||||
class crm_phonecall(osv.osv):
|
||||
_name = "crm.phonecall"
|
||||
@@ -67,7 +40,7 @@ class crm_phonecall(osv.osv):
|
||||
_inherit = 'crm.case'
|
||||
_columns = {
|
||||
'duration': fields.float('Duration'),
|
||||
'categ_id': fields.many2one('crm.phonecall.categ', 'Category', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.phonecall')]"),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
|
||||
@@ -84,7 +57,7 @@ class crm_phonecall(osv.osv):
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.phonecall.categ').browse(cr, uid, categ, context).probability
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
crm_phonecall()
|
||||
|
||||
@@ -6,29 +6,35 @@
|
||||
<!--
|
||||
Phonecall Categories
|
||||
-->
|
||||
<record model="crm.phonecall.categ" id="categ_phone1">
|
||||
<record model="crm.case.categ" id="categ_phone1">
|
||||
<field name="name">Inbound</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.phonecall')]" model="ir.model"/>
|
||||
|
||||
</record>
|
||||
<record model="crm.phonecall.categ" id="categ_phone2">
|
||||
<record model="crm.case.categ" id="categ_phone2">
|
||||
<field name="name">Outbound</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.phonecall')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Case Stage
|
||||
-->
|
||||
<record model="crm.phonecall.stage" id="stage_phone1">
|
||||
<record model="crm.case.stage" id="stage_phone1">
|
||||
<field name="name">Planned</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.phonecall')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.phonecall.stage" id="stage_phone2">
|
||||
<record model="crm.case.stage" id="stage_phone2">
|
||||
<field name="name">Held</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.phonecall')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.phonecall.stage" id="stage_phone3">
|
||||
<record model="crm.case.stage" id="stage_phone3">
|
||||
<field name="name">Not Held</field>
|
||||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.phonecall')]" model="ir.model"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -5,72 +5,27 @@
|
||||
# ------------------------------------------------------
|
||||
# Phonecall Categories
|
||||
# ------------------------------------------------------
|
||||
|
||||
<record id="crm_phonecall_categ_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.phonecall.categ.form</field>
|
||||
<field name="model">crm.phonecall.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Phonecall Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_phonecall_categ_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.phonecall.categ.tree</field>
|
||||
<field name="model">crm.phonecall.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Phonecall Category">
|
||||
<field name="name"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="crm_phonecall_categ_action" model="ir.actions.act_window">
|
||||
<field name="name">Phonecall Categories</field>
|
||||
<field name="res_model">crm.phonecall.categ</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_phonecall_categ_view_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.phonecall')]</field>
|
||||
<field name="context">{'object_id':'crm.phonecall'}</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="crm_phonecall_categ_action" id="menu_crm_case_phonecall-act" parent="crm.menu_crm_case_categ"/>
|
||||
# ------------------------------------------------------
|
||||
# Fund Stage
|
||||
# ------------------------------------------------------
|
||||
<record model="ir.ui.view" id="crm_phonecall_stage_tree">
|
||||
<field name="name">crm.phonecall.stage.tree</field>
|
||||
<field name="model">crm.phonecall.stage</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stages">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="crm_phonecall_stage_form">
|
||||
<field name="name">crm.phonecall.stage.form</field>
|
||||
<field name="model">crm.phonecall.stage</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stage">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_phonecall_stage_act" model="ir.actions.act_window">
|
||||
<field name="name">Phonecall Stages</field>
|
||||
<field name="res_model">crm.phonecall.stage</field>
|
||||
<field name="res_model">crm.case.stage</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_phonecall_stage_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_stage_tree"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.phonecall')]</field>
|
||||
<field name="context">{'object_id':'crm.phonecall'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_phonecall_stage_act" id="menu_crm_phonecall_stage_act" parent="crm.menu_crm_case_stage"/>
|
||||
|
||||
@@ -90,7 +45,7 @@
|
||||
<field name="partner_id" string="Partner"/>
|
||||
<field name="partner_address_id" string="Contact"/>
|
||||
<field name="opportunity_id"/>
|
||||
<button string="Opportunity" name="%(wizard_crm_phonecall_opportunity_set)d" type="action"/>
|
||||
<button string="Opportunity" name="%(wizard_crm_phonecall_opportunity_set)d" type="action" attrs="{'invisible':[('opportunity_id','!=',False)]}" />
|
||||
<button string="Meeting"
|
||||
name="%(wizard_crm_phonecall_meeting_set)d" type="action" />
|
||||
</tree>
|
||||
@@ -109,7 +64,7 @@
|
||||
<field name="partner_address_id" string="Contact"/>
|
||||
<group col="2">
|
||||
<field name="opportunity_id"/>
|
||||
<button string="Opportunity" name="%(wizard_crm_phonecall_opportunity_set)d" type="action"/>
|
||||
<button string="Opportunity" name="%(wizard_crm_phonecall_opportunity_set)d" type="action" attrs="{'invisible':[('opportunity_id','!=',False)]}" />
|
||||
<button string="Meeting"
|
||||
name="%(wizard_crm_phonecall_meeting_set)d" type="action" />
|
||||
</group>
|
||||
@@ -127,7 +82,7 @@
|
||||
<field name="name" string="Subject"/>
|
||||
<field name="section_id" colspan="1" widget="selection"/>
|
||||
<field name="user_id" string="Assigned to" select="2"/>
|
||||
<button string="Convert to Opportunity" name="%(wizard_crm_phonecall_opportunity_set)d" icon="gtk-index" type="action"/>
|
||||
<button string="Convert to Opportunity" name="%(wizard_crm_phonecall_opportunity_set)d" icon="gtk-index" type="action" attrs="{'invisible':[('opportunity_id','!=',False)]}" />
|
||||
<newline/>
|
||||
<field name="date" string="Planned Date"/>
|
||||
<field name="duration"/>
|
||||
@@ -147,7 +102,7 @@
|
||||
<field name="active" string="Reminder"/>
|
||||
<group colspan="2" col="3">
|
||||
<field name="partner_id" string="Partner"/>
|
||||
<button string="Convert to Partner" icon="terp-crm" name="%(wizard_crm_phonecall_partner_create)d" type="action" attrs="{'invisible':[('partner_id','!=',False)]}"/>
|
||||
<button string="Convert to Partner" icon="terp-crm" name="%(wizard_crm_phonecall_partner_create)d" type="action" attrs="{'invisible':[('partner_id','!=',False)]}" />
|
||||
</group>
|
||||
<field name="partner_address_id" string="Contact"/>
|
||||
<field name="partner_phone"/>
|
||||
|
||||
+70
-2
@@ -47,8 +47,76 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_case_section_view_tree"/>
|
||||
</record>
|
||||
<menuitem id="menu_crm_case_stage" name="Stages" parent="crm.menu_crm_configuration"/>
|
||||
<menuitem id="menu_crm_case_categ" name="Categories" parent="crm.menu_crm_configuration"/>
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Stage
|
||||
# ------------------------------------------------------
|
||||
<record model="ir.ui.view" id="crm_case_stage_tree">
|
||||
<field name="name">crm.case.stage.tree</field>
|
||||
<field name="model">crm.case.stage</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stages">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="crm_case_stage_form">
|
||||
<field name="name">crm.case.stage.form</field>
|
||||
<field name="model">crm.case.stage</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stage">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="object_id" invisible="1" />
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_case_stage_act" model="ir.actions.act_window">
|
||||
<field name="name">Stages</field>
|
||||
<field name="res_model">crm.case.stage</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_case_stage_tree"/>
|
||||
</record>
|
||||
<menuitem id="menu_crm_case_stage" name="Stages" parent="crm.menu_crm_configuration"/>
|
||||
<!-- Case Categories -->
|
||||
<record id="crm_case_categ-view" model="ir.ui.view">
|
||||
<field name="name">crm.case.categ.form</field>
|
||||
<field name="model">crm.case.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Case Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="object_id" invisible="1" />
|
||||
<field name="probability"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_case_categ_tree-view" model="ir.ui.view">
|
||||
<field name="name">crm.case.categ.tree</field>
|
||||
<field name="model">crm.case.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Case Category">
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
<field name="probability"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_case_categ-act" model="ir.actions.act_window">
|
||||
<field name="name">Categories</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_case_categ_tree-view"/>
|
||||
</record>
|
||||
<menuitem id="menu_crm_case_categ" name="Categories" parent="crm.menu_crm_configuration"/>
|
||||
|
||||
<menuitem action="crm_case_section_act" id="menu_crm_case_section_act" parent="crm.menu_crm_configuration"/>
|
||||
|
||||
|
||||
+443
-200
File diff suppressed because it is too large
Load Diff
@@ -23,12 +23,8 @@ import crm_opportunity_wizard
|
||||
import crm_lead_wizard
|
||||
import crm_phonecall_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
|
||||
|
||||
|
||||
|
||||
@@ -103,6 +103,8 @@ class lead2opportunity(wizard.interface):
|
||||
'planned_revenue': data['form']['planned_revenue'],
|
||||
'probability': data['form']['probability'],
|
||||
'partner_id': data['form']['partner_id'],
|
||||
'section_id':lead.section_id.id,
|
||||
'description':lead.description,
|
||||
})
|
||||
|
||||
new_opportunity = opportunity_case_obj.browse(cr, uid, new_opportunity_id)
|
||||
@@ -115,7 +117,7 @@ class lead2opportunity(wizard.interface):
|
||||
|
||||
lead_case_obj.write(cr, uid, [lead.id], vals)
|
||||
lead_case_obj.case_cancel(cr, uid, [lead.id])
|
||||
# opportunity_case_obj.case_open(cr, uid, [new_opportunity_id])
|
||||
opportunity_case_obj.case_open(cr, uid, [new_opportunity_id])
|
||||
|
||||
value = {
|
||||
'name': _('Opportunity'),
|
||||
|
||||
@@ -41,20 +41,20 @@ class opportunity2phonecall(wizard.interface):
|
||||
<field name='note' colspan="4"/>
|
||||
<newline />
|
||||
<field name='section_id' />
|
||||
<field name='category_id' domain="[('section_id','=',section_id)]"/>
|
||||
<field name='category_id' domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.phonecall')]"/>
|
||||
</form>"""
|
||||
|
||||
case_fields = {
|
||||
'user_id' : {'string' : 'Assign To', 'type' : 'many2one', 'relation' : 'res.users'},
|
||||
'deadline' : {'string' : 'Planned Date', 'type' : 'datetime'},
|
||||
'deadline' : {'string' : 'Planned Date', 'type' : 'datetime' ,'required' :True},
|
||||
'note' : {'string' : 'Goals', 'type' : 'text'},
|
||||
'category_id' : {'string' : 'Category', 'type' : 'many2one', 'relation' : 'crm.phonecall.categ', 'required' :True},
|
||||
'category_id' : {'string' : 'Category', 'type' : 'many2one', 'relation' : 'crm.case.categ', 'required' :True},
|
||||
'section_id' : {'string' : 'Section', 'type' : 'many2one', 'relation' : 'crm.case.section'},
|
||||
|
||||
}
|
||||
def _default_values(self, cr, uid, data, context):
|
||||
case_obj = pooler.get_pool(cr.dbname).get('crm.opportunity')
|
||||
categ_id = pooler.get_pool(cr.dbname).get('crm.phonecall.categ').search(cr, uid, [('name','=','Outbound')])
|
||||
categ_id = pooler.get_pool(cr.dbname).get('crm.case.categ').search(cr, uid, [('name','=','Outbound')])
|
||||
case = case_obj.browse(cr, uid, data['id'])
|
||||
return {
|
||||
'user_id' : case.user_id and case.user_id.id,
|
||||
@@ -91,9 +91,15 @@ class opportunity2phonecall(wizard.interface):
|
||||
'categ_id' : form['category_id'],
|
||||
'description' : form['note'],
|
||||
'date' : form['deadline'],
|
||||
'section_id' : form['section_id']
|
||||
'section_id' : form['section_id'],
|
||||
'partner_id': opportunity.partner_id.id,
|
||||
'partner_address_id':opportunity.partner_address_id.id,
|
||||
'description':opportunity.description
|
||||
}, context=context)
|
||||
|
||||
vals = {}
|
||||
if not opportunity.phonecall_id:
|
||||
vals.update({'phonecall_id' : new_case})
|
||||
opportunity_case_obj.write(cr, uid, [opportunity.id], vals)
|
||||
opportunity_case_obj.case_cancel(cr, uid, [opportunity.id])
|
||||
phonecall_case_obj.case_open(cr, uid, [new_case])
|
||||
|
||||
@@ -127,6 +133,19 @@ class opportunity2meeting(wizard.interface):
|
||||
|
||||
def _makeMeeting(self, cr, uid, data, context):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
opportunity_case_obj = pool.get('crm.opportunity')
|
||||
meeting_case_obj = pool.get('crm.meeting')
|
||||
for opportunity in opportunity_case_obj.browse(cr, uid, data['ids']):
|
||||
new_meeting_id = meeting_case_obj.create(cr, uid, {
|
||||
'name': opportunity.name,
|
||||
'date': opportunity.date,
|
||||
'date_deadline': opportunity.date_deadline,
|
||||
})
|
||||
new_meeting = meeting_case_obj.browse(cr, uid, new_meeting_id)
|
||||
vals = {}
|
||||
opportunity_case_obj.write(cr, uid, [opportunity.id], vals)
|
||||
opportunity_case_obj.case_cancel(cr, uid, [opportunity.id])
|
||||
meeting_case_obj.case_open(cr, uid, [new_meeting_id])
|
||||
data_obj = pool.get('ir.model.data')
|
||||
result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
|
||||
id = data_obj.read(cr, uid, result, ['res_id'])
|
||||
@@ -203,7 +222,7 @@ class partner_opportunity(wizard.interface):
|
||||
address = part_obj.address_get(cr, uid, data['ids' ])
|
||||
|
||||
|
||||
categ_obj = pool.get('crm.opportunity.categ')
|
||||
categ_obj = pool.get('crm.case.categ')
|
||||
categ_ids = categ_obj.search(cr, uid, [('name','ilike','Part%')])
|
||||
|
||||
case_obj = pool.get('crm.opportunity')
|
||||
|
||||
@@ -104,6 +104,8 @@ class phonecall2opportunity(wizard.interface):
|
||||
'probability': data['form']['probability'],
|
||||
'partner_id': data['form']['partner_id'],
|
||||
'phonecall_id':phonecall.id,
|
||||
'section_id':phonecall.section_id.id,
|
||||
'description':phonecall.description,
|
||||
})
|
||||
new_opportunity = opportunity_case_obj.browse(cr, uid, new_opportunity_id)
|
||||
vals = {
|
||||
@@ -192,6 +194,19 @@ class phonecall2meeting(wizard.interface):
|
||||
|
||||
def _makeMeeting(self, cr, uid, data, context):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
phonecall_case_obj = pool.get('crm.phonecall')
|
||||
meeting_case_obj = pool.get('crm.meeting')
|
||||
for phonecall in phonecall_case_obj.browse(cr, uid, data['ids']):
|
||||
new_meeting_id = meeting_case_obj.create(cr, uid, {
|
||||
'name': phonecall.name,
|
||||
'date': phonecall.date,
|
||||
'duration': phonecall.duration,
|
||||
})
|
||||
new_meeting = meeting_case_obj.browse(cr, uid, new_meeting_id)
|
||||
vals = {}
|
||||
phonecall_case_obj.write(cr, uid, [phonecall.id], vals)
|
||||
phonecall_case_obj.case_cancel(cr, uid, [phonecall.id])
|
||||
meeting_case_obj.case_open(cr, uid, [new_meeting_id])
|
||||
data_obj = pool.get('ir.model.data')
|
||||
result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
|
||||
id = data_obj.read(cr, uid, result, ['res_id'])
|
||||
|
||||
+5
-41
@@ -34,43 +34,6 @@ from osv.orm import except_orm
|
||||
|
||||
from crm import crm
|
||||
|
||||
class crm_job_categ(osv.osv):
|
||||
_name = "crm.job.categ"
|
||||
_description = "Job Categories"
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', size=64, required=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_job_categ()
|
||||
|
||||
class crm_job_type(osv.osv):
|
||||
_name = "crm.job.type"
|
||||
_description = "Job Type"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Claim Type Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
crm_job_type()
|
||||
|
||||
class crm_job_stage(osv.osv):
|
||||
_name = "crm.job.stage"
|
||||
_description = "Stage of job case"
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Stage Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
|
||||
}
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1
|
||||
}
|
||||
crm_job_stage()
|
||||
|
||||
class crm_job(osv.osv):
|
||||
_name = "crm.job"
|
||||
@@ -80,7 +43,7 @@ class crm_job(osv.osv):
|
||||
_columns = {
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'categ_id': fields.many2one('crm.job.categ', 'Category', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.job')]"),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'planned_cost': fields.float('Planned Costs'),
|
||||
'probability': fields.float('Probability (%)'),
|
||||
@@ -88,8 +51,8 @@ class crm_job(osv.osv):
|
||||
'partner_name2': fields.char('Employee Email', size=64),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'stage_id': fields.many2one ('crm.job.stage', 'Stage', domain="[('section_id','=',section_id)]"),
|
||||
'type_id': fields.many2one('crm.job.type', 'Type Name', domain="[('section_id','=',section_id)]"),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.job')]"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Type Name', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.job')]"),
|
||||
'duration': fields.float('Duration'),
|
||||
'case_id': fields.many2one('crm.case', 'Related Case'),
|
||||
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
@@ -99,13 +62,14 @@ class crm_job(osv.osv):
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
|
||||
"the partner mentality in relation to our services.The scale has" \
|
||||
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
|
||||
'phonecall_id':fields.many2one ('crm.phonecall', 'Phonecall'),
|
||||
|
||||
|
||||
}
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.categ.categ').browse(cr, uid, categ, context).probability
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
crm_job()
|
||||
|
||||
@@ -5,60 +5,72 @@
|
||||
|
||||
<!-- CASE CATEGORY(categ_id) -->
|
||||
|
||||
<record model="crm.job.categ" id="categ_job1">
|
||||
<record model="crm.case.categ" id="categ_job1">
|
||||
<field name="name">Salesman</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.job.categ" id="categ_job2">
|
||||
<record model="crm.case.categ" id="categ_job2">
|
||||
<field name="name">Junior Developer</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!-- CATEGORY2(category2_id) -->
|
||||
<!-- Resource(type_id) -->
|
||||
|
||||
<record model="crm.job.type" id="type_job1">
|
||||
<record model="crm.case.resource.type" id="type_job1">
|
||||
<field name="name">Graduate</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.job.type" id="type_job2">
|
||||
<record model="crm.case.resource.type" id="type_job2">
|
||||
<field name="name">Licenced</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.job.type" id="type_job3">
|
||||
<record model="crm.case.resource.type" id="type_job3">
|
||||
<field name="name"> > Bac +5</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!-- STAGE(stage_id) -->
|
||||
|
||||
<record model="crm.job.stage" id="stage_job1">
|
||||
<record model="crm.case.stage" id="stage_job1">
|
||||
<field name="name">Initial Jobs Demand</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.job.stage" id="stage_job2">
|
||||
<record model="crm.case.stage" id="stage_job2">
|
||||
<field name="name">First Interview</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.job.stage" id="stage_job3">
|
||||
<record model="crm.case.stage" id="stage_job3">
|
||||
<field name="name">Second Interview</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.job.stage" id="stage_job4">
|
||||
<record model="crm.case.stage" id="stage_job4">
|
||||
<field name="name">Contract Proposed</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.claim')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.job.stage" id="stage_job5">
|
||||
<record model="crm.case.stage" id="stage_job5">
|
||||
<field name="name">Contract Signed</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.job.stage" id="stage_job6">
|
||||
<record model="crm.case.stage" id="stage_job6">
|
||||
<field name="name">Refused by Employee</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.job.stage" id="stage_job7">
|
||||
<record model="crm.case.stage" id="stage_job7">
|
||||
<field name="name">Refused by Company</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.job')]" model="ir.model"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -5,70 +5,25 @@
|
||||
# ------------------------------------------------------
|
||||
# Job Categories
|
||||
# ------------------------------------------------------
|
||||
|
||||
<record id="crm_job_categ_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.job.categ.form</field>
|
||||
<field name="model">crm.job.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Job Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_job_categ_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.job.categ.tree</field>
|
||||
<field name="model">crm.job.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Job Category">
|
||||
<field name="name"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_job_categ_action" model="ir.actions.act_window">
|
||||
<field name="name">Job Categories</field>
|
||||
<field name="res_model">crm.job.categ</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_job_categ_view_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.claim')]</field>
|
||||
<field name="context">{'object_id':'crm.job'}</field>
|
||||
</record>
|
||||
# ------------------------------------------------------
|
||||
# Stage
|
||||
# Stage
|
||||
# ------------------------------------------------------
|
||||
<record model="ir.ui.view" id="crm_job_stage_tree">
|
||||
<field name="name">crm.job.stage.tree</field>
|
||||
<field name="model">crm.job.stage</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stages">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="crm_job_stage_form">
|
||||
<field name="name">crm.job.stage.form</field>
|
||||
<field name="model">crm.job.stage</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stage">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_job_stage_act" model="ir.actions.act_window">
|
||||
<field name="name">Job Stages</field>
|
||||
<field name="res_model">crm.claim.stage</field>
|
||||
<field name="res_model">crm.case.stage</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_job_stage_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_stage_tree"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.claim')]</field>
|
||||
<field name="context">{'object_id':'crm.job'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_job_stage_act" id="menu_crm_job_stage_act" parent="crm.menu_crm_case_stage"/>
|
||||
# ------------------------------------------------------
|
||||
@@ -110,8 +65,6 @@
|
||||
<field name="name" string="Description" colspan="2"/>
|
||||
<field name="section_id" colspan="1" widget="selection"/>
|
||||
<field name="user_id" string="Responsible" select="2"/>
|
||||
<button string="Schedule a Phone Call"
|
||||
name="%(wizard_crm_job_reschedule_phone_call)d" icon="gtk-redo" type="action" />
|
||||
<newline/>
|
||||
<label string="Stage: " align="1.0"/>
|
||||
<group colspan="1" col="2">
|
||||
@@ -121,6 +74,10 @@
|
||||
<field name="date" string="Next Interview"/>
|
||||
<field name="duration" widget="float_time"/>
|
||||
<button name="%(wizard_crm_job_meeting_set)d" string="Schedule Meeting" icon="terp-crm" type="action"/>
|
||||
<field name="phonecall_id" select="1"/>
|
||||
<button string="Schedule a Phone Call"
|
||||
name="%(wizard_crm_job_reschedule_phone_call)d" icon="gtk-redo" type="action" attrs="{'invisible':[('phonecall_id','!=',False)]}"/>
|
||||
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Job Info">
|
||||
|
||||
@@ -58,7 +58,8 @@ class job2phonecall(wizard.interface):
|
||||
case = case_obj.browse(cr, uid, data['id'])
|
||||
return {
|
||||
'user_id' : case.user_id and case.user_id.id,
|
||||
'category_id' : categ_id and categ_id[0] or case.categ_id and case.categ_id.id,
|
||||
'category_id' : categ_id and categ_id[0] or case.categ_id and case.categ_id.id,
|
||||
'section_id' : case.section_id and case.section_id.id or False,
|
||||
'note' : case.description
|
||||
}
|
||||
|
||||
@@ -84,17 +85,23 @@ class job2phonecall(wizard.interface):
|
||||
#TODO : Take other info from job
|
||||
new_phonecall_id = phonecall_case_obj.create(cr, uid, {
|
||||
'name' : job.name,
|
||||
'case_id' : job.inherit_case_id.id,
|
||||
'user_id' : form['user_id'],
|
||||
'categ_id' : form['category_id'],
|
||||
'description' : form['note'],
|
||||
'date' : form['deadline'],
|
||||
'section_id' : form['section_id']
|
||||
'section_id' : form['section_id'],
|
||||
'description':job.description,
|
||||
'partner_id':job.partner_id.id,
|
||||
'partner_address_id':job.partner_address_id.id,
|
||||
'partner_phone':job.partner_phone,
|
||||
'partner_mobile':job.partner_mobile,
|
||||
'description':job.description,
|
||||
'date':job.date,
|
||||
}, context=context)
|
||||
new_phonecall = phonecall_case_obj.browse(cr, uid, new_phonecall_id)
|
||||
vals = {}
|
||||
if not job.case_id:
|
||||
vals.update({'case_id' : new_phonecall.inherit_case_id.id})
|
||||
vals.update({'phonecall_id' : new_phonecall.id})
|
||||
job_case_obj.write(cr, uid, [job.id], vals)
|
||||
job_case_obj.case_cancel(cr, uid, [job.id])
|
||||
phonecall_case_obj.case_open(cr, uid, [new_phonecall_id])
|
||||
@@ -128,6 +135,20 @@ class job2meeting(wizard.interface):
|
||||
|
||||
def _makeMeeting(self, cr, uid, data, context):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
job_case_obj = pool.get('crm.job')
|
||||
meeting_case_obj = pool.get('crm.meeting')
|
||||
for job in job_case_obj.browse(cr, uid, data['ids']):
|
||||
new_meeting_id = meeting_case_obj.create(cr, uid, {
|
||||
'name': job.name,
|
||||
'date': job.date,
|
||||
'duration': job.duration,
|
||||
})
|
||||
new_meeting = meeting_case_obj.browse(cr, uid, new_meeting_id)
|
||||
vals = {}
|
||||
job_case_obj.write(cr, uid, [job.id], vals)
|
||||
job_case_obj.case_cancel(cr, uid, [job.id])
|
||||
meeting_case_obj.case_open(cr, uid, [new_meeting_id])
|
||||
|
||||
data_obj = pool.get('ir.model.data')
|
||||
result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
|
||||
id = data_obj.read(cr, uid, result, ['res_id'])
|
||||
|
||||
@@ -6,30 +6,35 @@
|
||||
-->
|
||||
<!-- For Bugs -->
|
||||
|
||||
<record model="crm.bug.categ" id="categ1">
|
||||
<record model="crm.case.categ" id="categ1">
|
||||
<field name="name">Bugs</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.categ" id="categ2">
|
||||
<record model="crm.case.categ" id="categ2">
|
||||
<field name="name">Patches</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.categ" id="categ3">
|
||||
<record model="crm.case.categ" id="categ3">
|
||||
<field name="name">Feature Requests</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Case Category2
|
||||
Case type_id
|
||||
-->
|
||||
<!-- For Bugs -->
|
||||
<record model="crm.bug.type" id="type1">
|
||||
<record model="crm.case.resource.type" id="type1">
|
||||
<field name="name">Version 4.2</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.type" id="type2">
|
||||
<record model="crm.case.resource.type" id="type2">
|
||||
<field name="name">Version 4.4</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
@@ -37,33 +42,40 @@
|
||||
-->
|
||||
<!-- For Bugs -->
|
||||
|
||||
<record model="crm.bug.stage" id="stage1">
|
||||
<record model="crm.case.stage" id="stage1">
|
||||
<field name="name">Accepted as Bug</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage2">
|
||||
<record model="crm.case.stage" id="stage2">
|
||||
<field name="name">Fixed</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage3">
|
||||
<record model="crm.case.stage" id="stage3">
|
||||
<field name="name">Won't fix</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage4">
|
||||
<record model="crm.case.stage" id="stage4">
|
||||
<field name="name">Invalid</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage5">
|
||||
<record model="crm.case.stage" id="stage5">
|
||||
<field name="name">Awaiting Response</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage6">
|
||||
<record model="crm.case.stage" id="stage6">
|
||||
<field name="name">Works For Me</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage7">
|
||||
<record model="crm.case.stage" id="stage7">
|
||||
<field name="name">Future</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -3,29 +3,35 @@
|
||||
<data noupdate="1">
|
||||
|
||||
|
||||
<record model="crm.bug.categ" id="categ1">
|
||||
<record model="crm.case.categ" id="categ1">
|
||||
<field name="name">Bugs</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.categ" id="categ2">
|
||||
<record model="crm.case.categ" id="categ2">
|
||||
<field name="name">Patches</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.categ" id="categ3">
|
||||
<record model="crm.case.categ" id="categ3">
|
||||
<field name="name">Feature Requests</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage2">
|
||||
<record model="crm.case.stage" id="stage2">
|
||||
<field name="name">Fixed</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage5">
|
||||
<record model="crm.case.stage" id="stage5">
|
||||
<field name="name">Awaiting Response</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="stage7">
|
||||
<record model="crm.case.stage" id="stage7">
|
||||
<field name="name">Future</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.bug')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
@@ -7,70 +7,25 @@
|
||||
# Bug Categories
|
||||
# ------------------------------------------------------
|
||||
|
||||
|
||||
<record id="crm_bug_categ_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.bug.categ.form</field>
|
||||
<field name="model">crm.bug.categ</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Bug Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_bug_categ_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.bug.categ.tree</field>
|
||||
<field name="model">crm.bug.categ</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Bug Category">
|
||||
<field name="name"/>
|
||||
<field name="probability"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_bug_categ_action" model="ir.actions.act_window">
|
||||
<field name="name">Bug Categories</field>
|
||||
<field name="res_model">crm.bug.categ</field>
|
||||
<field name="res_model">crm.case.categ</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_bug_categ_view_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.project.bug')]</field>
|
||||
<field name="context">{'object_id':'crm.project.bug'}</field>
|
||||
</record>
|
||||
# ------------------------------------------------------
|
||||
# Stage
|
||||
# ------------------------------------------------------
|
||||
<record model="ir.ui.view" id="crm_bug_stage_tree">
|
||||
<field name="name">crm.bug.stage.tree</field>
|
||||
<field name="model">crm.bug.stage</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stages">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="crm_bug_stage_form">
|
||||
<field name="name">crm.bug.stage.form</field>
|
||||
<field name="model">crm.bug.stage</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stage">
|
||||
<field name="name" select="1"/>
|
||||
<field name="section_id" select="1" widget="selection"/>
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_bug_stage_act" model="ir.actions.act_window">
|
||||
<field name="name">Bug Stages</field>
|
||||
<field name="res_model">crm.bug.stage</field>
|
||||
<field name="res_model">crm.case.stage</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_bug_stage_tree"/>
|
||||
<field name="view_id" ref="crm.crm_case_stage_tree"/>
|
||||
<field name="domain">[('object_id.model', '=', 'crm.project.bug')]</field>
|
||||
<field name="context">{'object_id':'crm.project.bug'}</field>
|
||||
</record>
|
||||
<menuitem action="crm_bug_stage_act" id="menu_crm_bug_stage_act" parent="crm.menu_crm_case_stage"/>
|
||||
|
||||
|
||||
@@ -3,17 +3,20 @@
|
||||
<data noupdate="1">
|
||||
|
||||
|
||||
<record model="crm.bug.categ" id="future_patch_categ">
|
||||
<record model="crm.case.categ" id="future_patch_categ">
|
||||
<field name="name">Patches</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.future')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="future_fixed_categ">
|
||||
<record model="crm.case.stage" id="future_fixed_categ">
|
||||
<field name="name">Fixed</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.future')]" model="ir.model"/>
|
||||
</record>
|
||||
<record model="crm.bug.stage" id="future_awaiting_categ">
|
||||
<record model="crm.case.stage" id="future_awaiting_categ">
|
||||
<field name="name">Awaiting Response</field>
|
||||
<field name="section_id" ref="crm.section_sales_department"/>
|
||||
<field name="object_id" search="[('model','=','crm.project.future')]" model="ir.model"/>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
@@ -34,44 +34,6 @@ from osv.orm import except_orm
|
||||
|
||||
from crm import crm
|
||||
|
||||
class crm_bug_categ(osv.osv):
|
||||
_name = "crm.bug.categ"
|
||||
_description = " Bug Categories"
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', size=64, required=True),
|
||||
'probability': fields.float('Probability (%)', required=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
_defaults = {
|
||||
'probability': lambda *args: 0.0
|
||||
}
|
||||
crm_bug_categ()
|
||||
|
||||
class crm_bug_type(osv.osv):
|
||||
_name = "crm.bug.type"
|
||||
_description = "Bug Type"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Claim Type Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
}
|
||||
|
||||
crm_bug_type()
|
||||
|
||||
class crm_bug_stage(osv.osv):
|
||||
_name = "crm.bug.stage"
|
||||
_description = "Stage of Project Bug"
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Stage Name', size=64, required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Case Section'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
|
||||
}
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1
|
||||
}
|
||||
crm_bug_stage()
|
||||
|
||||
class crm_project_bug(osv.osv):
|
||||
_name = "crm.project.bug"
|
||||
@@ -89,14 +51,14 @@ class crm_project_bug(osv.osv):
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
|
||||
"the partner mentality in relation to our services.The scale has" \
|
||||
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
|
||||
'categ_id': fields.many2one('crm.bug.categ','Category', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.project.bug')]"),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'type_id': fields.many2one('crm.bug.type', 'Bug Type', domain="[('section_id','=',section_id)]"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Bug Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.project.bug')]"),
|
||||
|
||||
'partner_name': fields.char("Employee's Name", size=64),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'stage_id': fields.many2one ('crm.bug.stage', 'Stage', domain="[('section_id','=',section_id)]"),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.project.bug')]"),
|
||||
'project_id':fields.many2one('project.project', 'Project'),
|
||||
'duration': fields.float('Duration') ,
|
||||
'probability': fields.float('Probability (%)'),
|
||||
@@ -114,7 +76,7 @@ class crm_project_bug(osv.osv):
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.bug.categ').browse(cr, uid, categ, context).probability
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
|
||||
|
||||
@@ -50,14 +50,14 @@ class crm_project_future_request(osv.osv):
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
|
||||
"the partner mentality in relation to our services.The scale has" \
|
||||
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
|
||||
'categ_id': fields.many2one('crm.bug.categ','Category', domain="[('section_id','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.project.future')]"),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'type_id': fields.many2one('crm.bug.type', 'Bug Type', domain="[('section_id','=',section_id)]"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Bug Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.project.future')]"),
|
||||
|
||||
'partner_name': fields.char("Employee's Name", size=64),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'stage_id': fields.many2one ('crm.bug.stage', 'Stage', domain="[('section_id','=',section_id)]"),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.project.future')]"),
|
||||
'project_id':fields.many2one('project.project', 'Project'),
|
||||
'duration': fields.float('Duration') ,
|
||||
'probability': fields.float('Probability (%)'),
|
||||
@@ -71,6 +71,12 @@ class crm_project_future_request(osv.osv):
|
||||
_defaults = {
|
||||
'project_id':_get_project
|
||||
}
|
||||
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
|
||||
if not categ:
|
||||
return {'value':{}}
|
||||
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
|
||||
return {'value':{'probability':cat}}
|
||||
|
||||
|
||||
crm_project_future_request()
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import netsvc
|
||||
import pooler
|
||||
import tools
|
||||
from tools.translate import _
|
||||
from crm import crm
|
||||
|
||||
class crm_case_log(osv.osv):
|
||||
_inherit = 'crm.case.log'
|
||||
@@ -241,6 +242,16 @@ class event_registration(osv.osv):
|
||||
"invoice_label":fields.char("Label Invoice",size=128,required=True),
|
||||
"tobe_invoiced":fields.boolean("To be Invoiced"),
|
||||
"invoice_id":fields.many2one("account.invoice","Invoice"),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128),
|
||||
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id)]"),
|
||||
'canal_id': fields.many2one('res.partner.canal', 'Channel',help="The channels represent the different communication modes available with the customer." \
|
||||
" With each commercial opportunity, you can indicate the canall which is this opportunity source."),
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
|
||||
"the partner mentality in relation to our services.The scale has" \
|
||||
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
|
||||
|
||||
}
|
||||
_defaults = {
|
||||
'nb_register': lambda *a: 1,
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
""",
|
||||
'author': 'Tiny',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base', 'process'],
|
||||
'depends': ['base', 'process', 'resource'],
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
'security/hr_security.xml',
|
||||
@@ -46,7 +46,8 @@
|
||||
'process/hr_process.xml',
|
||||
'hr_installer.xml'
|
||||
],
|
||||
'demo_xml': ['hr_demo.xml', 'hr_department_demo.xml'],
|
||||
'demo_xml': ['hr_demo.xml',
|
||||
'hr_department_demo.xml'],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '0086710558965',
|
||||
|
||||
Regular → Executable
+13
-95
@@ -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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
@@ -26,78 +26,16 @@ import math
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
|
||||
class hr_timesheet_group(osv.osv):
|
||||
_name = "hr.timesheet.group"
|
||||
_description = "Working Time"
|
||||
_columns = {
|
||||
'name' : fields.char("Group name", size=64, required=True),
|
||||
'timesheet_id' : fields.one2many('hr.timesheet', 'tgroup_id', 'Working Time'),
|
||||
'manager' : fields.many2one('res.users', 'Workgroup manager'),
|
||||
}
|
||||
def interval_min_get(self, cr, uid, id, dt_from, hours):
|
||||
if not id:
|
||||
return [(dt_from-DateTime.RelativeDateTime(hours=int(hours)*3), dt_from)]
|
||||
todo = hours
|
||||
cycle = 0
|
||||
result = []
|
||||
maxrecur = 100
|
||||
current_hour = dt_from.hour
|
||||
while (todo>0) and maxrecur:
|
||||
cr.execute("select hour_from,hour_to from hr_timesheet where dayofweek='%s' and tgroup_id=%s order by hour_from desc", (dt_from.day_of_week,id))
|
||||
for (hour_from,hour_to) in cr.fetchall():
|
||||
if (hour_from<current_hour) and (todo>0):
|
||||
m = min(hour_to, current_hour)
|
||||
if (m-hour_from)>todo:
|
||||
hour_from = m-todo
|
||||
d1 = DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_from)),int((hour_from%1) * 60))
|
||||
d2 = DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
|
||||
result.append((d1, d2))
|
||||
current_hour = hour_from
|
||||
todo -= (m-hour_from)
|
||||
dt_from -= DateTime.RelativeDateTime(days=1)
|
||||
current_hour = 24
|
||||
maxrecur -= 1
|
||||
result.reverse()
|
||||
return result
|
||||
|
||||
def interval_get(self, cr, uid, id, dt_from, hours, byday=True):
|
||||
if not id:
|
||||
return [(dt_from,dt_from+DateTime.RelativeDateTime(hours=int(hours)*3))]
|
||||
todo = hours
|
||||
cycle = 0
|
||||
result = []
|
||||
maxrecur = 100
|
||||
current_hour = dt_from.hour
|
||||
while (todo>0) and maxrecur:
|
||||
cr.execute("select hour_from,hour_to from hr_timesheet where dayofweek='%s' and tgroup_id=%s order by hour_from", (dt_from.day_of_week,id))
|
||||
for (hour_from,hour_to) in cr.fetchall():
|
||||
if (hour_to>current_hour) and (todo>0):
|
||||
m = max(hour_from, current_hour)
|
||||
if (hour_to-m)>todo:
|
||||
hour_to = m+todo
|
||||
d1 = DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
|
||||
d2 = DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
|
||||
result.append((d1, d2))
|
||||
current_hour = hour_to
|
||||
todo -= (hour_to - m)
|
||||
dt_from += DateTime.RelativeDateTime(days=1)
|
||||
current_hour = 0
|
||||
maxrecur -= 1
|
||||
return result
|
||||
|
||||
hr_timesheet_group()
|
||||
|
||||
|
||||
class hr_employee_category(osv.osv):
|
||||
_name = "hr.employee.category"
|
||||
_description = "Employee Category"
|
||||
|
||||
|
||||
_columns = {
|
||||
'name' : fields.char("Category", size=64, required=True),
|
||||
'parent_id': fields.many2one('hr.employee.category', 'Parent Category', select=True),
|
||||
'child_ids': fields.one2many('hr.employee.category', 'parent_id', 'Child Categories')
|
||||
}
|
||||
|
||||
|
||||
def _check_recursion(self, cr, uid, ids):
|
||||
level = 100
|
||||
while len(ids):
|
||||
@@ -107,23 +45,18 @@ class hr_employee_category(osv.osv):
|
||||
return False
|
||||
level -= 1
|
||||
return True
|
||||
|
||||
|
||||
_constraints = [
|
||||
(_check_recursion, 'Error ! You cannot create recursive Categories.', ['parent_id'])
|
||||
]
|
||||
|
||||
|
||||
hr_employee_category()
|
||||
|
||||
class hr_employee(osv.osv):
|
||||
_name = "hr.employee"
|
||||
_description = "Employee"
|
||||
|
||||
_inherits = {'resource.resource':"resource_id"}
|
||||
_columns = {
|
||||
'name' : fields.char("Employee's Name", size=128, required=True),
|
||||
'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the employee record without removing it."),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'user_id' : fields.many2one('res.users', 'Related User', help='Related user name for an employee to manage his access rights.'),
|
||||
|
||||
'country_id' : fields.many2one('res.country', 'Nationality'),
|
||||
'birthday' : fields.date("Birthday"),
|
||||
'ssnid': fields.char('SSN No', size=32, help='Social Security Number'),
|
||||
@@ -134,19 +67,20 @@ class hr_employee(osv.osv):
|
||||
|
||||
'address_id': fields.many2one('res.partner.address', 'Working Address'),
|
||||
'address_home_id': fields.many2one('res.partner.address', 'Home Address'),
|
||||
'work_phone': fields.char('Work Phone', size=32),
|
||||
'work_email': fields.char('Work Email', size=128),
|
||||
'work_phone': fields.related('address_id', 'phone', type='char', string='Work Phone'),
|
||||
'work_email': fields.related('address_id', 'email', type='char', string='Work E-mail'),
|
||||
'work_location': fields.char('Office Location', size=32),
|
||||
|
||||
'notes': fields.text('Notes'),
|
||||
'parent_id': fields.many2one('hr.employee', 'Manager', select=True),
|
||||
'category_id' : fields.many2one('hr.employee.category', 'Category'),
|
||||
'child_ids': fields.one2many('hr.employee', 'parent_id','Subordinates'),
|
||||
'resource_id': fields.many2one('resource.resource','Resource',ondelete='cascade'),
|
||||
}
|
||||
_defaults = {
|
||||
'active' : lambda *a: True,
|
||||
}
|
||||
|
||||
|
||||
def _check_recursion(self, cr, uid, ids):
|
||||
level = 100
|
||||
while len(ids):
|
||||
@@ -156,26 +90,10 @@ class hr_employee(osv.osv):
|
||||
return False
|
||||
level -= 1
|
||||
return True
|
||||
|
||||
|
||||
_constraints = [
|
||||
(_check_recursion, 'Error ! You cannot create recursive Hierarchy of Employees.', ['parent_id'])
|
||||
]
|
||||
|
||||
|
||||
hr_employee()
|
||||
|
||||
class hr_timesheet(osv.osv):
|
||||
_name = "hr.timesheet"
|
||||
_description = "Timesheet Line"
|
||||
_columns = {
|
||||
'name' : fields.char("Name", size=64, required=True),
|
||||
'dayofweek': fields.selection([('0','Monday'),('1','Tuesday'),('2','Wednesday'),('3','Thursday'),('4','Friday'),('5','Saturday'),('6','Sunday')], 'Day of week'),
|
||||
'date_from' : fields.date('Starting date'),
|
||||
'hour_from' : fields.float('Work from', size=8, required=True),
|
||||
'hour_to' : fields.float("Work to", size=8, required=True),
|
||||
'tgroup_id' : fields.many2one("hr.timesheet.group", "Employee's timesheet group", select=True),
|
||||
}
|
||||
_order = 'dayofweek, hour_from'
|
||||
hr_timesheet()
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
+26
-26
@@ -1,90 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<!-- Example employee -->
|
||||
|
||||
<record id="timesheet_group1" model="hr.timesheet.group">
|
||||
|
||||
<record id="timesheet_group1" model="resource.calendar">
|
||||
<field name="name">38 Hours/Week</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="employee1" model="hr.employee">
|
||||
<field name="name">Fabien Pinckaers</field>
|
||||
<!--<field name="regime">45</field>-->
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<!--<field name="holiday_max">25</field>-->
|
||||
</record>
|
||||
|
||||
<record model="hr.timesheet">
|
||||
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Monday morning</field>
|
||||
<field name="dayofweek">0</field>
|
||||
<field name="hour_from">08</field>
|
||||
<field name="hour_to">12</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Monday evening</field>
|
||||
<field name="dayofweek">0</field>
|
||||
<field name="hour_from">13</field>
|
||||
<field name="hour_to">18</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Tuesday morning</field>
|
||||
<field name="dayofweek">1</field>
|
||||
<field name="hour_from">08</field>
|
||||
<field name="hour_to">12</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Tuesday evening</field>
|
||||
<field name="dayofweek">1</field>
|
||||
<field name="hour_from">13</field>
|
||||
<field name="hour_to">18</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Wednesday morning</field>
|
||||
<field name="dayofweek">2</field>
|
||||
<field name="hour_from">08</field>
|
||||
<field name="hour_to">12</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Wednesday evening</field>
|
||||
<field name="dayofweek">2</field>
|
||||
<field name="hour_from">13</field>
|
||||
<field name="hour_to">18</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Thursday morning</field>
|
||||
<field name="dayofweek">3</field>
|
||||
<field name="hour_from">08</field>
|
||||
<field name="hour_to">12</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Thursday evening</field>
|
||||
<field name="hour_from">13</field>
|
||||
<field name="hour_to">18</field>
|
||||
<field name="dayofweek">3</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Friday morning</field>
|
||||
<field name="dayofweek">4</field>
|
||||
<field name="hour_from">08</field>
|
||||
<field name="hour_to">12</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
<record model="hr.timesheet">
|
||||
<record model="resource.calendar.week">
|
||||
<field name="name">Friday evening</field>
|
||||
<field name="dayofweek">4</field>
|
||||
<field name="hour_from">13</field>
|
||||
<field name="hour_to">18</field>
|
||||
<field name="tgroup_id" ref="timesheet_group1"/>
|
||||
<field name="calendar_id" ref="timesheet_group1"/>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
+7
-59
@@ -12,8 +12,12 @@
|
||||
id="menu_hr_configuration"
|
||||
name="Configuration"
|
||||
parent="hr.menu_hr_root"
|
||||
sequence="50" groups="group_hr_manager"/>
|
||||
|
||||
sequence="50" />
|
||||
<!-- <menuitem
|
||||
id="menu_hr_time"
|
||||
name="Time Tracking"
|
||||
parent="hr.menu_hr_root"/>
|
||||
-->
|
||||
<menuitem id="menu_view_employee_category_configuration_form" parent="hr.menu_hr_configuration" name="Employees" sequence="1"/>
|
||||
<!--
|
||||
==========
|
||||
@@ -105,6 +109,7 @@
|
||||
</record>
|
||||
<!-- <menuitem
|
||||
id="menu_open_view_employee_list"
|
||||
name="Employees"
|
||||
action="open_view_employee_list"
|
||||
groups="group_hr_manager"
|
||||
parent="menu_hr_human_resources"/>
|
||||
@@ -167,62 +172,6 @@
|
||||
<field eval="True" name="replace"/>
|
||||
</ir_set>
|
||||
|
||||
|
||||
<!--
|
||||
============
|
||||
Working Time
|
||||
============
|
||||
-->
|
||||
<record id="create_group" model="ir.ui.view">
|
||||
<field name="name">hr.timesheet.group.form</field>
|
||||
<field name="model">hr.timesheet.group</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Working Time Category">
|
||||
<field name="name" select="1"/>
|
||||
<field name="manager" select="1"/>
|
||||
<newline/>
|
||||
<field colspan="4" name="timesheet_id" nolabel="1" widget="one2many_list"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="edit_workgroup" model="ir.actions.act_window">
|
||||
<field name="name">Working Schedules</field>
|
||||
<field name="res_model">hr.timesheet.group</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
<menuitem action="edit_workgroup" id="menu_edit_workgroup" name="Work Schedules" parent="menu_view_employee_category_configuration_form" sequence="4"/>
|
||||
|
||||
<record id="view_timesheet_tree" model="ir.ui.view">
|
||||
<field name="name">hr.timesheet.tree</field>
|
||||
<field name="model">hr.timesheet</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Working Time">
|
||||
<field name="name"/>
|
||||
<field name="dayofweek"/>
|
||||
<field name="hour_from" widget="float_time"/>
|
||||
<field name="hour_to" widget="float_time"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_timesheet_form" model="ir.ui.view">
|
||||
<field name="name">hr.timesheet.form</field>
|
||||
<field name="model">hr.timesheet</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Working Time">
|
||||
<field colspan="4" name="name" select="1"/>
|
||||
<field name="date_from"/>
|
||||
<field name="dayofweek" select="1"/>
|
||||
<field name="hour_from" widget="float_time"/>
|
||||
<field name="hour_to" widget="float_time"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
============
|
||||
Employee Category
|
||||
@@ -272,7 +221,6 @@
|
||||
|
||||
<menuitem action="open_view_categ_form" id="menu_view_employee_category_form" parent="menu_view_employee_category_configuration_form" sequence="1"/>
|
||||
|
||||
|
||||
<record id="open_view_categ_tree" model="ir.actions.act_window">
|
||||
<field name="name">Categories structure</field>
|
||||
<field name="res_model">hr.employee.category</field>
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"access_hr_timesheet_group","hr.timesheet.group","model_hr_timesheet_group","hr.group_hr_user",1,0,0,0
|
||||
"access_hr_employee_category","hr.employee.category","model_hr_employee_category","hr.group_hr_user",1,0,0,0
|
||||
"access_hr_employee","hr.employee","model_hr_employee","hr.group_hr_user",1,1,1,1
|
||||
"access_hr_timesheet_manager","hr.timesheet manager","model_hr_timesheet","hr.group_hr_manager",1,1,1,1
|
||||
"access_hr_timesheet","hr.timesheet","model_hr_timesheet","hr.group_hr_user",1,1,1,1
|
||||
"access_hr_department","hr.department","model_hr_department","hr.group_hr_user",1,0,0,0
|
||||
"access_hr_timesheet_group_manager","hr.timesheet.group.manager","model_hr_timesheet_group","hr.group_hr_manager",1,1,1,1
|
||||
"access_hr_employee_category_manager","hr.employee.category.manager","model_hr_employee_category","hr.group_hr_manager",1,1,1,1
|
||||
"access_hr_department_manager","hr.department.manager","model_hr_department","hr.group_hr_manager",1,1,1,1
|
||||
|
||||
|
@@ -114,7 +114,11 @@ class hr_employee(osv.osv):
|
||||
def attendance_action_change(self, cr, uid, ids, type='action', context={}, dt=False, *args):
|
||||
id = False
|
||||
warning_sign = 'sign'
|
||||
|
||||
|
||||
#Special case when button calls this method :type=context
|
||||
if isinstance(type,dict):
|
||||
type = type.get('type','action')
|
||||
|
||||
if type == 'sign_in':
|
||||
warning_sign = "Sign In"
|
||||
elif type == 'sign_out':
|
||||
@@ -125,7 +129,7 @@ class hr_employee(osv.osv):
|
||||
raise osv.except_osv(_('Warning'), _('You tried to %s with a date anterior to another event !\nTry to contact the administrator to correct attendances.')%(warning_sign,))
|
||||
|
||||
res = {'action' : type, 'employee_id' : emp['id']}
|
||||
|
||||
|
||||
if dt:
|
||||
res['name'] = dt
|
||||
|
||||
|
||||
@@ -88,8 +88,8 @@
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_attendance_reason"/>
|
||||
</record>
|
||||
<menuitem sequence="9" id="menu_open_view_attendance_reason_config" parent="hr.menu_hr_configuration" name="Leaves"/>
|
||||
<menuitem action="open_view_attendance_reason" id="menu_open_view_attendance_reason" parent="menu_open_view_attendance_reason_config"/>
|
||||
<menuitem sequence="9" id="hr.menu_open_view_attendance_reason_config" parent="hr.menu_hr_configuration" name="Leaves"/>
|
||||
<menuitem action="open_view_attendance_reason" id="menu_open_view_attendance_reason" parent="hr.menu_open_view_attendance_reason_config"/>
|
||||
|
||||
<record id="hr_attendance_employee" model="ir.ui.view">
|
||||
<field name="name">hr.employee.form1</field>
|
||||
@@ -99,8 +99,8 @@
|
||||
<field name="arch" type="xml">
|
||||
<field name="parent_id" position="after">
|
||||
<field name="state"/>
|
||||
<button name="sign_in" states="absent" string="Sign In" type="object" icon="gtk-go-back"/>
|
||||
<button name="sign_out" states="present" string="Sign Out" type="object" icon="gtk-go-forward"/>
|
||||
<button name="attendance_action_change" states="absent" string="Sign In" type="object" icon="gtk-go-back" context="{'type':'sign_in'}"/>
|
||||
<button name="attendance_action_change" states="present" string="Sign Out" type="object" icon="gtk-go-forward" context="{'type':'sign_out'}"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
@@ -85,7 +85,7 @@ class hr_contract(osv.osv):
|
||||
'function' : fields.many2one('res.partner.function', 'Function'),
|
||||
'date_start' : fields.date('Start Date', required=True),
|
||||
'date_end' : fields.date('End Date'),
|
||||
'working_hours_per_day_id' : fields.many2one('hr.timesheet.group','Working hours per day'),
|
||||
'working_hours_per_day_id' : fields.many2one('resource.calendar','Working hours per day'),
|
||||
'wage_type_id' : fields.many2one('hr.contract.wage.type', 'Wage Type', required=True),
|
||||
'wage' : fields.float('Wage', required=True),
|
||||
'notes' : fields.text('Notes'),
|
||||
|
||||
Regular → Executable
+17
-9
@@ -54,7 +54,7 @@ class hr_holidays_status(osv.osv):
|
||||
return_false = False
|
||||
if context and context.has_key('employee_id'):
|
||||
if not context['employee_id']:
|
||||
return_false = True
|
||||
return_false = True
|
||||
employee_id = context['employee_id']
|
||||
else:
|
||||
employee_ids = self.pool.get('hr.employee').search(cr, uid, [('user_id','=',uid)])
|
||||
@@ -71,9 +71,9 @@ class hr_holidays_status(osv.osv):
|
||||
'color_name' : fields.selection([('red', 'Red'), ('lightgreen', 'Light Green'), ('lightblue','Light Blue'), ('lightyellow', 'Light Yellow'), ('magenta', 'Magenta'),('lightcyan', 'Light Cyan'),('black', 'Black'),('lightpink', 'Light Pink'),('brown', 'Brown'),('violet', 'Violet'),('lightcoral', 'Light Coral'),('lightsalmon', 'Light Salmon'),('lavender', 'Lavender'),('wheat', 'Wheat'),('ivory', 'Ivory')],'Color of the status', required=True, help='This color will be used in the leaves summary located in Reporting\Print Summary of Leaves'),
|
||||
'limit' : fields.boolean('Allow to override Limit', help='If you thick this checkbox, the system will allow, for this section, the employees to take more leaves than the available ones.'),
|
||||
'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the leave type without removing it."),
|
||||
'max_leaves' : fields.function(_user_left_days, method=True, string='Maximum Leaves Allowed', help='This value is given by the sum of all holidays requests with a positive value.', multi='user_left_days'),
|
||||
'leaves_taken' : fields.function(_user_left_days, method=True, string='Leaves Already Taken', help='This value is given by the sum of all holidays requests with a negative value.', multi='user_left_days'),
|
||||
'remaining_leaves' : fields.function(_user_left_days, method=True, string='Remaining Leaves', multi='user_left_days'),
|
||||
'max_leaves' : fields.function(_user_left_days, method=True, string='Maximum Leaves Allowed', help='This value is given by the sum of all holidays requests with a positive value.', multi='user_left_days'),
|
||||
'leaves_taken' : fields.function(_user_left_days, method=True, string='Leaves Already Taken', help='This value is given by the sum of all holidays requests with a negative value.', multi='user_left_days'),
|
||||
'remaining_leaves' : fields.function(_user_left_days, method=True, string='Remaining Leaves', multi='user_left_days'),
|
||||
|
||||
}
|
||||
_defaults = {
|
||||
@@ -165,7 +165,6 @@ class hr_holidays(osv.osv):
|
||||
_order = 'date_from desc'
|
||||
|
||||
def create(self, cr, uid, vals, context={}):
|
||||
print 'create', vals, context
|
||||
if context:
|
||||
if context.has_key('type'):
|
||||
vals['type'] = context['type']
|
||||
@@ -182,7 +181,7 @@ class hr_holidays(osv.osv):
|
||||
#~ return True
|
||||
|
||||
#_constraints = [(_check_date, 'Start date should not be greater than end date! ', ['number_of_days'])]
|
||||
|
||||
|
||||
def onchange_date_from(self, cr, uid, ids, date_to, date_from):
|
||||
result = {}
|
||||
if date_to and date_from:
|
||||
@@ -242,11 +241,10 @@ class hr_holidays(osv.osv):
|
||||
'state':'validate',
|
||||
}
|
||||
ids2 = self.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)])
|
||||
|
||||
if ids2:
|
||||
vals['manager_id'] = ids2[0]
|
||||
else:
|
||||
raise osv.except_osv(_('Warning !'),_('Either there is no Employee defined, or no User attached with it.'))
|
||||
raise osv.except_osv(_('Warning !'),_('Either there is no Employee defined, or no User attached with it.'))
|
||||
self.write(cr, uid, ids, vals)
|
||||
return True
|
||||
|
||||
@@ -269,6 +267,16 @@ class hr_holidays(osv.osv):
|
||||
'number_of_days': nb,
|
||||
'user_id': user_id
|
||||
})
|
||||
vals= {
|
||||
'name':record.name,
|
||||
'date_from':record.date_from,
|
||||
'date_to':record.date_to,
|
||||
'calendar_id':record.employee_id.calendar_id.id,
|
||||
'company_id':record.employee_id.company_id.id,
|
||||
'resource_id':record.employee_id.resource_id.id
|
||||
}
|
||||
self.pool.get('resource.calendar.leaves').create(cr,uid,vals)
|
||||
|
||||
return True
|
||||
|
||||
def holidays_refuse(self, cr, uid, ids, *args):
|
||||
@@ -325,7 +333,7 @@ class hr_holidays(osv.osv):
|
||||
'date_to' : record.date_to,
|
||||
'notes' : record.notes,
|
||||
'number_of_days': record.number_of_days,
|
||||
'number_of_days_temp': record.number_of_days_temp,
|
||||
'number_of_days_temp': record.number_of_days_temp,
|
||||
'type': record.type,
|
||||
'allocation_type': record.allocation_type,
|
||||
'parent_id': record.id,
|
||||
|
||||
@@ -258,6 +258,7 @@
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<menuitem sequence="9" id="hr.menu_open_view_attendance_reason_config" parent="hr.menu_hr_configuration" name="Leaves"/>
|
||||
<!--<menuitem
|
||||
action="open_view_holiday_status"
|
||||
id="menu_open_view_holiday_status"
|
||||
@@ -265,7 +266,7 @@
|
||||
<menuitem name="Leaves Statuses"
|
||||
action="open_view_holiday_status"
|
||||
id="menu_open_view_holiday_status"
|
||||
parent="hr_attendance.menu_open_view_attendance_reason_config"/>
|
||||
parent="hr.menu_open_view_attendance_reason_config"/>
|
||||
|
||||
<!-- Shortcuts -->
|
||||
<act_window name="My Holiday Requests"
|
||||
|
||||
@@ -639,8 +639,10 @@ class hr_timesheet_sheet_sheet_day(osv.osv):
|
||||
from
|
||||
hr_attendance a
|
||||
LEFT JOIN (hr_timesheet_sheet_sheet s
|
||||
LEFT JOIN hr_employee e
|
||||
ON (s.user_id = e.user_id))
|
||||
LEFT JOIN resource_resource r
|
||||
LEFT JOIN hr_employee e
|
||||
ON (e.resource_id = r.id)
|
||||
ON (s.user_id = r.user_id))
|
||||
ON (a.employee_id = e.id
|
||||
AND s.date_to >= date_trunc('day',a.name)
|
||||
AND s.date_from <= a.name)
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
<record id="hr_timesheet_day_form" model="ir.ui.view">
|
||||
<field name="name">hr.timesheet.day.form</field>
|
||||
<field name="model">hr_timesheet_sheet.sheet.day</field>
|
||||
@@ -61,7 +61,7 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="hr_timesheet_day_tree" model="ir.ui.view">
|
||||
<field name="name">hr.timesheet.day.tree</field>
|
||||
<field name="model">hr_timesheet_sheet.sheet.day</field>
|
||||
@@ -76,7 +76,7 @@
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
-->
|
||||
<record id="hr_timesheet_sheet_form" model="ir.ui.view">
|
||||
<field name="name">hr.timesheet.sheet.form</field>
|
||||
<field name="model">hr_timesheet_sheet.sheet</field>
|
||||
@@ -266,7 +266,7 @@
|
||||
</record>
|
||||
|
||||
<act_window domain="[('sheet_id', '=', active_id)]" id="act_hr_timesheet_sheet_sheet_by_day" name="Timesheet by Account" res_model="hr_timesheet_sheet.sheet.account" src_model="hr_timesheet_sheet.sheet"/>
|
||||
<act_window domain="[('sheet_id', '=', active_id)]" id="act_hr_timesheet_sheet_sheet_by_account" name="Timesheet by Day" res_model="hr_timesheet_sheet.sheet.day" src_model="hr_timesheet_sheet.sheet"/>
|
||||
<!-- <act_window domain="[('sheet_id', '=', active_id)]" id="act_hr_timesheet_sheet_sheet_by_account" name="Timesheet by Day" res_model="hr_timesheet_sheet.sheet.day" src_model="hr_timesheet_sheet.sheet"/> -->
|
||||
|
||||
|
||||
<act_window domain="[('sheet_id', '=', active_id)]" id="act_hr_timesheet_sheet_sheet_2_hr_analytic_timesheet" name="Timesheet Lines" res_model="hr.analytic.timesheet" src_model="hr_timesheet_sheet.sheet"/>
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
# Greek 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-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-01-18 19:17+0000\n"
|
||||
"Last-Translator: spyros <Unknown>\n"
|
||||
"Language-Team: Greek <el@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-19 04:41+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.category,name:0
|
||||
#: field:idea.idea,category_id:0
|
||||
msgid "Category"
|
||||
msgstr "Κατηγορία"
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,my_vote:0
|
||||
#: selection:idea.vote,score:0
|
||||
#: selection:idea.vote.stat,score:0
|
||||
msgid "Very Good"
|
||||
msgstr "Πολύ Καλό"
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
#: field:idea.idea,stat_vote_ids:0
|
||||
msgid "Statistics"
|
||||
msgstr "Στατιστικά"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_idea_my_idea
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_idea_my_idea
|
||||
msgid "My Ideas"
|
||||
msgstr "Οι ιδέες μου"
|
||||
|
||||
#. module: idea
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "Ιδέα"
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,my_vote:0
|
||||
#: selection:idea.vote,score:0
|
||||
#: selection:idea.vote.stat,score:0
|
||||
msgid "Not Voted"
|
||||
msgstr "Δεν έχει ψήφους"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_idea_open_my
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_idea_open_my
|
||||
msgid "My Open Ideas"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_idea
|
||||
#: model:ir.ui.menu,name:idea.menu_ideas
|
||||
#: model:ir.ui.menu,name:idea.menu_ideas1
|
||||
msgid "Ideas"
|
||||
msgstr "Ιδέες"
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.category,child_ids:0
|
||||
msgid "Child Categories"
|
||||
msgstr "Παράγωγες Κατηγορίες"
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "New Idea"
|
||||
msgstr "Νέα Ιδέα"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_category_tree
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_category_tree
|
||||
msgid "Ideas by Categories"
|
||||
msgstr "Ιδέες Ανά Κατηγορία"
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.vote,score:0
|
||||
#: field:idea.vote.stat,score:0
|
||||
msgid "Score"
|
||||
msgstr "Βαθμολογία"
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,state:0
|
||||
msgid "Draft"
|
||||
msgstr "Πρόχειρο"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_vote
|
||||
msgid "Idea's vote"
|
||||
msgstr "Βαθμολογία Ιδέας"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_vote_stat
|
||||
msgid "Statistics on Votes"
|
||||
msgstr "Στατιστικά Βαθμολογίας"
|
||||
|
||||
#. module: idea
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"Το όνομα του Αντικειμένου πρέπει να ξεκινά με x_ και δεν πρέπει να περιέχει "
|
||||
"ειδικούς χαρακτήρες!"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.model,name:idea.model_idea_category
|
||||
msgid "Category for an idea"
|
||||
msgstr "Κατηγορία Για Μια Ιδέα"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.module.module,shortdesc:idea.module_meta_information
|
||||
msgid "Idea Manager"
|
||||
msgstr "Διαχείρηση Ιδεών"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_vote_stat
|
||||
msgid "Vote Statistics"
|
||||
msgstr "Στατιστικά ψήφων"
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,state:0
|
||||
msgid "Opened"
|
||||
msgstr "Ανοιχτές"
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,state:0
|
||||
msgid "Status"
|
||||
msgstr "Κατάσταση"
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,my_vote:0
|
||||
#: selection:idea.vote,score:0
|
||||
#: selection:idea.vote.stat,score:0
|
||||
msgid "Good"
|
||||
msgstr "Καλή."
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,description:0
|
||||
msgid "Description"
|
||||
msgstr "Περιγραφή"
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,my_vote:0
|
||||
#: selection:idea.vote,score:0
|
||||
#: selection:idea.vote.stat,score:0
|
||||
msgid "Normal"
|
||||
msgstr "Κανονική"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.ui.menu,name:idea.menu_reporting
|
||||
msgid "Reporting"
|
||||
msgstr "Αναφορές"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.model,name:idea.model_idea_vote_stat
|
||||
msgid "Idea Votes Statistics"
|
||||
msgstr "Στατιστικά Ψήφων Ιδέας"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.model,name:idea.model_idea_vote
|
||||
msgid "idea.vote"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.comment,user_id:0
|
||||
#: field:idea.vote,user_id:0
|
||||
msgid "User"
|
||||
msgstr "Χρήστης"
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "Your comment"
|
||||
msgstr "Τα σχόλιά σας"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.ui.menu,name:idea.menu_config
|
||||
msgid "Configuration"
|
||||
msgstr "Παραμετροποίηση"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_category
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_category
|
||||
msgid "Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.stat:0
|
||||
msgid "stat"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,my_vote:0
|
||||
msgid "My Vote"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.vote:0
|
||||
msgid "Votes"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.module.module,description:idea.module_meta_information
|
||||
msgid ""
|
||||
"This module allows your user to easily and efficiently participate in the "
|
||||
"innovation of the enterprise. It allows everybody to express ideas about "
|
||||
"different subjects. Then, others users can comment these ideas and vote for "
|
||||
"particular ideas. Each idea as a score based on the different votes. The "
|
||||
"managers can obtain an easy view on best ideas from all the users. Once "
|
||||
"installed, check the menu 'Ideas' in the 'Tools' main menu."
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.comment,create_date:0
|
||||
#: field:idea.idea,create_date:0
|
||||
msgid "Creation date"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,count_votes:0
|
||||
msgid "Count of votes"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.vote.stat,nbr:0
|
||||
msgid "Number of Votes"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.model,name:idea.model_idea_idea
|
||||
msgid "idea.idea"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_idea_draft_my
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_idea_draft_my
|
||||
msgid "My Draft Ideas"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,vote_ids:0
|
||||
msgid "Vote"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,my_vote:0
|
||||
#: selection:idea.vote,score:0
|
||||
#: selection:idea.vote.stat,score:0
|
||||
msgid "Bad"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_idea
|
||||
msgid "All Ideas"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.comment:0
|
||||
#: view:idea.idea:0
|
||||
#: field:idea.idea,comment_ids:0
|
||||
#: model:ir.model,name:idea.model_idea_comment
|
||||
msgid "Comments"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,count_comments:0
|
||||
msgid "Count of comments"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,title:0
|
||||
msgid "Idea Summary"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.category:0
|
||||
msgid "Category of ideas"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.category,summary:0
|
||||
msgid "Summary"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_idea_categ_open
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_idea_open
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_idea_open
|
||||
msgid "Open Ideas"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
#: view:idea.vote.stat:0
|
||||
msgid "vote_stat of ideas"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.comment:0
|
||||
#: field:idea.comment,content:0
|
||||
#: view:idea.idea:0
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.category,parent_id:0
|
||||
msgid "Parent Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,user_id:0
|
||||
msgid "Creator"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.ui.menu,name:idea.menu_tools
|
||||
msgid "Tools"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.comment,idea_id:0
|
||||
#: view:idea.idea:0
|
||||
#: field:idea.vote,idea_id:0
|
||||
#: field:idea.vote.stat,idea_id:0
|
||||
msgid "Idea"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,my_vote:0
|
||||
#: selection:idea.vote,score:0
|
||||
#: selection:idea.vote.stat,score:0
|
||||
msgid "Very Bad"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,state:0
|
||||
msgid "Canceled"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.ui.menu,name:idea.menu_idea_vote
|
||||
msgid "All Votes"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,vote_avg:0
|
||||
msgid "Average Score"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#. module: idea
|
||||
#: help:idea.idea,description:0
|
||||
msgid "Content of the idea"
|
||||
msgstr ""
|
||||
+9
-19
@@ -40,21 +40,14 @@ from tools.translate import _
|
||||
class mrp_workcenter(osv.osv):
|
||||
_name = 'mrp.workcenter'
|
||||
_description = 'Work Center'
|
||||
_inherits = {'resource.resource':"resource_id"}
|
||||
_columns = {
|
||||
'name': fields.char('Work Center Name', size=64, required=True),
|
||||
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the work center without removing it."),
|
||||
'type': fields.selection([('machine','Machine'),('hr','Human Resource'),('tool','Tool')], 'Type', required=True),
|
||||
'code': fields.char('Code', size=16),
|
||||
'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="The normal working time of the workcenter."),
|
||||
# 'name': fields.char('Work Center Name', size=64, required=True),
|
||||
'note': fields.text('Description', help="Description of the workcenter. Explain here what's a cycle according to this workcenter."),
|
||||
|
||||
'capacity_per_cycle': fields.float('Capacity per Cycle', help="Number of operations this workcenter can do in parallel. If this workcenter represents a team of 5 workers, the capacity per cycle is 5."),
|
||||
|
||||
'time_cycle': fields.float('Time for 1 cycle (hour)', help="Time in hours for doing one cycle."),
|
||||
'time_start': fields.float('Time before prod.', help="Time in hours for the setup."),
|
||||
'time_stop': fields.float('Time after prod.', help="Time in hours for the cleaning."),
|
||||
'time_efficiency': fields.float('Efficiency factor', help="Factor to adjust the work center cycle and before and after production durations"),
|
||||
|
||||
'costs_hour': fields.float('Cost per hour'),
|
||||
'costs_hour_account_id': fields.many2one('account.analytic.account', 'Hour Account', domain=[('type','<>','view')],
|
||||
help="Complete this only if you want automatic analytic accounting entries on production orders."),
|
||||
@@ -63,15 +56,12 @@ class mrp_workcenter(osv.osv):
|
||||
help="Complete this only if you want automatic analytic accounting entries on production orders."),
|
||||
'costs_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'),
|
||||
'costs_general_account_id': fields.many2one('account.account', 'General Account', domain=[('type','<>','view')]),
|
||||
'company_id': fields.many2one('res.company','Company',required=True),
|
||||
# 'company_id': fields.many2one('res.company','Company',required=True),
|
||||
'resource_id': fields.many2one('resource.resource','Resource',ondelete='cascade'),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
'type': lambda *a: 'machine',
|
||||
'time_efficiency': lambda *a: 1.0,
|
||||
'capacity_per_cycle': lambda *a: 1.0,
|
||||
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.workcenter', context=c)
|
||||
}
|
||||
}
|
||||
mrp_workcenter()
|
||||
|
||||
|
||||
@@ -130,7 +120,7 @@ class mrp_routing_workcenter(osv.osv):
|
||||
'cycle_nbr': fields.float('Number of Cycles', required=True,
|
||||
help="Time in hours for doing one cycle."),
|
||||
'hour_nbr': fields.float('Number of Hours', required=True, help="Cost per hour"),
|
||||
'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True, ondelete='cascade',
|
||||
'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True, ondelete='cascade',
|
||||
help="Routing indicates all the workcenters used, for how long and/or cycles." \
|
||||
"If Routing is indicated then,the third tab of a production order (workcenters) will be automatically pre-completed."),
|
||||
'note': fields.text('Description')
|
||||
@@ -175,7 +165,7 @@ class mrp_bom(osv.osv):
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'code': fields.char('Code', size=16),
|
||||
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the bills of material without removing it."),
|
||||
'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True,
|
||||
'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True,
|
||||
help= "If a sub-product is used in several products, it can be useful to create its own BoM."\
|
||||
"Though if you don't want separated production orders for this sub-product, select Set/Phantom as BoM type."\
|
||||
"If a Phantom BoM is used for a root product, it will be sold and shipped as a set of components, instead of being produced."),
|
||||
@@ -833,7 +823,7 @@ class mrp_procurement(osv.osv):
|
||||
help='When a procurement is created the state is set to \'Draft\'.\n If the procurement is confirmed, the state is set to \'Confirmed\'.\
|
||||
\nAfter confirming the state is set to \'Running\'.\n If any exception arises in the order then the state is set to \'Exception\'.\n Once the exception is removed the state becomes \'Ready\'.\n It is in \'Waiting\'. state when the procurement is waiting for another one to finish.'),
|
||||
'note' : fields.text('Note'),
|
||||
'company_id': fields.many2one('res.company','Company',required=True),
|
||||
'company_id': fields.many2one('res.company','Company',required=True),
|
||||
}
|
||||
_defaults = {
|
||||
'state': lambda *a: 'draft',
|
||||
@@ -1205,7 +1195,7 @@ class stock_warehouse_orderpoint(osv.osv):
|
||||
'qty_multiple': fields.integer('Qty Multiple', required=True,
|
||||
help="The requisition quantity will by rounded up to this multiple."),
|
||||
'procurement_id': fields.many2one('mrp.procurement', 'Purchase Order'),
|
||||
'company_id': fields.many2one('res.company','Company',required=True),
|
||||
'company_id': fields.many2one('res.company','Company',required=True),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
|
||||
@@ -120,8 +120,8 @@
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Work Center">
|
||||
<field name="type"/>
|
||||
<field name="timesheet_id"/>
|
||||
<field name="resource_type"/>
|
||||
<field name="calendar_id"/>
|
||||
<separator colspan="4" string="Description"/>
|
||||
<field colspan="4" name="note" nolabel="1"/>
|
||||
<separator colspan="4" string="Capacity Information"/>
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
"access_account_account","account.account mrp_worker","account.model_account_account","mrp.group_mrp_user",1,0,0,0
|
||||
"access_purchase_order_mrp_worker","purchase.order mrp_worker","purchase.model_purchase_order","mrp.group_mrp_user",1,0,0,0
|
||||
"access_purchase_order_line_mrp_worker","purchase.order.line mrp_worker","purchase.model_purchase_order_line","mrp.group_mrp_user",1,0,0,0
|
||||
"access_hr_timesheet_group_mrp_worker","hr.timesheet.group mrp_worker","hr.model_hr_timesheet_group","mrp.group_mrp_user",1,0,0,0
|
||||
"access_hr_timesheet_group_mrp_worker","resource.calendar mrp_worker","resource.model_resource_calendar","mrp.group_mrp_user",1,0,0,0
|
||||
"access_mrp_procurement_stock_worker","mrp.procurement stock_worker","model_mrp_procurement","stock.group_stock_user",1,1,1,1
|
||||
"access_mrp_production_stock_worker","mrp.production stock_worker","model_mrp_production","stock.group_stock_user",1,0,0,0
|
||||
|
||||
|
@@ -60,7 +60,7 @@ class mrp_production_workcenter_line(osv.osv):
|
||||
res[op.id]= False
|
||||
if op.date_planned:
|
||||
d = DateTime.strptime(op.date_planned,'%Y-%m-%d %H:%M:%S')
|
||||
i = self.pool.get('hr.timesheet.group').interval_get(cr, uid, op.workcenter_id.timesheet_id.id or False, d, op.hour or 0.0)
|
||||
i = self.pool.get('resource.calendar').interval_get(cr, uid, op.workcenter_id.calendar_id.id or False, d, op.hour or 0.0)
|
||||
if i:
|
||||
res[op.id] = i[-1][1].strftime('%Y-%m-%d %H:%M:%S')
|
||||
else:
|
||||
@@ -204,10 +204,10 @@ class mrp_production(osv.osv):
|
||||
self.pool.get('mrp.production.workcenter.line').write(cr, uid, [wc.id], {
|
||||
'date_planned':dt.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}, context=context, update=False)
|
||||
i = self.pool.get('hr.timesheet.group').interval_get(
|
||||
i = self.pool.get('resource.calendar').interval_get(
|
||||
cr,
|
||||
uid,
|
||||
wc.workcenter_id.timesheet_id and wc.workcenter_id.timesheet_id.id or False,
|
||||
wc.workcenter_id.calendar_id and wc.workcenter_id.calendar_id.id or False,
|
||||
dt,
|
||||
wc.hour or 0.0
|
||||
)
|
||||
@@ -235,10 +235,10 @@ class mrp_production(osv.osv):
|
||||
if l.production_id and (l.production_id.date_finnished>dt):
|
||||
if l.production_id.state not in ('done','cancel'):
|
||||
for wc in l.production_id.workcenter_lines:
|
||||
i = self.pool.get('hr.timesheet.group').interval_min_get(
|
||||
i = self.pool.get('resource.calendar').interval_min_get(
|
||||
cr,
|
||||
uid,
|
||||
wc.workcenter_id.timesheet_id.id or False,
|
||||
wc.workcenter_id.calendar_id.id or False,
|
||||
dt, wc.hour or 0.0
|
||||
)
|
||||
dt = i[0][0]
|
||||
|
||||
@@ -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 ""
|
||||
@@ -245,7 +245,7 @@ class product_template(osv.osv):
|
||||
'description': fields.text('Description',translate=True),
|
||||
'description_purchase': fields.text('Purchase Description',translate=True),
|
||||
'description_sale': fields.text('Sale Description',translate=True),
|
||||
'type': fields.selection([('product','Stockable Product'),('consu', 'Consumable'),('service','Service')], 'Product Type', required=True, help="Will change the way requisitions are processed. Consumables are stockable products with infinite stock, or for use when you have no inventory management in the system."),
|
||||
'type': fields.selection([('product','Stockable Product'),('rima','Rima'),('consu', 'Consumable'),('service','Service')], 'Product Type', required=True, help="Will change the way requisitions are processed. Consumables are stockable products with infinite stock, or for use when you have no inventory management in the system."),
|
||||
'supply_method': fields.selection([('produce','Produce'),('buy','Buy')], 'Supply method', required=True, help="Produce will generate production order or tasks, according to the product type. Purchase will trigger purchase orders when requested."),
|
||||
'sale_delay': fields.float('Customer Lead Time', help="This is the average time between the confirmation of the customer order and the delivery of the finished products. It's the time you promise to your customers."),
|
||||
'produce_delay': fields.float('Manufacturing Lead Time', help="Average time to produce this product. This is only for the production order and, if it is a multi-level bill of material, it's only for the level of this product. Different lead times will be summed for all levels and purchase orders."),
|
||||
|
||||
@@ -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,7 +41,9 @@ 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,
|
||||
'certificate': '0075116868317',
|
||||
|
||||
+137
-58
@@ -20,18 +20,32 @@
|
||||
##############################################################################
|
||||
|
||||
from lxml import etree
|
||||
from mx import DateTime
|
||||
from mx.DateTime import now
|
||||
import mx.DateTime
|
||||
import datetime
|
||||
import time
|
||||
from tools.translate import _
|
||||
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
|
||||
class project_task_type(osv.osv):
|
||||
_name = 'project.task.type'
|
||||
_description = 'Project task type'
|
||||
_columns = {
|
||||
'name': fields.char('Type', required=True, size=64, translate=True),
|
||||
'description': fields.text('Description'),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
}
|
||||
_order = 'sequence'
|
||||
|
||||
_defaults = {
|
||||
'sequence': lambda *args: 1
|
||||
}
|
||||
project_task_type()
|
||||
|
||||
class project(osv.osv):
|
||||
_name = "project.project"
|
||||
_description = "Project"
|
||||
|
||||
_inherits = {'account.analytic.account':"category_id"}
|
||||
def _complete_name(self, cr, uid, ids, name, args, context):
|
||||
res = {}
|
||||
for m in self.browse(cr, uid, ids, context=context):
|
||||
@@ -73,7 +87,7 @@ class project(osv.osv):
|
||||
tocompute = [project]
|
||||
while tocompute:
|
||||
p = tocompute.pop()
|
||||
tocompute += p.child_id
|
||||
tocompute += p.child_ids
|
||||
for i in range(3):
|
||||
s[i] += progress.get(p.id, (0.0,0.0,0.0))[i]
|
||||
res[project.id] = {
|
||||
@@ -90,51 +104,60 @@ class project(osv.osv):
|
||||
raise osv.except_osv(_('Operation Not Permitted !'), _('You can not delete a project with tasks. I suggest you to deactivate it.'))
|
||||
return super(project, self).unlink(cr, uid, ids, *args, **kwargs)
|
||||
_columns = {
|
||||
'name': fields.char("Project Name", size=128, required=True),
|
||||
'complete_name': fields.function(_complete_name, method=True, string="Project Name", type='char', size=128),
|
||||
# 'name': fields.char("Project Name", size=128, required=True),
|
||||
# 'complete_name': fields.function(_complete_name, method=True, string="Project Name", type='char', size=128),
|
||||
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the project without removing it."),
|
||||
'category_id': fields.many2one('account.analytic.account','Analytic Account', help="Link this project to an analytic account if you need financial management on projects. It enables you to connect projects with budgets, planning, cost and revenue analysis, timesheets on projects, etc."),
|
||||
'priority': fields.integer('Sequence'),
|
||||
'manager': fields.many2one('res.users', 'Project Manager'),
|
||||
# 'manager': fields.many2one('res.users', 'Project Manager'),
|
||||
'warn_manager': fields.boolean('Warn Manager', help="If you check this field, the project manager will receive a request each time a task is completed by his team."),
|
||||
'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project Members', help="Project's member. Not used in any computation, just for information purpose."),
|
||||
'resource_ids': fields.many2many('resource.resource', 'project_resource_rel', 'project_id', 'resource_id', 'Project Members', help="Project's member. Not used in any computation, just for information purpose."),
|
||||
'tasks': fields.one2many('project.task', 'project_id', "Project tasks"),
|
||||
'parent_id': fields.many2one('project.project', 'Parent Project',\
|
||||
help="If you have [?] in the name, it means there are no analytic account linked to project."),
|
||||
'child_id': fields.one2many('project.project', 'parent_id', 'Subproject'),
|
||||
# 'parent_id': fields.many2one('project.project', 'Parent Project',\
|
||||
# help="If you have [?] in the name, it means there are no analytic account linked to project."),
|
||||
# 'child_id': fields.one2many('project.project', 'parent_id', 'Subproject'),
|
||||
'planned_hours': fields.function(_progress_rate, multi="progress", method=True, string='Planned Time', help="Sum of planned hours of all tasks related to this project."),
|
||||
'effective_hours': fields.function(_progress_rate, multi="progress", method=True, string='Time Spent', help="Sum of spent hours of all tasks related to this project."),
|
||||
'total_hours': fields.function(_progress_rate, multi="progress", method=True, string='Total Time', help="Sum of total hours of all tasks related to this project."),
|
||||
'progress_rate': fields.function(_progress_rate, multi="progress", method=True, string='Progress', type='float', help="Percent of tasks closed according to the total of tasks todo."),
|
||||
'date_start': fields.date('Starting Date'),
|
||||
'date_end': fields.date('Expected End'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'contact_id': fields.many2one('res.partner.address', 'Contact'),
|
||||
# 'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
# 'contact_id': fields.many2one('res.partner.address', 'Contact'),
|
||||
'warn_customer': fields.boolean('Warn Partner', help="If you check this, the user will have a popup when closing a task that propose a message to send by email to the customer."),
|
||||
'warn_header': fields.text('Mail Header', help="Header added at the beginning of the email for the warning message sent to the customer when a task is closed."),
|
||||
'warn_footer': fields.text('Mail Footer', help="Footer added at the beginning of the email for the warning message sent to the customer when a task is closed."),
|
||||
'notes': fields.text('Notes', help="Internal description of the project."),
|
||||
'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="Timetable working hours to adjust the gantt diagram report"),
|
||||
'state': fields.selection([('template', 'Template'), ('open', 'Running'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', required=True, readonly=True,
|
||||
help='The project can be in either if the states \'Template\' and \'Running\'.\n If it is template then we can make projects based on the template projects. If its in \'Running\' state it is a normal project.\
|
||||
\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'),
|
||||
# 'notes': fields.text('Notes', help="Internal description of the project."),
|
||||
'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report"),
|
||||
# 'state': fields.selection([('template', 'Template'), ('open', 'Running'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', required=True, readonly=True,
|
||||
# help='The project can be in either if the states \'Template\' and \'Running\'.\n If it is template then we can make projects based on the template projects. If its in \'Running\' state it is a normal project.\
|
||||
# \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"),
|
||||
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Allowed Task Types'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a: True,
|
||||
'manager': lambda object,cr,uid,context: uid,
|
||||
# 'manager': lambda object,cr,uid,context: uid,
|
||||
'priority': lambda *a: 1,
|
||||
'date_start': lambda *a: time.strftime('%Y-%m-%d'),
|
||||
'state': lambda *a: 'open',
|
||||
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.project', context=c)
|
||||
# 'state': lambda *a: 'open',
|
||||
# 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.project', context=c)
|
||||
}
|
||||
def _check_dates(self, cr, uid, ids):
|
||||
leave = self.read(cr, uid, ids[0],['date_start','date'])
|
||||
if leave['date_start'] and leave['date']:
|
||||
if leave['date_start'] > leave['date']:
|
||||
return False
|
||||
return True
|
||||
|
||||
_order = "parent_id,priority,name"
|
||||
_constraints = [
|
||||
(check_recursion, 'Error ! You can not create recursive projects.', ['parent_id'])
|
||||
(_check_dates, 'Error! project start-date must be lower then project end-date.', ['date_start', 'date'])
|
||||
]
|
||||
|
||||
# _order = "parent_id,priority,name"
|
||||
# _constraints = [
|
||||
# (check_recursion, 'Error ! You can not create recursive projects.', ['parent_id'])
|
||||
# ]
|
||||
|
||||
# toggle activity of projects, their sub projects and their tasks
|
||||
def set_template(self, cr, uid, ids, context={}):
|
||||
res = self.setActive(cr, uid, ids, value=False, context=context)
|
||||
@@ -206,19 +229,33 @@ class project(osv.osv):
|
||||
return True
|
||||
project()
|
||||
|
||||
class project_task_type(osv.osv):
|
||||
_name = 'project.task.type'
|
||||
_description = 'Project task type'
|
||||
_columns = {
|
||||
'name': fields.char('Type', required=True, size=64, translate=True),
|
||||
'description': fields.text('Description'),
|
||||
}
|
||||
project_task_type()
|
||||
|
||||
class task(osv.osv):
|
||||
_name = "project.task"
|
||||
_description = "Tasks"
|
||||
_date_name = "date_start"
|
||||
|
||||
# def compute_date(self,cr,uid):
|
||||
# project_id = self.pool.get('project.project').search(cr,uid,[])
|
||||
# for i in range(len(project_id)):
|
||||
# task_ids = self.pool.get('project.task').search(cr,uid,[('project_id','=',project_id[i])])
|
||||
# if task_ids:
|
||||
# task_obj = self.pool.get('project.task').browse(cr,uid,task_ids)
|
||||
# task_1 = task_obj[0]
|
||||
# task_1.date_start = self.pool.get('project.project').browse(cr,uid,project_id[i]).date_start
|
||||
# dt = mx.DateTime.strptime(task_1.date_start,"%Y-%m-%d").strftime("%Y-%m-%d")
|
||||
# def Project_1():
|
||||
# title = "New Project"
|
||||
# start = dt
|
||||
#
|
||||
# def task1():
|
||||
# start = dt
|
||||
# effort = task_1.planned_hours
|
||||
# title = "Task 1"
|
||||
## project_1 = BalancedProject(Project_1)
|
||||
## for t in project_1:
|
||||
## print 'details:::',t.indent_name(), t.start, t.end, t.effort
|
||||
|
||||
|
||||
def _str_get(self, task, level=0, border='***', context={}):
|
||||
return border+' '+(task.user_id and task.user_id.name.upper() or '')+(level and (': L'+str(level)) or '')+(' - %.1fh / %.1fh'%(task.effective_hours or 0.0,task.planned_hours))+' '+border+'\n'+ \
|
||||
border[0]+' '+(task.name or '')+'\n'+ \
|
||||
@@ -228,12 +265,12 @@ class task(osv.osv):
|
||||
result = {}
|
||||
for task in self.browse(cr, uid, ids, context=context):
|
||||
result[task.id] = self._str_get(task, border='===')
|
||||
t2 = task.parent_id
|
||||
t2 = task.parent_ids
|
||||
level = 0
|
||||
while t2:
|
||||
level -= 1
|
||||
result[task.id] = self._str_get(t2, level) + result[task.id]
|
||||
t2 = t2.parent_id
|
||||
t2 = t2.parent_ids
|
||||
t3 = map(lambda x: (x,1), task.child_ids)
|
||||
while t3:
|
||||
t2 = t3.pop(0)
|
||||
@@ -258,8 +295,19 @@ class task(osv.osv):
|
||||
res[task.id]['delay_hours'] = res[task.id]['total_hours'] - task.planned_hours
|
||||
return res
|
||||
|
||||
def onchange_planned(self, cr, uid, ids, planned, effective=0.0):
|
||||
return {'value':{'remaining_hours': planned-effective}}
|
||||
def onchange_planned(self, cr, uid, ids, planned, effective, date_start,occupation_rate=0.0):
|
||||
result = {}
|
||||
for res in self.browse(cr, uid, ids):
|
||||
if date_start and planned:
|
||||
resource_id = self.pool.get('resource.resource').search(cr,uid,[('user_id','=',res.user_id.id)])
|
||||
resource_obj = self.pool.get('resource.resource').browse(cr,uid,resource_id)[0]
|
||||
d = mx.DateTime.strptime(date_start,'%Y-%m-%d %H:%M:%S')
|
||||
hrs = (planned)/(occupation_rate)
|
||||
work_times = self.pool.get('resource.calendar').interval_get(cr, uid, resource_obj.calendar_id.id or False, d, hrs or 0.0, resource_obj.id)
|
||||
result['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S')
|
||||
result['remaining_hours'] = planned-effective
|
||||
return {'value':result}
|
||||
|
||||
|
||||
def _default_project(self, cr, uid, context={}):
|
||||
if 'project_id' in context and context['project_id']:
|
||||
@@ -275,26 +323,34 @@ class task(osv.osv):
|
||||
default['work_ids'] = []
|
||||
return super(task, self).copy_data(cr, uid, id, default, context)
|
||||
|
||||
def _check_date(self,cr,uid,ids):
|
||||
for res in self.browse(cr,uid,ids):
|
||||
if res.date_start and res.date_end:
|
||||
if res.date_start > res.date_end:
|
||||
return False
|
||||
return True
|
||||
|
||||
_columns = {
|
||||
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the task without removing it."),
|
||||
'name': fields.char('Task summary', size=128, required=True),
|
||||
'name': fields.char('Task Summary', size=128, required=True),
|
||||
'description': fields.text('Description'),
|
||||
'priority' : fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Urgent'), ('0','Very urgent')], 'Importance'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of tasks."),
|
||||
'type': fields.many2one('project.task.type', 'Type'),
|
||||
'type': fields.many2one('project.task.type', 'Type', readonly=True),
|
||||
'state': fields.selection([('draft', 'Draft'),('open', 'In Progress'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
|
||||
help='If the task is created the state \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\
|
||||
\n If the task is over, the states is set to \'Done\'.'),
|
||||
'date_start': fields.datetime('Starting Date'),
|
||||
'date_end': fields.datetime('Ending Date'),
|
||||
'date_deadline': fields.datetime('Deadline'),
|
||||
'date_close': fields.datetime('Date Closed', readonly=True),
|
||||
'project_id': fields.many2one('project.project', 'Project', ondelete='cascade',
|
||||
help="If you have [?] in the project name, it means there are no analytic account linked to this project."),
|
||||
'parent_id': fields.many2one('project.task', 'Parent Task'),
|
||||
'child_ids': fields.one2many('project.task', 'parent_id', 'Delegated Tasks'),
|
||||
'parent_ids': fields.many2many('project.task', 'project_task_parent_rel', 'task_id', 'parent_id', 'Parent Tasks'),
|
||||
'child_ids': fields.many2many('project.task', 'project_task_child_rel', 'task_id', 'child_id', 'Delegated Tasks'),
|
||||
'history': fields.function(_history_get, method=True, string="Task Details", type="text"),
|
||||
'notes': fields.text('Notes'),
|
||||
|
||||
'occupation_rate': fields.float('Occupation Rate', help='The occupation rate fields indicates how much of his time a user is working on a task. A 100% occupation rate means the user works full time on the tasks. The ending date of a task is computed like this: Starting Date + Duration / Occupation Rate.'),
|
||||
'planned_hours': fields.float('Planned Hours', required=True, help='Estimated time to do the task, usually set by the project manager when the task is in draft state.'),
|
||||
'effective_hours': fields.function(_hours_get, method=True, string='Hours Spent', multi='hours', store=True, help="Computed using the sum of the task work done."),
|
||||
'remaining_hours': fields.float('Remaining Hours', digits=(16,4), help="Total remaining time, can be re-estimated periodically by the assignee of the task."),
|
||||
@@ -318,6 +374,7 @@ class task(osv.osv):
|
||||
'active': lambda *a: True,
|
||||
'date_start': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'project_id': _default_project,
|
||||
'occupation_rate':lambda *a: '1',
|
||||
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.task', context=c)
|
||||
}
|
||||
_order = "sequence, priority, date_deadline, id"
|
||||
@@ -359,24 +416,24 @@ class task(osv.osv):
|
||||
for task in tasks:
|
||||
project = task.project_id
|
||||
if project:
|
||||
if project.warn_manager and project.manager and (project.manager.id != uid):
|
||||
if project.warn_manager and project.user_id and (project.user_id.id != uid):
|
||||
request.create(cr, uid, {
|
||||
'name': _("Task '%s' closed") % task.name,
|
||||
'state': 'waiting',
|
||||
'act_from': uid,
|
||||
'act_to': project.manager.id,
|
||||
'act_to': project.user_id.id,
|
||||
'ref_partner_id': task.partner_id.id,
|
||||
'ref_doc1': 'project.task,%d'% (task.id,),
|
||||
'ref_doc2': 'project.project,%d'% (project.id,),
|
||||
})
|
||||
self.write(cr, uid, [task.id], {'state': 'done', 'date_close':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
|
||||
if task.parent_id and task.parent_id.state in ('pending','draft'):
|
||||
if task.parent_ids and task.parent_ids.state in ('pending','draft'):
|
||||
reopen = True
|
||||
for child in task.parent_id.child_ids:
|
||||
for child in task.parent_ids.child_ids:
|
||||
if child.id != task.id and child.state not in ('done','cancelled'):
|
||||
reopen = False
|
||||
if reopen:
|
||||
self.do_reopen(cr, uid, [task.parent_id.id])
|
||||
self.do_reopen(cr, uid, [task.parent_ids.id])
|
||||
return True
|
||||
|
||||
def do_reopen(self, cr, uid, ids, *args):
|
||||
@@ -384,12 +441,12 @@ class task(osv.osv):
|
||||
tasks = self.browse(cr, uid, ids)
|
||||
for task in tasks:
|
||||
project = task.project_id
|
||||
if project and project.warn_manager and project.manager.id and (project.manager.id != uid):
|
||||
if project and project.warn_manager and project.user_id.id and (project.user_id.id != uid):
|
||||
request.create(cr, uid, {
|
||||
'name': _("Task '%s' set in progress") % task.name,
|
||||
'state': 'waiting',
|
||||
'act_from': uid,
|
||||
'act_to': project.manager.id,
|
||||
'act_to': project.user_id.id,
|
||||
'ref_partner_id': task.partner_id.id,
|
||||
'ref_doc1': 'project.task,%d' % task.id,
|
||||
'ref_doc2': 'project.project,%d' % project.id,
|
||||
@@ -403,12 +460,12 @@ class task(osv.osv):
|
||||
tasks = self.browse(cr, uid, ids)
|
||||
for task in tasks:
|
||||
project = task.project_id
|
||||
if project.warn_manager and project.manager and (project.manager.id != uid):
|
||||
if project.warn_manager and project.user_id and (project.user_id.id != uid):
|
||||
request.create(cr, uid, {
|
||||
'name': _("Task '%s' cancelled") % task.name,
|
||||
'state': 'waiting',
|
||||
'act_from': uid,
|
||||
'act_to': project.manager.id,
|
||||
'act_to': project.user_id.id,
|
||||
'ref_partner_id': task.partner_id.id,
|
||||
'ref_doc1': 'project.task,%d' % task.id,
|
||||
'ref_doc2': 'project.project,%d' % project.id,
|
||||
@@ -431,6 +488,25 @@ class task(osv.osv):
|
||||
self.write(cr, uid, ids, {'state': 'pending'})
|
||||
return True
|
||||
|
||||
def next_type(self, cr, uid, ids, *args):
|
||||
for typ in self.browse(cr, uid, ids):
|
||||
typeid = typ.type.id
|
||||
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)
|
||||
self.write(cr, uid, typ.id, {'type': types[index+1]})
|
||||
return True
|
||||
|
||||
def prev_type(self, cr, uid, ids, *args):
|
||||
for typ in self.browse(cr, uid, ids):
|
||||
typeid = typ.type.id
|
||||
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)
|
||||
self.write(cr, uid, typ.id, {'type': types[index-1]})
|
||||
return True
|
||||
|
||||
task()
|
||||
|
||||
@@ -508,10 +584,13 @@ class message(osv.osv):
|
||||
message()
|
||||
|
||||
def _project_get(self, cr, uid, context={}):
|
||||
if uid==1:
|
||||
ids = self.pool.get('project.project').search(cr, uid, [])
|
||||
res = self.pool.get('project.project').read(cr, uid, ids, ['id','name'], context)
|
||||
return [(str(r['id']),r['name']) for r in res]
|
||||
cr.execute("""SELECT to_char(id, '99999'),name FROM project_project where manager=%s OR
|
||||
id IN (SELECT project_id from project_user_rel where uid=%s)""" % (uid, uid))
|
||||
projects = cr.fetchall()
|
||||
return projects
|
||||
return cr.fetchall()
|
||||
|
||||
class users(osv.osv):
|
||||
_inherit = 'res.users'
|
||||
@@ -522,4 +601,4 @@ class users(osv.osv):
|
||||
|
||||
users()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -9,23 +9,30 @@
|
||||
<field name="project_time_mode_id" ref="product.uom_hour"></field>
|
||||
</record>
|
||||
|
||||
<record id="project_tt_analysis" model="project.task.type">
|
||||
<field name="name">Analysis</field>
|
||||
<!-- Task Types -->
|
||||
<record id="project_tt_specification" model="project.task.type">
|
||||
<field name="sequence">1</field>
|
||||
<field name="name">Specification</field>
|
||||
</record>
|
||||
<record id="project_tt_feature" model="project.task.type">
|
||||
<field name="name">New Feature</field>
|
||||
<record id="project_tt_development" model="project.task.type">
|
||||
<field name="sequence">2</field>
|
||||
<field name="name">Development</field>
|
||||
</record>
|
||||
<record id="project_tt_quote" model="project.task.type">
|
||||
<field name="name">Quotation</field>
|
||||
<record id="project_tt_testing" model="project.task.type">
|
||||
<field name="sequence">3</field>
|
||||
<field name="name">Testing</field>
|
||||
</record>
|
||||
<record id="project_tt_bug" model="project.task.type">
|
||||
<field name="name">Bug</field>
|
||||
<record id="project_tt_merge" model="project.task.type">
|
||||
<field name="sequence">4</field>
|
||||
<field name="name">Merge</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Projects -->
|
||||
<record id="project_project_9" model="project.project">
|
||||
<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="type_ids"/>
|
||||
</record>
|
||||
<record id="project_project_21" model="project.project">
|
||||
<field name="warn_manager">1</field>
|
||||
@@ -34,6 +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="type_ids"/>
|
||||
</record>
|
||||
<record id="project_project_22" model="project.project">
|
||||
<field name="priority">20</field>
|
||||
@@ -41,6 +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="type_ids"/>
|
||||
</record>
|
||||
<record id="project_project_23" model="project.project">
|
||||
<field name="priority">30</field>
|
||||
@@ -48,12 +57,14 @@
|
||||
<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="type_ids"/>
|
||||
</record>
|
||||
|
||||
<!-- Tasks -->
|
||||
<record id="project_task_116" model="project.task">
|
||||
<field name="planned_hours">38.0</field>
|
||||
<field name="remaining_hours">38.0</field>
|
||||
<field name="type" ref="project_tt_feature"/>
|
||||
<field name="type" ref="project_tt_development"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="project_id" ref="project_project_22"/>
|
||||
<field name="description">BoM, After sales returns, interventions. Tracability.</field>
|
||||
@@ -62,7 +73,7 @@
|
||||
<record id="project_task_130" model="project.task">
|
||||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field name="type" ref="project_tt_feature"/>
|
||||
<field name="type" ref="project_tt_development"/>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="project_id" ref="project_project_23"/>
|
||||
<field name="name">Data importation + Doc</field>
|
||||
@@ -70,7 +81,7 @@
|
||||
<record id="project_task_131" model="project.task">
|
||||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field name="type" ref="project_tt_feature"/>
|
||||
<field name="type" ref="project_tt_development"/>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="project_id" ref="project_project_23"/>
|
||||
<field name="name">Modifications asked by the customer.</field>
|
||||
@@ -78,7 +89,7 @@
|
||||
<record id="project_task_184" model="project.task">
|
||||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field name="type" ref="project_tt_feature"/>
|
||||
<field name="type" ref="project_tt_development"/>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="priority">0</field>
|
||||
<field name="project_id" ref="project_project_21"/>
|
||||
@@ -88,7 +99,7 @@
|
||||
<field name="sequence">15</field>
|
||||
<field name="planned_hours">8.0</field>
|
||||
<field name="remaining_hours">8.0</field>
|
||||
<field name="type" ref="project_tt_feature"/>
|
||||
<field name="type" ref="project_tt_development"/>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="project_id" ref="project_project_21"/>
|
||||
<field name="name">Internal testing + Software Install</field>
|
||||
@@ -98,7 +109,7 @@
|
||||
<field name="sequence">17</field>
|
||||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field name="type" ref="project_tt_feature"/>
|
||||
<field name="type" ref="project_tt_development"/>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="state">open</field>
|
||||
|
||||
+59
-131
@@ -30,11 +30,11 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Project">
|
||||
<group colspan="6" col="6">
|
||||
<field name="name" select="1"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="manager" select="1"/>
|
||||
<field name="name" string="Project Name" select="1"/>
|
||||
<field name="parent_id" string="Parent Project"/>
|
||||
<field name="user_id" string="Project Manager" select="1"/>
|
||||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
<field name="date"/>
|
||||
<field name="progress_rate" widget="progressbar"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
@@ -42,14 +42,14 @@
|
||||
<field name="warn_manager"/>
|
||||
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
|
||||
<field name="priority"/>
|
||||
<field name="timesheet_id"/>
|
||||
<field name="resource_calendar_id"/>
|
||||
<field name="active" select="2"/>
|
||||
<field name="planned_hours" widget="float_time"/>
|
||||
<field name="effective_hours" widget="float_time"/>
|
||||
<field name="category_id" select="2" context="{'default_name':name}"/>
|
||||
|
||||
<newline/>
|
||||
<separator colspan="4" string="Project's members"/>
|
||||
<field colspan="4" name="members" nolabel="1"/>
|
||||
<field colspan="4" name="resource_ids" nolabel="1"/>
|
||||
<group col="9" colspan="8">
|
||||
<field name="state" select="1"/>
|
||||
<button name="set_template" string="Set as Template" type="object" states="open" icon="gtk-convert"/>
|
||||
@@ -83,25 +83,12 @@
|
||||
<label string="Date Stop: %%(date_stop)s"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Tasks">
|
||||
<field name="tasks" nolabel="1" attrs="{'readonly':[('state','in',['cancelled','done'])]}">
|
||||
<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"/>
|
||||
<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>
|
||||
<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="notes" nolabel="1"/>
|
||||
<field colspan="4" name="description" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<newline/>
|
||||
@@ -115,9 +102,9 @@
|
||||
<field name="priority" eval="5"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Projects">
|
||||
<field name="complete_name"/>
|
||||
<field name="manager"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="complete_name" string="Project Name"/>
|
||||
<field name="user_id" string="Project Manager"/>
|
||||
<field name="partner_id" string="Partner"/>
|
||||
<field name="effective_hours" widget="float_time"/>
|
||||
<field name="total_hours" widget="float_time"/>
|
||||
<field name="state"/>
|
||||
@@ -132,11 +119,11 @@
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Project">
|
||||
<group col='8' colspan='4'>
|
||||
<filter icon="terp-project" string="My Projects" domain="[('manager', '=', uid)]" help="My Projects"/>
|
||||
<filter icon="terp-project" string="My Projects" domain="[('user_id', '=', uid)]" help="My Projects"/>
|
||||
<filter icon="terp-project" string="Templates" domain="[('state','=','template')]" help="Template Projects"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name" select='1'/>
|
||||
<field name="partner_id" select='1'/>
|
||||
<field name="name" string="Project Name" select='1'/>
|
||||
<field name="partner_id" string="Partner" select='1'/>
|
||||
<field name="state" select="1"/>
|
||||
</group>
|
||||
</search>
|
||||
@@ -147,12 +134,12 @@
|
||||
<field name="name">project.project.tree</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_id</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Projects">
|
||||
<field name="name"/>
|
||||
<field name="manager"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="name" string="Project Name"/>
|
||||
<field name="user_id" string="Project Manager"/>
|
||||
<field name="partner_id" string="Partner"/>
|
||||
<field name="planned_hours" widget="float_time"/>
|
||||
<field name="total_hours" widget="float_time"/>
|
||||
<field name="effective_hours" widget="float_time"/>
|
||||
@@ -216,11 +203,11 @@
|
||||
<field name="name">project.project.tree</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_id</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="My projects">
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="name" string="Project Name"/>
|
||||
<field name="partner_id" string="Partner"/>
|
||||
<field name="planned_hours" widget="float_time"/>
|
||||
<field name="effective_hours" widget="float_time"/>
|
||||
<field name="progress_rate" widget="progressbar"/>
|
||||
@@ -281,7 +268,10 @@
|
||||
<field name="name" select="1"/>
|
||||
<field name="project_id" required="1" select="1"/>
|
||||
<field name="total_hours" widget="float_time"/>
|
||||
<field name="date_start"/>
|
||||
<field name="date_deadline" select="2"/>
|
||||
<field name="occupation_rate"/>
|
||||
<field name="date_end"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<field name="progress" widget="progressbar"/>
|
||||
</group>
|
||||
@@ -292,7 +282,7 @@
|
||||
name="planned_hours"
|
||||
widget="float_time"
|
||||
attrs="{'readonly':[('state','!=','draft')]}"
|
||||
on_change="onchange_planned(planned_hours,effective_hours)"/>
|
||||
on_change="onchange_planned(planned_hours,effective_hours,date_start,occupation_rate)"/>
|
||||
<field name="remaining_hours" select="2" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" colspan="2"/>
|
||||
<button name="%(action_config_compute_remaining)d" string="Review" type="action" colspan="1" target="new" states="open,pending" icon="gtk-edit"/>
|
||||
</group>
|
||||
@@ -304,10 +294,10 @@
|
||||
<field colspan="4" name="description" nolabel="1" select="2" attrs="{'readonly':[('state','=','done')]}" widget="text_wiki"/>
|
||||
<field colspan="4" name="work_ids" nolabel="1" attrs="{'readonly':[('state','in',['draft','done'])]}">
|
||||
<tree string="Task Work" editable="top">
|
||||
<field name="date" />
|
||||
<field name="user_id" />
|
||||
<field name="hours" widget="float_time" />
|
||||
<field name="name" />
|
||||
<field name="hours" widget="float_time" />
|
||||
<field name="user_id" />
|
||||
<field name="date" />
|
||||
</tree>
|
||||
</field>
|
||||
<newline/>
|
||||
@@ -320,12 +310,12 @@
|
||||
<button groups="base.group_extended" name="%(wizard_delegate_task)d" states="pending,open" string="Delegate" type="action" icon="gtk-sort-descending"/>
|
||||
<button name="%(wizard_close_task)d" states="pending,open" string="Done" type="action" icon="gtk-jump-to"/>
|
||||
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel"/>
|
||||
|
||||
</group>
|
||||
</page>
|
||||
<page groups="base.group_extended" string="Delegations">
|
||||
<field name="parent_id"/>
|
||||
<newline/>
|
||||
<separator string="Parent Tasks" colspan="4"/>
|
||||
<field colspan="4" height="150" name="parent_ids" nolabel="1"/>
|
||||
<separator string="Delegated tasks" colspan="4"/>
|
||||
<field colspan="4" height="150" name="child_ids" nolabel="1" attrs="{'readonly':[('state','!=','draft')]}">
|
||||
<tree string="Delegated tasks">
|
||||
<field name="name"/>
|
||||
@@ -339,6 +329,7 @@
|
||||
</field>
|
||||
<field colspan="4" name="history" nolabel="1"/>
|
||||
</page>
|
||||
|
||||
<page groups="base.group_extended" string="Extra Info" attrs="{'readonly':[('state','=','done')]}">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Planning" colspan="2"/>
|
||||
@@ -347,14 +338,17 @@
|
||||
</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"/>
|
||||
<field name="type" widget="selection"/>
|
||||
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
|
||||
<field name="active" select="2"/>
|
||||
<field name="partner_id" select="2"/>
|
||||
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
|
||||
<group col="4" colspan="2">
|
||||
<field name="type" widget="selection" />
|
||||
<button name="prev_type" string="Previous" type="object" icon="gtk-go-back" help="Change to Previous Type"/>
|
||||
<button name="next_type" string="Next" type="object" icon="gtk-go-forward" help="Change to Next Type"/>
|
||||
</group>
|
||||
<field name="active" select="2"/>
|
||||
<separator colspan="4" string="Notes"/>
|
||||
<field colspan="4" name="notes" nolabel="1"/>
|
||||
</page>
|
||||
@@ -369,12 +363,14 @@
|
||||
<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"/>
|
||||
<field name="date_deadline"/>
|
||||
<field name="remaining_hours" widget="float_time"/>
|
||||
<field name="type"/>
|
||||
<button name="next_type" states="draft,open,pending" string="Change Type" type="object" icon="gtk-go-forward" help="Change Type"/>
|
||||
<field name="progress" widget="progressbar"/>
|
||||
<field name="state"/>
|
||||
<button name="do_open" states="pending,draft" string="Start Task" type="object" icon="gtk-execute" help="For changing to open state"/>
|
||||
@@ -474,19 +470,21 @@
|
||||
<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="Open" domain="[('state','=','open')]" help="Open 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="project_id" select="1" widget="selection">
|
||||
<filter domain="[('manager_id','=',False)]" help="Unassigned Project" icon="terp-project"/>
|
||||
</field>
|
||||
</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"/>
|
||||
<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"/>
|
||||
</field>
|
||||
</group>
|
||||
@@ -495,70 +493,18 @@
|
||||
</record>
|
||||
|
||||
<record id="action_view_task" model="ir.actions.act_window">
|
||||
<field name="name">All Tasks</field>
|
||||
<field name="name">Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,gantt,graph</field>
|
||||
<field eval="False" name="view_id"/>
|
||||
<field eval="True" name="filter"/>
|
||||
<field name="view_id" ref="view_task_tree2"/>
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
</record>
|
||||
<!--<menuitem action="action_view_task" id="menu_action_view_task" parent="project.menu_tasks"/> -->
|
||||
<menuitem action="action_view_task" id="menu_action_view_task" parent="project.menu_project_management" name="Tasks"/>
|
||||
|
||||
<record id="action_view_task_department" model="ir.actions.act_window">
|
||||
<field name="name">My Department Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,gantt,graph</field>
|
||||
<field eval="True" name="filter"/>
|
||||
<field name="domain">[('user_id', 'child_of', [uid])]</field>
|
||||
<field eval="True" name="filter"/>
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_task5_departments_pending" model="ir.actions.act_window">
|
||||
<field name="name">My Department's Pending Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('user_id', 'child_of', [uid]),('state','=','pending')]</field>
|
||||
<field name="view_id" ref="my_pending_task"/>
|
||||
<field name="filter" eval="True"/>
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_task5_departments_prog" model="ir.actions.act_window">
|
||||
<field name="name">My Department's Current Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field eval="True" name="filter"/>
|
||||
<field name="domain">[('user_id', 'child_of', [uid]),('state','in',('open','draft'))]</field>
|
||||
<field name="filter" eval="True"/>
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_task5_departments_prog_prog" model="ir.actions.act_window">
|
||||
<field name="name">My Department's Tasks in Progress</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('user_id', 'child_of', [uid]),('state','=','open')]</field>
|
||||
<field name="filter" eval="True"/>
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_task5_departments_prog_draft" model="ir.actions.act_window">
|
||||
<field name="name">My Department's Draft Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('user_id', 'child_of', [uid]),('state','=','draft')]</field>
|
||||
<field name="filter" eval="True"/>
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_task_overpassed_draft" model="ir.actions.act_window">
|
||||
<field name="name">Overpassed Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
@@ -569,26 +515,6 @@
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_task6_prog" model="ir.actions.act_window">
|
||||
<field name="name">Tasks in Progress</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph,gantt</field>
|
||||
<field name="filter" eval="True"/>
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
<field name="domain">[('state','=','open')]</field>
|
||||
</record>
|
||||
menu_main
|
||||
<record id="action_view_task7" model="ir.actions.act_window">
|
||||
<field name="name">Unassigned Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph,gantt</field>
|
||||
<field name="domain">[('user_id', '=', False)]</field>
|
||||
<field name="filter" eval="True"/>
|
||||
<field name="search_view_id" ref="view_task_search_form"/>
|
||||
</record>
|
||||
|
||||
<!-- Opening task when double clicking on project -->
|
||||
<record id="dblc_proj" model="ir.actions.act_window">
|
||||
<field name="res_model">project.task</field>
|
||||
@@ -613,7 +539,8 @@ menu_main
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Task type">
|
||||
<field colspan="4" name="name" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="sequence"/>
|
||||
<field colspan="4" name="description" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
@@ -624,6 +551,7 @@ menu_main
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Task type">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -636,7 +564,7 @@ menu_main
|
||||
</record>
|
||||
<menuitem action="open_task_type_form" id="menu_task_types" parent="project.menu_definitions"/>
|
||||
|
||||
<act_window domain="[('manager', '=', active_id)]" id="act_res_users_2_project_project" name="User's projects" res_model="project.project" src_model="res.users" view_mode="tree,form" view_type="form"/>
|
||||
<act_window domain="[('user_id', '=', active_id)]" id="act_res_users_2_project_project" name="User's projects" res_model="project.project" src_model="res.users" view_mode="tree,form" view_type="form"/>
|
||||
|
||||
<act_window
|
||||
domain="[('project_id', '=', active_id)]"
|
||||
@@ -650,7 +578,7 @@ menu_main
|
||||
<act_window
|
||||
domain="[('project_id', '=', active_id)]"
|
||||
id="act_project_project_2_project_task_all"
|
||||
name="All Tasks"
|
||||
name="Tasks"
|
||||
res_model="project.task"
|
||||
src_model="project.project"
|
||||
view_mode="tree,form,calendar,graph"
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
<data>
|
||||
<wizard id="wizard_close_task" menu="False" model="project.task" name="project.task.close" string="Close Task"/>
|
||||
<wizard id="wizard_delegate_task" menu="False" model="project.task" name="project.task.delegate" string="Delegate Task"/>
|
||||
<!-- <wizard id="wizard_attachment_task" model="project.task" name="project.task.attachment" string="All Attachments"/> -->
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
@@ -58,7 +58,7 @@ def _compute_tasks(cr, uid, task_list, date_begin):
|
||||
|
||||
# Compute the closing date of the task
|
||||
tasks[task.id] = []
|
||||
res = pooler.get_pool(cr.dbname).get('hr.timesheet.group').interval_get(cr, uid, task.project_id.timesheet_id.id, date_start, task.remaining_hours)
|
||||
res = pooler.get_pool(cr.dbname).get('resource.calendar').interval_get(cr, uid, task.project_id.resource_calendar_id.id, date_start, task.remaining_hours)
|
||||
for (d1,d2) in res:
|
||||
tasks[task.id].append((d1, d2, task.name, task.user_id.login))
|
||||
date_close = tasks[task.id][-1][1]
|
||||
@@ -72,7 +72,7 @@ def _compute_tasks(cr, uid, task_list, date_begin):
|
||||
|
||||
def _compute_project(cr, uid, project, date_begin):
|
||||
tasks, last_date = _compute_tasks(cr, uid, project.tasks, date_begin)
|
||||
for proj in project.child_id:
|
||||
for proj in project.child_ids:
|
||||
d0 = DateTime.strptime(proj.date_start,'%Y-%m-%d')
|
||||
if d0 > last_date:
|
||||
last_date = d0
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
import close_task
|
||||
import task_delegate
|
||||
import task_attachment
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
||||
@@ -1,49 +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
|
||||
|
||||
'''View the attachments of the parent + children tasks'''
|
||||
|
||||
def _show_attachment(self, cr, uid, data, context):
|
||||
task_obj = pooler.get_pool(cr.dbname).get('project.task')
|
||||
task_browse_id = task_obj.browse(cr, uid, [data['id']], context)[0]
|
||||
attachment_list = [child_id.id for child_id in task_browse_id.child_ids]
|
||||
attachment_list.extend([task_browse_id.parent_id.id])
|
||||
value = {
|
||||
'domain': [('res_model','=',data['model']),('res_id','in',attachment_list)],
|
||||
'name': 'Attachments',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'ir.attachment',
|
||||
'context': { },
|
||||
'type': 'ir.actions.act_window'
|
||||
}
|
||||
return value
|
||||
class wizard_attachment(wizard.interface):
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type':'action', 'action':_show_attachment, 'state': 'end'},
|
||||
},
|
||||
}
|
||||
wizard_attachment('project.task.attachment')
|
||||
@@ -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:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user