[MERGE] merged with main addons
bzr revid: bde@tinyerp.com-20131231052502-k8uge2fxeulestpa
This commit is contained in:
+13
-15
@@ -28,7 +28,7 @@ import time
|
||||
import openerp
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp import tools
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.osv import fields, osv, expression
|
||||
from openerp.tools.translate import _
|
||||
from openerp.tools.float_utils import float_round
|
||||
|
||||
@@ -579,15 +579,18 @@ class account_account(osv.osv):
|
||||
except:
|
||||
pass
|
||||
if name:
|
||||
ids = self.search(cr, user, [('code', '=like', name+"%")]+args, limit=limit)
|
||||
if not ids:
|
||||
ids = self.search(cr, user, [('shortcut', '=', name)]+ args, limit=limit)
|
||||
if not ids:
|
||||
ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit)
|
||||
if not ids and len(name.split()) >= 2:
|
||||
#Separating code and name of account for searching
|
||||
operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A.
|
||||
ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2)]+ args, limit=limit)
|
||||
if operator not in expression.NEGATIVE_TERM_OPERATORS:
|
||||
ids = self.search(cr, user, ['|', ('code', '=like', name+"%"), '|', ('shortcut', '=', name), ('name', operator, name)]+args, limit=limit)
|
||||
if not ids and len(name.split()) >= 2:
|
||||
#Separating code and name of account for searching
|
||||
operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A.
|
||||
ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2)]+ args, limit=limit)
|
||||
else:
|
||||
ids = self.search(cr, user, ['&','!', ('code', '=like', name+"%"), ('name', operator, name)]+args, limit=limit)
|
||||
# as negation want to restric, do if already have results
|
||||
if ids and len(name.split()) >= 2:
|
||||
operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A.
|
||||
ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2), ('id', 'in', ids)]+ args, limit=limit)
|
||||
else:
|
||||
ids = self.search(cr, user, args, context=context, limit=limit)
|
||||
return self.name_get(cr, user, ids, context=context)
|
||||
@@ -1573,11 +1576,6 @@ class account_move(osv.osv):
|
||||
obj_analytic_line = self.pool.get('account.analytic.line')
|
||||
obj_move_line = self.pool.get('account.move.line')
|
||||
for move in self.browse(cr, uid, ids, context):
|
||||
# Unlink old analytic lines on move_lines
|
||||
for obj_line in move.line_id:
|
||||
for obj in obj_line.analytic_lines:
|
||||
obj_analytic_line.unlink(cr,uid,obj.id)
|
||||
|
||||
journal = move.journal_id
|
||||
amount = 0
|
||||
line_ids = []
|
||||
|
||||
@@ -193,6 +193,8 @@ class account_move_line(osv.osv):
|
||||
if obj_line.analytic_account_id:
|
||||
if not obj_line.journal_id.analytic_journal_id:
|
||||
raise osv.except_osv(_('No Analytic Journal!'),_("You have to define an analytic journal on the '%s' journal!") % (obj_line.journal_id.name, ))
|
||||
if obj_line.analytic_lines:
|
||||
acc_ana_line_obj.unlink(cr,uid,[obj.id for obj in obj_line.analytic_lines])
|
||||
vals_line = self._prepare_analytic_line(cr, uid, obj_line, context=context)
|
||||
acc_ana_line_obj.create(cr, uid, vals_line)
|
||||
return True
|
||||
@@ -1207,20 +1209,6 @@ class account_move_line(osv.osv):
|
||||
if not ok:
|
||||
raise osv.except_osv(_('Bad Account!'), _('You cannot use this general account in this journal, check the tab \'Entry Controls\' on the related journal.'))
|
||||
|
||||
if vals.get('analytic_account_id',False):
|
||||
if journal.analytic_journal_id:
|
||||
vals['analytic_lines'] = [(0,0, {
|
||||
'name': vals['name'],
|
||||
'date': vals.get('date', time.strftime('%Y-%m-%d')),
|
||||
'account_id': vals.get('analytic_account_id', False),
|
||||
'unit_amount': vals.get('quantity', 1.0),
|
||||
'amount': vals.get('debit', 0.0) or vals.get('credit', 0.0),
|
||||
'general_account_id': vals.get('account_id', False),
|
||||
'journal_id': journal.analytic_journal_id.id,
|
||||
'ref': vals.get('ref', False),
|
||||
'user_id': uid
|
||||
})]
|
||||
|
||||
result = super(account_move_line, self).create(cr, uid, vals, context=context)
|
||||
# CREATE Taxes
|
||||
if vals.get('account_tax_id', False):
|
||||
|
||||
@@ -3,9 +3,15 @@
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="analytic_journal_sale" model="account.analytic.journal">
|
||||
<field name="code">SAL</field>
|
||||
<field name="name">Sales</field>
|
||||
<field name="type">sale</field>
|
||||
</record>
|
||||
<record id="exp" model="account.analytic.journal">
|
||||
<field name="code">PUR</field>
|
||||
<field name="name">Purchases</field>
|
||||
<field name="type">purchase</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Payment term
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+1395
-663
File diff suppressed because it is too large
Load Diff
@@ -7,14 +7,14 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-07-02 06:32+0000\n"
|
||||
"PO-Revision-Date: 2013-12-19 08:06+0000\n"
|
||||
"Last-Translator: Chertykov Denis <chertykov@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: 2013-09-12 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-20 05:11+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
|
||||
#. module: account
|
||||
#: model:process.transition,name:account.process_transition_supplierreconcilepaid0
|
||||
@@ -184,6 +184,13 @@ msgid ""
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Щелкните, чтобы добавить отчетный период.\n"
|
||||
" </p><p>\n"
|
||||
" Отчетный период как правило - месяц или квартал .\n"
|
||||
" Обычно он соответствует периодам налоговой декларации.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.act_window,name:account.action_view_created_invoice_dashboard
|
||||
|
||||
@@ -6,11 +6,6 @@
|
||||
<field name="name">Sales</field>
|
||||
<field name="type">sale</field>
|
||||
</record>
|
||||
<record id="exp" model="account.analytic.journal">
|
||||
<field name="code">PUR</field>
|
||||
<field name="name">Purchases</field>
|
||||
<field name="type">purchase</field>
|
||||
</record>
|
||||
<record id="sit" model="account.analytic.journal">
|
||||
<field name="code">START</field>
|
||||
<field name="name">Miscellaneous Operation</field>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
from . import test_tax
|
||||
from . import test_search
|
||||
|
||||
fast_suite = [test_tax,
|
||||
]
|
||||
fast_suite = [
|
||||
test_tax,
|
||||
test_search,
|
||||
]
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
class TestSearch(TransactionCase):
|
||||
"""Tests for search on name_search (account.account)
|
||||
|
||||
The name search on account.account is quite complexe, make sure
|
||||
we have all the correct results
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestSearch, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
self.account_model = self.registry('account.account')
|
||||
self.account_type_model = self.registry('account.account.type')
|
||||
ac_ids = self.account_type_model.search(cr, uid, [], limit=1)
|
||||
self.atax = (int(self.account_model.create(cr, uid, dict(
|
||||
name="Tax Received",
|
||||
code="121",
|
||||
user_type=ac_ids[0],
|
||||
))), "121 Tax Received")
|
||||
|
||||
self.apurchase = (int(self.account_model.create(cr, uid, dict(
|
||||
name="Purchased Stocks",
|
||||
code="1101",
|
||||
user_type=ac_ids[0],
|
||||
))), "1101 Purchased Stocks")
|
||||
|
||||
self.asale = (int(self.account_model.create(cr, uid, dict(
|
||||
name="Product Sales",
|
||||
code="200",
|
||||
user_type=ac_ids[0],
|
||||
))), "200 Product Sales")
|
||||
|
||||
self.all_ids = [self.atax[0], self.apurchase[0], self.asale[0]]
|
||||
|
||||
def test_name_search(self):
|
||||
cr, uid = self.cr, self.uid
|
||||
atax_ids = self.account_model.name_search(cr, uid, name="Tax", operator='ilike', args=[('id', 'in', self.all_ids)])
|
||||
self.assertEqual(set([self.atax[0]]), set([a[0] for a in atax_ids]), "name_search 'ilike Tax' should have returned Tax Received account only")
|
||||
|
||||
atax_ids = self.account_model.name_search(cr, uid, name="Tax", operator='not ilike', args=[('id', 'in', self.all_ids)])
|
||||
self.assertEqual(set([self.apurchase[0], self.asale[0]]), set([a[0] for a in atax_ids]), "name_search 'not ilike Tax' should have returned all but Tax Received account")
|
||||
|
||||
apur_ids = self.account_model.name_search(cr, uid, name='1101', operator='ilike', args=[('id', 'in', self.all_ids)])
|
||||
self.assertEqual(set([self.apurchase[0]]), set([a[0] for a in apur_ids]), "name_search 'ilike 1101' should have returned Purchased Stocks account only")
|
||||
|
||||
apur_ids = self.account_model.name_search(cr, uid, name='1101', operator='not ilike', args=[('id', 'in', self.all_ids)])
|
||||
self.assertEqual(set([self.atax[0], self.asale[0]]), set([a[0] for a in apur_ids]), "name_search 'not ilike 1101' should have returned all but Purchased Stocks account")
|
||||
|
||||
asale_ids = self.account_model.name_search(cr, uid, name='200 Sales', operator='ilike', args=[('id', 'in', self.all_ids)])
|
||||
self.assertEqual(set([self.asale[0]]), set([a[0] for a in asale_ids]), "name_search 'ilike 200 Sales' should have returned Product Sales account only")
|
||||
|
||||
asale_ids = self.account_model.name_search(cr, uid, name='200 Sales', operator='not ilike', args=[('id', 'in', self.all_ids)])
|
||||
self.assertEqual(set([self.atax[0], self.apurchase[0]]), set([a[0] for a in asale_ids]), "name_search 'not ilike 200 Sales' should have returned all but Product Sales account")
|
||||
|
||||
asale_ids = self.account_model.name_search(cr, uid, name='Product Sales', operator='ilike', args=[('id', 'in', self.all_ids)])
|
||||
self.assertEqual(set([self.asale[0]]), set([a[0] for a in asale_ids]), "name_search 'ilike Product Sales' should have returned Product Sales account only")
|
||||
|
||||
asale_ids = self.account_model.name_search(cr, uid, name='Product Sales', operator='not ilike', args=[('id', 'in', self.all_ids)])
|
||||
self.assertEqual(set([self.atax[0], self.apurchase[0]]), set([a[0] for a in asale_ids]), "name_search 'not ilike Product Sales' should have returned all but Product Sales account")
|
||||
@@ -0,0 +1,23 @@
|
||||
# Spanish (Peru) translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-12-11 21:56+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish (Peru) <es_PE@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: 2013-12-12 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 16869)\n"
|
||||
|
||||
#. module: account_accountant
|
||||
#: model:ir.actions.client,name:account_accountant.action_client_account_menu
|
||||
msgid "Open Accounting Menu"
|
||||
msgstr ""
|
||||
@@ -450,6 +450,7 @@ class account_analytic_account(osv.osv):
|
||||
'is_overdue_quantity' : fields.function(_is_overdue_quantity, method=True, type='boolean', string='Overdue Quantity',
|
||||
store={
|
||||
'account.analytic.line' : (_get_analytic_account, None, 20),
|
||||
'account.analytic.account': (lambda self, cr, uid, ids, c=None: ids, ['quantity_max'], 10),
|
||||
}),
|
||||
'ca_invoiced': fields.function(_ca_invoiced_calc, type='float', string='Invoiced Amount',
|
||||
help="Total customer invoiced amount for this account.",
|
||||
|
||||
@@ -21,21 +21,25 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import osv
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
class account_invoice_line(osv.osv):
|
||||
_inherit = "account.invoice.line"
|
||||
|
||||
_columns = {
|
||||
'move_id': fields.many2one('stock.move', string="Move line", help="If the invoice was generated from a stock.picking, reference to the related move line."),
|
||||
}
|
||||
|
||||
def move_line_get(self, cr, uid, invoice_id, context=None):
|
||||
res = super(account_invoice_line,self).move_line_get(cr, uid, invoice_id, context=context)
|
||||
inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id, context=context)
|
||||
company_currency = inv.company_id.currency_id.id
|
||||
def get_price(cr, uid, inv, company_currency,i_line):
|
||||
def get_price(cr, uid, inv, company_currency, i_line, price_unit):
|
||||
cur_obj = self.pool.get('res.currency')
|
||||
if inv.currency_id.id != company_currency:
|
||||
price = cur_obj.compute(cr, uid, company_currency, inv.currency_id.id, i_line.product_id.standard_price * i_line.quantity, context={'date': inv.date_invoice})
|
||||
price = cur_obj.compute(cr, uid, company_currency, inv.currency_id.id, price_unit * i_line.quantity, context={'date': inv.date_invoice})
|
||||
else:
|
||||
price = i_line.product_id.standard_price * i_line.quantity
|
||||
price = price_unit * i_line.quantity
|
||||
return price
|
||||
|
||||
if inv.type in ('out_invoice','out_refund'):
|
||||
@@ -60,12 +64,13 @@ class account_invoice_line(osv.osv):
|
||||
if not cacc:
|
||||
cacc = i_line.product_id.categ_id.property_account_expense_categ and i_line.product_id.categ_id.property_account_expense_categ.id
|
||||
if dacc and cacc:
|
||||
price_unit = i_line.move_id and i_line.move_id.price_unit or i_line.product_id.standard_price
|
||||
res.append({
|
||||
'type':'src',
|
||||
'name': i_line.name[:64],
|
||||
'price_unit':i_line.product_id.standard_price,
|
||||
'price_unit':price_unit,
|
||||
'quantity':i_line.quantity,
|
||||
'price':get_price(cr, uid, inv, company_currency, i_line),
|
||||
'price':get_price(cr, uid, inv, company_currency, i_line, price_unit),
|
||||
'account_id':dacc,
|
||||
'product_id':i_line.product_id.id,
|
||||
'uos_id':i_line.uos_id.id,
|
||||
@@ -76,9 +81,9 @@ class account_invoice_line(osv.osv):
|
||||
res.append({
|
||||
'type':'src',
|
||||
'name': i_line.name[:64],
|
||||
'price_unit':i_line.product_id.standard_price,
|
||||
'price_unit':price_unit,
|
||||
'quantity':i_line.quantity,
|
||||
'price': -1 * get_price(cr, uid, inv, company_currency, i_line),
|
||||
'price': -1 * get_price(cr, uid, inv, company_currency, i_line, price_unit),
|
||||
'account_id':cacc,
|
||||
'product_id':i_line.product_id.id,
|
||||
'uos_id':i_line.uos_id.id,
|
||||
|
||||
@@ -28,6 +28,15 @@ class stock_picking(osv.osv):
|
||||
_inherit = "stock.picking"
|
||||
_description = "Picking List"
|
||||
|
||||
def _prepare_invoice_line(self, cr, uid, group, picking, move_line, invoice_id,
|
||||
invoice_vals, context=None):
|
||||
"""Overwrite to add move_id reference"""
|
||||
res = super(stock_picking, self)._prepare_invoice_line(cr, uid, group, picking, move_line, invoice_id, invoice_vals, context=context)
|
||||
res.update({
|
||||
'move_id': move_line.id,
|
||||
})
|
||||
return res
|
||||
|
||||
def action_invoice_create(self, cr, uid, ids, journal_id=False,
|
||||
group=False, type='out_invoice', context=None):
|
||||
'''Return ids of created invoices for the pickings'''
|
||||
|
||||
@@ -7,19 +7,19 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2012-08-19 10:21+0000\n"
|
||||
"Last-Translator: Eric Huang <eh@cenoq.com>\n"
|
||||
"PO-Revision-Date: 2013-12-29 09:12+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.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: 2013-09-12 06:05+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-30 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: account_chart
|
||||
#: model:ir.module.module,description:account_chart.module_meta_information
|
||||
msgid "Remove minimal account chart"
|
||||
msgstr "移除小的會計科目表"
|
||||
msgstr "移除最小的會計科目表"
|
||||
|
||||
#. module: account_chart
|
||||
#: model:ir.module.module,shortdesc:account_chart.module_meta_information
|
||||
|
||||
@@ -8,14 +8,14 @@ msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2012-08-22 06:48+0000\n"
|
||||
"Last-Translator: Eric Huang <eh@cenoq.com>\n"
|
||||
"PO-Revision-Date: 2013-12-29 09:09+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.com>\n"
|
||||
"Language-Team: Cenoq\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-09-12 06:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-30 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: selection:res.company,check_layout:0
|
||||
@@ -56,13 +56,13 @@ msgstr "支票位於底部"
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.act_window,name:account_check_writing.action_account_check_write
|
||||
msgid "Print Check in Batch"
|
||||
msgstr ""
|
||||
msgstr "整批列印支票"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: code:addons/account_check_writing/wizard/account_check_batch_printing.py:59
|
||||
#, python-format
|
||||
msgid "One of the printed check already got a number."
|
||||
msgstr ""
|
||||
msgstr "已列印的支票中有一張已有號碼。"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: help:account.journal,allow_check_writing:0
|
||||
@@ -109,7 +109,7 @@ msgstr "原始金額"
|
||||
#. module: account_check_writing
|
||||
#: field:res.company,check_layout:0
|
||||
msgid "Check Layout"
|
||||
msgstr ""
|
||||
msgstr "支票格式"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.voucher,allow_check:0
|
||||
@@ -131,7 +131,7 @@ msgstr "使用套表列印的支票"
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_bottom
|
||||
msgid "Print Check (Bottom)"
|
||||
msgstr ""
|
||||
msgstr "列印支票(底端)"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.act_window,help:account_check_writing.action_write_check
|
||||
@@ -160,7 +160,7 @@ msgstr "到期日期"
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_middle
|
||||
msgid "Print Check (Middle)"
|
||||
msgstr ""
|
||||
msgstr "列印支票(中間)"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.model,name:account_check_writing.model_res_company
|
||||
@@ -171,12 +171,12 @@ msgstr "公司"
|
||||
#: code:addons/account_check_writing/wizard/account_check_batch_printing.py:59
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr ""
|
||||
msgstr "錯誤!"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: help:account.check.write,check_number:0
|
||||
msgid "The number of the next check number to be printed."
|
||||
msgstr ""
|
||||
msgstr "下一張列印的支票的號碼"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
@@ -187,7 +187,7 @@ msgstr "截止餘額"
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_top
|
||||
msgid "Print Check (Top)"
|
||||
msgstr ""
|
||||
msgstr "列印支票(頂端)"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
@@ -204,7 +204,7 @@ msgstr "手工憑證"
|
||||
#. module: account_check_writing
|
||||
#: view:account.check.write:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
msgstr "或"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.voucher,amount_in_word:0
|
||||
@@ -214,22 +214,22 @@ msgstr "金額大寫"
|
||||
#. module: account_check_writing
|
||||
#: model:ir.model,name:account_check_writing.model_account_check_write
|
||||
msgid "Prin Check in Batch"
|
||||
msgstr ""
|
||||
msgstr "整批列印支票"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: view:account.check.write:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "取消"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.check.write,check_number:0
|
||||
msgid "Next Check Number"
|
||||
msgstr ""
|
||||
msgstr "下一個支票號碼"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: view:account.check.write:0
|
||||
msgid "Check"
|
||||
msgstr ""
|
||||
msgstr "支票"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The check payment form allows you to track the payment you do to your "
|
||||
|
||||
@@ -7,14 +7,14 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2012-08-24 12:49+0000\n"
|
||||
"Last-Translator: Eric Huang <eh@cenoq.com>\n"
|
||||
"PO-Revision-Date: 2013-12-24 10:29+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.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: 2013-09-12 05:21+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-25 06:02+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: account_followup
|
||||
#: model:email.template,subject:account_followup.email_template_account_followup_default
|
||||
@@ -22,12 +22,12 @@ msgstr ""
|
||||
#: model:email.template,subject:account_followup.email_template_account_followup_level1
|
||||
#: model:email.template,subject:account_followup.email_template_account_followup_level2
|
||||
msgid "${user.company_id.name} Payment Reminder"
|
||||
msgstr ""
|
||||
msgstr "${user.company_id.name} 提醒付款"
|
||||
|
||||
#. module: account_followup
|
||||
#: help:res.partner,latest_followup_level_id:0
|
||||
msgid "The maximum follow-up level"
|
||||
msgstr ""
|
||||
msgstr "最大後續追蹤層級"
|
||||
|
||||
#. module: account_followup
|
||||
#: view:account_followup.stat:0
|
||||
@@ -48,13 +48,13 @@ msgstr ""
|
||||
#. module: account_followup
|
||||
#: field:res.partner,payment_next_action_date:0
|
||||
msgid "Next Action Date"
|
||||
msgstr ""
|
||||
msgstr "下個動作日期"
|
||||
|
||||
#. module: account_followup
|
||||
#: view:account_followup.followup.line:0
|
||||
#: field:account_followup.followup.line,manual_action:0
|
||||
msgid "Manual Action"
|
||||
msgstr ""
|
||||
msgstr "手動動作"
|
||||
|
||||
#. module: account_followup
|
||||
#: field:account_followup.sending.results,needprinting:0
|
||||
@@ -64,7 +64,7 @@ msgstr ""
|
||||
#. module: account_followup
|
||||
#: view:res.partner:0
|
||||
msgid "⇾ Mark as Done"
|
||||
msgstr ""
|
||||
msgstr "⇾ 標為已完成"
|
||||
|
||||
#. module: account_followup
|
||||
#: field:account_followup.followup.line,manual_action_note:0
|
||||
@@ -104,17 +104,17 @@ msgstr ""
|
||||
#. module: account_followup
|
||||
#: view:account_followup.followup.line:0
|
||||
msgid "Follow-up Steps"
|
||||
msgstr ""
|
||||
msgstr "後續追蹤步驟"
|
||||
|
||||
#. module: account_followup
|
||||
#: field:account_followup.print,email_body:0
|
||||
msgid "Email Body"
|
||||
msgstr ""
|
||||
msgstr "Email內文"
|
||||
|
||||
#. module: account_followup
|
||||
#: model:ir.actions.act_window,name:account_followup.action_account_followup_print
|
||||
msgid "Send Follow-Ups"
|
||||
msgstr ""
|
||||
msgstr "送出後續追蹤"
|
||||
|
||||
#. module: account_followup
|
||||
#: report:account_followup.followup.print:0
|
||||
@@ -133,7 +133,7 @@ msgstr ""
|
||||
#. module: account_followup
|
||||
#: view:res.partner:0
|
||||
msgid "No Responsible"
|
||||
msgstr ""
|
||||
msgstr "沒有負責人"
|
||||
|
||||
#. module: account_followup
|
||||
#: model:account_followup.followup.line,description:account_followup.demo_followup_line2
|
||||
@@ -209,17 +209,17 @@ msgstr "借方合計"
|
||||
#. module: account_followup
|
||||
#: field:res.partner,payment_next_action:0
|
||||
msgid "Next Action"
|
||||
msgstr ""
|
||||
msgstr "下個動作"
|
||||
|
||||
#. module: account_followup
|
||||
#: view:account_followup.followup.line:0
|
||||
msgid ": Partner Name"
|
||||
msgstr ""
|
||||
msgstr "業務夥伴名稱"
|
||||
|
||||
#. module: account_followup
|
||||
#: field:account_followup.followup.line,manual_action_responsible_id:0
|
||||
msgid "Assign a Responsible"
|
||||
msgstr ""
|
||||
msgstr "指定一負責人"
|
||||
|
||||
#. module: account_followup
|
||||
#: view:account_followup.followup:0
|
||||
@@ -269,7 +269,7 @@ msgstr "合夥人"
|
||||
#. module: account_followup
|
||||
#: sql_constraint:account_followup.followup:0
|
||||
msgid "Only one follow-up per company is allowed"
|
||||
msgstr ""
|
||||
msgstr "一間公司僅允許一項後續追蹤"
|
||||
|
||||
#. module: account_followup
|
||||
#: code:addons/account_followup/wizard/account_followup_print.py:254
|
||||
@@ -300,7 +300,7 @@ msgstr ""
|
||||
#. module: account_followup
|
||||
#: model:ir.actions.act_window,name:account_followup.action_customer_followup
|
||||
msgid "Manual Follow-Ups"
|
||||
msgstr ""
|
||||
msgstr "手動後續追蹤"
|
||||
|
||||
#. module: account_followup
|
||||
#: view:account_followup.followup.line:0
|
||||
@@ -356,12 +356,12 @@ msgstr "借方"
|
||||
#. module: account_followup
|
||||
#: model:ir.model,name:account_followup.model_account_followup_stat
|
||||
msgid "Follow-up Statistics"
|
||||
msgstr ""
|
||||
msgstr "後續追蹤統計分析"
|
||||
|
||||
#. module: account_followup
|
||||
#: view:res.partner:0
|
||||
msgid "Send Overdue Email"
|
||||
msgstr ""
|
||||
msgstr "送出帳務逾期通知信"
|
||||
|
||||
#. module: account_followup
|
||||
#: model:ir.model,name:account_followup.model_account_followup_followup_line
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<field name="journal"/>
|
||||
<field name="bank_id" domain="[('partner_id','=',partner_id)]" />
|
||||
<field name="company_id" widget='selection' groups="base.group_multi_company" on_change="onchange_company_id(company_id)"/>
|
||||
<field name="partner_id" widget='selection' invisible="1"/>
|
||||
<field name="partner_id" invisible="1"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -7,14 +7,14 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2012-08-29 15:27+0000\n"
|
||||
"Last-Translator: Eric Huang <eh@cenoq.com>\n"
|
||||
"PO-Revision-Date: 2013-12-29 09:05+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.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: 2013-09-12 05:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-30 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: account_payment
|
||||
#: model:ir.actions.act_window,help:account_payment.action_payment_order_tree
|
||||
@@ -106,7 +106,7 @@ msgstr "到期日"
|
||||
#. module: account_payment
|
||||
#: view:payment.order.create:0
|
||||
msgid "_Add to payment order"
|
||||
msgstr ""
|
||||
msgstr "新增至付款單"
|
||||
|
||||
#. module: account_payment
|
||||
#: model:ir.actions.act_window,name:account_payment.action_account_payment_populate_statement
|
||||
@@ -127,7 +127,7 @@ msgstr ""
|
||||
#: code:addons/account_payment/account_move_line.py:110
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr ""
|
||||
msgstr "錯誤!"
|
||||
|
||||
#. module: account_payment
|
||||
#: report:payment.order:0
|
||||
@@ -148,7 +148,7 @@ msgstr "取消"
|
||||
#. module: account_payment
|
||||
#: model:ir.actions.act_window,name:account_payment.action_payment_order_tree_new
|
||||
msgid "New Payment Order"
|
||||
msgstr ""
|
||||
msgstr "新增付款單"
|
||||
|
||||
#. module: account_payment
|
||||
#: report:payment.order:0
|
||||
@@ -165,12 +165,12 @@ msgstr ""
|
||||
#: model:ir.actions.act_window,name:account_payment.action_payment_order_tree
|
||||
#: model:ir.ui.menu,name:account_payment.menu_action_payment_order_form
|
||||
msgid "Payment Orders"
|
||||
msgstr ""
|
||||
msgstr "付款單"
|
||||
|
||||
#. module: account_payment
|
||||
#: selection:payment.order,date_prefered:0
|
||||
msgid "Directly"
|
||||
msgstr ""
|
||||
msgstr "直接"
|
||||
|
||||
#. module: account_payment
|
||||
#: model:ir.actions.act_window,name:account_payment.action_payment_line_form
|
||||
@@ -217,7 +217,7 @@ msgstr ""
|
||||
#. module: account_payment
|
||||
#: view:account.bank.statement:0
|
||||
msgid "Import Payment Lines"
|
||||
msgstr ""
|
||||
msgstr "匯入付款細項"
|
||||
|
||||
#. module: account_payment
|
||||
#: view:payment.line:0
|
||||
@@ -256,17 +256,17 @@ msgstr ""
|
||||
#. module: account_payment
|
||||
#: field:payment.order,date_created:0
|
||||
msgid "Creation Date"
|
||||
msgstr ""
|
||||
msgstr "建立日期"
|
||||
|
||||
#. module: account_payment
|
||||
#: help:payment.mode,journal:0
|
||||
msgid "Bank or Cash Journal for the Payment Mode"
|
||||
msgstr ""
|
||||
msgstr "付款模式的銀行或現金日記帳簿"
|
||||
|
||||
#. module: account_payment
|
||||
#: selection:payment.order,date_prefered:0
|
||||
msgid "Fixed date"
|
||||
msgstr ""
|
||||
msgstr "固定日期"
|
||||
|
||||
#. module: account_payment
|
||||
#: field:payment.line,info_partner:0
|
||||
@@ -282,12 +282,12 @@ msgstr "目的帳號"
|
||||
#. module: account_payment
|
||||
#: view:payment.order:0
|
||||
msgid "Search Payment Orders"
|
||||
msgstr ""
|
||||
msgstr "搜尋付款單"
|
||||
|
||||
#. module: account_payment
|
||||
#: field:payment.line,create_date:0
|
||||
msgid "Created"
|
||||
msgstr ""
|
||||
msgstr "已建立"
|
||||
|
||||
#. module: account_payment
|
||||
#: view:payment.order:0
|
||||
@@ -394,7 +394,7 @@ msgstr "草稿"
|
||||
#: view:payment.order:0
|
||||
#: field:payment.order,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
msgstr "狀態"
|
||||
|
||||
#. module: account_payment
|
||||
#: help:payment.line,communication2:0
|
||||
@@ -424,7 +424,7 @@ msgstr "付款明細"
|
||||
#. module: account_payment
|
||||
#: model:ir.model,name:account_payment.model_account_move_line
|
||||
msgid "Journal Items"
|
||||
msgstr ""
|
||||
msgstr "日記簿項目"
|
||||
|
||||
#. module: account_payment
|
||||
#: help:payment.line,move_line_id:0
|
||||
@@ -441,7 +441,7 @@ msgstr "搜尋"
|
||||
#. module: account_payment
|
||||
#: field:payment.order,user_id:0
|
||||
msgid "Responsible"
|
||||
msgstr ""
|
||||
msgstr "負責人"
|
||||
|
||||
#. module: account_payment
|
||||
#: field:payment.line,date:0
|
||||
@@ -456,7 +456,7 @@ msgstr "總計:"
|
||||
#. module: account_payment
|
||||
#: field:payment.order,date_done:0
|
||||
msgid "Execution Date"
|
||||
msgstr ""
|
||||
msgstr "執行日期"
|
||||
|
||||
#. module: account_payment
|
||||
#: view:account.payment.populate.statement:0
|
||||
@@ -501,7 +501,7 @@ msgstr "您的參考"
|
||||
#. module: account_payment
|
||||
#: view:payment.order:0
|
||||
msgid "Payment order"
|
||||
msgstr ""
|
||||
msgstr "付款單"
|
||||
|
||||
#. module: account_payment
|
||||
#: view:payment.line:0
|
||||
@@ -535,7 +535,7 @@ msgstr "取消"
|
||||
#. module: account_payment
|
||||
#: field:payment.line,bank_id:0
|
||||
msgid "Destination Bank Account"
|
||||
msgstr ""
|
||||
msgstr "目的銀行帳戶"
|
||||
|
||||
#. module: account_payment
|
||||
#: view:payment.line:0
|
||||
@@ -548,7 +548,7 @@ msgstr "資訊"
|
||||
#: model:ir.model,name:account_payment.model_payment_order
|
||||
#: view:payment.order:0
|
||||
msgid "Payment Order"
|
||||
msgstr ""
|
||||
msgstr "付款單"
|
||||
|
||||
#. module: account_payment
|
||||
#: help:payment.line,amount:0
|
||||
@@ -573,7 +573,7 @@ msgstr "通訊 2"
|
||||
#. module: account_payment
|
||||
#: field:payment.order,date_scheduled:0
|
||||
msgid "Scheduled Date"
|
||||
msgstr ""
|
||||
msgstr "預定日期"
|
||||
|
||||
#. module: account_payment
|
||||
#: view:account.payment.make.payment:0
|
||||
@@ -584,7 +584,7 @@ msgstr "是否進行付款?"
|
||||
#: view:payment.mode:0
|
||||
#: field:payment.mode,journal:0
|
||||
msgid "Journal"
|
||||
msgstr ""
|
||||
msgstr "帳簿"
|
||||
|
||||
#. module: account_payment
|
||||
#: field:payment.mode,bank_id:0
|
||||
@@ -612,12 +612,12 @@ msgstr "付款"
|
||||
#. module: account_payment
|
||||
#: report:payment.order:0
|
||||
msgid "Payment Order / Payment"
|
||||
msgstr ""
|
||||
msgstr "付款單 / 付款"
|
||||
|
||||
#. module: account_payment
|
||||
#: field:payment.line,move_line_id:0
|
||||
msgid "Entry line"
|
||||
msgstr ""
|
||||
msgstr "分錄細項"
|
||||
|
||||
#. module: account_payment
|
||||
#: help:payment.line,communication:0
|
||||
@@ -640,7 +640,7 @@ msgstr "銀行帳戶"
|
||||
#: view:payment.line:0
|
||||
#: view:payment.order:0
|
||||
msgid "Entry Information"
|
||||
msgstr ""
|
||||
msgstr "分錄資訊"
|
||||
|
||||
#. module: account_payment
|
||||
#: model:ir.model,name:account_payment.model_payment_order_create
|
||||
@@ -673,7 +673,7 @@ msgstr ""
|
||||
#: view:account.payment.populate.statement:0
|
||||
#: view:payment.order.create:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
msgstr "或"
|
||||
|
||||
#. module: account_payment
|
||||
#: help:payment.mode,bank_id:0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,19 +7,19 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2012-08-28 02:30+0000\n"
|
||||
"Last-Translator: Eric Huang <eh@cenoq.com>\n"
|
||||
"PO-Revision-Date: 2013-12-29 08:26+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.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: 2013-09-12 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-30 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.bank.statement.line,voucher_id:0
|
||||
msgid "Reconciliation"
|
||||
msgstr ""
|
||||
msgstr "核銷"
|
||||
|
||||
#. module: account_voucher
|
||||
#: model:ir.model,name:account_voucher.model_account_config_settings
|
||||
@@ -63,7 +63,7 @@ msgstr "計算公式 : 憑證上输入的金额 - 憑證行的金额合計."
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "(Update)"
|
||||
msgstr ""
|
||||
msgstr "(更新)"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -90,7 +90,7 @@ msgstr "三月"
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,message_unread:0
|
||||
msgid "Unread Messages"
|
||||
msgstr ""
|
||||
msgstr "未讀訊息"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -100,7 +100,7 @@ msgstr "付賬"
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "Are you sure you want to cancel this receipt?"
|
||||
msgstr ""
|
||||
msgstr "你確定要取消這張收據嗎?"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -121,7 +121,7 @@ msgstr "依發票年份分組"
|
||||
#: view:sale.receipt.report:0
|
||||
#: field:sale.receipt.report,user_id:0
|
||||
msgid "Salesperson"
|
||||
msgstr ""
|
||||
msgstr "業務人員"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -134,7 +134,7 @@ msgstr "換領券統計"
|
||||
msgid ""
|
||||
"You can not change the journal as you already reconciled some statement "
|
||||
"lines!"
|
||||
msgstr ""
|
||||
msgstr "你已經核銷部分項目,所以無法變更日記帳簿!"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -145,7 +145,7 @@ msgstr "驗證"
|
||||
#: model:ir.actions.act_window,name:account_voucher.action_vendor_payment
|
||||
#: model:ir.ui.menu,name:account_voucher.menu_action_vendor_payment
|
||||
msgid "Supplier Payments"
|
||||
msgstr ""
|
||||
msgstr "供應商付款"
|
||||
|
||||
#. module: account_voucher
|
||||
#: model:ir.actions.act_window,help:account_voucher.action_purchase_receipt
|
||||
@@ -207,13 +207,13 @@ msgstr "備註"
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,message_ids:0
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
msgstr "訊息"
|
||||
|
||||
#. module: account_voucher
|
||||
#: model:ir.actions.act_window,name:account_voucher.action_purchase_receipt
|
||||
#: model:ir.ui.menu,name:account_voucher.menu_action_purchase_receipt
|
||||
msgid "Purchase Receipts"
|
||||
msgstr ""
|
||||
msgstr "採購單據"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher.line,move_line_id:0
|
||||
@@ -225,7 +225,7 @@ msgstr "會計憑證行"
|
||||
#: code:addons/account_voucher/account_voucher.py:1073
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr ""
|
||||
msgstr "錯誤!"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher.line,amount:0
|
||||
@@ -271,7 +271,7 @@ msgstr ""
|
||||
#. module: account_voucher
|
||||
#: help:account.voucher,message_unread:0
|
||||
msgid "If checked new messages require your attention."
|
||||
msgstr ""
|
||||
msgstr "當有新訊息時通知您。"
|
||||
|
||||
#. module: account_voucher
|
||||
#: model:ir.model,name:account_voucher.model_account_bank_statement_line
|
||||
@@ -294,7 +294,7 @@ msgstr "稅"
|
||||
#: code:addons/account_voucher/account_voucher.py:971
|
||||
#, python-format
|
||||
msgid "Invalid Action!"
|
||||
msgstr ""
|
||||
msgstr "無效的動作!"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,comment:0
|
||||
@@ -326,7 +326,7 @@ msgstr "付款資料"
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "(update)"
|
||||
msgstr ""
|
||||
msgstr "(更新)"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -395,7 +395,7 @@ msgstr "供應商換領券"
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,message_follower_ids:0
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
msgstr "關注者"
|
||||
|
||||
#. module: account_voucher
|
||||
#: selection:account.voucher.line,type:0
|
||||
@@ -406,7 +406,7 @@ msgstr "借方"
|
||||
#: code:addons/account_voucher/account_voucher.py:1641
|
||||
#, python-format
|
||||
msgid "Unable to change journal !"
|
||||
msgstr ""
|
||||
msgstr "無法變更日記帳簿!"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:sale.receipt.report:0
|
||||
@@ -544,7 +544,7 @@ msgstr ""
|
||||
#: field:account.config.settings,expense_currency_exchange_account_id:0
|
||||
#: field:res.company,expense_currency_exchange_account_id:0
|
||||
msgid "Loss Exchange Rate Account"
|
||||
msgstr ""
|
||||
msgstr "匯損科目"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -587,7 +587,7 @@ msgstr "支出明細"
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "Sale voucher"
|
||||
msgstr ""
|
||||
msgstr "銷售單據"
|
||||
|
||||
#. module: account_voucher
|
||||
#: help:account.voucher,is_multi_currency:0
|
||||
@@ -599,7 +599,7 @@ msgstr "此字段由系統內部使用,區分該憑證是否涉及外幣"
|
||||
#. module: account_voucher
|
||||
#: view:account.invoice:0
|
||||
msgid "Register Payment"
|
||||
msgstr ""
|
||||
msgstr "登記付款紀錄"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.statement.from.invoice.lines,line_ids:0
|
||||
@@ -638,17 +638,17 @@ msgstr "應收應付"
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "Voucher Payment"
|
||||
msgstr ""
|
||||
msgstr "付款單據"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:sale.receipt.report,state:0
|
||||
msgid "Voucher Status"
|
||||
msgstr ""
|
||||
msgstr "單據狀態"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "Are you sure to unreconcile this record?"
|
||||
msgstr ""
|
||||
msgstr "你是否要取消核銷此紀錄?"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,company_id:0
|
||||
@@ -672,7 +672,7 @@ msgstr "核銷付款餘額"
|
||||
#: code:addons/account_voucher/account_voucher.py:1067
|
||||
#, python-format
|
||||
msgid "Configuration Error !"
|
||||
msgstr ""
|
||||
msgstr "設置錯誤!"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -689,14 +689,14 @@ msgstr "連稅總額"
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "Purchase Voucher"
|
||||
msgstr ""
|
||||
msgstr "採購單據"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
#: field:account.voucher,state:0
|
||||
#: view:sale.receipt.report:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
msgstr "狀態"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -707,7 +707,7 @@ msgstr "分配"
|
||||
#: view:account.statement.from.invoice.lines:0
|
||||
#: view:account.voucher:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
msgstr "或"
|
||||
|
||||
#. module: account_voucher
|
||||
#: selection:sale.receipt.report,month:0
|
||||
@@ -717,7 +717,7 @@ msgstr "八月"
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "Validate Payment"
|
||||
msgstr ""
|
||||
msgstr "認可付款"
|
||||
|
||||
#. module: account_voucher
|
||||
#: help:account.voucher,audit:0
|
||||
@@ -756,12 +756,12 @@ msgstr "已付款"
|
||||
#: model:ir.actions.act_window,name:account_voucher.action_sale_receipt
|
||||
#: model:ir.ui.menu,name:account_voucher.menu_action_sale_receipt
|
||||
msgid "Sales Receipts"
|
||||
msgstr ""
|
||||
msgstr "銷售收據"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,message_is_follower:0
|
||||
msgid "Is a Follower"
|
||||
msgstr ""
|
||||
msgstr "為關注者"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,analytic_id:0
|
||||
@@ -815,7 +815,7 @@ msgstr "預付款?"
|
||||
#: code:addons/account_voucher/account_voucher.py:1208
|
||||
#, python-format
|
||||
msgid "The invoice you are willing to pay is not valid anymore."
|
||||
msgstr ""
|
||||
msgstr "你要付款的發票已經不再有效。"
|
||||
|
||||
#. module: account_voucher
|
||||
#: selection:sale.receipt.report,month:0
|
||||
@@ -836,12 +836,12 @@ msgstr "公司"
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,message_summary:0
|
||||
msgid "Summary"
|
||||
msgstr ""
|
||||
msgstr "摘要"
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,active:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
msgstr "啟用"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1074
|
||||
@@ -854,14 +854,14 @@ msgstr ""
|
||||
#: model:ir.actions.act_window,name:account_voucher.action_vendor_receipt
|
||||
#: model:ir.ui.menu,name:account_voucher.menu_action_vendor_receipt
|
||||
msgid "Customer Payments"
|
||||
msgstr ""
|
||||
msgstr "客戶付款"
|
||||
|
||||
#. module: account_voucher
|
||||
#: model:ir.actions.act_window,name:account_voucher.action_sale_receipt_report_all
|
||||
#: model:ir.ui.menu,name:account_voucher.menu_action_sale_receipt_report_all
|
||||
#: view:sale.receipt.report:0
|
||||
msgid "Sales Receipts Analysis"
|
||||
msgstr ""
|
||||
msgstr "銷售收據分析"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:sale.receipt.report:0
|
||||
@@ -956,7 +956,7 @@ msgstr "取消"
|
||||
#. module: account_voucher
|
||||
#: model:ir.actions.client,name:account_voucher.action_client_invoice_menu
|
||||
msgid "Open Invoicing Menu"
|
||||
msgstr ""
|
||||
msgstr "開啟發票開立選單"
|
||||
|
||||
#. module: account_voucher
|
||||
#: selection:account.voucher,state:0
|
||||
@@ -1044,7 +1044,7 @@ msgstr "五月"
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
msgid "Sale Receipt"
|
||||
msgstr ""
|
||||
msgstr "銷售收據"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
@@ -1129,7 +1129,7 @@ msgstr "年份"
|
||||
#: field:account.config.settings,income_currency_exchange_account_id:0
|
||||
#: field:res.company,income_currency_exchange_account_id:0
|
||||
msgid "Gain Exchange Rate Account"
|
||||
msgstr ""
|
||||
msgstr "匯益科目"
|
||||
|
||||
#. module: account_voucher
|
||||
#: selection:account.voucher,type:0
|
||||
@@ -1155,7 +1155,7 @@ msgstr "預設類型"
|
||||
#. module: account_voucher
|
||||
#: help:account.voucher,message_ids:0
|
||||
msgid "Messages and communication history"
|
||||
msgstr ""
|
||||
msgstr "訊息及聯絡紀錄"
|
||||
|
||||
#. module: account_voucher
|
||||
#: model:ir.model,name:account_voucher.model_account_statement_from_invoice_lines
|
||||
@@ -1194,7 +1194,7 @@ msgstr "會計分錄的生效日期"
|
||||
#. module: account_voucher
|
||||
#: model:mail.message.subtype,name:account_voucher.mt_voucher_state_change
|
||||
msgid "Status Change"
|
||||
msgstr ""
|
||||
msgstr "狀態變更"
|
||||
|
||||
#. module: account_voucher
|
||||
#: selection:account.voucher,payment_option:0
|
||||
@@ -1241,14 +1241,14 @@ msgstr "未結餘額"
|
||||
#. module: account_voucher
|
||||
#: model:mail.message.subtype,description:account_voucher.mt_voucher_state_change
|
||||
msgid "Status <b>changed</b>"
|
||||
msgstr ""
|
||||
msgstr "狀態<b>已變更</b>"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1106
|
||||
#: code:addons/account_voucher/account_voucher.py:1110
|
||||
#, python-format
|
||||
msgid "Insufficient Configuration!"
|
||||
msgstr ""
|
||||
msgstr "設置不夠完整!"
|
||||
|
||||
#. module: account_voucher
|
||||
#: help:account.voucher,active:0
|
||||
|
||||
@@ -1,43 +1,28 @@
|
||||
# Chinese (Traditional) translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
|
||||
"PO-Revision-Date: 2012-08-19 10:28+0000\n"
|
||||
"Last-Translator: Eric Huang <eh@cenoq.com>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-29 17:06+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Chinese (Traditional) <zh_TW@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: 2012-12-04 05:53+0000\n"
|
||||
"X-Generator: Launchpad (build 16335)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-30 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: base_crypt
|
||||
#: model:ir.model,name:base_crypt.model_res_users
|
||||
#. module: auth_crypt
|
||||
#: field:res.users,password_crypt:0
|
||||
msgid "Encrypted Password"
|
||||
msgstr "已加密的密碼"
|
||||
|
||||
#. module: auth_crypt
|
||||
#: model:ir.model,name:auth_crypt.model_res_users
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Base - Password Encryption"
|
||||
#~ msgstr "基礎 - 密碼加密"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Please specify the password !"
|
||||
#~ msgstr "請指定密碼 !"
|
||||
|
||||
#~ msgid "You can not have two users with the same login !"
|
||||
#~ msgstr "您不能同時登入二個使用者!"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Error"
|
||||
#~ msgstr "錯誤"
|
||||
|
||||
#~ msgid "The chosen company is not in the allowed companies for this user"
|
||||
#~ msgstr "所選的公司不是使用者被允許的公司。"
|
||||
|
||||
#~ msgid "res.users"
|
||||
#~ msgstr "res.users"
|
||||
msgstr "使用者"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
<field name="active" eval="False"/>
|
||||
<!-- Avoid auto-including this user in any default group, just like a typical portal member -->
|
||||
<field name="groups_id" eval="[(5,)]"/>
|
||||
<!-- no alias for portal users -->
|
||||
<field name="alias_name" eval="False"/>
|
||||
<!-- allow signuped users to have a alias -->
|
||||
<field name="alias_name">_usertemplate</field>
|
||||
</record>
|
||||
|
||||
<record id="default_template_user_config" model="ir.config_parameter">
|
||||
|
||||
@@ -8,14 +8,14 @@ msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-09-19 09:40+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"PO-Revision-Date: 2013-12-29 09:17+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.com>\n"
|
||||
"Language-Team: Chinese (Traditional) <zh_TW@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: 2013-09-20 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16765)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-30 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_type:0
|
||||
@@ -66,19 +66,19 @@ msgstr ""
|
||||
#. module: auth_signup
|
||||
#: model:email.template,subject:auth_signup.reset_password_email
|
||||
msgid "Password reset"
|
||||
msgstr ""
|
||||
msgstr "密碼重設"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:120
|
||||
#, python-format
|
||||
msgid "Please enter a password and confirm it."
|
||||
msgstr ""
|
||||
msgstr "請輸入密碼並確認"
|
||||
|
||||
#. module: auth_signup
|
||||
#: view:res.users:0
|
||||
msgid "Send an email to the user to (re)set their password."
|
||||
msgstr ""
|
||||
msgstr "寄出密碼重設電子郵件給該使用者"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
@@ -86,23 +86,23 @@ msgstr ""
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:29
|
||||
#, python-format
|
||||
msgid "Sign Up"
|
||||
msgstr ""
|
||||
msgstr "註冊"
|
||||
|
||||
#. module: auth_signup
|
||||
#: selection:res.users,state:0
|
||||
msgid "New"
|
||||
msgstr ""
|
||||
msgstr "新增"
|
||||
|
||||
#. module: auth_signup
|
||||
#: code:addons/auth_signup/res_users.py:258
|
||||
#, python-format
|
||||
msgid "Mail sent to:"
|
||||
msgstr ""
|
||||
msgstr "信件已寄給:"
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.users,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
msgstr "狀態"
|
||||
|
||||
#. module: auth_signup
|
||||
#: model:email.template,body_html:auth_signup.reset_password_email
|
||||
@@ -122,29 +122,29 @@ msgstr ""
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:114
|
||||
#, python-format
|
||||
msgid "Please enter a name."
|
||||
msgstr ""
|
||||
msgstr "請輸入名字"
|
||||
|
||||
#. module: auth_signup
|
||||
#: model:ir.model,name:auth_signup.model_res_users
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
msgstr "使用者"
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_url:0
|
||||
msgid "Signup URL"
|
||||
msgstr ""
|
||||
msgstr "註冊網址"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:117
|
||||
#, python-format
|
||||
msgid "Please enter a username."
|
||||
msgstr ""
|
||||
msgstr "請輸入使用者名稱。"
|
||||
|
||||
#. module: auth_signup
|
||||
#: selection:res.users,state:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
msgstr "啟用"
|
||||
|
||||
#. module: auth_signup
|
||||
#: code:addons/auth_signup/res_users.py:270
|
||||
@@ -159,26 +159,26 @@ msgstr ""
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:12
|
||||
#, python-format
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
msgstr "使用者名稱"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:8
|
||||
#, python-format
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
msgstr "名稱"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:173
|
||||
#, python-format
|
||||
msgid "Please enter a username or email address."
|
||||
msgstr ""
|
||||
msgstr "請輸入使用者名稱或電子郵件地址"
|
||||
|
||||
#. module: auth_signup
|
||||
#: selection:res.users,state:0
|
||||
msgid "Resetting Password"
|
||||
msgstr ""
|
||||
msgstr "重設密碼中"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
@@ -202,7 +202,7 @@ msgstr ""
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:25
|
||||
#, python-format
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
msgstr "登入"
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_valid:0
|
||||
@@ -220,7 +220,7 @@ msgstr ""
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:173
|
||||
#, python-format
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
msgstr "登入"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
@@ -242,36 +242,36 @@ msgstr ""
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:170
|
||||
#, python-format
|
||||
msgid "No database selected !"
|
||||
msgstr ""
|
||||
msgstr "未選定資料庫!"
|
||||
|
||||
#. module: auth_signup
|
||||
#: view:res.users:0
|
||||
msgid "Reset Password"
|
||||
msgstr ""
|
||||
msgstr "重設密碼"
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:base.config.settings,auth_signup_reset_password:0
|
||||
msgid "Enable password reset from Login page"
|
||||
msgstr ""
|
||||
msgstr "於登入頁面啟用密碼重設"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:30
|
||||
#, python-format
|
||||
msgid "Back to Login"
|
||||
msgstr ""
|
||||
msgstr "返回登入畫面"
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:22
|
||||
#, python-format
|
||||
msgid "Sign up"
|
||||
msgstr ""
|
||||
msgstr "註冊"
|
||||
|
||||
#. module: auth_signup
|
||||
#: model:ir.model,name:auth_signup.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
msgstr "業務夥伴"
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_token:0
|
||||
|
||||
@@ -234,8 +234,6 @@ class res_users(osv.Model):
|
||||
|
||||
# create a copy of the template user (attached to a specific partner_id if given)
|
||||
values['active'] = True
|
||||
if 'alias_name' not in values: # allow behavior change via inheritance (like using the name)
|
||||
values['alias_name'] = False
|
||||
context = dict(context or {}, no_reset_password=True)
|
||||
return self.copy(cr, uid, template_user_id, values, context=context)
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ from datetime import datetime, timedelta
|
||||
import time
|
||||
import logging
|
||||
|
||||
import openerp
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
@@ -222,6 +223,7 @@ class base_action_rule(osv.osv):
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
res_id = super(base_action_rule, self).create(cr, uid, vals, context=context)
|
||||
self._register_hook(cr, [res_id])
|
||||
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
|
||||
return res_id
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
@@ -229,6 +231,7 @@ class base_action_rule(osv.osv):
|
||||
ids = [ids]
|
||||
super(base_action_rule, self).write(cr, uid, ids, vals, context=context)
|
||||
self._register_hook(cr, ids)
|
||||
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
|
||||
return True
|
||||
|
||||
def onchange_model_id(self, cr, uid, ids, model_id, context=None):
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 18:37+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule.lead.test,state:0
|
||||
msgid "In Progress"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid ""
|
||||
"- In this same \"Search\" view, select the menu \"Save Current Filter\", "
|
||||
"enter the name (Ex: Create the 01/01/2012) and add the option \"Share with "
|
||||
"all users\""
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: model:ir.model,name:base_action_rule.model_base_action_rule
|
||||
msgid "Action Rules"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Select a filter or a timer as condition."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule.lead.test,user_id:0
|
||||
msgid "Responsible"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: help:base.action.rule,server_action_ids:0
|
||||
msgid "Examples: email reminders, call object service, etc."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,act_followers:0
|
||||
msgid "Add Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,act_user_id:0
|
||||
msgid "Set Responsible"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: help:base.action.rule,trg_date_range:0
|
||||
msgid ""
|
||||
"Delay after the trigger date.You can put a negative number if you need a "
|
||||
"delay before thetrigger date, like sending a reminder 15 minutes before a "
|
||||
"meeting."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: model:ir.model,name:base_action_rule.model_base_action_rule_lead_test
|
||||
msgid "base.action.rule.lead.test"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule.lead.test,state:0
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule.lead.test,state:0
|
||||
msgid "New"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,trg_date_range:0
|
||||
msgid "Delay after trigger date"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Conditions"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule.lead.test,state:0
|
||||
msgid "Pending"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule.lead.test,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,filter_pre_id:0
|
||||
msgid "Before Update Filter"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Action Rule"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: help:base.action.rule,filter_id:0
|
||||
msgid ""
|
||||
"If present, this condition must be satisfied after the update of the record."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Fields to Change"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "The filter must therefore be available in this page."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,filter_id:0
|
||||
msgid "After Update Filter"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule,trg_date_range_type:0
|
||||
msgid "Hours"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "To create a new filter:"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,active:0
|
||||
#: field:base.action.rule.lead.test,active:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Delay After Trigger Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid ""
|
||||
"An action rule is checked when you create or modify the \"Related Document "
|
||||
"Model\". The precondition filter is checked right before the modification "
|
||||
"while the postcondition filter is checked after the modification. A "
|
||||
"precondition filter will therefore not work during a creation."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Filter Condition"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid ""
|
||||
"- Go to your \"Related Document Model\" page and set the filter parameters "
|
||||
"in the \"Search\" view (Example of filter based on Leads/Opportunities: "
|
||||
"Creation Date \"is equal to\" 01/01/2012)"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,name:0
|
||||
msgid "Rule Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: model:ir.actions.act_window,name:base_action_rule.base_action_rule_act
|
||||
#: model:ir.ui.menu,name:base_action_rule.menu_base_action_rule_form
|
||||
msgid "Automated Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: help:base.action.rule,sequence:0
|
||||
msgid "Gives the sequence order when displaying a list of rules."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule,trg_date_range_type:0
|
||||
msgid "Months"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule,trg_date_range_type:0
|
||||
msgid "Days"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Timer"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,trg_date_range_type:0
|
||||
msgid "Delay type"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Server actions to run"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: help:base.action.rule,active:0
|
||||
msgid "When unchecked, the rule is hidden and will not be executed."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule.lead.test,state:0
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,model:0
|
||||
msgid "Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,last_run:0
|
||||
msgid "Last Run"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: selection:base.action.rule,trg_date_range_type:0
|
||||
msgid "Minutes"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,model_id:0
|
||||
msgid "Related Document Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: help:base.action.rule,filter_pre_id:0
|
||||
msgid ""
|
||||
"If present, this condition must be satisfied before the update of the record."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,sequence:0
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
msgid "Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: model:ir.actions.act_window,help:base_action_rule.base_action_rule_act
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to setup a new automated action rule. \n"
|
||||
" </p><p>\n"
|
||||
" Use automated actions to automatically trigger actions for\n"
|
||||
" various screens. Example: a lead created by a specific user "
|
||||
"may\n"
|
||||
" be automatically set to a specific sales team, or an\n"
|
||||
" opportunity which still has status pending after 14 days "
|
||||
"might\n"
|
||||
" trigger an automatic reminder email.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,create_date:0
|
||||
msgid "Create Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule.lead.test,date_action_last:0
|
||||
msgid "Last Action"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule.lead.test,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,trg_date_id:0
|
||||
msgid "Trigger Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: view:base.action.rule:0
|
||||
#: field:base.action.rule,server_action_ids:0
|
||||
msgid "Server Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule.lead.test,name:0
|
||||
msgid "Subject"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,370 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 18:38+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Emails Integration"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: selection:base.setup.terminology,partner:0
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Contacts"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: model:ir.model,name:base_setup.model_base_config_settings
|
||||
msgid "base.config.settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:base.config.settings,module_auth_oauth:0
|
||||
msgid ""
|
||||
"Use external authentication providers, sign in with google, facebook, ..."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
msgid ""
|
||||
"OpenERP allows to automatically create leads (or others documents)\n"
|
||||
" from incoming emails. You can automatically "
|
||||
"synchronize emails with OpenERP\n"
|
||||
" using regular POP/IMAP accounts, using a direct "
|
||||
"email integration script for your\n"
|
||||
" email server, or by manually pushing emails to "
|
||||
"OpenERP using specific\n"
|
||||
" plugins for your preferred email application."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:sale.config.settings,module_sale:0
|
||||
msgid "SALE"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: selection:base.setup.terminology,partner:0
|
||||
msgid "Member"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "Portal access"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "Authentication"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Quotations and Sales Orders"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
#: model:ir.actions.act_window,name:base_setup.action_general_configuration
|
||||
#: model:ir.ui.menu,name:base_setup.menu_general_configuration
|
||||
msgid "General Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: selection:base.setup.terminology,partner:0
|
||||
msgid "Donor"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:sale.config.settings,module_crm:0
|
||||
msgid "CRM"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: selection:base.setup.terminology,partner:0
|
||||
msgid "Patient"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:base.config.settings,module_base_import:0
|
||||
msgid "Allow users to import data from CSV files"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:base.config.settings,module_multi_company:0
|
||||
msgid "Manage multiple companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
msgid "On Mail Client"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "--db-filter=YOUR_DATABAE"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:sale.config.settings,module_web_linkedin:0
|
||||
msgid "Get contacts automatically from linkedIn"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:sale.config.settings,module_plugin_thunderbird:0
|
||||
msgid "Enable Thunderbird plug-in"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.setup.terminology:0
|
||||
msgid "res_config_contents"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Customer Features"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "Import / Export"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Sale Features"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:sale.config.settings,module_plugin_outlook:0
|
||||
msgid "Enable Outlook plug-in"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.setup.terminology:0
|
||||
msgid ""
|
||||
"You can use this wizard to change the terminologies for customers in the "
|
||||
"whole application."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: selection:base.setup.terminology,partner:0
|
||||
msgid "Tenant"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: help:base.config.settings,module_share:0
|
||||
msgid "Share or embbed any screen of openerp."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: selection:base.setup.terminology,partner:0
|
||||
msgid "Customer"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: help:sale.config.settings,module_web_linkedin:0
|
||||
msgid ""
|
||||
"When you create a new contact (person or company), you will be able to load "
|
||||
"all the data from LinkedIn (photos, address, etc)."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: help:base.config.settings,module_multi_company:0
|
||||
msgid ""
|
||||
"Work in multi-company environments, with appropriate security access between "
|
||||
"companies.\n"
|
||||
" This installs the module multi_company."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid ""
|
||||
"The public portal is accessible only if you are in a single database mode. "
|
||||
"You can\n"
|
||||
" launch the OpenERP Server with the option"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid ""
|
||||
"You will find more options in your company details: address for the header "
|
||||
"and footer, overdue payments texts, etc."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: model:ir.model,name:base_setup.model_sale_config_settings
|
||||
msgid "sale.config.settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:base.setup.terminology,partner:0
|
||||
msgid "How do you call a Customer"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid ""
|
||||
"When you send a document to a customer\n"
|
||||
" (quotation, invoice), your customer will "
|
||||
"be\n"
|
||||
" able to signup to get all his "
|
||||
"documents,\n"
|
||||
" read your company news, check his "
|
||||
"projects,\n"
|
||||
" etc."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: model:ir.model,name:base_setup.model_base_setup_terminology
|
||||
msgid "base.setup.terminology"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: selection:base.setup.terminology,partner:0
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: help:base.config.settings,module_portal_anonymous:0
|
||||
msgid "Enable the public part of openerp, openerp becomes a public website."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: help:sale.config.settings,module_plugin_thunderbird:0
|
||||
msgid ""
|
||||
"The plugin allows you archive email and its attachments to the selected\n"
|
||||
" OpenERP objects. You can select a partner, or a lead and\n"
|
||||
" attach the selected mail as a .eml file in\n"
|
||||
" the attachment of a selected record. You can create "
|
||||
"documents for CRM Lead,\n"
|
||||
" Partner from the selected emails.\n"
|
||||
" This installs the module plugin_thunderbird."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: selection:base.setup.terminology,partner:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: model:ir.actions.act_window,name:base_setup.action_partner_terminology_config_form
|
||||
msgid "Use another word to say \"Customer\""
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: model:ir.actions.act_window,name:base_setup.action_sale_config
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Configure Sales"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: help:sale.config.settings,module_plugin_outlook:0
|
||||
msgid ""
|
||||
"The Outlook plugin allows you to select an object that you would like to "
|
||||
"add\n"
|
||||
" to your email and its attachments from MS Outlook. You can "
|
||||
"select a partner,\n"
|
||||
" or a lead object and archive a selected\n"
|
||||
" email into an OpenERP mail message with attachments.\n"
|
||||
" This installs the module plugin_outlook."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:base.config.settings,module_portal:0
|
||||
msgid "Activate the customer portal"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid ""
|
||||
"to do so.\n"
|
||||
" Once activated, the login page will be "
|
||||
"replaced by the public website."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:base.config.settings,module_share:0
|
||||
msgid "Allow documents sharing"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "(company news, jobs, contact form, etc.)"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: field:base.config.settings,module_portal_anonymous:0
|
||||
msgid "Activate the public portal"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "Configure outgoing email servers"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Social Network Integration"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: help:base.config.settings,module_portal:0
|
||||
msgid "Give your customers access to their documents."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Apply"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.setup.terminology:0
|
||||
msgid "Specify Your Terminology"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
#: view:sale.config.settings:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_setup
|
||||
#: view:base.config.settings:0
|
||||
msgid "Configure your company data"
|
||||
msgstr ""
|
||||
@@ -7,14 +7,14 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2011-11-07 12:53+0000\n"
|
||||
"Last-Translator: Walter Cheuk <wwycheuk@gmail.com>\n"
|
||||
"PO-Revision-Date: 2013-12-29 15:39+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.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: 2013-09-12 05:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-30 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: base_setup
|
||||
#: view:sale.config.settings:0
|
||||
@@ -189,7 +189,7 @@ msgstr "客戶"
|
||||
msgid ""
|
||||
"When you create a new contact (person or company), you will be able to load "
|
||||
"all the data from LinkedIn (photos, address, etc)."
|
||||
msgstr ""
|
||||
msgstr "當建立新的聯絡人時(個人或公司),你就可以從 LinkedIn 載入所有資料(照片、地址等)。"
|
||||
|
||||
#. module: base_setup
|
||||
#: help:base.config.settings,module_multi_company:0
|
||||
@@ -212,7 +212,7 @@ msgstr ""
|
||||
msgid ""
|
||||
"You will find more options in your company details: address for the header "
|
||||
"and footer, overdue payments texts, etc."
|
||||
msgstr ""
|
||||
msgstr "您可在貴公司的詳細資訊中找到更多選項,如表頭和頁尾的地址、付款過期通知等等。"
|
||||
|
||||
#. module: base_setup
|
||||
#: model:ir.model,name:base_setup.model_sale_config_settings
|
||||
|
||||
@@ -68,7 +68,7 @@ class base_config_settings(osv.osv_memory):
|
||||
|
||||
def set_base_defaults(self, cr, uid, ids, context=None):
|
||||
ir_model_data = self.pool.get('ir.model.data')
|
||||
wizard = self.browse(cr, uid, ids)[0]
|
||||
wizard = self.browse(cr, uid, ids, context)[0]
|
||||
if wizard.font:
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context)
|
||||
font_name = wizard.font.name
|
||||
@@ -76,7 +76,7 @@ class base_config_settings(osv.osv_memory):
|
||||
return {}
|
||||
|
||||
def act_discover_fonts(self, cr, uid, ids, context=None):
|
||||
return self.pool.get("res.font").discover_fonts(cr, uid, ids, context)
|
||||
return self.pool.get("res.font").font_scan(cr, uid, context=context)
|
||||
|
||||
# Preferences wizard for Sales & CRM.
|
||||
# It is defined here because it is inherited independently in modules sale, crm,
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
<label for="font" />
|
||||
<div>
|
||||
<div>
|
||||
<field name="font" class="oe_inline"/>
|
||||
<field name="font" class="oe_inline" domain="[('mode', 'in', ('normal', 'regular', 'all', 'book'))]" />
|
||||
<button string="(reload fonts)" name="act_discover_fonts" type="object" class="oe_link"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# Spanish (Peru) translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-09 17:26+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish (Peru) <es_PE@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: 2013-12-11 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16869)\n"
|
||||
|
||||
#. module: base_vat
|
||||
#: view:res.partner:0
|
||||
msgid "Check Validity"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_vat
|
||||
#: code:addons/base_vat/base_vat.py:152
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This VAT number does not seem to be valid.\n"
|
||||
"Note: the expected format is %s"
|
||||
msgstr "El RUC no es válido. El formato esperado es %s"
|
||||
|
||||
#. module: base_vat
|
||||
#: field:res.company,vat_check_vies:0
|
||||
msgid "VIES VAT Check"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_vat
|
||||
#: model:ir.model,name:base_vat.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_vat
|
||||
#: code:addons/base_vat/base_vat.py:113
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_vat
|
||||
#: help:res.partner,vat_subjected:0
|
||||
msgid ""
|
||||
"Check this box if the partner is subjected to the VAT. It will be used for "
|
||||
"the VAT legal statement."
|
||||
msgstr ""
|
||||
"Marque esta opción si la empresa está sujeta a Impuestos. Será utilizado "
|
||||
"para la declaración legal de Impuestos."
|
||||
|
||||
#. module: base_vat
|
||||
#: model:ir.model,name:base_vat.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_vat
|
||||
#: help:res.company,vat_check_vies:0
|
||||
msgid ""
|
||||
"If checked, Partners VAT numbers will be fully validated against EU's VIES "
|
||||
"service rather than via a simple format validation (checksum)."
|
||||
msgstr ""
|
||||
"Si se marca, el RUC de la empresa se validará contra el servicio europeo "
|
||||
"VIES VAT en lugar de sólo validar el formato."
|
||||
|
||||
#. module: base_vat
|
||||
#: field:res.partner,vat_subjected:0
|
||||
msgid "VAT Legal Statement"
|
||||
msgstr "Sujeto a Impuestos"
|
||||
@@ -7,19 +7,19 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2009-01-30 12:44+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"PO-Revision-Date: 2013-12-27 04:38+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.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: 2013-09-12 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-28 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: base_vat
|
||||
#: view:res.partner:0
|
||||
msgid "Check Validity"
|
||||
msgstr ""
|
||||
msgstr "檢查有效性"
|
||||
|
||||
#. module: base_vat
|
||||
#: code:addons/base_vat/base_vat.py:152
|
||||
@@ -28,11 +28,13 @@ msgid ""
|
||||
"This VAT number does not seem to be valid.\n"
|
||||
"Note: the expected format is %s"
|
||||
msgstr ""
|
||||
"這個統編似乎是無效的。\n"
|
||||
"提醒:格式應為 %s"
|
||||
|
||||
#. module: base_vat
|
||||
#: field:res.company,vat_check_vies:0
|
||||
msgid "VIES VAT Check"
|
||||
msgstr ""
|
||||
msgstr "VIES 統編(VAT)檢查"
|
||||
|
||||
#. module: base_vat
|
||||
#: model:ir.model,name:base_vat.model_res_company
|
||||
@@ -43,7 +45,7 @@ msgstr "公司"
|
||||
#: code:addons/base_vat/base_vat.py:113
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr "錯誤!"
|
||||
msgstr "錯誤!"
|
||||
|
||||
#. module: base_vat
|
||||
#: help:res.partner,vat_subjected:0
|
||||
@@ -51,20 +53,23 @@ msgid ""
|
||||
"Check this box if the partner is subjected to the VAT. It will be used for "
|
||||
"the VAT legal statement."
|
||||
msgstr ""
|
||||
"Check this box if the partner is subjected to the VAT. It will be used for "
|
||||
"the VAT legal statement.\r\n"
|
||||
"如果該業務夥伴需申報(加值型)營業稅,則勾選此框。這會用在營業稅相關的稅務報告。"
|
||||
|
||||
#. module: base_vat
|
||||
#: model:ir.model,name:base_vat.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr "夥伴"
|
||||
msgstr "業務夥伴"
|
||||
|
||||
#. module: base_vat
|
||||
#: help:res.company,vat_check_vies:0
|
||||
msgid ""
|
||||
"If checked, Partners VAT numbers will be fully validated against EU's VIES "
|
||||
"service rather than via a simple format validation (checksum)."
|
||||
msgstr ""
|
||||
msgstr "如果勾選此框,則業務夥伴的統編會以歐盟的 VIES 做完整檢查,否則僅會作基本格式檢查(checksum檢查)。"
|
||||
|
||||
#. module: base_vat
|
||||
#: field:res.partner,vat_subjected:0
|
||||
msgid "VAT Legal Statement"
|
||||
msgstr ""
|
||||
msgstr "營業稅報告"
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 18:41+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.act_window,name:board.action_board_create
|
||||
#: model:ir.ui.menu,name:board.menu_board_create
|
||||
msgid "Create Board"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: view:board.create:0
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:4
|
||||
#, python-format
|
||||
msgid "Reset Layout.."
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: view:board.create:0
|
||||
msgid "Create New Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:40
|
||||
#, python-format
|
||||
msgid "Choose dashboard layout"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:70
|
||||
#, python-format
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/js/dashboard.js:139
|
||||
#, python-format
|
||||
msgid "Are you sure you want to remove this item ?"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: model:ir.model,name:board.model_board_board
|
||||
msgid "Board"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: view:board.board:0
|
||||
#: model:ir.actions.act_window,name:board.open_board_my_dash_action
|
||||
#: model:ir.ui.menu,name:board.menu_board_my_dash
|
||||
msgid "My Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: field:board.create,name:0
|
||||
msgid "Board Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: model:ir.model,name:board.model_board_create
|
||||
msgid "Board Creation"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:67
|
||||
#, python-format
|
||||
msgid "Add to Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:28
|
||||
#, python-format
|
||||
msgid " "
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.act_window,help:board.open_board_my_dash_action
|
||||
msgid ""
|
||||
"<div class=\"oe_empty_custom_dashboard\">\n"
|
||||
" <p>\n"
|
||||
" <b>Your personal dashboard is empty.</b>\n"
|
||||
" </p><p>\n"
|
||||
" To add your first report into this dashboard, go to any\n"
|
||||
" menu, switch to list or graph view, and click <i>'Add "
|
||||
"to\n"
|
||||
" Dashboard'</i> in the extended search options.\n"
|
||||
" </p><p>\n"
|
||||
" You can filter and group data before inserting into the\n"
|
||||
" dashboard using the search options.\n"
|
||||
" </p>\n"
|
||||
" </div>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:6
|
||||
#, python-format
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: field:board.create,menu_parent_id:0
|
||||
msgid "Parent Menu"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:8
|
||||
#, python-format
|
||||
msgid "Change Layout.."
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/js/dashboard.js:93
|
||||
#, python-format
|
||||
msgid "Edit Layout"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:10
|
||||
#, python-format
|
||||
msgid "Change Layout"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: view:board.create:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#: view:board.create:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#. module: board
|
||||
#. openerp-web
|
||||
#: code:addons/board/static/src/xml/board.xml:69
|
||||
#, python-format
|
||||
msgid "Title of new dashboard item"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,37 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 18:41+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: contacts
|
||||
#: model:ir.actions.act_window,help:contacts.action_contacts
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to add a contact in your address book.\n"
|
||||
" </p><p>\n"
|
||||
" OpenERP helps you easily track all activities related to\n"
|
||||
" a customer; discussions, history of business opportunities,\n"
|
||||
" documents, etc.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: contacts
|
||||
#: model:ir.actions.act_window,name:contacts.action_contacts
|
||||
#: model:ir.ui.menu,name:contacts.menu_contacts
|
||||
msgid "Contacts"
|
||||
msgstr ""
|
||||
@@ -13,7 +13,6 @@
|
||||
<field name="search_view_id" ref="crm.view_crm_case_leads_filter"/>
|
||||
<field name="context">{
|
||||
'search_default_section_id': [active_id],
|
||||
'search_default_open': 1,
|
||||
'default_section_id': active_id,
|
||||
'default_type': 'lead',
|
||||
'stage_type': 'lead',
|
||||
@@ -43,7 +42,6 @@
|
||||
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
|
||||
<field name="context">{
|
||||
'search_default_section_id': [active_id],
|
||||
'search_default_assigned_to_me': 1,
|
||||
'default_section_id': active_id,
|
||||
'stage_type': 'opportunity',
|
||||
'default_type': 'opportunity',
|
||||
@@ -64,6 +62,26 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_report_crm_lead_salesteam" model="ir.actions.act_window">
|
||||
<field name="name">Leads Analysis</field>
|
||||
<field name="res_model">crm.lead.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="context">{"search_default_month":1}</field>
|
||||
<field name="view_mode">tree,graph</field>
|
||||
<field name="domain">[('type','=', 'lead'),('section_id', '=', active_id)]</field>
|
||||
<field name="help">Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis.</field>
|
||||
</record>
|
||||
|
||||
<record id="action_report_crm_opportunity_salesteam" model="ir.actions.act_window">
|
||||
<field name="name">Opportunities Analysis</field>
|
||||
<field name="res_model">crm.lead.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="context">{"search_default_month":1}</field>
|
||||
<field name="view_mode">tree,graph</field>
|
||||
<field name="domain">[('type','=', 'opportunity'), ('section_id', '=', active_id)]</field>
|
||||
<field name="help">Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline.</field>
|
||||
</record>
|
||||
|
||||
<!-- Case Sections Salesteams kanban view -->
|
||||
|
||||
<record model="ir.ui.view" id="crm_case_section_salesteams_view_kanban">
|
||||
@@ -99,13 +117,25 @@
|
||||
<div class="oe_items_list">
|
||||
<div class="oe_salesteams_leads" t-if="record.use_leads.raw_value">
|
||||
<a name="%(crm_case_form_view_salesteams_lead)d" type="action">Leads</a>
|
||||
<a name="%(action_report_crm_lead)d" type="action" class="oe_sparkline_bar_link"><field name="monthly_open_leads" widget="sparkline_bar" options="{'height': '20px', 'barWidth': 4, 'barSpacing': 1}">Open Leads per Month<br/>Click to see a detailed analysis of leads.</field></a>
|
||||
<a name="%(action_report_crm_lead_salesteam)d" type="action" class="oe_sparkline_bar_link">
|
||||
<field name="monthly_open_leads" widget="sparkline_bar"
|
||||
options="{'height': '20px', 'barWidth': 4, 'barSpacing': 1, 'delayIn': '3000', 'tooltip_suffix': 'Leads'}">Open Leads per Month<br/>Click to see a detailed analysis of leads.</field>
|
||||
</a>
|
||||
</div>
|
||||
<div class="oe_salesteams_opportunities">
|
||||
<a name="%(crm_case_form_view_salesteams_opportunity)d" type="action">Opportunities</a>
|
||||
<a name="%(action_report_crm_opportunity)d" type="action"><field name="monthly_planned_revenue" widget="sparkline_bar" height="20px" barWidth="4" barSpacing="1">Planned Revenue per Month<br/>Click to see a detailed analysis of opportunities.</field></a>
|
||||
<a name="%(action_report_crm_opportunity_salesteam)d" type="action">
|
||||
<field name="monthly_planned_revenue" widget="sparkline_bar"
|
||||
options="{'height': '20px', 'barWidth': '4', 'barSpacing': '1', 'delayIn': '3000', 'tooltip_suffix': 'Opportunities'}">Planned Revenue per Month<br/>Click to see a detailed analysis of opportunities.</field>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_clear"></div>
|
||||
<div class="oe_kanban_salesteams_avatars">
|
||||
<t t-foreach="record.member_ids.raw_value.slice(0,10)" t-as="member">
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', member)" t-att-data-member_id="member"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -6,14 +6,20 @@
|
||||
<field name="groups_id" eval="[(4,ref('base.group_sale_salesman'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="crm.section_sales_department" model="crm.case.section">
|
||||
<field name="member_ids" eval="[(4, ref('base.user_demo'))]"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.case.section" id="crm_case_section_1">
|
||||
<field name="name">Indirect Sales</field>
|
||||
<field name="code">IM</field>
|
||||
<field name="member_ids" eval="[(4, ref('base.user_root')),(4, ref('base.user_demo'))]"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.case.section" id="crm_case_section_2">
|
||||
<field name="name">Marketing</field>
|
||||
<field name="code">SPD</field>
|
||||
<field name="member_ids" eval="[(4, ref('base.user_root')),(4, ref('base.user_demo'))]"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.segmentation" id="crm_segmentation0">
|
||||
|
||||
@@ -411,7 +411,7 @@
|
||||
on_change="on_change_partner_id(partner_id)"
|
||||
string="Customer"
|
||||
context="{'default_name': partner_name, 'default_email': email_from, 'default_phone': phone}"/>
|
||||
<field name="email_from" string="Email"/>
|
||||
<field name="email_from" string="Email" widget="email"/>
|
||||
<field name="phone"/>
|
||||
</group>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -66,9 +66,6 @@
|
||||
<field name="model">crm.lead.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Leads Analysis">
|
||||
<filter icon="terp-personal" name="lead" string="Lead" domain="[('type','=', 'lead')]" help="Show only lead"/>
|
||||
<filter icon="terp-personal+" string="Opportunity" name="opportunity" domain="[('type','=','opportunity')]" help="Show only opportunity"/>
|
||||
<separator/>
|
||||
<filter string="New" name="new"
|
||||
domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
|
||||
<filter string="Won" name="won"
|
||||
@@ -115,7 +112,7 @@
|
||||
<separator orientation="vertical" />
|
||||
<filter string="Year" icon="terp-go-year"
|
||||
domain="[]" context="{'group_by':'creation_year'}"/>
|
||||
<filter string="Month" icon="terp-go-month"
|
||||
<filter string="Month" name="month" icon="terp-go-month"
|
||||
domain="[]" context="{'group_by':'creation_month'}"/>
|
||||
<filter string="Day" icon="terp-go-today"
|
||||
domain="[]" context="{'group_by':'creation_day'}"/>
|
||||
@@ -168,9 +165,9 @@
|
||||
<field name="name">Leads Analysis</field>
|
||||
<field name="res_model">crm.lead.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="context">{'search_default_year': 1,'search_default_lead': 1, "search_default_user":1, "search_default_this_month":1, 'group_by_no_leaf':1, 'group_by':[]}</field>
|
||||
<field name="context">{'search_default_year': 1, "search_default_user":1, "search_default_month":1, 'group_by_no_leaf':1, 'group_by':[]}</field>
|
||||
<field name="view_mode">tree,graph</field>
|
||||
<field name="domain">[]</field>
|
||||
<field name="domain">[('type','=', 'lead')]</field>
|
||||
<field name="help">Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis.</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window.view" id="action_report_crm_lead_tree">
|
||||
@@ -190,8 +187,9 @@
|
||||
<field name="name">Opportunities Analysis</field>
|
||||
<field name="res_model">crm.lead.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="context">{"search_default_year":1,"search_default_opportunity":1, "search_default_user":1,"search_default_this_month":1,'group_by_no_leaf':1,'group_by':[]}</field>
|
||||
<field name="context">{"search_default_year":1, "search_default_user":1,"search_default_month":1,'group_by_no_leaf':1,'group_by':[]}</field>
|
||||
<field name="view_mode">tree,graph</field>
|
||||
<field name="domain">[('type','=', 'opportunity')]</field>
|
||||
<field name="help">Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline.</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -91,5 +91,19 @@
|
||||
<field name="groups" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="crm_rule_personal_lead_report" model="ir.rule">
|
||||
<field name="name">Personal Leads Analysis</field>
|
||||
<field ref="model_crm_lead_report" name="model_id"/>
|
||||
<field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_sale_salesman'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="crm_rule_all_lead_report" model="ir.rule">
|
||||
<field name="name">All Leads Analysis</field>
|
||||
<field ref="model_crm_lead_report" name="model_id"/>
|
||||
<field name="domain_force">[(1,'=',1)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
crm.css: crm.sass
|
||||
sass --trace -t expanded crm.sass:crm.css
|
||||
@@ -1,67 +1,62 @@
|
||||
@charset "utf-8";
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams {
|
||||
/* Customize width and height of kanban according bootstrap3 */
|
||||
width: 357px;
|
||||
min-height: 254px !important;
|
||||
/* End of customize */
|
||||
/* Customize width and height of kanban according bootstrap3 */
|
||||
width: 357px;
|
||||
min-height: 254px !important;
|
||||
/* End of customize */
|
||||
cursor: default;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_avatars {
|
||||
text-align: right;
|
||||
margin: -5px 0 -10px 0;
|
||||
}
|
||||
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_avatars img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
padding-left: 0px;
|
||||
margin-top: 3px;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list {
|
||||
position: relative;
|
||||
margin: 10px 0 10px 9px; /* Improved margin to set alignment of list items according bootstrap3 */
|
||||
position: relative;
|
||||
/* Improved margin to set alignment of list items according bootstrap3 */
|
||||
margin: 10px 0 10px 9px;
|
||||
min-height: 10px;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div {
|
||||
width: 160px;
|
||||
height: 22px;
|
||||
margin: 0 !important;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a:hover {
|
||||
text-decoration: underline !important;
|
||||
width: 160px;
|
||||
height: 22px;
|
||||
margin: 0 !important;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div a:nth-child(2n) {
|
||||
position: absolute;
|
||||
left: 90px;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
left: 90px;
|
||||
top: 0;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div:nth-child(2n) a:nth-child(2n) {
|
||||
left: 110px;
|
||||
left: 110px;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center {
|
||||
text-align: center;
|
||||
margin: 3px 0;
|
||||
text-align: center;
|
||||
margin: 3px 0;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_sum {
|
||||
margin: 0;
|
||||
font-size: 40px;
|
||||
margin: 0;
|
||||
font-size: 40px;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_subsum {
|
||||
font-size: 10px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.openerp .oe_kanban_view .oe_justgage {
|
||||
color: black;
|
||||
display: inline-block;
|
||||
.openerp .oe_kanban_view .oe_salesteams_help {
|
||||
display: inline-block;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_salesteams_avatars {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_salesteams_avatars img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
padding-left: 0px;
|
||||
margin-top: 3px;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.openerp .oe_kanban_view .oe_sparkline_bar {
|
||||
height: 20px;
|
||||
width: 36px;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
@charset "utf-8"
|
||||
|
||||
.openerp
|
||||
.oe_kanban_view
|
||||
.oe_kanban_crm_salesteams
|
||||
/* Customize width and height of kanban according bootstrap3 */
|
||||
width: 357px
|
||||
min-height: 254px !important
|
||||
/* End of customize */
|
||||
cursor: default
|
||||
.oe_items_list
|
||||
position: relative
|
||||
/* Improved margin to set alignment of list items according bootstrap3 */
|
||||
margin: 10px 0 10px 9px
|
||||
min-height: 10px
|
||||
div
|
||||
width: 160px
|
||||
height: 22px
|
||||
margin: 0 !important
|
||||
position: relative
|
||||
display: inline-block
|
||||
float: left
|
||||
a:nth-child(2n)
|
||||
position: absolute
|
||||
left: 90px
|
||||
top: 0
|
||||
div:nth-child(2n)
|
||||
a:nth-child(2n)
|
||||
left: 110px
|
||||
a:hover
|
||||
text-decoration: underline !important
|
||||
.oe_center
|
||||
text-align: center
|
||||
margin: 3px 0
|
||||
.oe_sum
|
||||
margin: 0
|
||||
font-size: 40px
|
||||
.oe_subsum
|
||||
font-size: 10px
|
||||
.oe_salesteams_help
|
||||
display: inline-block
|
||||
.oe_kanban_salesteams_avatars
|
||||
margin-top: 20px
|
||||
.oe_kanban_salesteams_avatars
|
||||
img
|
||||
width: 30px
|
||||
height: 30px
|
||||
padding-left: 0px
|
||||
margin-top: 3px
|
||||
-moz-border-radius: 2px
|
||||
-webkit-border-radius: 2px
|
||||
border-radius: 2px
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2)
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2)
|
||||
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2)
|
||||
@@ -1,4 +1,40 @@
|
||||
openerp.crm = function(openerp) {
|
||||
openerp.web_kanban.KanbanView.include({
|
||||
crm_display_members_names: function() {
|
||||
/*
|
||||
* Set avatar title for members.
|
||||
* In kanban views, many2many fields only return a list of ids.
|
||||
* We can implement return value of m2m fields like [(1,"Adminstration"),...].
|
||||
*/
|
||||
var self = this;
|
||||
var members_ids = [];
|
||||
|
||||
// Collect members ids
|
||||
self.$el.find('img[data-member_id]').each(function() {
|
||||
members_ids.push($(this).data('member_id'));
|
||||
});
|
||||
|
||||
// Find their matching names
|
||||
var dataset = new openerp.web.DataSetSearch(self, 'res.users', self.session.context, [['id', 'in', _.uniq(members_ids)]]);
|
||||
dataset.read_slice(['id', 'name']).done(function(result) {
|
||||
_.each(result, function(v, k) {
|
||||
// Set the proper value in the DOM
|
||||
self.$el.find('img[data-member_id=' + v.id + ']').attr('title', v.name).tipsy({
|
||||
offset: 10
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
on_groups_started: function() {
|
||||
var self = this;
|
||||
self._super.apply(self, arguments);
|
||||
|
||||
if (self.dataset.model === 'crm.case.section') {
|
||||
self.crm_display_members_names();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
openerp.web_kanban.KanbanRecord.include({
|
||||
on_card_clicked: function() {
|
||||
if (this.view.dataset.model === 'crm.case.section') {
|
||||
@@ -8,5 +44,4 @@ openerp.crm = function(openerp) {
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,708 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 18:48+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk.report,delay_close:0
|
||||
msgid "Delay to Close"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk.report,nbr:0
|
||||
msgid "# of Cases"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Group By..."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,email_from:0
|
||||
msgid "Destination email for email gateway"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "March"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,message_unread:0
|
||||
msgid "Unread Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,company_id:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,company_id:0
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,email_cc:0
|
||||
msgid "Watchers Emails"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Salesperson"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,priority:0
|
||||
#: selection:crm.helpdesk.report,priority:0
|
||||
msgid "Highest"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,day:0
|
||||
msgid "Day"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Date of helpdesk requests"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,message_ids:0
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "My company"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,state:0
|
||||
#: selection:crm.helpdesk.report,state:0
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,message_unread:0
|
||||
msgid "If checked new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.actions.act_window,name:crm_helpdesk.action_report_crm_helpdesk
|
||||
#: model:ir.ui.menu,name:crm_helpdesk.menu_report_crm_helpdesks_tree
|
||||
msgid "Helpdesk Analysis"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,date_closed:0
|
||||
msgid "Close Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,ref:0
|
||||
msgid "Reference"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,date_action_next:0
|
||||
msgid "Next Action"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,message_summary:0
|
||||
msgid ""
|
||||
"Holds the Chatter summary (number of messages, ...). This summary is "
|
||||
"directly in html format in order to be inserted in kanban views."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Helpdesk Supports"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Extra Info"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: field:crm.helpdesk,partner_id:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Estimates"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk.report,section_id:0
|
||||
msgid "Section"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: field:crm.helpdesk,priority:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,priority:0
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,message_follower_ids:0
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: selection:crm.helpdesk,state:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "New"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.model,name:crm_helpdesk.model_crm_helpdesk_report
|
||||
msgid "Helpdesk report after Sales Services"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,email_from:0
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,channel_id:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,channel_id:0
|
||||
msgid "Channel"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,priority:0
|
||||
#: selection:crm.helpdesk.report,priority:0
|
||||
msgid "Lowest"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "# Mails"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "My Sales Team(s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,create_date:0
|
||||
#: field:crm.helpdesk.report,create_date:0
|
||||
msgid "Creation Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Reset to Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: field:crm.helpdesk,date_deadline:0
|
||||
#: field:crm.helpdesk.report,date_deadline:0
|
||||
msgid "Deadline"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "July"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.actions.act_window,name:crm_helpdesk.crm_helpdesk_categ_action
|
||||
msgid "Helpdesk Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.ui.menu,name:crm_helpdesk.menu_crm_case_helpdesk-act
|
||||
msgid "Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "New Helpdesk Request"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Dates"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Month of helpdesk requests"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: code:addons/crm_helpdesk/crm_helpdesk.py:104
|
||||
#, python-format
|
||||
msgid "No Subject"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid ""
|
||||
"Helpdesk requests that are assigned to me or to one of the sale teams I "
|
||||
"manage"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "#Helpdesk"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "All pending Helpdesk Request"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Year of helpdesk requests"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "September"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "December"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,month:0
|
||||
msgid "Month"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,write_date:0
|
||||
msgid "Update Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Query"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,ref2:0
|
||||
msgid "Reference 2"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,categ_id:0
|
||||
#: field:crm.helpdesk.report,categ_id:0
|
||||
msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Responsible User"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Helpdesk Support"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,planned_cost:0
|
||||
#: field:crm.helpdesk.report,planned_cost:0
|
||||
msgid "Planned Costs"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,channel_id:0
|
||||
msgid "Communication channel."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,email_cc:0
|
||||
msgid ""
|
||||
"These email addresses will be added to the CC field of all inbound and "
|
||||
"outbound emails for this record before being sent. Separate multiple email "
|
||||
"addresses with a comma"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Search Helpdesk"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,state:0
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,priority:0
|
||||
#: selection:crm.helpdesk.report,priority:0
|
||||
msgid "Low"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,date_closed:0
|
||||
#: selection:crm.helpdesk,state:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: selection:crm.helpdesk.report,state:0
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: selection:crm.helpdesk,state:0
|
||||
#: selection:crm.helpdesk.report,state:0
|
||||
msgid "Pending"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: field:crm.helpdesk,state:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "August"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,priority:0
|
||||
#: selection:crm.helpdesk.report,priority:0
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Escalate"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "June"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,id:0
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.actions.act_window,help:crm_helpdesk.crm_case_helpdesk_act111
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to create a new request. \n"
|
||||
" </p><p>\n"
|
||||
" Helpdesk and Support allow you to track your interventions.\n"
|
||||
" </p><p>\n"
|
||||
" Use the OpenERP Issues system to manage your support\n"
|
||||
" activities. Issues can be connected to the email gateway: "
|
||||
"new\n"
|
||||
" emails may create issues, each of them automatically gets "
|
||||
"the\n"
|
||||
" history of the conversation with the customer.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,planned_revenue:0
|
||||
msgid "Planned Revenue"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,message_is_follower:0
|
||||
msgid "Is a Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk.report,user_id:0
|
||||
msgid "User"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,active:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "November"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Extended Filters..."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.actions.act_window,name:crm_helpdesk.crm_case_helpdesk_act111
|
||||
msgid "Helpdesk Requests"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,section_id:0
|
||||
msgid ""
|
||||
"Responsible sales team. Define Responsible user and Email account for mail "
|
||||
"gateway."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "October"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "January"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,message_summary:0
|
||||
msgid "Summary"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: field:crm.helpdesk,date:0
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Misc"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "My Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "References"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Communication"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: selection:crm.helpdesk.report,state:0
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Helpdesk Support Tree"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,state:0
|
||||
msgid "In Progress"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Categorization"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: model:ir.model,name:crm_helpdesk.model_crm_helpdesk
|
||||
#: model:ir.ui.menu,name:crm_helpdesk.menu_config_helpdesk
|
||||
msgid "Helpdesk"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: field:crm.helpdesk,user_id:0
|
||||
msgid "Responsible"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk.report,delay_expected:0
|
||||
msgid "Overpassed Deadline"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,description:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "May"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,probability:0
|
||||
msgid "Probability (%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk.report,email:0
|
||||
msgid "# Emails"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.actions.act_window,help:crm_helpdesk.action_report_crm_helpdesk
|
||||
msgid ""
|
||||
"Have a general overview of all support requests by sorting them with "
|
||||
"specific criteria such as the processing time, number of requests answered, "
|
||||
"emails sent and costs."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "February"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
#: field:crm.helpdesk.report,name:0
|
||||
msgid "Year"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.ui.menu,name:crm_helpdesk.menu_help_support_main
|
||||
msgid "Helpdesk and Support"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk.report,month:0
|
||||
msgid "April"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "My Case(s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,state:0
|
||||
msgid ""
|
||||
"The status is set to 'Draft', when a case is created. "
|
||||
" \n"
|
||||
"If the case is in progress the status is set to 'Open'. "
|
||||
" \n"
|
||||
"When the case is over, the status is set to 'Done'. "
|
||||
" \n"
|
||||
"If the case needs to be reviewed then the status is set to 'Pending'."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,message_ids:0
|
||||
msgid "Messages and communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.actions.act_window,help:crm_helpdesk.crm_helpdesk_categ_action
|
||||
msgid ""
|
||||
"Create and manage helpdesk categories to better manage and classify your "
|
||||
"support requests."
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Request Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Open Helpdesk Request"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,priority:0
|
||||
#: selection:crm.helpdesk.report,priority:0
|
||||
msgid "High"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: field:crm.helpdesk,section_id:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Sales Team"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,date_action_last:0
|
||||
msgid "Last Action"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Assigned to Me or My Sales Team(s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,duration:0
|
||||
msgid "Duration"
|
||||
msgstr ""
|
||||
@@ -32,6 +32,7 @@ import psycopg2
|
||||
|
||||
import openerp
|
||||
from openerp import tools
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.osv.orm import except_orm
|
||||
import openerp.report.interface
|
||||
@@ -322,7 +323,7 @@ class document_directory(osv.osv):
|
||||
ressource_parent_type_id=vals.get('ressource_parent_type_id',False)
|
||||
ressource_id=vals.get('ressource_id',0)
|
||||
if op=='write':
|
||||
for directory in self.browse(cr, uid, ids):
|
||||
for directory in self.browse(cr, SUPERUSER_ID, ids):
|
||||
if not name:
|
||||
name=directory.name
|
||||
if not parent_id:
|
||||
@@ -336,7 +337,7 @@ class document_directory(osv.osv):
|
||||
if len(res):
|
||||
return False
|
||||
if op=='create':
|
||||
res=self.search(cr,uid,[('name','=',name),('parent_id','=',parent_id),('ressource_parent_type_id','=',ressource_parent_type_id),('ressource_id','=',ressource_id)])
|
||||
res = self.search(cr, SUPERUSER_ID, [('name','=',name),('parent_id','=',parent_id),('ressource_parent_type_id','=',ressource_parent_type_id),('ressource_id','=',ressource_id)])
|
||||
if len(res):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -0,0 +1,758 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 18:49+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,parent_id:0
|
||||
msgid "Parent Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: code:addons/document/document.py:350
|
||||
#, python-format
|
||||
msgid "Directory name contains special characters!"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Search Document Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,resource_field:0
|
||||
msgid ""
|
||||
"Field to be used as name on resource directories. If empty, the \"name\" "
|
||||
"will be used."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Group By..."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Modification"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Resources"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,file_ids:0
|
||||
#: view:report.document.user:0
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content.type,mimetype:0
|
||||
msgid "Mime Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "March"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.dctx,expr:0
|
||||
msgid "Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
#: field:document.directory,company_id:0
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_directory_content
|
||||
msgid "Directory Content"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "My Document(s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_document_management_configuration
|
||||
msgid "Document Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory.dctx,expr:0
|
||||
msgid ""
|
||||
"A python expression used to evaluate the field.\n"
|
||||
"You can use 'dir_id' for current dir, 'res_id', 'res_model' as a reference "
|
||||
"to the current record, in dynamic folders"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory.dctx,field:0
|
||||
msgid "The name of the field."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: code:addons/document/document.py:340
|
||||
#: code:addons/document/document.py:345
|
||||
#, python-format
|
||||
msgid "Directory name must be unique!"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Filter on my documents"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
#: field:ir.attachment,index_content:0
|
||||
msgid "Indexed Content"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,resource_find_all:0
|
||||
msgid ""
|
||||
"If true, all attachments that match this resource will be located. If "
|
||||
"false, only ones that have this as parent."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
#: model:ir.actions.act_window,name:document.action_document_directory_form
|
||||
#: model:ir.ui.menu,name:document.menu_document_directories
|
||||
msgid "Directories"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_report_document_user
|
||||
msgid "Files details by Users"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,resource_find_all:0
|
||||
msgid "Find all resources"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:document.directory,type:0
|
||||
msgid "Folders per resource"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,suffix:0
|
||||
msgid "Suffix"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.user,change_date:0
|
||||
msgid "Modified Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration:0
|
||||
msgid "Knowledge Application Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
#: field:ir.attachment,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.act_res_partner_document
|
||||
#: model:ir.actions.act_window,name:document.zoom_directory
|
||||
msgid "Related Documents"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,help:document.action_document_file_form
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to create a new document. \n"
|
||||
" </p><p>\n"
|
||||
" The Documents repository gives you access to all attachments, "
|
||||
"such\n"
|
||||
" as mails, project documents, invoices etc.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: code:addons/document/document.py:340
|
||||
#: code:addons/document/document.py:345
|
||||
#: code:addons/document/document.py:350
|
||||
#, python-format
|
||||
msgid "ValidateError"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_ir_actions_report_xml
|
||||
msgid "ir.actions.report.xml"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_document_file_form
|
||||
#: model:ir.ui.menu,name:document.menu_document_doc
|
||||
#: model:ir.ui.menu,name:document.menu_document_files
|
||||
msgid "Documents"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_type_id:0
|
||||
msgid "Resource model"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.file,file_size:0
|
||||
#: field:report.document.user,file_size:0
|
||||
msgid "File Size"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content.type,name:0
|
||||
#: field:ir.attachment,file_type:0
|
||||
msgid "Content Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
#: field:document.directory,type:0
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: sql_constraint:ir.attachment:0
|
||||
msgid "The filename must be unique in a directory !"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: code:addons/document/document.py:110
|
||||
#: code:addons/document/document.py:310
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,ressource_type_id:0
|
||||
msgid ""
|
||||
"Select an object here and there will be one folder per record of that "
|
||||
"resource."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,domain:0
|
||||
msgid ""
|
||||
"Use a domain if you want to apply an automatic filter on visible resources."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: constraint:document.directory:0
|
||||
msgid "Error! You cannot create recursive directories."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,resource_field:0
|
||||
msgid "Name field"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,dctx_ids:0
|
||||
msgid "Context fields"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
#: field:report.document.user,type:0
|
||||
msgid "Directory Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,report_id:0
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "July"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content.type,code:0
|
||||
msgid "Extension"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,content_ids:0
|
||||
msgid "Virtual Files"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: code:addons/document/document.py:576
|
||||
#, python-format
|
||||
msgid "Error at doc write!"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Generated Files"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration:0
|
||||
msgid ""
|
||||
"When executing this wizard, it will configure your directories automatically "
|
||||
"according to modules installed."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,directory_id:0
|
||||
#: field:document.directory.dctx,dir_id:0
|
||||
#: model:ir.actions.act_window,name:document.action_document_file_directory_form
|
||||
#: view:ir.attachment:0
|
||||
#: field:ir.attachment,parent_id:0
|
||||
#: model:ir.model,name:document.model_document_directory
|
||||
#: field:report.document.user,directory:0
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Security"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,write_uid:0
|
||||
#: field:ir.attachment,write_uid:0
|
||||
msgid "Last Modification User"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_files_by_user_graph
|
||||
#: view:report.document.user:0
|
||||
msgid "Files by User"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "on"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,domain:0
|
||||
msgid "Domain"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,write_date:0
|
||||
#: field:ir.attachment,write_date:0
|
||||
msgid "Date Modified"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_report_document_file
|
||||
msgid "Files details by Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:report.document.user:0
|
||||
msgid "All users files"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_size_month
|
||||
#: view:report.document.file:0
|
||||
msgid "File Size by Month"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "December"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:document.directory,type:0
|
||||
msgid "Static Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.file,month:0
|
||||
#: field:report.document.user,month:0
|
||||
msgid "Month"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Define words in the context, for all child directories and files"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Static"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.user,user:0
|
||||
msgid "unknown"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
#: field:document.directory,user_id:0
|
||||
#: view:ir.attachment:0
|
||||
#: field:ir.attachment,user_id:0
|
||||
#: field:report.document.user,user_id:0
|
||||
msgid "Owner"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "PDF Report"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Contents"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,create_date:0
|
||||
#: field:report.document.user,create_date:0
|
||||
msgid "Date Created"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory.content,include_name:0
|
||||
msgid ""
|
||||
"Check this field if you want that the name of the file to contain the record "
|
||||
"name.\n"
|
||||
"If set, the directory will have to be a resource one."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration:0
|
||||
#: model:ir.actions.act_window,name:document.action_config_auto_directory
|
||||
msgid "Configure Directories"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,include_name:0
|
||||
msgid "Include Record Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:ir.actions.report.xml,model_id:0
|
||||
msgid "Model Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,ressource_tree:0
|
||||
msgid ""
|
||||
"Check this if you want to use the same tree structure as the object selected "
|
||||
"in the system."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,ressource_id:0
|
||||
msgid ""
|
||||
"Along with Parent Model, this ID attaches this folder to a specific record "
|
||||
"of Parent Model."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#. openerp-web
|
||||
#: code:addons/document/static/src/js/document.js:6
|
||||
#, python-format
|
||||
msgid "Attachment(s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "August"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Dynamic context"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: sql_constraint:document.directory:0
|
||||
msgid "Directory cannot be parent of itself!"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "June"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,group_ids:0
|
||||
msgid "Groups"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content.type,active:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "November"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,ressource_parent_type_id:0
|
||||
msgid ""
|
||||
"If you put an object here, this directory template will appear bellow all of "
|
||||
"these objects. Such directories are \"attached\" to the specific model or "
|
||||
"record, just like attachments. Don't put a parent directory if you select a "
|
||||
"parent model."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Definition"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "October"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Seq."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_all_document_tree1
|
||||
msgid "All Users files"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "January"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Document Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: sql_constraint:document.directory:0
|
||||
msgid "The directory name must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Attachments"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,create_uid:0
|
||||
msgid "Creator"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration:0
|
||||
msgid ""
|
||||
"OpenERP's Document Management System supports mapping virtual folders with "
|
||||
"documents. The virtual folder of a document can be used to manage the files "
|
||||
"attached to the document, or to print and download any report. This tool "
|
||||
"will create directories automatically according to modules installed."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_files_by_month_graph
|
||||
#: view:report.document.user:0
|
||||
msgid "Files by Month"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "September"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,prefix:0
|
||||
msgid "Prefix"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,child_ids:0
|
||||
msgid "Children"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_id:0
|
||||
msgid "Resource ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.dctx,field:0
|
||||
msgid "Field"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_directory_dctx
|
||||
msgid "Directory Dynamic Context"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_parent_type_id:0
|
||||
msgid "Parent Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid ""
|
||||
"These groups, however, do NOT apply to children directories, which must "
|
||||
"define their own groups."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "May"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "For each entry here, virtual files will appear in this folder."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_ir_attachment
|
||||
msgid "ir.attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:report.document.user:0
|
||||
msgid "Users File"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_configuration
|
||||
msgid "Directory Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,type:0
|
||||
msgid ""
|
||||
"Each directory can either have the type Static or be linked to another "
|
||||
"resource. A static directory, as with Operating Systems, is the classic "
|
||||
"directory that can contain a set of files. The directories linked to systems "
|
||||
"resources automatically possess sub-directories for each of resource types "
|
||||
"defined in the parent directory."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "February"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Fields"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: selection:report.document.user,month:0
|
||||
msgid "April"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.file,nbr:0
|
||||
#: field:report.document.user,nbr:0
|
||||
msgid "# of Files"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_directory_content_type
|
||||
msgid "Directory Content Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid ""
|
||||
"Only members of these groups will have access to this directory and its "
|
||||
"files."
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#. openerp-web
|
||||
#: code:addons/document/static/src/js/document.js:17
|
||||
#, python-format
|
||||
msgid "%s (%s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,sequence:0
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,name:0
|
||||
msgid "Content Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.user,datas_fname:0
|
||||
msgid "File Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_tree:0
|
||||
msgid "Tree Structure"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration:0
|
||||
msgid "res_config_contents"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_document_directory_tree
|
||||
#: model:ir.ui.menu,name:document.menu_document_directories_tree
|
||||
msgid "Directories' Structure"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.user,name:0
|
||||
msgid "Year"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_storage
|
||||
msgid "Storage Media"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,extension:0
|
||||
msgid "Document Type"
|
||||
msgstr ""
|
||||
@@ -31,7 +31,7 @@ class report_document_user(osv.osv):
|
||||
'name': fields.char('Year', size=64,readonly=True),
|
||||
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'), ('05','May'), ('06','June'),
|
||||
('07','July'), ('08','August'), ('09','September'), ('10','October'), ('11','November'), ('12','December')],'Month',readonly=True),
|
||||
'user_id':fields.integer('Owner', readonly=True),
|
||||
'user_id': fields.many2one('res.users', 'Owner', readonly=True),
|
||||
'user': fields.related('user_id', 'name', type='char', size=64, readonly=True),
|
||||
'directory': fields.char('Directory',size=64,readonly=True),
|
||||
'datas_fname': fields.char('File Name',size=64,readonly=True),
|
||||
|
||||
@@ -58,6 +58,23 @@
|
||||
!python {model: ir.attachment}: |
|
||||
ids = self.search(cr, uid, [('res_model', '=', 'res.country'), ('res_id', '=', ref("base.za"))])
|
||||
assert ids == [ ref("attach_3rd")], ids
|
||||
-
|
||||
I test that I can't create duplicate directories (even when duplicates are hidden by a record rule)
|
||||
-
|
||||
!python {model: document.directory}: |
|
||||
duplicate_detected = False
|
||||
from openerp.osv.osv import except_osv
|
||||
try:
|
||||
demo_uid = ref('base.user_demo')
|
||||
dir_vals = {
|
||||
'name': 'Testing (will be deleted!)',
|
||||
'parent_id': ref('document.dir_root')
|
||||
}
|
||||
new_dir_id = self.create(cr, demo_uid, dir_vals, context=None)
|
||||
self.unlink(cr, uid, [new_dir_id], context=None)
|
||||
except except_osv, e:
|
||||
duplicate_detected = e.value == u'Directory name must be unique!'
|
||||
assert duplicate_detected is True, 'Failed to detect duplicate directory'
|
||||
-
|
||||
I delete the attachments
|
||||
-
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 18:50+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: edi
|
||||
#. openerp-web
|
||||
#: code:addons/edi/static/src/js/edi.js:67
|
||||
#, python-format
|
||||
msgid "Reason:"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#. openerp-web
|
||||
#: code:addons/edi/static/src/js/edi.js:60
|
||||
#, python-format
|
||||
msgid "The document has been successfully imported!"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#. openerp-web
|
||||
#: code:addons/edi/static/src/js/edi.js:65
|
||||
#, python-format
|
||||
msgid "Sorry, the document could not be imported."
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: model:ir.model,name:edi.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: model:ir.model,name:edi.model_res_currency
|
||||
msgid "Currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#. openerp-web
|
||||
#: code:addons/edi/static/src/js/edi.js:71
|
||||
#, python-format
|
||||
msgid "Document Import Notification"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: code:addons/edi/models/edi.py:130
|
||||
#, python-format
|
||||
msgid "Missing application."
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: code:addons/edi/models/edi.py:131
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The document you are trying to import requires the OpenERP `%s` application. "
|
||||
"You can install it by connecting as the administrator and opening the "
|
||||
"configuration assistant."
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: code:addons/edi/models/edi.py:47
|
||||
#, python-format
|
||||
msgid "'%s' is an invalid external ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: model:ir.model,name:edi.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: model:ir.model,name:edi.model_edi_edi
|
||||
msgid "EDI Subsystem"
|
||||
msgstr ""
|
||||
@@ -411,7 +411,17 @@ class email_template(osv.osv):
|
||||
# create a mail_mail based on values, without attachments
|
||||
values = self.generate_email(cr, uid, template_id, res_id, context=context)
|
||||
assert values.get('email_from'), 'email_from is missing or empty after template rendering, send_mail() cannot proceed'
|
||||
del values['partner_to'] # TODO Properly use them.
|
||||
|
||||
# process partner_to field that is a comma separated list of partner_ids -> recipient_ids
|
||||
# NOTE: only usable if force_send is True, because otherwise the value is
|
||||
# not stored on the mail_mail, and therefore lost -> fixed in v8
|
||||
values['recipient_ids'] = []
|
||||
partner_to = values.pop('partner_to', '')
|
||||
if partner_to:
|
||||
# placeholders could generate '', 3, 2 due to some empty field values
|
||||
tpl_partner_ids = [pid for pid in partner_to.split(',') if pid]
|
||||
values['recipient_ids'] += [(4, pid) for pid in self.pool['res.partner'].exists(cr, SUPERUSER_ID, tpl_partner_ids, context=context)]
|
||||
|
||||
attachment_ids = values.pop('attachment_ids', [])
|
||||
attachments = values.pop('attachments', [])
|
||||
msg_id = mail_mail.create(cr, uid, values, context=context)
|
||||
@@ -420,11 +430,11 @@ class email_template(osv.osv):
|
||||
# manage attachments
|
||||
for attachment in attachments:
|
||||
attachment_data = {
|
||||
'name': attachment[0],
|
||||
'datas_fname': attachment[0],
|
||||
'datas': attachment[1],
|
||||
'res_model': 'mail.message',
|
||||
'res_id': mail.mail_message_id.id,
|
||||
'name': attachment[0],
|
||||
'datas_fname': attachment[0],
|
||||
'datas': attachment[1],
|
||||
'res_model': 'mail.message',
|
||||
'res_id': mail.mail_message_id.id,
|
||||
}
|
||||
context.pop('default_type', None)
|
||||
attachment_ids.append(ir_attachment.create(cr, uid, attachment_data, context=context))
|
||||
|
||||
@@ -0,0 +1,488 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 18:51+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,email_from:0
|
||||
#: field:email_template.preview,email_from:0
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:mail.compose.message,template_id:0
|
||||
msgid "Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,ref_ir_value:0
|
||||
#: help:email_template.preview,ref_ir_value:0
|
||||
msgid "Sidebar button to open the sidebar action"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:res.partner,opt_out:0
|
||||
msgid "Opt-Out"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,email_to:0
|
||||
#: field:email_template.preview,email_to:0
|
||||
msgid "To (Emails)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,mail_server_id:0
|
||||
#: field:email_template.preview,mail_server_id:0
|
||||
msgid "Outgoing Mail Server"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,ref_ir_act_window:0
|
||||
#: help:email_template.preview,ref_ir_act_window:0
|
||||
msgid ""
|
||||
"Sidebar action to make this template available on records of the related "
|
||||
"document model"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,model_object_field:0
|
||||
#: field:email_template.preview,model_object_field:0
|
||||
msgid "Field"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,email_from:0
|
||||
#: help:email_template.preview,email_from:0
|
||||
msgid "Sender address (placeholders may be used here)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Remove context action"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,mail_server_id:0
|
||||
#: help:email_template.preview,mail_server_id:0
|
||||
msgid ""
|
||||
"Optional preferred server for outgoing mails. If not set, the highest "
|
||||
"priority one will be used."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,report_name:0
|
||||
#: field:email_template.preview,report_name:0
|
||||
msgid "Report Filename"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Preview"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,reply_to:0
|
||||
#: field:email_template.preview,reply_to:0
|
||||
msgid "Reply-To"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:mail.compose.message:0
|
||||
msgid "Use template"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,body_html:0
|
||||
#: field:email_template.preview,body_html:0
|
||||
msgid "Body"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: code:addons/email_template/email_template.py:247
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,user_signature:0
|
||||
#: help:email_template.preview,user_signature:0
|
||||
msgid ""
|
||||
"If checked, the user's signature will be appended to the text version of the "
|
||||
"message"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "SMTP Server"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:mail.compose.message:0
|
||||
msgid "Save as new template"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,sub_object:0
|
||||
#: help:email_template.preview,sub_object:0
|
||||
msgid ""
|
||||
"When a relationship field is selected as first field, this field shows the "
|
||||
"document model the relationship goes to."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.model,name:email_template.model_email_template
|
||||
msgid "Email Templates"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,report_name:0
|
||||
#: help:email_template.preview,report_name:0
|
||||
msgid ""
|
||||
"Name to use for the generated report file (may contain placeholders)\n"
|
||||
"The extension can be omitted and will then come from the report type."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,ref_ir_act_window:0
|
||||
#: field:email_template.preview,ref_ir_act_window:0
|
||||
msgid "Sidebar action"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,lang:0
|
||||
#: help:email_template.preview,lang:0
|
||||
msgid ""
|
||||
"Optional translation language (ISO code) to select when sending out an "
|
||||
"email. If not set, the english version will be used. This should usually be "
|
||||
"a placeholder expression that provides the appropriate language code, e.g. "
|
||||
"${object.partner_id.lang.code}."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email_template.preview,res_id:0
|
||||
msgid "Sample Document"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,model_object_field:0
|
||||
#: help:email_template.preview,model_object_field:0
|
||||
msgid ""
|
||||
"Select target field from the related document model.\n"
|
||||
"If it is a relationship field you will be able to select a target field at "
|
||||
"the destination of the relationship."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Dynamic Value Builder"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
|
||||
msgid "Template Preview"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:mail.compose.message:0
|
||||
msgid "Save as a new template"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid ""
|
||||
"Display an option on related documents to open a composition wizard with "
|
||||
"this template"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,email_cc:0
|
||||
#: help:email_template.preview,email_cc:0
|
||||
msgid "Carbon copy recipients (placeholders may be used here)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,email_to:0
|
||||
#: help:email_template.preview,email_to:0
|
||||
msgid "Comma-separated recipient addresses (placeholders may be used here)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Advanced"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email_template.preview:0
|
||||
msgid "Preview of"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email_template.preview:0
|
||||
msgid "Using sample document"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
#: model:ir.actions.act_window,name:email_template.action_email_template_tree_all
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_templates
|
||||
msgid "Templates"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,name:0
|
||||
#: field:email_template.preview,name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,lang:0
|
||||
#: field:email_template.preview,lang:0
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.model,name:email_template.model_email_template_preview
|
||||
msgid "Email Template Preview"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email_template.preview:0
|
||||
msgid "Email Preview"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid ""
|
||||
"Remove the contextual action to use this template on related documents"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,copyvalue:0
|
||||
#: field:email_template.preview,copyvalue:0
|
||||
msgid "Placeholder Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,sub_object:0
|
||||
#: field:email_template.preview,sub_object:0
|
||||
msgid "Sub-model"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,subject:0
|
||||
#: help:email_template.preview,subject:0
|
||||
msgid "Subject (placeholders may be used here)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,reply_to:0
|
||||
#: help:email_template.preview,reply_to:0
|
||||
msgid "Preferred response address (placeholders may be used here)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,ref_ir_value:0
|
||||
#: field:email_template.preview,ref_ir_value:0
|
||||
msgid "Sidebar Button"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,report_template:0
|
||||
#: field:email_template.preview,report_template:0
|
||||
msgid "Optional report to print and attach"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,null_value:0
|
||||
#: help:email_template.preview,null_value:0
|
||||
msgid "Optional value to use if the target field is empty"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.model,name:email_template.model_mail_compose_message
|
||||
msgid "Email composition wizard"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Add context action"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,model_id:0
|
||||
#: help:email_template.preview,model_id:0
|
||||
msgid "The kind of document with with this template can be used"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,email_recipients:0
|
||||
#: field:email_template.preview,email_recipients:0
|
||||
msgid "To (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,auto_delete:0
|
||||
#: field:email_template.preview,auto_delete:0
|
||||
msgid "Auto Delete"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,copyvalue:0
|
||||
#: help:email_template.preview,copyvalue:0
|
||||
msgid ""
|
||||
"Final placeholder expression, to be copy-pasted in the desired template "
|
||||
"field."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,model:0
|
||||
#: field:email_template.preview,model:0
|
||||
msgid "Related Document Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Addressing"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,email_recipients:0
|
||||
#: help:email_template.preview,email_recipients:0
|
||||
msgid ""
|
||||
"Comma-separated ids of recipient partners (placeholders may be used here)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,attachment_ids:0
|
||||
#: field:email_template.preview,attachment_ids:0
|
||||
msgid "Attachments"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: code:addons/email_template/email_template.py:234
|
||||
#, python-format
|
||||
msgid "Deletion of the action record failed."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,email_cc:0
|
||||
#: field:email_template.preview,email_cc:0
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,model_id:0
|
||||
#: field:email_template.preview,model_id:0
|
||||
msgid "Applies to"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,sub_model_object_field:0
|
||||
#: field:email_template.preview,sub_model_object_field:0
|
||||
msgid "Sub-field"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Email Details"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: code:addons/email_template/email_template.py:199
|
||||
#, python-format
|
||||
msgid "Send Mail (%s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:res.partner,opt_out:0
|
||||
msgid ""
|
||||
"If checked, this partner will not receive any automated email notifications, "
|
||||
"such as the availability of invoices."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,auto_delete:0
|
||||
#: help:email_template.preview,auto_delete:0
|
||||
msgid "Permanently delete this email after sending it, to save space"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Group by..."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,sub_model_object_field:0
|
||||
#: help:email_template.preview,sub_model_object_field:0
|
||||
msgid ""
|
||||
"When a relationship field is selected as first field, this field lets you "
|
||||
"select the target field within the destination document model (sub-model)."
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: code:addons/email_template/email_template.py:234
|
||||
#, python-format
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,user_signature:0
|
||||
#: field:email_template.preview,user_signature:0
|
||||
msgid "Add Signature"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.model,name:email_template.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,null_value:0
|
||||
#: field:email_template.preview,null_value:0
|
||||
msgid "Default Value"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,attachment_ids:0
|
||||
#: help:email_template.preview,attachment_ids:0
|
||||
msgid ""
|
||||
"You may attach files to this template, to be added to all emails created "
|
||||
"from this template"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,body_html:0
|
||||
#: help:email_template.preview,body_html:0
|
||||
msgid "Rich-text/HTML version of the message (placeholders may be used here)"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Contents"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: field:email.template,subject:0
|
||||
#: field:email_template.preview,subject:0
|
||||
msgid "Subject"
|
||||
msgstr ""
|
||||
@@ -33,7 +33,7 @@ class TestServerActionsEmail(TestServerActionsBase):
|
||||
'name': 'TestTemplate',
|
||||
'email_from': 'myself@example.com',
|
||||
'email_to': 'brigitte@example.com',
|
||||
'partner_to': '[%s]' % self.test_partner_id,
|
||||
'partner_to': '%s' % self.test_partner_id,
|
||||
'model_id': self.res_partner_model_id,
|
||||
'subject': 'About ${object.name}',
|
||||
'body_html': '<p>Dear ${object.name}, your parent is ${object.parent_id and object.parent_id.name or "False"}</p>',
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
import base64
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class test_message_compose(TestMail):
|
||||
@@ -200,3 +201,44 @@ class test_message_compose(TestMail):
|
||||
# Generate messsage with default email and partner on template
|
||||
mail_value = mail_compose.generate_email_for_composer(cr, uid, email_template_id, uid)
|
||||
self.assertEqual(set(mail_value['partner_ids']), set(send_to), 'mail.message partner_ids list created by template is incorrect')
|
||||
|
||||
@mute_logger('openerp.osv.orm', 'openerp.osv.orm')
|
||||
def test_10_email_templating(self):
|
||||
""" Tests designed for the mail.compose.message wizard updated by email_template. """
|
||||
cr, uid, context = self.cr, self.uid, {}
|
||||
|
||||
# create the email.template on mail.group model
|
||||
group_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'mail.group')])[0]
|
||||
email_template = self.registry('email.template')
|
||||
email_template_id = email_template.create(cr, uid, {
|
||||
'model_id': group_model_id,
|
||||
'name': 'Pigs Template',
|
||||
'email_from': 'Raoul Grosbedon <raoul@example.com>',
|
||||
'subject': '${object.name}',
|
||||
'body_html': '${object.description}',
|
||||
'user_signature': True,
|
||||
'email_to': 'b@b.b c@c.c',
|
||||
'email_cc': 'd@d.d',
|
||||
'partner_to': '${user.partner_id.id},%s,%s,-1' % (self.user_raoul.partner_id.id, self.user_bert.partner_id.id)
|
||||
})
|
||||
|
||||
# not force send: email_recipients is not taken into account
|
||||
msg_id = email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, context=context)
|
||||
mail = self.mail_mail.browse(cr, uid, msg_id, context=context)
|
||||
self.assertEqual(mail.subject, 'Pigs', 'email_template: send_mail: wrong subject')
|
||||
self.assertEqual(mail.email_to, 'b@b.b c@c.c', 'email_template: send_mail: wrong email_to')
|
||||
self.assertEqual(mail.email_cc, 'd@d.d', 'email_template: send_mail: wrong email_cc')
|
||||
self.assertEqual(
|
||||
set([partner.id for partner in mail.recipient_ids]),
|
||||
set((self.partner_admin_id, self.user_raoul.partner_id.id, self.user_bert.partner_id.id)),
|
||||
'email_template: send_mail: wrong management of partner_to')
|
||||
|
||||
# force send: take email_recipients into account
|
||||
email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, force_send=True, context=context)
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
email_to_lst = [
|
||||
['b@b.b', 'c@c.c'], ['"Followers of Pigs" <admin@example.com>'],
|
||||
['"Followers of Pigs" <raoul@raoul.fr>'], ['"Followers of Pigs" <bert@bert.fr>']]
|
||||
self.assertEqual(len(sent_emails), 4, 'email_template: send_mail: 3 valid email recipients + email_to -> should send 4 emails')
|
||||
for email in sent_emails:
|
||||
self.assertIn(email['email_to'], email_to_lst, 'email_template: send_mail: wrong email_recipients')
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import tools
|
||||
from openerp import tools, SUPERUSER_ID
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
|
||||
@@ -143,9 +143,9 @@ class mail_compose_message(osv.TransientModel):
|
||||
partner_ids.append(partner_id)
|
||||
partner_to = rendered_values.pop('partner_to', '')
|
||||
if partner_to:
|
||||
for partner_id in partner_to.split(','):
|
||||
if partner_id: # placeholders could generate '', 3, 2 due to some empty field values
|
||||
partner_ids.append(int(partner_id))
|
||||
# placeholders could generate '', 3, 2 due to some empty field values
|
||||
tpl_partner_ids = [pid for pid in partner_to.split(',') if pid]
|
||||
partner_ids += self.pool['res.partner'].exists(cr, SUPERUSER_ID, tpl_partner_ids, context=context)
|
||||
return partner_ids
|
||||
|
||||
def generate_email_for_composer_batch(self, cr, uid, template_id, res_ids, context=None):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://openerp.com>).
|
||||
#
|
||||
# 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 models
|
||||
import wizard
|
||||
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://openerp.com>).
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
{
|
||||
'name': 'Gamification',
|
||||
'version': '1.0',
|
||||
'author': 'OpenERP SA',
|
||||
'category': 'Human Ressources',
|
||||
'depends': ['mail', 'email_template', 'web_kanban_gauge'],
|
||||
'description': """
|
||||
Gamification process
|
||||
====================
|
||||
The Gamification module provides ways to evaluate and motivate the users of OpenERP.
|
||||
|
||||
The users can be evaluated using goals and numerical objectives to reach.
|
||||
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.
|
||||
|
||||
For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.
|
||||
|
||||
Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover OpenERP and configure their user profile.
|
||||
""",
|
||||
|
||||
'data': [
|
||||
'wizard/update_goal.xml',
|
||||
'wizard/grant_badge.xml',
|
||||
'views/badge.xml',
|
||||
'views/challenge.xml',
|
||||
'views/goal.xml',
|
||||
'data/cron.xml',
|
||||
'security/gamification_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'data/goal_base.xml',
|
||||
'data/badge.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
'auto_install': False,
|
||||
|
||||
'css': ['static/src/css/gamification.css'],
|
||||
'js': ['static/src/js/gamification.js',],
|
||||
'qweb': ['static/src/xml/gamification.xml'],
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record forcecreate="True" id="ir_cron_check_challenge"
|
||||
model="ir.cron">
|
||||
<field name="name">Run Goal Challenge Checker</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall" />
|
||||
<field name="model">gamification.challenge</field>
|
||||
<field name="function">_cron_update</field>
|
||||
<field name="args">()</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,208 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<!-- Mail template is done in a NOUPDATE block
|
||||
so users can freely customize/delete them -->
|
||||
<data noupdate="0">
|
||||
<!--Email template -->
|
||||
|
||||
<record id="email_template_goal_reminder" model="email.template">
|
||||
<field name="name">Reminder for Goal Update</field>
|
||||
<field name="body_html"><![CDATA[
|
||||
<header>
|
||||
<strong>Reminder ${object.name}</strong>
|
||||
</header>
|
||||
|
||||
<p>You have not updated your progress for the goal ${object.definition_id.name} (currently reached at ${object.completeness}%) for at least ${object.remind_update_delay} days. Do not forget to do it.</p>
|
||||
|
||||
<p>If you have not changed your score yet, you can use the button "The current value is up to date" to indicate so.</p>
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<record id="simple_report_template" model="email.template">
|
||||
<field name="name">Simple Challenge Report Progress</field>
|
||||
<field name="body_html"><![CDATA[
|
||||
<header>
|
||||
<strong>${object.name}</strong>
|
||||
</header>
|
||||
<p class="oe_grey">The following message contains the current progress for the challenge ${object.name}</p>
|
||||
|
||||
% if object.visibility_mode == 'personal':
|
||||
<table width="100%" border="1">
|
||||
<tr>
|
||||
<th>Goal</th>
|
||||
<th>Target</th>
|
||||
<th>Current</th>
|
||||
<th>Completeness</th>
|
||||
</tr>
|
||||
% for line in ctx["challenge_lines"]:
|
||||
<tr
|
||||
% if line['completeness'] >= 100:
|
||||
style="font-weight:bold;"
|
||||
% endif
|
||||
>
|
||||
<td>${line['name']}</td>
|
||||
<td>${line['target']}
|
||||
% if line['suffix']:
|
||||
${line['suffix']}
|
||||
% endif
|
||||
</td>
|
||||
<td>${line['current']}
|
||||
% if line['suffix']:
|
||||
${line['suffix']}
|
||||
% endif
|
||||
</td>
|
||||
<td>${line['completeness']} %</td>
|
||||
</tr>
|
||||
% endfor
|
||||
</table>
|
||||
% else:
|
||||
% for line in ctx["challenge_lines"]:
|
||||
<table width="100%" border="1">
|
||||
<tr>
|
||||
<th colspan="4">${line['name']}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Person</th>
|
||||
<th>Completeness</th>
|
||||
<th>Current</th>
|
||||
</tr>
|
||||
% for goal in line['goals']:
|
||||
<tr
|
||||
% if goal.completeness >= 100:
|
||||
style="font-weight:bold;"
|
||||
% endif
|
||||
>
|
||||
<td>${goal['rank']}</td>
|
||||
<td>${goal['name']}</td>
|
||||
<td>${goal['completeness']}%</td>
|
||||
<td>${goal['current']}/${line['target']}
|
||||
% if line['suffix']:
|
||||
${line['suffix']}
|
||||
% endif
|
||||
</td>
|
||||
</tr>
|
||||
% endfor
|
||||
</table>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
% endfor
|
||||
% endif
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
<data>
|
||||
|
||||
<!-- goal definitions -->
|
||||
<record model="gamification.goal.definition" id="definition_base_timezone">
|
||||
<field name="name">Set your Timezone</field>
|
||||
<field name="description">Configure your profile and specify your timezone</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="display_mode">boolean</field>
|
||||
<field name="model_id" eval="ref('base.model_res_users')" />
|
||||
<field name="domain">[('id','=',user.id),('partner_id.tz', '!=', False)]</field>
|
||||
<field name="action_id" eval="ref('base.action_res_users_my')" />
|
||||
<field name="res_id_field">user.id</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_base_company_data">
|
||||
<field name="name">Set your Company Data</field>
|
||||
<field name="description">Write some information about your company (specify at least a name)</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="display_mode">boolean</field>
|
||||
<field name="model_id" eval="ref('base.model_res_company')" />
|
||||
<field name="domain">[('user_ids', 'in', [user.id]), ('name', '=', 'Your Company')]</field>
|
||||
<field name="condition">lower</field>
|
||||
<field name="action_id" eval="ref('base.action_res_company_form')" />
|
||||
<field name="res_id_field">user.company_id.id</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_base_company_logo">
|
||||
<field name="name">Set your Company Logo</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="display_mode">boolean</field>
|
||||
<field name="model_id" eval="ref('base.model_res_company')" />
|
||||
<field name="domain">[('user_ids', 'in', user.id),('logo', '!=', False)]</field>
|
||||
<field name="action_id" eval="ref('base.action_res_company_form')" />
|
||||
<field name="res_id_field">user.company_id.id</field>
|
||||
</record>
|
||||
|
||||
<record id="action_new_simplified_res_users" model="ir.actions.act_window">
|
||||
<field name="name">Create User</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.users</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="target">current</field>
|
||||
<field name="view_id" ref="base.view_users_simple_form"/>
|
||||
<field name="context">{'default_groups_ref': ['base.group_user']}</field>
|
||||
<field name="help">Create and manage users that will connect to the system. Users can be deactivated should there be a period of time during which they will/should not connect to the system. You can assign them groups in order to give them specific access to the applications they need to use in the system.</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_base_invite">
|
||||
<field name="name">Invite new Users</field>
|
||||
<field name="description">Create at least another user</field>
|
||||
<field name="display_mode">boolean</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="model_id" eval="ref('base.model_res_users')" />
|
||||
<field name="domain">[('id', '!=', user.id)]</field>
|
||||
<field name="action_id" eval="ref('action_new_simplified_res_users')" />
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_nbr_following">
|
||||
<field name="name">Mail Group Following</field>
|
||||
<field name="description">Follow mail groups to receive news</field>
|
||||
<field name="computation_mode">python</field>
|
||||
<field name="compute_code">result = pool.get('mail.followers').search(cr, uid, [('res_model', '=', 'mail.group'), ('partner_id', '=', object.user_id.partner_id.id)], count=True, context=context)</field>
|
||||
<field name="action_id" eval="ref('mail.action_view_groups')" />
|
||||
</record>
|
||||
|
||||
|
||||
<!-- challenges -->
|
||||
<record model="gamification.challenge" id="challenge_base_discover">
|
||||
<field name="name">Complete your Profile</field>
|
||||
<field name="period">once</field>
|
||||
<field name="visibility_mode">personal</field>
|
||||
<field name="report_message_frequency">never</field>
|
||||
<field name="autojoin_group_id" eval="ref('base.group_user')" />
|
||||
<field name="state">inprogress</field>
|
||||
<field name="category">other</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.challenge" id="challenge_base_configure">
|
||||
<field name="name">Setup your Company</field>
|
||||
<field name="period">once</field>
|
||||
<field name="visibility_mode">personal</field>
|
||||
<field name="report_message_frequency">never</field>
|
||||
<field name="user_ids" eval="[(4, ref('base.user_root'))]" />
|
||||
<field name="state">inprogress</field>
|
||||
<field name="category">other</field>
|
||||
</record>
|
||||
|
||||
<!-- lines -->
|
||||
<record model="gamification.challenge.line" id="line_base_discover1">
|
||||
<field name="definition_id" eval="ref('definition_base_timezone')" />
|
||||
<field name="target_goal">1</field>
|
||||
<field name="challenge_id" eval="ref('challenge_base_discover')" />
|
||||
</record>
|
||||
|
||||
<record model="gamification.challenge.line" id="line_base_admin2">
|
||||
<field name="definition_id" eval="ref('definition_base_company_logo')" />
|
||||
<field name="target_goal">1</field>
|
||||
<field name="challenge_id" eval="ref('challenge_base_configure')" />
|
||||
</record>
|
||||
<record model="gamification.challenge.line" id="line_base_admin1">
|
||||
<field name="definition_id" eval="ref('definition_base_company_data')" />
|
||||
<field name="target_goal">0</field>
|
||||
<field name="challenge_id" eval="ref('challenge_base_configure')" />
|
||||
</record>
|
||||
<record model="gamification.challenge.line" id="line_base_admin3">
|
||||
<field name="definition_id" eval="ref('definition_base_invite')" />
|
||||
<field name="target_goal">1</field>
|
||||
<field name="challenge_id" eval="ref('challenge_base_configure')" />
|
||||
</record>
|
||||
</data>
|
||||
|
||||
</openerp>
|
||||
@@ -0,0 +1,86 @@
|
||||
<section class="oe_container">
|
||||
<div class="oe_row oe_spaced">
|
||||
<div class="oe_span12">
|
||||
<h2 class="oe_slogan">Drive Engagement with Gamification</h2>
|
||||
<h3 class="oe_slogan">Leverage natural desire for competition</h3>
|
||||
<p class="oe_mt32">
|
||||
Reinforce good habits and improve win rates with real-time recognition and rewards inspired by <a href="http://en.wikipedia.org/wiki/Gamification">game mechanics</a>. Align teams around clear business objectives with challenges, personal objectives and team leader boards.
|
||||
</p>
|
||||
<div class="oe_span4 oe_centered">
|
||||
<h3>Leaderboards</h3>
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture" src="crm_game_01.png">
|
||||
</div>
|
||||
<p>
|
||||
Promote leaders and competition amongst sales team with performance ratios.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span4 oe_centered">
|
||||
<h3>Personnal Objectives</h3>
|
||||
<div class="oe_row_img">
|
||||
<img class="oe_picture" src="crm_game_02.png">
|
||||
</div>
|
||||
<p>
|
||||
Assign clear goals to users to align them with the company objectives.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span4 oe_centered">
|
||||
<h3>Visual Information</h3>
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture" src="crm_game_03.png">
|
||||
</div>
|
||||
<p>
|
||||
See in an glance the progress of each user.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row oe_spaced">
|
||||
<h2 class="oe_slogan">Create custom Challenges</h2>
|
||||
<div class="oe_span6">
|
||||
<p class="oe_mt32">
|
||||
Use predefined goals to generate easily your own challenges. Assign it to a team or individual users. Receive feedback as often as needed: daily, weekly... Repeat it automatically to compare progresses through time.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture oe_screenshot" src="crm_sc_05.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container">
|
||||
<div class="oe_row oe_spaced">
|
||||
<h2 class="oe_slogan">Motivate with Badges</h2>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture" src="crm_linkedin.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<p class="oe_mt32">
|
||||
Inspire achievement with recognition of coworker's good work by rewarding badges. These can be deserved manually or upon completion of challenges. Add fun to the competition with rare badges.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row oe_spaced">
|
||||
<h2 class="oe_slogan">Adapt to any module</h2>
|
||||
<div class="oe_span6">
|
||||
<p class="oe_mt32">
|
||||
Create goals linked to any module. The evaluation system is very flexible and can be used for many different tasks : sales evaluation, creation of events, project completion or even helping new users to complete their profile.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture oe_screenshot" src="crm_sc_02.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://openerp.com>).
|
||||
#
|
||||
# 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 goal
|
||||
import challenge
|
||||
import res_users
|
||||
import badge
|
||||
@@ -0,0 +1,276 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
|
||||
from openerp.tools.translate import _
|
||||
|
||||
from datetime import date
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class gamification_badge_user(osv.Model):
|
||||
"""User having received a badge"""
|
||||
|
||||
_name = 'gamification.badge.user'
|
||||
_description = 'Gamification user badge'
|
||||
_order = "create_date desc"
|
||||
|
||||
_columns = {
|
||||
'user_id': fields.many2one('res.users', string="User", required=True),
|
||||
'sender_id': fields.many2one('res.users', string="Sender", help="The user who has send the badge"),
|
||||
'badge_id': fields.many2one('gamification.badge', string='Badge', required=True),
|
||||
'comment': fields.text('Comment'),
|
||||
'badge_name': fields.related('badge_id', 'name', type="char", string="Badge Name"),
|
||||
'create_date': fields.datetime('Created', readonly=True),
|
||||
'create_uid': fields.many2one('res.users', string='Creator', readonly=True),
|
||||
}
|
||||
|
||||
|
||||
def _send_badge(self, cr, uid, ids, context=None):
|
||||
"""Send a notification to a user for receiving a badge
|
||||
|
||||
Does not verify constrains on badge granting.
|
||||
The users are added to the owner_ids (create badge_user if needed)
|
||||
The stats counters are incremented
|
||||
:param ids: list(int) of badge users that will receive the badge
|
||||
"""
|
||||
res = True
|
||||
temp_obj = self.pool.get('email.template')
|
||||
user_obj = self.pool.get('res.users')
|
||||
template_id = self.pool['ir.model.data'].get_object(cr, uid, 'gamification', 'email_template_badge_received', context)
|
||||
for badge_user in self.browse(cr, uid, ids, context=context):
|
||||
body_html = temp_obj.render_template(cr, uid, template_id.body_html, 'gamification.badge.user', badge_user.id, context=context)
|
||||
res = user_obj.message_post(cr, uid, badge_user.user_id.id, body=body_html, context=context)
|
||||
return res
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
self.pool.get('gamification.badge').check_granting(cr, uid, badge_id=vals.get('badge_id'), context=context)
|
||||
return super(gamification_badge_user, self).create(cr, uid, vals, context=context)
|
||||
|
||||
|
||||
class gamification_badge(osv.Model):
|
||||
"""Badge object that users can send and receive"""
|
||||
|
||||
CAN_GRANT = 1
|
||||
NOBODY_CAN_GRANT = 2
|
||||
USER_NOT_VIP = 3
|
||||
BADGE_REQUIRED = 4
|
||||
TOO_MANY = 5
|
||||
|
||||
_name = 'gamification.badge'
|
||||
_description = 'Gamification badge'
|
||||
_inherit = ['mail.thread']
|
||||
|
||||
def _get_owners_info(self, cr, uid, ids, name, args, context=None):
|
||||
"""Return:
|
||||
the list of unique res.users ids having received this badge
|
||||
the total number of time this badge was granted
|
||||
the total number of users this badge was granted to
|
||||
"""
|
||||
result = dict.fromkeys(ids, False)
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
res = list(set(owner.user_id.id for owner in obj.owner_ids))
|
||||
result[obj.id] = {
|
||||
'unique_owner_ids': res,
|
||||
'stat_count': len(obj.owner_ids),
|
||||
'stat_count_distinct': len(res)
|
||||
}
|
||||
return result
|
||||
|
||||
def _get_badge_user_stats(self, cr, uid, ids, name, args, context=None):
|
||||
"""Return stats related to badge users"""
|
||||
result = dict.fromkeys(ids, False)
|
||||
badge_user_obj = self.pool.get('gamification.badge.user')
|
||||
first_month_day = date.today().replace(day=1).strftime(DF)
|
||||
for bid in ids:
|
||||
result[bid] = {
|
||||
'stat_my': badge_user_obj.search(cr, uid, [('badge_id', '=', bid), ('user_id', '=', uid)], context=context, count=True),
|
||||
'stat_this_month': badge_user_obj.search(cr, uid, [('badge_id', '=', bid), ('create_date', '>=', first_month_day)], context=context, count=True),
|
||||
'stat_my_this_month': badge_user_obj.search(cr, uid, [('badge_id', '=', bid), ('user_id', '=', uid), ('create_date', '>=', first_month_day)], context=context, count=True),
|
||||
'stat_my_monthly_sending': badge_user_obj.search(cr, uid, [('badge_id', '=', bid), ('create_uid', '=', uid), ('create_date', '>=', first_month_day)], context=context, count=True)
|
||||
}
|
||||
return result
|
||||
|
||||
def _remaining_sending_calc(self, cr, uid, ids, name, args, context=None):
|
||||
"""Computes the number of badges remaining the user can send
|
||||
|
||||
0 if not allowed or no remaining
|
||||
integer if limited sending
|
||||
-1 if infinite (should not be displayed)
|
||||
"""
|
||||
result = dict.fromkeys(ids, False)
|
||||
for badge in self.browse(cr, uid, ids, context=context):
|
||||
if self._can_grant_badge(cr, uid, badge.id, context) != 1:
|
||||
# if the user cannot grant this badge at all, result is 0
|
||||
result[badge.id] = 0
|
||||
elif not badge.rule_max:
|
||||
# if there is no limitation, -1 is returned which means 'infinite'
|
||||
result[badge.id] = -1
|
||||
else:
|
||||
result[badge.id] = badge.rule_max_number - badge.stat_my_monthly_sending
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Badge', required=True, translate=True),
|
||||
'description': fields.text('Description'),
|
||||
'image': fields.binary("Image", help="This field holds the image used for the badge, limited to 256x256"),
|
||||
'rule_auth': fields.selection([
|
||||
('everyone', 'Everyone'),
|
||||
('users', 'A selected list of users'),
|
||||
('having', 'People having some badges'),
|
||||
('nobody', 'No one, assigned through challenges'),
|
||||
],
|
||||
string="Allowance to Grant",
|
||||
help="Who can grant this badge",
|
||||
required=True),
|
||||
'rule_auth_user_ids': fields.many2many('res.users', 'rel_badge_auth_users',
|
||||
string='Authorized Users',
|
||||
help="Only these people can give this badge"),
|
||||
'rule_auth_badge_ids': fields.many2many('gamification.badge',
|
||||
'rel_badge_badge', 'badge1_id', 'badge2_id',
|
||||
string='Required Badges',
|
||||
help="Only the people having these badges can give this badge"),
|
||||
|
||||
'rule_max': fields.boolean('Monthly Limited Sending',
|
||||
help="Check to set a monthly limit per person of sending this badge"),
|
||||
'rule_max_number': fields.integer('Limitation Number',
|
||||
help="The maximum number of time this badge can be sent per month per person."),
|
||||
'stat_my_monthly_sending': fields.function(_get_badge_user_stats,
|
||||
type="integer",
|
||||
string='My Monthly Sending Total',
|
||||
multi='badge_users',
|
||||
help="The number of time the current user has sent this badge this month."),
|
||||
'remaining_sending': fields.function(_remaining_sending_calc, type='integer',
|
||||
string='Remaining Sending Allowed', help="If a maxium is set"),
|
||||
|
||||
'challenge_ids': fields.one2many('gamification.challenge', 'reward_id',
|
||||
string="Reward of Challenges"),
|
||||
|
||||
'goal_definition_ids': fields.many2many('gamification.goal.definition', 'badge_unlocked_definition_rel',
|
||||
string='Rewarded by',
|
||||
help="The users that have succeeded theses goals will receive automatically the badge."),
|
||||
|
||||
'owner_ids': fields.one2many('gamification.badge.user', 'badge_id',
|
||||
string='Owners', help='The list of instances of this badge granted to users'),
|
||||
'active': fields.boolean('Active'),
|
||||
'unique_owner_ids': fields.function(_get_owners_info,
|
||||
string='Unique Owners',
|
||||
help="The list of unique users having received this badge.",
|
||||
multi='unique_users',
|
||||
type="many2many", relation="res.users"),
|
||||
|
||||
'stat_count': fields.function(_get_owners_info, string='Total',
|
||||
type="integer",
|
||||
multi='unique_users',
|
||||
help="The number of time this badge has been received."),
|
||||
'stat_count_distinct': fields.function(_get_owners_info,
|
||||
type="integer",
|
||||
string='Number of users',
|
||||
multi='unique_users',
|
||||
help="The number of time this badge has been received by unique users."),
|
||||
'stat_this_month': fields.function(_get_badge_user_stats,
|
||||
type="integer",
|
||||
string='Monthly total',
|
||||
multi='badge_users',
|
||||
help="The number of time this badge has been received this month."),
|
||||
'stat_my': fields.function(_get_badge_user_stats, string='My Total',
|
||||
type="integer",
|
||||
multi='badge_users',
|
||||
help="The number of time the current user has received this badge."),
|
||||
'stat_my_this_month': fields.function(_get_badge_user_stats,
|
||||
type="integer",
|
||||
string='My Monthly Total',
|
||||
multi='badge_users',
|
||||
help="The number of time the current user has received this badge this month."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'rule_auth': 'everyone',
|
||||
'active': True,
|
||||
}
|
||||
|
||||
def check_granting(self, cr, uid, badge_id, context=None):
|
||||
"""Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception
|
||||
if not
|
||||
|
||||
Do not check for SUPERUSER_ID
|
||||
"""
|
||||
status_code = self._can_grant_badge(cr, uid, badge_id, context=context)
|
||||
if status_code == self.CAN_GRANT:
|
||||
return True
|
||||
elif status_code == self.NOBODY_CAN_GRANT:
|
||||
raise osv.except_osv(_('Warning!'), _('This badge can not be sent by users.'))
|
||||
elif status_code == self.USER_NOT_VIP:
|
||||
raise osv.except_osv(_('Warning!'), _('You are not in the user allowed list.'))
|
||||
elif status_code == self.BADGE_REQUIRED:
|
||||
raise osv.except_osv(_('Warning!'), _('You do not have the required badges.'))
|
||||
elif status_code == self.TOO_MANY:
|
||||
raise osv.except_osv(_('Warning!'), _('You have already sent this badge too many time this month.'))
|
||||
else:
|
||||
_logger.exception("Unknown badge status code: %d" % int(status_code))
|
||||
return False
|
||||
|
||||
def _can_grant_badge(self, cr, uid, badge_id, context=None):
|
||||
"""Check if a user can grant a badge to another user
|
||||
|
||||
:param uid: the id of the res.users trying to send the badge
|
||||
:param badge_id: the granted badge id
|
||||
:return: integer representing the permission.
|
||||
"""
|
||||
if uid == SUPERUSER_ID:
|
||||
return self.CAN_GRANT
|
||||
|
||||
badge = self.browse(cr, uid, badge_id, context=context)
|
||||
|
||||
if badge.rule_auth == 'nobody':
|
||||
return self.NOBODY_CAN_GRANT
|
||||
|
||||
elif badge.rule_auth == 'users' and uid not in [user.id for user in badge.rule_auth_user_ids]:
|
||||
return self.USER_NOT_VIP
|
||||
|
||||
elif badge.rule_auth == 'having':
|
||||
all_user_badges = self.pool.get('gamification.badge.user').search(cr, uid, [('user_id', '=', uid)], context=context)
|
||||
for required_badge in badge.rule_auth_badge_ids:
|
||||
if required_badge.id not in all_user_badges:
|
||||
return self.BADGE_REQUIRED
|
||||
|
||||
if badge.rule_max and badge.stat_my_monthly_sending >= badge.rule_max_number:
|
||||
return self.TOO_MANY
|
||||
|
||||
# badge.rule_auth == 'everyone' -> no check
|
||||
return self.CAN_GRANT
|
||||
|
||||
def check_progress(self, cr, uid, context=None):
|
||||
try:
|
||||
model, res_id = template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'gamification', 'badge_hidden')
|
||||
except ValueError:
|
||||
return True
|
||||
badge_user_obj = self.pool.get('gamification.badge.user')
|
||||
if not badge_user_obj.search(cr, uid, [('user_id', '=', uid), ('badge_id', '=', res_id)], context=context):
|
||||
values = {
|
||||
'user_id': uid,
|
||||
'badge_id': res_id,
|
||||
}
|
||||
badge_user_obj.create(cr, SUPERUSER_ID, values, context=context)
|
||||
return True
|
||||
@@ -0,0 +1,821 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
|
||||
from openerp.tools.translate import _
|
||||
|
||||
from datetime import date, datetime, timedelta
|
||||
import calendar
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
# display top 3 in ranking, could be db variable
|
||||
MAX_VISIBILITY_RANKING = 3
|
||||
|
||||
def start_end_date_for_period(period, default_start_date=False, default_end_date=False):
|
||||
"""Return the start and end date for a goal period based on today
|
||||
|
||||
:return: (start_date, end_date), datetime.date objects, False if the period is
|
||||
not defined or unknown"""
|
||||
today = date.today()
|
||||
if period == 'daily':
|
||||
start_date = today
|
||||
end_date = start_date
|
||||
elif period == 'weekly':
|
||||
delta = timedelta(days=today.weekday())
|
||||
start_date = today - delta
|
||||
end_date = start_date + timedelta(days=7)
|
||||
elif period == 'monthly':
|
||||
month_range = calendar.monthrange(today.year, today.month)
|
||||
start_date = today.replace(day=1)
|
||||
end_date = today.replace(day=month_range[1])
|
||||
elif period == 'yearly':
|
||||
start_date = today.replace(month=1, day=1)
|
||||
end_date = today.replace(month=12, day=31)
|
||||
else: # period == 'once':
|
||||
start_date = default_start_date # for manual goal, start each time
|
||||
end_date = default_end_date
|
||||
|
||||
if start_date and end_date:
|
||||
return (start_date.strftime(DF), end_date.strftime(DF))
|
||||
else:
|
||||
return (start_date, end_date)
|
||||
|
||||
|
||||
class gamification_challenge(osv.Model):
|
||||
"""Gamification challenge
|
||||
|
||||
Set of predifined objectives assigned to people with rules for recurrence and
|
||||
rewards
|
||||
|
||||
If 'user_ids' is defined and 'period' is different than 'one', the set will
|
||||
be assigned to the users for each period (eg: every 1st of each month if
|
||||
'monthly' is selected)
|
||||
"""
|
||||
|
||||
_name = 'gamification.challenge'
|
||||
_description = 'Gamification challenge'
|
||||
_inherit = 'mail.thread'
|
||||
|
||||
def _get_next_report_date(self, cr, uid, ids, field_name, arg, context=None):
|
||||
"""Return the next report date based on the last report date and report
|
||||
period.
|
||||
|
||||
:return: a string in DEFAULT_SERVER_DATE_FORMAT representing the date"""
|
||||
res = {}
|
||||
for challenge in self.browse(cr, uid, ids, context):
|
||||
last = datetime.strptime(challenge.last_report_date, DF).date()
|
||||
if challenge.report_message_frequency == 'daily':
|
||||
next = last + timedelta(days=1)
|
||||
res[challenge.id] = next.strftime(DF)
|
||||
elif challenge.report_message_frequency == 'weekly':
|
||||
next = last + timedelta(days=7)
|
||||
res[challenge.id] = next.strftime(DF)
|
||||
elif challenge.report_message_frequency == 'monthly':
|
||||
month_range = calendar.monthrange(last.year, last.month)
|
||||
next = last.replace(day=month_range[1]) + timedelta(days=1)
|
||||
res[challenge.id] = next.strftime(DF)
|
||||
elif challenge.report_message_frequency == 'yearly':
|
||||
res[challenge.id] = last.replace(year=last.year + 1).strftime(DF)
|
||||
# frequency == 'once', reported when closed only
|
||||
else:
|
||||
res[challenge.id] = False
|
||||
|
||||
return res
|
||||
|
||||
def _get_categories(self, cr, uid, context=None):
|
||||
return [
|
||||
('hr', 'Human Ressources / Engagement'),
|
||||
('other', 'Settings / Gamification Tools'),
|
||||
]
|
||||
|
||||
def _get_report_template(self, cr, uid, context=None):
|
||||
try:
|
||||
return self.pool.get('ir.model.data').get_object_reference(cr, uid, 'gamification', 'simple_report_template')[1]
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
_order = 'end_date, start_date, name, id'
|
||||
_columns = {
|
||||
'name': fields.char('Challenge Name', required=True, translate=True),
|
||||
'description': fields.text('Description', translate=True),
|
||||
'state': fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('inprogress', 'In Progress'),
|
||||
('done', 'Done'),
|
||||
],
|
||||
string='State', required=True, track_visibility='onchange'),
|
||||
'manager_id': fields.many2one('res.users',
|
||||
string='Responsible', help="The user responsible for the challenge."),
|
||||
|
||||
'user_ids': fields.many2many('res.users', 'user_ids',
|
||||
string='Users',
|
||||
help="List of users participating to the challenge"),
|
||||
'autojoin_group_id': fields.many2one('res.groups',
|
||||
string='Auto-subscription Group',
|
||||
help='Group of users whose members will be automatically added to user_ids once the challenge is started'),
|
||||
|
||||
'period': fields.selection([
|
||||
('once', 'Non recurring'),
|
||||
('daily', 'Daily'),
|
||||
('weekly', 'Weekly'),
|
||||
('monthly', 'Monthly'),
|
||||
('yearly', 'Yearly')
|
||||
],
|
||||
string='Periodicity',
|
||||
help='Period of automatic goal assigment. If none is selected, should be launched manually.',
|
||||
required=True),
|
||||
'start_date': fields.date('Start Date',
|
||||
help="The day a new challenge will be automatically started. If no periodicity is set, will use this date as the goal start date."),
|
||||
'end_date': fields.date('End Date',
|
||||
help="The day a new challenge will be automatically closed. If no periodicity is set, will use this date as the goal end date."),
|
||||
|
||||
'invited_user_ids': fields.many2many('res.users', 'invited_user_ids',
|
||||
string="Suggest to users"),
|
||||
|
||||
'line_ids': fields.one2many('gamification.challenge.line', 'challenge_id',
|
||||
string='Lines',
|
||||
help="List of goals that will be set",
|
||||
required=True),
|
||||
|
||||
'reward_id': fields.many2one('gamification.badge', string="For Every Succeding User"),
|
||||
'reward_first_id': fields.many2one('gamification.badge', string="For 1st user"),
|
||||
'reward_second_id': fields.many2one('gamification.badge', string="For 2nd user"),
|
||||
'reward_third_id': fields.many2one('gamification.badge', string="For 3rd user"),
|
||||
'reward_failure': fields.boolean('Reward Bests if not Succeeded?'),
|
||||
|
||||
'visibility_mode': fields.selection([
|
||||
('personal', 'Individual Goals'),
|
||||
('ranking', 'Leader Board (Group Ranking)'),
|
||||
],
|
||||
string="Display Mode", required=True),
|
||||
|
||||
'report_message_frequency': fields.selection([
|
||||
('never', 'Never'),
|
||||
('onchange', 'On change'),
|
||||
('daily', 'Daily'),
|
||||
('weekly', 'Weekly'),
|
||||
('monthly', 'Monthly'),
|
||||
('yearly', 'Yearly')
|
||||
],
|
||||
string="Report Frequency", required=True),
|
||||
'report_message_group_id': fields.many2one('mail.group',
|
||||
string='Send a copy to',
|
||||
help='Group that will receive a copy of the report in addition to the user'),
|
||||
'report_template_id': fields.many2one('email.template', string="Report Template", required=True),
|
||||
'remind_update_delay': fields.integer('Non-updated manual goals will be reminded after',
|
||||
help="Never reminded if no value or zero is specified."),
|
||||
'last_report_date': fields.date('Last Report Date'),
|
||||
'next_report_date': fields.function(_get_next_report_date,
|
||||
type='date', string='Next Report Date', store=True),
|
||||
|
||||
'category': fields.selection(lambda s, *a, **k: s._get_categories(*a, **k),
|
||||
string="Appears in", help="Define the visibility of the challenge through menus", required=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'period': 'once',
|
||||
'state': 'draft',
|
||||
'visibility_mode': 'personal',
|
||||
'report_message_frequency': 'never',
|
||||
'last_report_date': fields.date.today,
|
||||
'start_date': fields.date.today,
|
||||
'manager_id': lambda s, cr, uid, c: uid,
|
||||
'category': 'hr',
|
||||
'reward_failure': False,
|
||||
'report_template_id': lambda s, *a, **k: s._get_report_template(*a, **k),
|
||||
}
|
||||
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
"""Overwrite the create method to add the user of groups"""
|
||||
|
||||
# add users when change the group auto-subscription
|
||||
if vals.get('autojoin_group_id'):
|
||||
new_group = self.pool.get('res.groups').browse(cr, uid, vals['autojoin_group_id'], context=context)
|
||||
|
||||
if not vals.get('user_ids'):
|
||||
vals['user_ids'] = []
|
||||
vals['user_ids'] += [(4, user.id) for user in new_group.users]
|
||||
|
||||
create_res = super(gamification_challenge, self).create(cr, uid, vals, context=context)
|
||||
|
||||
# subscribe new users to the challenge
|
||||
if vals.get('user_ids'):
|
||||
# done with browse after super to be sure catch all after orm process
|
||||
challenge = self.browse(cr, uid, create_res, context=context)
|
||||
self.message_subscribe_users(cr, uid, [challenge.id], [user.id for user in challenge.user_ids], context=context)
|
||||
|
||||
return create_res
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
|
||||
# add users when change the group auto-subscription
|
||||
if vals.get('autojoin_group_id'):
|
||||
new_group = self.pool.get('res.groups').browse(cr, uid, vals['autojoin_group_id'], context=context)
|
||||
|
||||
if not vals.get('user_ids'):
|
||||
vals['user_ids'] = []
|
||||
vals['user_ids'] += [(4, user.id) for user in new_group.users]
|
||||
|
||||
if vals.get('state') == 'inprogress':
|
||||
# starting a challenge
|
||||
if not vals.get('autojoin_group_id'):
|
||||
# starting challenge, add users in autojoin group
|
||||
if not vals.get('user_ids'):
|
||||
vals['user_ids'] = []
|
||||
for challenge in self.browse(cr, uid, ids, context=context):
|
||||
if challenge.autojoin_group_id:
|
||||
vals['user_ids'] += [(4, user.id) for user in challenge.autojoin_group_id.users]
|
||||
|
||||
self.generate_goals_from_challenge(cr, uid, ids, context=context)
|
||||
|
||||
elif vals.get('state') == 'done':
|
||||
self.check_challenge_reward(cr, uid, ids, force=True, context=context)
|
||||
|
||||
elif vals.get('state') == 'draft':
|
||||
# resetting progress
|
||||
if self.pool.get('gamification.goal').search(cr, uid, [('challenge_id', 'in', ids), ('state', 'in', ['inprogress', 'inprogress_update'])], context=context):
|
||||
raise osv.except_osv("Error", "You can not reset a challenge with unfinished goals.")
|
||||
|
||||
write_res = super(gamification_challenge, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
# subscribe new users to the challenge
|
||||
if vals.get('user_ids'):
|
||||
# done with browse after super if changes in groups
|
||||
for challenge in self.browse(cr, uid, ids, context=context):
|
||||
self.message_subscribe_users(cr, uid, [challenge.id], [user.id for user in challenge.user_ids], context=context)
|
||||
|
||||
return write_res
|
||||
|
||||
|
||||
##### Update #####
|
||||
|
||||
def _cron_update(self, cr, uid, context=None, ids=False):
|
||||
"""Daily cron check.
|
||||
|
||||
- Start planned challenges (in draft and with start_date = today)
|
||||
- Create the missing goals (eg: modified the challenge to add lines)
|
||||
- Update every running challenge
|
||||
"""
|
||||
# start planned challenges
|
||||
planned_challenge_ids = self.search(cr, uid, [
|
||||
('state', '=', 'draft'),
|
||||
('start_date', '<=', fields.date.today())])
|
||||
self.write(cr, uid, planned_challenge_ids, {'state': 'inprogress'}, context=context)
|
||||
|
||||
# close planned challenges
|
||||
planned_challenge_ids = self.search(cr, uid, [
|
||||
('state', '=', 'inprogress'),
|
||||
('end_date', '>=', fields.date.today())])
|
||||
self.write(cr, uid, planned_challenge_ids, {'state': 'done'}, context=context)
|
||||
|
||||
if not ids:
|
||||
ids = self.search(cr, uid, [('state', '=', 'inprogress')], context=context)
|
||||
|
||||
return self._update_all(cr, uid, ids, context=context)
|
||||
|
||||
def _update_all(self, cr, uid, ids, context=None):
|
||||
"""Update the challenges and related goals
|
||||
|
||||
:param list(int) ids: the ids of the challenges to update, if False will
|
||||
update only challenges in progress."""
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
|
||||
goal_obj = self.pool.get('gamification.goal')
|
||||
|
||||
# we use yesterday to update the goals that just ended
|
||||
yesterday = date.today() - timedelta(days=1)
|
||||
goal_ids = goal_obj.search(cr, uid, [
|
||||
('challenge_id', 'in', ids),
|
||||
'|',
|
||||
('state', 'in', ('inprogress', 'inprogress_update')),
|
||||
'&',
|
||||
('state', 'in', ('reached', 'failed')),
|
||||
'|',
|
||||
('end_date', '>=', yesterday.strftime(DF)),
|
||||
('end_date', '=', False)
|
||||
], context=context)
|
||||
# update every running goal already generated linked to selected challenges
|
||||
goal_obj.update(cr, uid, goal_ids, context=context)
|
||||
|
||||
for challenge in self.browse(cr, uid, ids, context=context):
|
||||
if challenge.autojoin_group_id:
|
||||
# check in case of new users in challenge, this happens if manager removed users in challenge manually
|
||||
self.write(cr, uid, [challenge.id], {'user_ids': [(4, user.id) for user in challenge.autojoin_group_id.users]}, context=context)
|
||||
self.generate_goals_from_challenge(cr, uid, [challenge.id], context=context)
|
||||
|
||||
# goals closed but still opened at the last report date
|
||||
closed_goals_to_report = goal_obj.search(cr, uid, [
|
||||
('challenge_id', '=', challenge.id),
|
||||
('start_date', '>=', challenge.last_report_date),
|
||||
('end_date', '<=', challenge.last_report_date)
|
||||
])
|
||||
|
||||
if len(closed_goals_to_report) > 0:
|
||||
# some goals need a final report
|
||||
self.report_progress(cr, uid, challenge, subset_goal_ids=closed_goals_to_report, context=context)
|
||||
|
||||
if fields.date.today() == challenge.next_report_date:
|
||||
self.report_progress(cr, uid, challenge, context=context)
|
||||
|
||||
self.check_challenge_reward(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
def quick_update(self, cr, uid, challenge_id, context=None):
|
||||
"""Update all the goals of a challenge, no generation of new goals"""
|
||||
goal_ids = self.pool.get('gamification.goal').search(cr, uid, [('challenge_id', '=', challenge_id)], context=context)
|
||||
self.pool.get('gamification.goal').update(cr, uid, goal_ids, context=context)
|
||||
return True
|
||||
|
||||
|
||||
def action_check(self, cr, uid, ids, context=None):
|
||||
"""Check a challenge
|
||||
|
||||
Create goals that haven't been created yet (eg: if added users)
|
||||
Recompute the current value for each goal related"""
|
||||
return self._update_all(cr, uid, ids=ids, context=context)
|
||||
|
||||
def action_report_progress(self, cr, uid, ids, context=None):
|
||||
"""Manual report of a goal, does not influence automatic report frequency"""
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
for challenge in self.browse(cr, uid, ids, context):
|
||||
self.report_progress(cr, uid, challenge, context=context)
|
||||
return True
|
||||
|
||||
|
||||
##### Automatic actions #####
|
||||
|
||||
def generate_goals_from_challenge(self, cr, uid, ids, context=None):
|
||||
"""Generate the goals for each line and user.
|
||||
|
||||
If goals already exist for this line and user, the line is skipped. This
|
||||
can be called after each change in the list of users or lines.
|
||||
:param list(int) ids: the list of challenge concerned"""
|
||||
|
||||
for challenge in self.browse(cr, uid, ids, context):
|
||||
(start_date, end_date) = start_end_date_for_period(challenge.period)
|
||||
|
||||
# if no periodicity, use challenge dates
|
||||
if not start_date and challenge.start_date:
|
||||
start_date = challenge.start_date
|
||||
if not end_date and challenge.end_date:
|
||||
end_date = challenge.end_date
|
||||
|
||||
for line in challenge.line_ids:
|
||||
for user in challenge.user_ids:
|
||||
|
||||
goal_obj = self.pool.get('gamification.goal')
|
||||
domain = [('line_id', '=', line.id), ('user_id', '=', user.id)]
|
||||
if start_date:
|
||||
domain.append(('start_date', '=', start_date))
|
||||
|
||||
# goal already existing for this line ?
|
||||
if len(goal_obj.search(cr, uid, domain, context=context)) > 0:
|
||||
|
||||
# resume canceled goals
|
||||
domain.append(('state', '=', 'canceled'))
|
||||
canceled_goal_ids = goal_obj.search(cr, uid, domain, context=context)
|
||||
goal_obj.write(cr, uid, canceled_goal_ids, {'state': 'inprogress'}, context=context)
|
||||
goal_obj.update(cr, uid, canceled_goal_ids, context=context)
|
||||
|
||||
# skip to next user
|
||||
continue
|
||||
|
||||
values = {
|
||||
'definition_id': line.definition_id.id,
|
||||
'line_id': line.id,
|
||||
'user_id': user.id,
|
||||
'target_goal': line.target_goal,
|
||||
'state': 'inprogress',
|
||||
}
|
||||
|
||||
if start_date:
|
||||
values['start_date'] = start_date
|
||||
if end_date:
|
||||
values['end_date'] = end_date
|
||||
|
||||
if challenge.remind_update_delay:
|
||||
values['remind_update_delay'] = challenge.remind_update_delay
|
||||
|
||||
new_goal_id = goal_obj.create(cr, uid, values, context)
|
||||
|
||||
goal_obj.update(cr, uid, [new_goal_id], context=context)
|
||||
|
||||
return True
|
||||
|
||||
##### JS utilities #####
|
||||
|
||||
def _get_serialized_challenge_lines(self, cr, uid, challenge, user_id=False, restrict_goal_ids=False, restrict_top=False, context=None):
|
||||
"""Return a serialised version of the goals information
|
||||
|
||||
:challenge: browse record of challenge to compute
|
||||
:user_id: res.users id of the user retrieving progress (False if no distinction, only for ranking challenges)
|
||||
:restrict_goal_ids: <list(int)> compute only the results for this subset if gamification.goal ids, if False retrieve every goal of current running challenge
|
||||
:restrict_top: <int> for challenge lines where visibility_mode == 'ranking', retrieve only these bests results and itself, if False retrieve all
|
||||
restrict_goal_ids has priority over restrict_top
|
||||
|
||||
format list
|
||||
# if visibility_mode == 'ranking'
|
||||
{
|
||||
'name': <gamification.goal.description name>,
|
||||
'description': <gamification.goal.description description>,
|
||||
'condition': <reach condition {lower,higher}>,
|
||||
'computation_mode': <target computation {manually,count,sum,python}>,
|
||||
'monetary': <{True,False}>,
|
||||
'suffix': <value suffix>,
|
||||
'action': <{True,False}>,
|
||||
'display_mode': <{progress,boolean}>,
|
||||
'target': <challenge line target>,
|
||||
'own_goal_id': <gamification.goal id where user_id == uid>,
|
||||
'goals': [
|
||||
{
|
||||
'id': <gamification.goal id>,
|
||||
'rank': <user ranking>,
|
||||
'user_id': <res.users id>,
|
||||
'name': <res.users name>,
|
||||
'state': <gamification.goal state {draft,inprogress,inprogress_update,reached,failed,canceled}>,
|
||||
'completeness': <percentage>,
|
||||
'current': <current value>,
|
||||
}
|
||||
]
|
||||
},
|
||||
# if visibility_mode == 'personal'
|
||||
{
|
||||
'id': <gamification.goal id>,
|
||||
'name': <gamification.goal.description name>,
|
||||
'description': <gamification.goal.description description>,
|
||||
'condition': <reach condition {lower,higher}>,
|
||||
'computation_mode': <target computation {manually,count,sum,python}>,
|
||||
'monetary': <{True,False}>,
|
||||
'suffix': <value suffix>,
|
||||
'action': <{True,False}>,
|
||||
'display_mode': <{progress,boolean}>,
|
||||
'target': <challenge line target>,
|
||||
'state': <gamification.goal state {draft,inprogress,inprogress_update,reached,failed,canceled}>,
|
||||
'completeness': <percentage>,
|
||||
'current': <current value>,
|
||||
}
|
||||
"""
|
||||
goal_obj = self.pool.get('gamification.goal')
|
||||
(start_date, end_date) = start_end_date_for_period(challenge.period)
|
||||
|
||||
res_lines = []
|
||||
for line in challenge.line_ids:
|
||||
line_data = {
|
||||
'name': line.definition_id.name,
|
||||
'description': line.definition_id.description,
|
||||
'condition': line.definition_id.condition,
|
||||
'computation_mode': line.definition_id.computation_mode,
|
||||
'monetary': line.definition_id.monetary,
|
||||
'suffix': line.definition_id.suffix,
|
||||
'action': True if line.definition_id.action_id else False,
|
||||
'display_mode': line.definition_id.display_mode,
|
||||
'target': line.target_goal,
|
||||
}
|
||||
domain = [
|
||||
('line_id', '=', line.id),
|
||||
('state', '!=', 'draft'),
|
||||
]
|
||||
if restrict_goal_ids:
|
||||
domain.append(('ids', 'in', restrict_goal_ids))
|
||||
else:
|
||||
# if no subset goals, use the dates for restriction
|
||||
if start_date:
|
||||
domain.append(('start_date', '=', start_date))
|
||||
if end_date:
|
||||
domain.append(('end_date', '=', end_date))
|
||||
|
||||
if challenge.visibility_mode == 'personal':
|
||||
if not user_id:
|
||||
raise osv.except_osv(_('Error!'),_("Retrieving progress for personal challenge without user information"))
|
||||
domain.append(('user_id', '=', user_id))
|
||||
sorting = goal_obj._order
|
||||
limit = 1
|
||||
# initialise in case search returns no results
|
||||
line_data.update({
|
||||
'id': 0,
|
||||
'current': 0,
|
||||
'completeness': 0,
|
||||
'state': 'draft',
|
||||
})
|
||||
else:
|
||||
line_data.update({
|
||||
'own_goal_id': False,
|
||||
'goals': [],
|
||||
})
|
||||
sorting = "completeness desc, current desc"
|
||||
limit = False
|
||||
|
||||
goal_ids = goal_obj.search(cr, uid, domain, order=sorting, limit=limit, context=context)
|
||||
ranking = 0
|
||||
for goal in goal_obj.browse(cr, uid, goal_ids, context=context):
|
||||
if challenge.visibility_mode == 'personal':
|
||||
# limit=1 so only one result
|
||||
line_data.update({
|
||||
'id': goal.id,
|
||||
'current': goal.current,
|
||||
'completeness': goal.completeness,
|
||||
'state': goal.state,
|
||||
})
|
||||
else:
|
||||
ranking += 1
|
||||
if user_id and goal.user_id.id == user_id:
|
||||
line_data['own_goal_id'] = goal.id
|
||||
elif restrict_top and ranking > restrict_top:
|
||||
# not own goal, over top, skipping
|
||||
continue
|
||||
|
||||
line_data['goals'].append({
|
||||
'id': goal.id,
|
||||
'user_id': goal.user_id.id,
|
||||
'name': goal.user_id.name,
|
||||
'rank': ranking,
|
||||
'current': goal.current,
|
||||
'completeness': goal.completeness,
|
||||
'state': goal.state,
|
||||
})
|
||||
res_lines.append(line_data)
|
||||
return res_lines
|
||||
|
||||
##### Reporting #####
|
||||
|
||||
def report_progress(self, cr, uid, challenge, context=None, users=False, subset_goal_ids=False):
|
||||
"""Post report about the progress of the goals
|
||||
|
||||
:param challenge: the challenge object that need to be reported
|
||||
:param users: the list(res.users) of users that are concerned by
|
||||
the report. If False, will send the report to every user concerned
|
||||
(goal users and group that receive a copy). Only used for challenge with
|
||||
a visibility mode set to 'personal'.
|
||||
:param goal_ids: the list(int) of goal ids linked to the challenge for
|
||||
the report. If not specified, use the goals for the current challenge
|
||||
period. This parameter can be used to produce report for previous challenge
|
||||
periods.
|
||||
:param subset_goal_ids: a list(int) of goal ids to restrict the report
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
temp_obj = self.pool.get('email.template')
|
||||
ctx = context.copy()
|
||||
if challenge.visibility_mode == 'ranking':
|
||||
lines_boards = self._get_serialized_challenge_lines(cr, uid, challenge, user_id=False, restrict_goal_ids=subset_goal_ids, restrict_top=False, context=context)
|
||||
|
||||
ctx.update({'challenge_lines': lines_boards})
|
||||
body_html = temp_obj.render_template(cr, uid, challenge.report_template_id.body_html, 'gamification.challenge', challenge.id, context=ctx)
|
||||
|
||||
# send to every follower of the challenge
|
||||
self.message_post(cr, uid, challenge.id,
|
||||
body=body_html,
|
||||
context=context,
|
||||
subtype='mail.mt_comment')
|
||||
if challenge.report_message_group_id:
|
||||
self.pool.get('mail.group').message_post(cr, uid, challenge.report_message_group_id.id,
|
||||
body=body_html,
|
||||
context=context,
|
||||
subtype='mail.mt_comment')
|
||||
|
||||
else:
|
||||
# generate individual reports
|
||||
for user in users or challenge.user_ids:
|
||||
goals = self._get_serialized_challenge_lines(cr, uid, challenge, user.id, restrict_goal_ids=subset_goal_ids, context=context)
|
||||
if not goals:
|
||||
continue
|
||||
|
||||
ctx.update({'challenge_lines': goals})
|
||||
body_html = temp_obj.render_template(cr, user.id, challenge.report_template_id.body_html, 'gamification.challenge', challenge.id, context=ctx)
|
||||
|
||||
# send message only to users, not on the challenge
|
||||
self.message_post(cr, uid, 0,
|
||||
body=body_html,
|
||||
partner_ids=[(4, user.partner_id.id)],
|
||||
context=context,
|
||||
subtype='mail.mt_comment')
|
||||
if challenge.report_message_group_id:
|
||||
self.pool.get('mail.group').message_post(cr, uid, challenge.report_message_group_id.id,
|
||||
body=body_html,
|
||||
context=context,
|
||||
subtype='mail.mt_comment')
|
||||
return self.write(cr, uid, challenge.id, {'last_report_date': fields.date.today()}, context=context)
|
||||
|
||||
##### Challenges #####
|
||||
def accept_challenge(self, cr, uid, challenge_ids, context=None, user_id=None):
|
||||
"""The user accept the suggested challenge"""
|
||||
user_id = user_id or uid
|
||||
user = self.pool.get('res.users').browse(cr, uid, user_id, context=context)
|
||||
message = "%s has joined the challenge" % user.name
|
||||
self.message_post(cr, uid, challenge_ids, body=message, context=context)
|
||||
self.write(cr, SUPERUSER_ID, challenge_ids, {'invited_user_ids': [(3, user_id)], 'user_ids': [(4, user_id)]}, context=context)
|
||||
return self.generate_goals_from_challenge(cr, uid, challenge_ids, context=context)
|
||||
|
||||
def discard_challenge(self, cr, uid, challenge_ids, context=None, user_id=None):
|
||||
"""The user discard the suggested challenge"""
|
||||
user_id = user_id or uid
|
||||
user = self.pool.get('res.users').browse(cr, uid, user_id, context=context)
|
||||
message = "%s has refused the challenge" % user.name
|
||||
self.message_post(cr, SUPERUSER_ID, challenge_ids, body=message, context=context)
|
||||
return self.write(cr, uid, challenge_ids, {'invited_user_ids': (3, user_id)}, context=context)
|
||||
|
||||
def reply_challenge_wizard(self, cr, uid, challenge_id, context=None):
|
||||
result = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'gamification', 'challenge_wizard')
|
||||
id = result and result[1] or False
|
||||
result = self.pool.get('ir.actions.act_window').read(cr, uid, [id], context=context)[0]
|
||||
result['res_id'] = challenge_id
|
||||
return result
|
||||
|
||||
def check_challenge_reward(self, cr, uid, ids, force=False, context=None):
|
||||
"""Actions for the end of a challenge
|
||||
|
||||
If a reward was selected, grant it to the correct users.
|
||||
Rewards granted at:
|
||||
- the end date for a challenge with no periodicity
|
||||
- the end of a period for challenge with periodicity
|
||||
- when a challenge is manually closed
|
||||
(if no end date, a running challenge is never rewarded)
|
||||
"""
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
context = context or {}
|
||||
for challenge in self.browse(cr, uid, ids, context=context):
|
||||
(start_date, end_date) = start_end_date_for_period(challenge.period, challenge.start_date, challenge.end_date)
|
||||
yesterday = date.today() - timedelta(days=1)
|
||||
if end_date == yesterday.strftime(DF) or force:
|
||||
# open chatter message
|
||||
message_body = _("The challenge %s is finished." % challenge.name)
|
||||
|
||||
# reward for everybody succeeding
|
||||
rewarded_users = []
|
||||
if challenge.reward_id:
|
||||
for user in challenge.user_ids:
|
||||
reached_goal_ids = self.pool.get('gamification.goal').search(cr, uid, [
|
||||
('challenge_id', '=', challenge.id),
|
||||
('user_id', '=', user.id),
|
||||
('start_date', '=', start_date),
|
||||
('end_date', '=', end_date),
|
||||
('state', '=', 'reached')
|
||||
], context=context)
|
||||
if len(reached_goal_ids) == len(challenge.line_ids):
|
||||
self.reward_user(cr, uid, user.id, challenge.reward_id.id, context)
|
||||
rewarded_users.append(user)
|
||||
|
||||
if rewarded_users:
|
||||
message_body += _("<br/>Reward (badge %s) for every succeeding user was sent to %s." % (challenge.reward_id.name, ", ".join([user.name for user in rewarded_users])))
|
||||
else:
|
||||
message_body += _("<br/>Nobody has succeeded to reach every goal, no badge is rewared for this challenge.")
|
||||
|
||||
# reward bests
|
||||
if challenge.reward_first_id:
|
||||
(first_user, second_user, third_user) = self.get_top3_users(cr, uid, challenge, context)
|
||||
if first_user:
|
||||
self.reward_user(cr, uid, first_user.id, challenge.reward_first_id.id, context)
|
||||
message_body += _("<br/>Special rewards were sent to the top competing users. The ranking for this challenge is :")
|
||||
message_body += "<br/> 1. %s - %s" % (first_user.name, challenge.reward_first_id.name)
|
||||
else:
|
||||
message_body += _("Nobody reached the required conditions to receive special badges.")
|
||||
|
||||
if second_user and challenge.reward_second_id:
|
||||
self.reward_user(cr, uid, second_user.id, challenge.reward_second_id.id, context)
|
||||
message_body += "<br/> 2. %s - %s" % (second_user.name, challenge.reward_second_id.name)
|
||||
if third_user and challenge.reward_third_id:
|
||||
self.reward_user(cr, uid, third_user.id, challenge.reward_second_id.id, context)
|
||||
message_body += "<br/> 3. %s - %s" % (third_user.name, challenge.reward_third_id.name)
|
||||
|
||||
self.message_post(cr, uid, challenge.id, body=message_body, context=context)
|
||||
return True
|
||||
|
||||
def get_top3_users(self, cr, uid, challenge, context=None):
|
||||
"""Get the top 3 users for a defined challenge
|
||||
|
||||
Ranking criterias:
|
||||
1. succeed every goal of the challenge
|
||||
2. total completeness of each goal (can be over 100)
|
||||
Top 3 is computed only for users succeeding every goal of the challenge,
|
||||
except if reward_failure is True, in which case every user is
|
||||
considered.
|
||||
:return: ('first', 'second', 'third'), tuple containing the res.users
|
||||
objects of the top 3 users. If no user meets the criterias for a rank,
|
||||
it is set to False. Nobody can receive a rank is noone receives the
|
||||
higher one (eg: if 'second' == False, 'third' will be False)
|
||||
"""
|
||||
goal_obj = self.pool.get('gamification.goal')
|
||||
(start_date, end_date) = start_end_date_for_period(challenge.period, challenge.start_date, challenge.end_date)
|
||||
challengers = []
|
||||
for user in challenge.user_ids:
|
||||
all_reached = True
|
||||
total_completness = 0
|
||||
# every goal of the user for the running period
|
||||
goal_ids = goal_obj.search(cr, uid, [
|
||||
('challenge_id', '=', challenge.id),
|
||||
('user_id', '=', user.id),
|
||||
('start_date', '=', start_date),
|
||||
('end_date', '=', end_date)
|
||||
], context=context)
|
||||
for goal in goal_obj.browse(cr, uid, goal_ids, context=context):
|
||||
if goal.state != 'reached':
|
||||
all_reached = False
|
||||
if goal.definition_condition == 'higher':
|
||||
# can be over 100
|
||||
total_completness += 100.0 * goal.current / goal.target_goal
|
||||
elif goal.state == 'reached':
|
||||
# for lower goals, can not get percentage so 0 or 100
|
||||
total_completness += 100
|
||||
|
||||
challengers.append({'user': user, 'all_reached': all_reached, 'total_completness': total_completness})
|
||||
sorted_challengers = sorted(challengers, key=lambda k: (k['all_reached'], k['total_completness']), reverse=True)
|
||||
|
||||
if len(sorted_challengers) == 0 or (not challenge.reward_failure and not sorted_challengers[0]['all_reached']):
|
||||
# nobody succeeded
|
||||
return (False, False, False)
|
||||
if len(sorted_challengers) == 1 or (not challenge.reward_failure and not sorted_challengers[1]['all_reached']):
|
||||
# only one user succeeded
|
||||
return (sorted_challengers[0]['user'], False, False)
|
||||
if len(sorted_challengers) == 2 or (not challenge.reward_failure and not sorted_challengers[2]['all_reached']):
|
||||
# only one user succeeded
|
||||
return (sorted_challengers[0]['user'], sorted_challengers[1]['user'], False)
|
||||
return (sorted_challengers[0]['user'], sorted_challengers[1]['user'], sorted_challengers[2]['user'])
|
||||
|
||||
def reward_user(self, cr, uid, user_id, badge_id, context=None):
|
||||
"""Create a badge user and send the badge to him
|
||||
|
||||
:param user_id: the user to reward
|
||||
:param badge_id: the concerned badge
|
||||
"""
|
||||
badge_user_obj = self.pool.get('gamification.badge.user')
|
||||
user_badge_id = badge_user_obj.create(cr, uid, {'user_id': user_id, 'badge_id': badge_id}, context=context)
|
||||
return badge_user_obj._send_badge(cr, uid, [user_badge_id], context=context)
|
||||
|
||||
|
||||
class gamification_challenge_line(osv.Model):
|
||||
"""Gamification challenge line
|
||||
|
||||
Predifined goal for 'gamification_challenge'
|
||||
These are generic list of goals with only the target goal defined
|
||||
Should only be created for the gamification_challenge object
|
||||
"""
|
||||
|
||||
_name = 'gamification.challenge.line'
|
||||
_description = 'Gamification generic goal for challenge'
|
||||
_order = "sequence, id"
|
||||
|
||||
def on_change_definition_id(self, cr, uid, ids, definition_id=False, context=None):
|
||||
goal_definition = self.pool.get('gamification.goal.definition')
|
||||
if not definition_id:
|
||||
return {'value': {'definition_id': False}}
|
||||
goal_definition = goal_definition.browse(cr, uid, definition_id, context=context)
|
||||
ret = {
|
||||
'value': {
|
||||
'condition': goal_definition.condition,
|
||||
'definition_full_suffix': goal_definition.full_suffix
|
||||
}
|
||||
}
|
||||
return ret
|
||||
|
||||
_columns = {
|
||||
'name': fields.related('definition_id', 'name', string="Name"),
|
||||
'challenge_id': fields.many2one('gamification.challenge',
|
||||
string='Challenge',
|
||||
required=True,
|
||||
ondelete="cascade"),
|
||||
'definition_id': fields.many2one('gamification.goal.definition',
|
||||
string='Goal Definition',
|
||||
required=True,
|
||||
ondelete="cascade"),
|
||||
'target_goal': fields.float('Target Value to Reach',
|
||||
required=True),
|
||||
'sequence': fields.integer('Sequence',
|
||||
help='Sequence number for ordering'),
|
||||
'condition': fields.related('definition_id', 'condition', type="selection",
|
||||
readonly=True, string="Condition", selection=[('lower', '<='), ('higher', '>=')]),
|
||||
'definition_suffix': fields.related('definition_id', 'suffix', type="char", readonly=True, string="Unit"),
|
||||
'definition_monetary': fields.related('definition_id', 'monetary', type="boolean", readonly=True, string="Monetary"),
|
||||
'definition_full_suffix': fields.related('definition_id', 'full_suffix', type="char", readonly=True, string="Suffix"),
|
||||
}
|
||||
|
||||
_default = {
|
||||
'sequence': 1,
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
|
||||
from openerp.tools.safe_eval import safe_eval
|
||||
from openerp.tools.translate import _
|
||||
|
||||
import logging
|
||||
import time
|
||||
from datetime import date, datetime, timedelta
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class gamification_goal_definition(osv.Model):
|
||||
"""Goal definition
|
||||
|
||||
A goal definition contains the way to evaluate an objective
|
||||
Each module wanting to be able to set goals to the users needs to create
|
||||
a new gamification_goal_definition
|
||||
"""
|
||||
_name = 'gamification.goal.definition'
|
||||
_description = 'Gamification goal definition'
|
||||
|
||||
def _get_suffix(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = dict.fromkeys(ids, '')
|
||||
for goal in self.browse(cr, uid, ids, context=context):
|
||||
if goal.suffix and not goal.monetary:
|
||||
res[goal.id] = goal.suffix
|
||||
elif goal.monetary:
|
||||
# use the current user's company currency
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context)
|
||||
if goal.suffix:
|
||||
res[goal.id] = "%s %s" % (user.company_id.currency_id.symbol, goal.suffix)
|
||||
else:
|
||||
res[goal.id] = user.company_id.currency_id.symbol
|
||||
else:
|
||||
res[goal.id] = ""
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Goal Definition', required=True, translate=True),
|
||||
'description': fields.text('Goal Description'),
|
||||
'monetary': fields.boolean('Monetary Value', help="The target and current value are defined in the company currency."),
|
||||
'suffix': fields.char('Suffix', help="The unit of the target and current values", translate=True),
|
||||
'full_suffix': fields.function(_get_suffix, type="char", string="Full Suffix", help="The currency and suffix field"),
|
||||
'computation_mode': fields.selection([
|
||||
('manually', 'Recorded manually'),
|
||||
('count', 'Automatic: number of records'),
|
||||
('sum', 'Automatic: sum on a field'),
|
||||
('python', 'Automatic: execute a specific Python code'),
|
||||
],
|
||||
string="Computation Mode",
|
||||
help="Defined how will be computed the goals. The result of the operation will be stored in the field 'Current'.",
|
||||
required=True),
|
||||
'display_mode': fields.selection([
|
||||
('progress', 'Progressive (using numerical values)'),
|
||||
('boolean', 'Exclusive (done or not-done)'),
|
||||
],
|
||||
string="Displayed as", required=True),
|
||||
'model_id': fields.many2one('ir.model',
|
||||
string='Model',
|
||||
help='The model object for the field to evaluate'),
|
||||
'field_id': fields.many2one('ir.model.fields',
|
||||
string='Field to Sum',
|
||||
help='The field containing the value to evaluate'),
|
||||
'field_date_id': fields.many2one('ir.model.fields',
|
||||
string='Date Field',
|
||||
help='The date to use for the time period evaluated'),
|
||||
'domain': fields.char("Filter Domain",
|
||||
help="Domain for filtering records. The rule can contain reference to 'user' that is a browse record of the current user, e.g. [('user_id', '=', user.id)].",
|
||||
required=True),
|
||||
'compute_code': fields.text('Python Code',
|
||||
help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id."),
|
||||
'condition': fields.selection([
|
||||
('higher', 'The higher the better'),
|
||||
('lower', 'The lower the better')
|
||||
],
|
||||
string='Goal Performance',
|
||||
help='A goal is considered as completed when the current value is compared to the value to reach',
|
||||
required=True),
|
||||
'action_id': fields.many2one('ir.actions.act_window', string="Action",
|
||||
help="The action that will be called to update the goal value."),
|
||||
'res_id_field': fields.char("ID Field of user",
|
||||
help="The field name on the user profile (res.users) containing the value for res_id for action.")
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'condition': 'higher',
|
||||
'computation_mode': 'manually',
|
||||
'domain': "[]",
|
||||
'monetary': False,
|
||||
'display_mode': 'progress',
|
||||
}
|
||||
|
||||
def number_following(self, cr, uid, model_name="mail.thread", context=None):
|
||||
"""Return the number of 'model_name' objects the user is following
|
||||
|
||||
The model specified in 'model_name' must inherit from mail.thread
|
||||
"""
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
return self.pool.get('mail.followers').search(cr, uid, [('res_model', '=', model_name), ('partner_id', '=', user.partner_id.id)], count=True, context=context)
|
||||
|
||||
|
||||
|
||||
class gamification_goal(osv.Model):
|
||||
"""Goal instance for a user
|
||||
|
||||
An individual goal for a user on a specified time period"""
|
||||
|
||||
_name = 'gamification.goal'
|
||||
_description = 'Gamification goal instance'
|
||||
_inherit = 'mail.thread'
|
||||
|
||||
def _get_completion(self, cr, uid, ids, field_name, arg, context=None):
|
||||
"""Return the percentage of completeness of the goal, between 0 and 100"""
|
||||
res = dict.fromkeys(ids, 0.0)
|
||||
for goal in self.browse(cr, uid, ids, context=context):
|
||||
if goal.definition_condition == 'higher':
|
||||
if goal.current >= goal.target_goal:
|
||||
res[goal.id] = 100.0
|
||||
else:
|
||||
res[goal.id] = round(100.0 * goal.current / goal.target_goal, 2)
|
||||
elif goal.current < goal.target_goal:
|
||||
# a goal 'lower than' has only two values possible: 0 or 100%
|
||||
res[goal.id] = 100.0
|
||||
else:
|
||||
res[goal.id] = 0.0
|
||||
return res
|
||||
|
||||
def on_change_definition_id(self, cr, uid, ids, definition_id=False, context=None):
|
||||
goal_definition = self.pool.get('gamification.goal.definition')
|
||||
if not definition_id:
|
||||
return {'value': {'definition_id': False}}
|
||||
goal_definition = goal_definition.browse(cr, uid, definition_id, context=context)
|
||||
return {'value': {'computation_mode': goal_definition.computation_mode, 'definition_condition': goal_definition.condition}}
|
||||
|
||||
_columns = {
|
||||
'definition_id': fields.many2one('gamification.goal.definition', string='Goal Definition', required=True, ondelete="cascade"),
|
||||
'user_id': fields.many2one('res.users', string='User', required=True),
|
||||
'line_id': fields.many2one('gamification.challenge.line', string='Goal Line', ondelete="cascade"),
|
||||
'challenge_id': fields.related('line_id', 'challenge_id',
|
||||
string="Challenge",
|
||||
type='many2one',
|
||||
relation='gamification.challenge',
|
||||
store=True),
|
||||
'start_date': fields.date('Start Date'),
|
||||
'end_date': fields.date('End Date'), # no start and end = always active
|
||||
'target_goal': fields.float('To Reach',
|
||||
required=True,
|
||||
track_visibility='always'), # no goal = global index
|
||||
'current': fields.float('Current Value', required=True, track_visibility='always'),
|
||||
'completeness': fields.function(_get_completion, type='float', string='Completeness'),
|
||||
'state': fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('inprogress', 'In progress'),
|
||||
('inprogress_update', 'In progress (to update)'),
|
||||
('reached', 'Reached'),
|
||||
('failed', 'Failed'),
|
||||
('canceled', 'Canceled'),
|
||||
],
|
||||
string='State',
|
||||
required=True,
|
||||
track_visibility='always'),
|
||||
|
||||
'computation_mode': fields.related('definition_id', 'computation_mode', type='char', string="Computation mode"),
|
||||
'remind_update_delay': fields.integer('Remind delay',
|
||||
help="The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified."),
|
||||
'last_update': fields.date('Last Update',
|
||||
help="In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge."),
|
||||
|
||||
'definition_description': fields.related('definition_id', 'description', type='char', string='Definition Description', readonly=True),
|
||||
'definition_condition': fields.related('definition_id', 'condition', type='char', string='Definition Condition', readonly=True),
|
||||
'definition_suffix': fields.related('definition_id', 'full_suffix', type="char", string="Suffix", readonly=True),
|
||||
'definition_display': fields.related('definition_id', 'display_mode', type="char", string="Display Mode", readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'current': 0,
|
||||
'state': 'draft',
|
||||
'start_date': fields.date.today,
|
||||
}
|
||||
_order = 'create_date desc, end_date desc, definition_id, id'
|
||||
|
||||
def _check_remind_delay(self, cr, uid, goal, context=None):
|
||||
"""Verify if a goal has not been updated for some time and send a
|
||||
reminder message of needed.
|
||||
|
||||
:return: data to write on the goal object
|
||||
"""
|
||||
if goal.remind_update_delay and goal.last_update:
|
||||
delta_max = timedelta(days=goal.remind_update_delay)
|
||||
last_update = datetime.strptime(goal.last_update, DF).date()
|
||||
if date.today() - last_update > delta_max and goal.state == 'inprogress':
|
||||
# generate a remind report
|
||||
temp_obj = self.pool.get('email.template')
|
||||
template_id = self.pool['ir.model.data'].get_object(cr, uid, 'gamification', 'email_template_goal_reminder', context)
|
||||
body_html = temp_obj.render_template(cr, uid, template_id.body_html, 'gamification.goal', goal.id, context=context)
|
||||
|
||||
self.message_post(cr, uid, goal.id, body=body_html, partner_ids=[goal.user_id.partner_id.id], context=context, subtype='mail.mt_comment')
|
||||
return {'state': 'inprogress_update'}
|
||||
return {}
|
||||
|
||||
def update(self, cr, uid, ids, context=None):
|
||||
"""Update the goals to recomputes values and change of states
|
||||
|
||||
If a manual goal is not updated for enough time, the user will be
|
||||
reminded to do so (done only once, in 'inprogress' state).
|
||||
If a goal reaches the target value, the status is set to reached
|
||||
If the end date is passed (at least +1 day, time not considered) without
|
||||
the target value being reached, the goal is set as failed."""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
for goal in self.browse(cr, uid, ids, context=context):
|
||||
towrite = {}
|
||||
if goal.state in ('draft', 'canceled'):
|
||||
# skip if goal draft or canceled
|
||||
continue
|
||||
|
||||
if goal.definition_id.computation_mode == 'manually':
|
||||
towrite.update(self._check_remind_delay(cr, uid, goal, context))
|
||||
|
||||
elif goal.definition_id.computation_mode == 'python':
|
||||
# execute the chosen method
|
||||
cxt = {
|
||||
'self': self.pool.get('gamification.goal'),
|
||||
'object': goal,
|
||||
'pool': self.pool,
|
||||
'cr': cr,
|
||||
'context': dict(context), # copy context to prevent side-effects of eval
|
||||
'uid': uid,
|
||||
'result': False,
|
||||
'date': date, 'datetime': datetime, 'timedelta': timedelta, 'time': time
|
||||
}
|
||||
code = goal.definition_id.compute_code.strip()
|
||||
safe_eval(code, cxt, mode="exec", nocopy=True)
|
||||
# the result of the evaluated codeis put in the 'result' local variable, propagated to the context
|
||||
result = cxt.get('result', False)
|
||||
if result and type(result) in (float, int, long):
|
||||
if result != goal.current:
|
||||
towrite['current'] = result
|
||||
else:
|
||||
_logger.exception(_('Invalid return content from the evaluation of %s' % code))
|
||||
|
||||
else: # count or sum
|
||||
obj = self.pool.get(goal.definition_id.model_id.model)
|
||||
field_date_name = goal.definition_id.field_date_id.name
|
||||
|
||||
# eval the domain with user replaced by goal user object
|
||||
domain = safe_eval(goal.definition_id.domain, {'user': goal.user_id})
|
||||
|
||||
# add temporal clause(s) to the domain if fields are filled on the goal
|
||||
if goal.start_date and field_date_name:
|
||||
domain.append((field_date_name, '>=', goal.start_date))
|
||||
if goal.end_date and field_date_name:
|
||||
domain.append((field_date_name, '<=', goal.end_date))
|
||||
|
||||
if goal.definition_id.computation_mode == 'sum':
|
||||
field_name = goal.definition_id.field_id.name
|
||||
res = obj.read_group(cr, uid, domain, [field_name], [''], context=context)
|
||||
new_value = res and res[0][field_name] or 0.0
|
||||
|
||||
else: # computation mode = count
|
||||
new_value = obj.search(cr, uid, domain, context=context, count=True)
|
||||
|
||||
# avoid useless write if the new value is the same as the old one
|
||||
if new_value != goal.current:
|
||||
towrite['current'] = new_value
|
||||
|
||||
# check goal target reached
|
||||
if (goal.definition_condition == 'higher' and towrite.get('current', goal.current) >= goal.target_goal) or (goal.definition_condition == 'lower' and towrite.get('current', goal.current) <= goal.target_goal):
|
||||
towrite['state'] = 'reached'
|
||||
|
||||
# check goal failure
|
||||
elif goal.end_date and fields.date.today() > goal.end_date:
|
||||
towrite['state'] = 'failed'
|
||||
if towrite:
|
||||
self.write(cr, uid, [goal.id], towrite, context=context)
|
||||
return True
|
||||
|
||||
def action_start(self, cr, uid, ids, context=None):
|
||||
"""Mark a goal as started.
|
||||
|
||||
This should only be used when creating goals manually (in draft state)"""
|
||||
self.write(cr, uid, ids, {'state': 'inprogress'}, context=context)
|
||||
return self.update(cr, uid, ids, context=context)
|
||||
|
||||
def action_reach(self, cr, uid, ids, context=None):
|
||||
"""Mark a goal as reached.
|
||||
|
||||
If the target goal condition is not met, the state will be reset to In
|
||||
Progress at the next goal update until the end date."""
|
||||
return self.write(cr, uid, ids, {'state': 'reached'}, context=context)
|
||||
|
||||
def action_fail(self, cr, uid, ids, context=None):
|
||||
"""Set the state of the goal to failed.
|
||||
|
||||
A failed goal will be ignored in future checks."""
|
||||
return self.write(cr, uid, ids, {'state': 'failed'}, context=context)
|
||||
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
"""Reset the completion after setting a goal as reached or failed.
|
||||
|
||||
This is only the current state, if the date and/or target criterias
|
||||
match the conditions for a change of state, this will be applied at the
|
||||
next goal update."""
|
||||
return self.write(cr, uid, ids, {'state': 'inprogress'}, context=context)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
"""Overwrite the create method to add a 'no_remind_goal' field to True"""
|
||||
if context is None:
|
||||
context = {}
|
||||
context['no_remind_goal'] = True
|
||||
return super(gamification_goal, self).create(cr, uid, vals, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
"""Overwrite the write method to update the last_update field to today
|
||||
|
||||
If the current value is changed and the report frequency is set to On
|
||||
change, a report is generated
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
vals['last_update'] = fields.date.today()
|
||||
result = super(gamification_goal, self).write(cr, uid, ids, vals, context=context)
|
||||
for goal in self.browse(cr, uid, ids, context=context):
|
||||
if goal.state != "draft" and ('definition_id' in vals or 'user_id' in vals):
|
||||
# avoid drag&drop in kanban view
|
||||
raise osv.except_osv(_('Error!'), _('Can not modify the configuration of a started goal'))
|
||||
|
||||
if vals.get('current'):
|
||||
if 'no_remind_goal' in context:
|
||||
# new goals should not be reported
|
||||
continue
|
||||
|
||||
if goal.challenge_id and goal.challenge_id.report_message_frequency == 'onchange':
|
||||
self.pool.get('gamification.challenge').report_progress(cr, SUPERUSER_ID, goal.challenge_id, users=[goal.user_id], context=context)
|
||||
return result
|
||||
|
||||
def get_action(self, cr, uid, goal_id, context=None):
|
||||
"""Get the ir.action related to update the goal
|
||||
|
||||
In case of a manual goal, should return a wizard to update the value
|
||||
:return: action description in a dictionnary
|
||||
"""
|
||||
goal = self.browse(cr, uid, goal_id, context=context)
|
||||
|
||||
if goal.definition_id.action_id:
|
||||
# open a the action linked to the goal
|
||||
action = goal.definition_id.action_id.read()[0]
|
||||
|
||||
if goal.definition_id.res_id_field:
|
||||
current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
action['res_id'] = safe_eval(goal.definition_id.res_id_field, {'user': current_user})
|
||||
|
||||
# if one element to display, should see it in form mode if possible
|
||||
action['views'] = [(view_id, mode) for (view_id, mode) in action['views'] if mode == 'form'] or action['views']
|
||||
return action
|
||||
|
||||
if goal.computation_mode == 'manually':
|
||||
# open a wizard window to update the value manually
|
||||
action = {
|
||||
'name': _("Update %s") % goal.definition_id.name,
|
||||
'id': goal_id,
|
||||
'type': 'ir.actions.act_window',
|
||||
'views': [[False, 'form']],
|
||||
'target': 'new',
|
||||
'context': {'default_goal_id': goal_id, 'default_current': goal.current},
|
||||
'res_model': 'gamification.goal.wizard'
|
||||
}
|
||||
return action
|
||||
|
||||
return False
|
||||
@@ -0,0 +1,132 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import osv
|
||||
from challenge import MAX_VISIBILITY_RANKING
|
||||
|
||||
class res_users_gamification_group(osv.Model):
|
||||
""" Update of res.users class
|
||||
- if adding groups to an user, check gamification.challenge linked to
|
||||
this group, and the user. This is done by overriding the write method.
|
||||
"""
|
||||
_name = 'res.users'
|
||||
_inherit = ['res.users']
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
"""Overwrite to autosubscribe users if added to a group marked as autojoin, user will be added to challenge"""
|
||||
write_res = super(res_users_gamification_group, self).write(cr, uid, ids, vals, context=context)
|
||||
if vals.get('groups_id'):
|
||||
# form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
|
||||
user_group_ids = [command[1] for command in vals['groups_id'] if command[0] == 4]
|
||||
user_group_ids += [id for command in vals['groups_id'] if command[0] == 6 for id in command[2]]
|
||||
|
||||
challenge_obj = self.pool.get('gamification.challenge')
|
||||
challenge_ids = challenge_obj.search(cr, uid, [('autojoin_group_id', 'in', user_group_ids)], context=context)
|
||||
if challenge_ids:
|
||||
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, user_id) for user_id in ids]}, context=context)
|
||||
return write_res
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
"""Overwrite to autosubscribe users if added to a group marked as autojoin, user will be added to challenge"""
|
||||
write_res = super(res_users_gamification_group, self).create(cr, uid, vals, context=context)
|
||||
if vals.get('groups_id'):
|
||||
# form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
|
||||
user_group_ids = [command[1] for command in vals['groups_id'] if command[0] == 4]
|
||||
user_group_ids += [id for command in vals['groups_id'] if command[0] == 6 for id in command[2]]
|
||||
|
||||
challenge_obj = self.pool.get('gamification.challenge')
|
||||
challenge_ids = challenge_obj.search(cr, uid, [('autojoin_group_id', 'in', user_group_ids)], context=context)
|
||||
if challenge_ids:
|
||||
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, write_res)]}, context=context)
|
||||
return write_res
|
||||
|
||||
# def get_goals_todo_info(self, cr, uid, context=None):
|
||||
|
||||
def get_serialised_gamification_summary(self, cr, uid, context=None):
|
||||
return self._serialised_goals_summary(cr, uid, user_id=uid, context=context)
|
||||
|
||||
def _serialised_goals_summary(self, cr, uid, user_id, context=None):
|
||||
"""Return a serialised list of goals assigned to the user, grouped by challenge
|
||||
|
||||
[
|
||||
{
|
||||
'id': <gamification.challenge id>,
|
||||
'name': <gamification.challenge name>,
|
||||
'visibility_mode': <visibility {ranking,personal}>,
|
||||
'currency': <res.currency id>,
|
||||
'lines': [(see gamification_challenge._get_serialized_challenge_lines() format)]
|
||||
},
|
||||
]
|
||||
"""
|
||||
all_goals_info = []
|
||||
challenge_obj = self.pool.get('gamification.challenge')
|
||||
|
||||
user = self.browse(cr, uid, uid, context=context)
|
||||
challenge_ids = challenge_obj.search(cr, uid, [('user_ids', 'in', uid), ('state', '=', 'inprogress')], context=context)
|
||||
for challenge in challenge_obj.browse(cr, uid, challenge_ids, context=context):
|
||||
# serialize goals info to be able to use it in javascript
|
||||
all_goals_info.append({
|
||||
'id': challenge.id,
|
||||
'name': challenge.name,
|
||||
'visibility_mode': challenge.visibility_mode,
|
||||
'currency': user.company_id.currency_id.id,
|
||||
'lines': challenge_obj._get_serialized_challenge_lines(cr, uid, challenge, user_id, restrict_top=MAX_VISIBILITY_RANKING, context=context),
|
||||
})
|
||||
|
||||
return all_goals_info
|
||||
|
||||
def get_challenge_suggestions(self, cr, uid, context=None):
|
||||
"""Return the list of challenges suggested to the user"""
|
||||
challenge_info = []
|
||||
challenge_obj = self.pool.get('gamification.challenge')
|
||||
challenge_ids = challenge_obj.search(cr, uid, [('invited_user_ids', 'in', uid), ('state', '=', 'inprogress')], context=context)
|
||||
for challenge in challenge_obj.browse(cr, uid, challenge_ids, context=context):
|
||||
values = {
|
||||
'id': challenge.id,
|
||||
'name': challenge.name,
|
||||
'description': challenge.description,
|
||||
}
|
||||
challenge_info.append(values)
|
||||
return challenge_info
|
||||
|
||||
|
||||
class res_groups_gamification_group(osv.Model):
|
||||
""" Update of res.groups class
|
||||
- if adding users from a group, check gamification.challenge linked to
|
||||
this group, and the user. This is done by overriding the write method.
|
||||
"""
|
||||
_name = 'res.groups'
|
||||
_inherit = 'res.groups'
|
||||
|
||||
# No need to overwrite create as very unlikely to be the value in the autojoin_group_id field
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
"""Overwrite to autosubscribe users if add users to a group marked as autojoin, these will be added to the challenge"""
|
||||
write_res = super(res_groups_gamification_group, self).write(cr, uid, ids, vals, context=context)
|
||||
if vals.get('users'):
|
||||
# form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
|
||||
user_ids = [command[1] for command in vals['users'] if command[0] == 4]
|
||||
user_ids += [id for command in vals['users'] if command[0] == 6 for id in command[2]]
|
||||
|
||||
challenge_obj = self.pool.get('gamification.challenge')
|
||||
challenge_ids = challenge_obj.search(cr, uid, [('autojoin_group_id', 'in', ids)], context=context)
|
||||
if challenge_ids:
|
||||
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, user_id) for user_id in user_ids]}, context=context)
|
||||
return write_res
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" ?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<record model="ir.module.category" id="module_goal_category">
|
||||
<field name="name">Gamification</field>
|
||||
<field name="description"></field>
|
||||
<field name="sequence">17</field>
|
||||
</record>
|
||||
<record id="group_goal_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="category_id" ref="module_goal_category"/>
|
||||
<field name="users" eval="[(4, ref('base.user_root'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="goal_user_visibility" model="ir.rule">
|
||||
<field name="name">User can only see his/her goals or goal from the same challenge in board visibility</field>
|
||||
<field name="model_id" ref="model_gamification_goal"/>
|
||||
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
<field name="domain_force">[
|
||||
'|',
|
||||
('user_id','=',user.id),
|
||||
'&',
|
||||
('challenge_id.user_ids','in',user.id),
|
||||
('challenge_id.visibility_mode','=','ranking')]</field>
|
||||
</record>
|
||||
|
||||
<record id="goal_gamification_manager_visibility" model="ir.rule">
|
||||
<field name="name">Gamification Manager can see any goal</field>
|
||||
<field name="model_id" ref="model_gamification_goal"/>
|
||||
<field name="groups" eval="[(4, ref('group_goal_manager'))]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,19 @@
|
||||
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
|
||||
|
||||
goal_employee,"Goal Employee",model_gamification_goal,base.group_user,1,1,0,0
|
||||
goal_manager,"Goal Manager",model_gamification_goal,group_goal_manager,1,1,1,1
|
||||
|
||||
goal_definition_employee,"Goal Definition Employee",model_gamification_goal_definition,base.group_user,1,0,0,0
|
||||
goal_definition_manager,"Goal Definition Manager",model_gamification_goal_definition,group_goal_manager,1,1,1,1
|
||||
|
||||
challenge_employee,"Goal Challenge Employee",model_gamification_challenge,base.group_user,1,0,0,0
|
||||
challenge_manager,"Goal Challenge Manager",model_gamification_challenge,group_goal_manager,1,1,1,1
|
||||
|
||||
challenge_line_employee,"Challenge Line Employee",model_gamification_challenge_line,base.group_user,1,0,0,0
|
||||
challenge_line_manager,"Challenge Line Manager",model_gamification_challenge_line,group_goal_manager,1,1,1,1
|
||||
|
||||
badge_employee,"Badge Employee",model_gamification_badge,base.group_user,1,0,0,0
|
||||
badge_manager,"Badge Manager",model_gamification_badge,group_goal_manager,1,1,1,1
|
||||
|
||||
badge_user_employee,"Badge-user Employee",model_gamification_badge_user,base.group_user,1,1,1,0
|
||||
badge_user_manager,"Badge-user Manager",model_gamification_badge_user,group_goal_manager,1,1,1,1
|
||||
|
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,3 @@
|
||||
gamification.css: gamification.sass
|
||||
sass --trace -t expanded gamification.sass gamification.css
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
@charset "UTF-8";
|
||||
.openerp .oe_kanban_view .oe_kanban_card.oe_kanban_goal {
|
||||
width: 230px;
|
||||
min-height: 200px;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_card.oe_kanban_badge {
|
||||
width: 250px;
|
||||
min-height: 150px;
|
||||
}
|
||||
.openerp .oe_kanban_badge_avatars {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.openerp .oe_kanban_badge_avatars img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
padding-left: 0;
|
||||
margin-top: 3px;
|
||||
border-radius: 2px;
|
||||
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.openerp .oe_kanban_goal .oe_goal_state_block {
|
||||
width: 200px;
|
||||
height: 130px;
|
||||
margin: auto;
|
||||
margin-bottom: -20px;
|
||||
}
|
||||
.openerp .oe_kanban_goal .oe_goal_state_block .oe_goal_state {
|
||||
font-size: 2.5em;
|
||||
font-weight: bold;
|
||||
padding-top: 30px;
|
||||
}
|
||||
.openerp .oe_kanban_goal .oe_goal_state_block .oe_goal_state.oe_e {
|
||||
font-size: 7em;
|
||||
}
|
||||
.openerp .oe_kanban_goal .oe_goal_state_block, .openerp .oe_kanban_goal p {
|
||||
text-align: center;
|
||||
}
|
||||
.openerp .oe_kanban_content .oe_goal_gauge:first-child {
|
||||
margin: auto;
|
||||
}
|
||||
.openerp .oe_kanban_content .oe_goal_gauge svg {
|
||||
margin-top: -20px;
|
||||
}
|
||||
.openerp .oe_no_overflow {
|
||||
overflow: hidden;
|
||||
}
|
||||
.openerp .oe_red {
|
||||
color: red;
|
||||
}
|
||||
.openerp .oe_green {
|
||||
color: green;
|
||||
}
|
||||
.openerp .oe_orange {
|
||||
color: orange;
|
||||
}
|
||||
.openerp .oe_form td .oe_no_padding {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_mail_wall_aside {
|
||||
margin-top: 15px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 280px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_mail_wall_aside .oe_gamification_challenge_list {
|
||||
background-color: #ededf6;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_mail_wall_aside .oe_gamification_suggestion {
|
||||
background-color: #d3def1;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_mail_wall_aside .oe_gamification_suggestion ul {
|
||||
padding-left: 15px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_mail_wall_aside h4, .openerp .oe_mail_wall .oe_mail_wall_aside .oe_goals_list .oe_thead {
|
||||
text-align: center;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_mail_wall_aside > div {
|
||||
border-bottom: solid 5px white;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal {
|
||||
border-bottom: solid 3px white;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_update_challenge.oe_e, .openerp .oe_mail_wall .oe_goal .oe_goal_action.oe_e {
|
||||
visibility: hidden;
|
||||
font-size: 25px;
|
||||
float: right;
|
||||
position: relative;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal div:hover > .oe_update_challenge, .openerp .oe_mail_wall .oe_goal div:hover > .oe_goal_action, .openerp .oe_mail_wall .oe_goal th:hover > .oe_goal_action {
|
||||
visibility: visible;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list {
|
||||
padding-left: 0;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_no_progress div {
|
||||
display: inline-block;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_no_progress::before {
|
||||
content: "•";
|
||||
padding-right: 4px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_no_progress.oe_goal_reached::before {
|
||||
content: "✓";
|
||||
padding-right: 0;
|
||||
margin-left: -2px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_no_progress.oe_goal_reached .oe_cell {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_cell.oe_goal_current {
|
||||
font-size: 150%;
|
||||
font-weight: bold;
|
||||
min-width: 50px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_goal_outer_box {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
border: solid 1px rgba(0, 0, 0, 0.03);
|
||||
border-radius: 2px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_goal_outer_box.oe_no_progress {
|
||||
border: none;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_goal_progress_background {
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: -2;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_goal_progress {
|
||||
background-color: #d4e9de;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 0;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_thead {
|
||||
font-weight: normal;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_cell {
|
||||
padding: 3px 0;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_table.oe_goals_list .col0 {
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
width: 25px;
|
||||
text-align: center;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_table.oe_goals_list .col1 {
|
||||
padding: 0 5px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_table.oe_goals_list .col2 {
|
||||
width: auto;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_user_avatar {
|
||||
width: 24px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_mail {
|
||||
display: inline-block;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_table {
|
||||
display: table;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_row {
|
||||
display: table-row;
|
||||
}
|
||||
.openerp .oe_mail_wall .oe_cell {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
@charset "utf-8"
|
||||
|
||||
.openerp
|
||||
// Kanban views
|
||||
.oe_kanban_view
|
||||
.oe_kanban_card.oe_kanban_goal
|
||||
width: 230px
|
||||
min-height: 200px
|
||||
.oe_kanban_card.oe_kanban_badge
|
||||
width: 250px
|
||||
min-height: 150px
|
||||
.oe_kanban_badge_avatars
|
||||
margin-top: 8px
|
||||
img
|
||||
width: 30px
|
||||
height: 30px
|
||||
padding-left: 0
|
||||
margin-top: 3px
|
||||
border-radius: 2px
|
||||
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2)
|
||||
|
||||
.oe_kanban_goal
|
||||
.oe_goal_state_block
|
||||
width: 200px
|
||||
height: 130px
|
||||
margin: auto
|
||||
margin-bottom: -20px
|
||||
.oe_goal_state
|
||||
font-size: 2.5em
|
||||
font-weight: bold
|
||||
padding-top: 30px
|
||||
.oe_goal_state.oe_e
|
||||
font-size: 7em
|
||||
.oe_goal_state_block,p
|
||||
text-align: center
|
||||
|
||||
.oe_kanban_content
|
||||
.oe_goal_gauge:first-child
|
||||
margin: auto /* avoid margin-right: 16px */
|
||||
.oe_goal_gauge
|
||||
svg
|
||||
margin-top: -20px
|
||||
.oe_no_overflow
|
||||
overflow: hidden
|
||||
|
||||
|
||||
.oe_red
|
||||
color: red
|
||||
.oe_green
|
||||
color: green
|
||||
.oe_orange
|
||||
color: orange
|
||||
|
||||
|
||||
// compensate padding from .openerp .oe_form td.oe_form_group_cell + .oe_form_group_cell
|
||||
.oe_form td .oe_no_padding
|
||||
margin-left: -6px
|
||||
|
||||
|
||||
.oe_mail_wall
|
||||
.oe_mail_wall_aside
|
||||
margin-top: 15px
|
||||
position: relative
|
||||
display: inline-block
|
||||
vertical-align: top
|
||||
width: 280px
|
||||
border-radius: 2px
|
||||
|
||||
.oe_gamification_challenge_list
|
||||
background-color: #EDEDF6
|
||||
.oe_gamification_suggestion
|
||||
background-color: rgb(211, 222, 241)
|
||||
ul
|
||||
padding-left: 15px
|
||||
|
||||
h4, .oe_goals_list .oe_thead
|
||||
text-align: center
|
||||
padding-bottom: 15px
|
||||
|
||||
.oe_mail_wall_aside > div
|
||||
border-bottom: solid 5px white
|
||||
border-radius: 2px
|
||||
|
||||
.oe_goal
|
||||
border-bottom: solid 3px white
|
||||
padding: 5px 10px
|
||||
.oe_update_challenge.oe_e, .oe_goal_action.oe_e
|
||||
visibility: hidden
|
||||
font-size: 25px
|
||||
float: right
|
||||
position: relative
|
||||
div:hover > .oe_update_challenge, div:hover > .oe_goal_action, th:hover > .oe_goal_action
|
||||
visibility: visible
|
||||
|
||||
.oe_goals_list
|
||||
padding-left: 0
|
||||
margin-top: 5px
|
||||
margin-bottom: 10px
|
||||
width: 100%
|
||||
|
||||
.oe_no_progress
|
||||
div
|
||||
display: inline-block
|
||||
.oe_no_progress::before
|
||||
content: "•"
|
||||
padding-right: 4px
|
||||
.oe_no_progress.oe_goal_reached::before
|
||||
content: "✓"
|
||||
padding-right: 0
|
||||
margin-left: -2px
|
||||
.oe_no_progress.oe_goal_reached
|
||||
.oe_cell
|
||||
text-decoration: line-through
|
||||
|
||||
.oe_cell.oe_goal_current
|
||||
font-size: 150%
|
||||
font-weight: bold
|
||||
min-width: 50px
|
||||
padding: 0 5px
|
||||
|
||||
.oe_goal_outer_box
|
||||
display: inline-block
|
||||
position: relative
|
||||
z-index: 0
|
||||
vertical-align: middle
|
||||
width: 100%
|
||||
border: solid 1px rgba(0,0,0,0.03)
|
||||
border-radius: 2px
|
||||
.oe_goal_outer_box.oe_no_progress
|
||||
border: none
|
||||
|
||||
.oe_goal_progress_background
|
||||
background-color: white
|
||||
position: absolute
|
||||
height: 100%
|
||||
width: 100%
|
||||
z-index: -2
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
.oe_goal_progress
|
||||
background-color: rgb(212, 233, 222)
|
||||
position: absolute
|
||||
height: 100%
|
||||
width: 0
|
||||
z-index: -1
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
.oe_thead
|
||||
font-weight: normal
|
||||
padding: 5px
|
||||
text-align: center
|
||||
.oe_cell
|
||||
padding: 3px 0
|
||||
|
||||
.oe_table.oe_goals_list
|
||||
.col0
|
||||
font-size: 200%
|
||||
font-weight: bold
|
||||
width: 25px
|
||||
text-align: center
|
||||
.col1
|
||||
padding: 0 5px
|
||||
.col2
|
||||
width: auto
|
||||
|
||||
.oe_user_avatar
|
||||
width: 24px
|
||||
padding-right: 5px
|
||||
|
||||
.oe_mail
|
||||
display: inline-block
|
||||
|
||||
.oe_table
|
||||
display: table
|
||||
.oe_row
|
||||
display: table-row
|
||||
.oe_cell
|
||||
display: table-cell
|
||||
vertical-align: middle
|
||||
@@ -0,0 +1,148 @@
|
||||
openerp.gamification = function(instance) {
|
||||
var QWeb = instance.web.qweb;
|
||||
|
||||
instance.gamification.Sidebar = instance.web.Widget.extend({
|
||||
template: 'gamification.UserWallSidebar',
|
||||
init: function (parent, action) {
|
||||
var self = this;
|
||||
this._super(parent, action);
|
||||
this.deferred = $.Deferred();
|
||||
this.goals_info = {};
|
||||
this.challenge_suggestions = {};
|
||||
$(document).off('keydown.klistener');
|
||||
},
|
||||
events: {
|
||||
// update a challenge and related goals
|
||||
'click a.oe_update_challenge': function(event) {
|
||||
var self = this;
|
||||
var challenge_id = parseInt(event.currentTarget.id, 10);
|
||||
var goals_updated = new instance.web.Model('gamification.challenge').call('quick_update', [challenge_id]);
|
||||
$.when(goals_updated).done(function() {
|
||||
self.get_goal_todo_info();
|
||||
});
|
||||
},
|
||||
// action to modify a goal
|
||||
'click a.oe_goal_action': function(event) {
|
||||
var self = this;
|
||||
var goal_id = parseInt(event.currentTarget.id, 10);
|
||||
var goal_action = new instance.web.Model('gamification.goal').call('get_action', [goal_id]).then(function(res) {
|
||||
goal_action['action'] = res;
|
||||
});
|
||||
$.when(goal_action).done(function() {
|
||||
var action = self.do_action(goal_action.action);
|
||||
$.when(action).done(function () {
|
||||
new instance.web.Model('gamification.goal').call('update', [[goal_id]]).then(function(res) {
|
||||
self.get_goal_todo_info();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
// get more info about a challenge request
|
||||
'click a.oe_challenge_reply': function(event) {
|
||||
var self = this;
|
||||
var challenge_id = parseInt(event.currentTarget.id, 10);
|
||||
var challenge_action = new instance.web.Model('gamification.challenge').call('reply_challenge_wizard', [challenge_id]).then(function(res) {
|
||||
challenge_action['action'] = res;
|
||||
});
|
||||
$.when(challenge_action).done(function() {
|
||||
self.do_action(challenge_action.action).done(function () {
|
||||
self.get_goal_todo_info();
|
||||
});
|
||||
});
|
||||
},
|
||||
'click .oe_goal h4': function(event) {
|
||||
var self = this;
|
||||
this.kkeys = [];
|
||||
$(document).on('keydown.klistener', function(event) {
|
||||
if ("37,38,39,40,65,66".indexOf(event.keyCode) < 0) {
|
||||
$(document).off('keydown.klistener');
|
||||
} else {
|
||||
self.kkeys.push(event.keyCode);
|
||||
if (self.kkeys.toString().indexOf("38,38,40,40,37,39,37,39,66,65") >= 0) {
|
||||
new instance.web.Model('gamification.badge').call('check_progress', []);
|
||||
$(document).off('keydown.klistener');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
self.get_goal_todo_info();
|
||||
self.get_challenge_suggestions();
|
||||
},
|
||||
get_goal_todo_info: function() {
|
||||
var self = this;
|
||||
var challenges = new instance.web.Model('res.users').call('get_serialised_gamification_summary', []).then(function(result) {
|
||||
if (result.length === 0) {
|
||||
self.$el.find(".oe_gamification_challenge_list").hide();
|
||||
} else {
|
||||
self.$el.find(".oe_gamification_challenge_list").empty();
|
||||
_.each(result, function(item){
|
||||
var $item = $(QWeb.render("gamification.ChallengeSummary", {challenge: item}));
|
||||
self.render_money_fields($item);
|
||||
self.render_user_avatars($item);
|
||||
self.$el.find('.oe_gamification_challenge_list').append($item);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
get_challenge_suggestions: function() {
|
||||
var self = this;
|
||||
var challenge_suggestions = new instance.web.Model('res.users').call('get_challenge_suggestions', []).then(function(result) {
|
||||
if (result.length === 0) {
|
||||
self.$el.find(".oe_gamification_suggestion").hide();
|
||||
} else {
|
||||
var $item = $(QWeb.render("gamification.ChallengeSuggestion", {challenges: result}));
|
||||
self.$el.find('.oe_gamification_suggestion').append($item);
|
||||
}
|
||||
});
|
||||
},
|
||||
render_money_fields: function(item) {
|
||||
var self = this;
|
||||
self.dfm = new instance.web.form.DefaultFieldManager(self);
|
||||
// Generate a FieldMonetary for each .oe_goal_field_monetary
|
||||
item.find(".oe_goal_field_monetary").each(function() {
|
||||
var currency_id = parseInt( $(this).attr('data-id'), 10);
|
||||
money_field = new instance.web.form.FieldMonetary(self.dfm, {
|
||||
attrs: {
|
||||
modifiers: '{"readonly": true}'
|
||||
}
|
||||
});
|
||||
money_field.set('currency', currency_id);
|
||||
money_field.get_currency_info();
|
||||
money_field.set('value', parseInt($(this).text(), 10));
|
||||
money_field.replace($(this));
|
||||
});
|
||||
},
|
||||
render_user_avatars: function(item) {
|
||||
var self = this;
|
||||
item.find(".oe_user_avatar").each(function() {
|
||||
var user_id = parseInt( $(this).attr('data-id'), 10);
|
||||
var url = instance.session.url('/web/binary/image', {model: 'res.users', field: 'image_small', id: user_id});
|
||||
$(this).attr("src", url);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
instance.mail.Widget.include({
|
||||
start: function() {
|
||||
this._super();
|
||||
var sidebar = new instance.gamification.Sidebar(this);
|
||||
sidebar.appendTo($('.oe_mail_wall_aside'));
|
||||
},
|
||||
});
|
||||
|
||||
instance.web_kanban.KanbanRecord.include({
|
||||
// open related goals when clicking on challenge kanban view
|
||||
on_card_clicked: function() {
|
||||
if (this.view.dataset.model === 'gamification.challenge') {
|
||||
this.$('.oe_kanban_project_list a').first().click();
|
||||
} else {
|
||||
this._super.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
<templates>
|
||||
<t t-name="gamification.UserWallSidebar" class="oe_gamification_user_wall_sidebar">
|
||||
<div>
|
||||
<div class="oe_gamification_suggestion"></div>
|
||||
<div class="oe_gamification_challenge_list"></div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="gamification.ChallengeSummary">
|
||||
<div class="oe_goal">
|
||||
<div>
|
||||
<a class="oe_update_challenge oe_e" rol="button" t-attf-id="{challenge.id}">e</a>
|
||||
<h4><t t-esc="challenge.name" /></h4>
|
||||
</div>
|
||||
|
||||
<t t-if="challenge.visibility_mode == 'personal'">
|
||||
<div class="oe_table oe_goals_list">
|
||||
<div t-foreach="challenge.lines" t-as="line" t-attf-class="oe_row oe_goal_outer_box #{line.state == 'reached' ? 'oe_goal_reached' : ''} #{line.display_mode != 'progress' ? 'oe_no_progress' : ''}">
|
||||
<t t-if="line.display_mode == 'progress'">
|
||||
<div class="oe_goal_progress_background"></div>
|
||||
<div class="oe_goal_progress" t-attf-style="#{line.display_mode == 'progress' ? 'width: '+line.completeness+'%;' : 'width:0;'}"></div>
|
||||
<div class="oe_cell oe_goal_current"><t t-esc="line.current" /></div>
|
||||
</t>
|
||||
<div class="oe_cell">
|
||||
<t t-if="line.computation_mode != 'manually' and !line.action">
|
||||
<span t-att-title="line.description"><t t-esc="line.name" /></span>
|
||||
</t>
|
||||
<t t-if="line.action or line.computation_mode == 'manually'">
|
||||
<span t-att-title="line.description"><a class="oe_goal_action" t-att-id="line.id"><t t-esc="line.name" /></a></span>
|
||||
</t>
|
||||
<t t-if="line.display_mode == 'progress'"><br/>
|
||||
<div class="oe_grey">
|
||||
<t t-if="line.definition_condition == 'higher'">
|
||||
Target:
|
||||
</t>
|
||||
<t t-if="line.definition_condition == 'lower'">
|
||||
Target: <=
|
||||
</t>
|
||||
<span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="line.target"/></span>
|
||||
<t t-if="line.suffix"><t t-esc="line.suffix"/></t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-if="challenge.visibility_mode == 'ranking'">
|
||||
<div t-foreach="challenge.lines" t-as="line" class="oe_goals_list oe_table">
|
||||
<div class="oe_row">
|
||||
<div class="oe_cell oe_thead" colspan="3" t-attf-title="#{line.description ? line.description : ''}">
|
||||
<strong><t t-esc="line.name"/></strong>
|
||||
<br/>
|
||||
<div class="oe_grey">
|
||||
<t t-if="line.definition_condition == 'higher'">
|
||||
Target:
|
||||
</t>
|
||||
<t t-if="line.definition_condition == 'lower'">
|
||||
Target: <=
|
||||
</t>
|
||||
<span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="line.target" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div t-foreach="line.goals" t-as="goal" t-attf-class="#{goal.id == line.own_goal_id ? 'oe_bold' : ''}">
|
||||
<div t-attf-class="oe_row oe_goal_outer_box #{goal.state == 'reached' ? 'oe_goal_reached' : ''} #{line.display_mode != 'progress' ? 'oe_no_progress' : ''}">
|
||||
<t t-if="line.display_mode == 'progress'">
|
||||
<div class="oe_goal_progress_background"></div>
|
||||
<div class="oe_goal_progress" t-attf-style="#{line.display_mode == 'progress' ? 'width: '+goal.completeness+'%;' : 'width:0;'}"></div>
|
||||
</t>
|
||||
|
||||
<div class="oe_cell col0"><t t-esc="goal.rank" /></div>
|
||||
<div class="oe_cell col1"><img class="oe_user_avatar" t-attf-alt="#{goal.name}" t-attf-data-id="#{goal.user_id}"/></div>
|
||||
<div class="oe_cell col2">
|
||||
<t t-if="line.display_mode == 'progress'">
|
||||
<!-- progress, action on current value -->
|
||||
<t t-esc="goal.name"/><br/>
|
||||
<t t-if="goal.id != line.own_goal_id or (line.computation_mode != 'manually' and !line.action)">
|
||||
<span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="goal.current" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t>
|
||||
</t>
|
||||
<t t-if="goal.id == line.own_goal_id and (line.action or line.computation_mode == 'manually')">
|
||||
<a class="oe_goal_action" t-att-id="line.own_goal_id">
|
||||
<span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="goal.current" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t>
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="line.display_mode != 'progress'">
|
||||
<!-- not progress, action on user name -->
|
||||
<t t-if="goal.id != line.own_goal_id or (line.computation_mode != 'manually' and !line.action)">
|
||||
<t t-esc="goal.name"/>
|
||||
</t>
|
||||
<t t-if="goal.id == line.own_goal_id and (line.action or line.computation_mode == 'manually')">
|
||||
<a class="oe_goal_action" t-att-id="line.own_goal_id"><t t-esc="goal.name"/></a>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="gamification.ChallengeSuggestion">
|
||||
<div class="oe_goal">
|
||||
<h4>Invited Challenges</h4>
|
||||
<ul t-foreach="challenges" t-as="challenge" class="oe_goals_list">
|
||||
<li>
|
||||
<strong><a class="oe_challenge_reply" t-attf-title="#{challenge.description.value ? challenge.description.value : ''}" t-attf-id="{challenge.id}" title="more details..."><t t-esc="challenge.name"/></a></strong>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013 OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import test_challenge
|
||||
|
||||
checks = [
|
||||
test_challenge,
|
||||
]
|
||||
@@ -0,0 +1,89 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013 OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.tests import common
|
||||
|
||||
|
||||
class test_challenge(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(test_challenge, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
self.data_obj = self.registry('ir.model.data')
|
||||
self.user_obj = self.registry('res.users')
|
||||
|
||||
self.challenge_obj = self.registry('gamification.challenge')
|
||||
self.line_obj = self.registry('gamification.challenge.line')
|
||||
self.goal_obj = self.registry('gamification.goal')
|
||||
self.badge_obj = self.registry('gamification.badge')
|
||||
self.badge_user_obj = self.registry('gamification.badge.user')
|
||||
|
||||
self.demo_user_id = self.data_obj.get_object_reference(cr, uid, 'base', 'user_demo')[1]
|
||||
self.group_user_id = self.data_obj.get_object_reference(cr, uid, 'base', 'group_user')[1]
|
||||
self.challenge_base_id = self.data_obj.get_object_reference(cr, uid, 'gamification', 'challenge_base_discover')[1]
|
||||
self.definition_timezone_id = self.data_obj.get_object_reference(cr, uid, 'gamification', 'definition_base_timezone')[1]
|
||||
self.badge_id = self.data_obj.get_object_reference(cr, uid, 'gamification', 'badge_good_job')[1]
|
||||
|
||||
def test_00_join_challenge(self):
|
||||
cr, uid, context = self.cr, self.uid, {}
|
||||
|
||||
user_ids = self.user_obj.search(cr, uid, [('groups_id', '=', self.group_user_id)])
|
||||
challenge = self.challenge_obj.browse(cr, uid, self.challenge_base_id, context=context)
|
||||
|
||||
self.assertGreaterEqual(len(challenge.user_ids), len(user_ids), "Not enough users in base challenge")
|
||||
|
||||
self.user_obj.create(cr, uid, {
|
||||
'name': 'R2D2',
|
||||
'login': 'r2d2@openerp.com',
|
||||
'email': 'r2d2@openerp.com',
|
||||
'groups_id': [(6, 0, [self.group_user_id])]
|
||||
}, {'no_reset_password': True})
|
||||
|
||||
challenge = self.challenge_obj.browse(cr, uid, self.challenge_base_id, context=context)
|
||||
self.assertGreaterEqual(len(challenge.user_ids), len(user_ids)+1, "These are not droids you are looking for")
|
||||
|
||||
def test_10_reach_challenge(self):
|
||||
cr, uid, context = self.cr, self.uid, {}
|
||||
|
||||
self.challenge_obj.write(cr, uid, [self.challenge_base_id], {'state': 'inprogress'}, context=context)
|
||||
challenge = self.challenge_obj.browse(cr, uid, self.challenge_base_id, context=context)
|
||||
challenge_user_ids = [user.id for user in challenge.user_ids]
|
||||
|
||||
self.assertEqual(challenge.state, 'inprogress', "Challenge failed the change of state")
|
||||
|
||||
line_ids = self.line_obj.search(cr, uid, [('challenge_id', '=', self.challenge_base_id)], context=context)
|
||||
goal_ids = self.goal_obj.search(cr, uid, [('challenge_id', '=', self.challenge_base_id), ('state', '!=', 'draft')], context=context)
|
||||
self.assertEqual(len(goal_ids), len(line_ids)*len(challenge_user_ids), "Incorrect number of goals generated, should be 1 goal per user, per challenge line")
|
||||
|
||||
# demo user will set a timezone
|
||||
self.user_obj.write(cr, uid, self.demo_user_id, {'tz': "Europe/Brussels"}, context=context)
|
||||
goal_ids = self.goal_obj.search(cr, uid, [('user_id', '=', self.demo_user_id), ('definition_id', '=', self.definition_timezone_id)], context=context)
|
||||
|
||||
self.goal_obj.update(cr, uid, goal_ids, context=context)
|
||||
reached_goal_ids = self.goal_obj.search(cr, uid, [('id', 'in', goal_ids), ('state', '=', 'reached')], context=context)
|
||||
self.assertEqual(set(goal_ids), set(reached_goal_ids), "Not every goal was reached after changing timezone")
|
||||
|
||||
# reward for two firsts as admin may have timezone
|
||||
self.challenge_obj.write(cr, uid, self.challenge_base_id, {'reward_first_id': self.badge_id, 'reward_second_id': self.badge_id}, context=context)
|
||||
self.challenge_obj.write(cr, uid, self.challenge_base_id, {'state': 'done'}, context=context)
|
||||
|
||||
badge_ids = self.badge_user_obj.search(cr, uid, [('badge_id', '=', self.badge_id), ('user_id', '=', self.demo_user_id)])
|
||||
self.assertGreater(len(badge_ids), 0, "Demo user has not received the badge")
|
||||
@@ -0,0 +1,194 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Badge views -->
|
||||
<record id="badge_list_action" model="ir.actions.act_window">
|
||||
<field name="name">Badges</field>
|
||||
<field name="res_model">gamification.badge</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a badge.
|
||||
</p>
|
||||
<p>
|
||||
A badge is a symbolic token granted to a user as a sign of reward.
|
||||
It can be deserved automatically when some conditions are met or manually by users.
|
||||
Some badges are harder than others to get with specific conditions.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="badge_list_view" model="ir.ui.view">
|
||||
<field name="name">Badge List</field>
|
||||
<field name="model">gamification.badge</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Badge List">
|
||||
<field name="name"/>
|
||||
<field name="stat_count"/>
|
||||
<field name="stat_this_month"/>
|
||||
<field name="stat_my"/>
|
||||
<field name="rule_auth"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="badge_form_view" model="ir.ui.view">
|
||||
<field name="name">Badge Form</field>
|
||||
<field name="model">gamification.badge</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Badge" version="7.0">
|
||||
<header>
|
||||
<button string="Grant this Badge" type="action" name="%(action_grant_wizard)d" class="oe_highlight" attrs="{'invisible': [('remaining_sending','=',0)]}" />
|
||||
<button string="Check Badge" type="object" name="check_automatic" groups="base.group_no_one" />
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
</div>
|
||||
<field name="image" widget='image' class="oe_left oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<field name="description" nolabel="1" placeholder="Badge Description" />
|
||||
</group>
|
||||
<group string="Granting">
|
||||
<div class="oe_grey" colspan="4">
|
||||
Security rules to define who is allowed to manually grant badges. Not enforced for administrator.
|
||||
</div>
|
||||
<field name="rule_auth" widget="radio" />
|
||||
<field name="rule_auth_user_ids" attrs="{'invisible': [('rule_auth','!=','users')]}" widget="many2many_tags" />
|
||||
<field name="rule_auth_badge_ids" attrs="{'invisible': [('rule_auth','!=','having')]}" widget="many2many_tags" />
|
||||
<field name="rule_max" attrs="{'invisible': [('rule_auth','=','nobody')]}" />
|
||||
<field name="rule_max_number" attrs="{'invisible': ['|',('rule_max','=',False),('rule_auth','=','nobody')]}"/>
|
||||
<label for="stat_my_monthly_sending"/>
|
||||
<div>
|
||||
<field name="stat_my_monthly_sending" attrs="{'invisible': [('rule_auth','=','nobody')]}" />
|
||||
<div attrs="{'invisible': [('remaining_sending','=',-1)]}" class="oe_grey">
|
||||
You can still grant <field name="remaining_sending" class="oe_inline"/> badges this month
|
||||
</div>
|
||||
<div attrs="{'invisible': [('remaining_sending','!=',-1)]}" class="oe_grey">
|
||||
No monthly sending limit
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<group string="Rewards for challenges">
|
||||
<field name="challenge_ids" widget="many2many_kanban" nolabel="1" />
|
||||
</group>
|
||||
<group string="Statistics">
|
||||
<group>
|
||||
<field name="stat_count"/>
|
||||
<field name="stat_this_month"/>
|
||||
<field name="stat_count_distinct"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="stat_my"/>
|
||||
<field name="stat_my_this_month"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="badge_kanban_view" model="ir.ui.view" >
|
||||
<field name="name">Badge Kanban View</field>
|
||||
<field name="model">gamification.badge</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban version="7.0" class="oe_background_grey">
|
||||
<field name="name"/>
|
||||
<field name="description"/>
|
||||
<field name="image"/>
|
||||
<field name="stat_my"/>
|
||||
<field name="stat_count"/>
|
||||
<field name="stat_this_month"/>
|
||||
<field name="unique_owner_ids"/>
|
||||
<field name="stat_my_monthly_sending"/>
|
||||
<field name="remaining_sending" />
|
||||
<field name="rule_max_number" />
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="#{record.stat_my.raw_value ? 'oe_kanban_color_5' : 'oe_kanban_color_white'} oe_kanban_card oe_kanban_global_click oe_kanban_badge">
|
||||
<div class="oe_kanban_content">
|
||||
<div class="oe_kanban_left">
|
||||
<a type="open"><img t-att-src="kanban_image('gamification.badge', 'image', record.image.raw_value)" t-att-title="record.name.value" width="90" height="90" /></a>
|
||||
</div>
|
||||
<div class="oe_no_overflow">
|
||||
<h4><field name="name"/></h4>
|
||||
<t t-if="record.remaining_sending.value != 0">
|
||||
<button type="action" name="%(action_grant_wizard)d" class="oe_highlight">Grant</button>
|
||||
<span class="oe_grey">
|
||||
<t t-if="record.remaining_sending.value != -1">
|
||||
<t t-esc="record.stat_my_monthly_sending.value"/>/<t t-esc="record.rule_max_number.value"/>
|
||||
</t>
|
||||
<t t-if="record.remaining_sending.value == -1">
|
||||
<t t-esc="record.stat_my_monthly_sending.value"/>/∞
|
||||
</t>
|
||||
</span>
|
||||
</t>
|
||||
<t t-if="record.remaining_sending.value == 0">
|
||||
<div class="oe_grey">Can not grant</div>
|
||||
</t>
|
||||
<p>
|
||||
<strong><t t-esc="record.stat_count.raw_value"/></strong> granted,<br/>
|
||||
<strong><t t-esc="record.stat_this_month.raw_value"/></strong> this month
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_kanban_badge_avatars">
|
||||
<t t-if="record.description.value">
|
||||
<p><em><field name="description"/></em></p>
|
||||
</t>
|
||||
<a type="object" name="get_granted_employees">
|
||||
<t t-foreach="record.unique_owner_ids.raw_value.slice(0,11)" t-as="owner">
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', owner)" t-att-data-member_id="owner"/>
|
||||
</t>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Badge user viewss -->
|
||||
|
||||
<record id="badge_user_kanban_view" model="ir.ui.view" >
|
||||
<field name="name">Badge User Kanban View</field>
|
||||
<field name="model">gamification.badge.user</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban version="7.0" class="oe_background_grey">
|
||||
<field name="badge_name"/>
|
||||
<field name="badge_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="comment"/>
|
||||
<field name="create_date"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_card oe_kanban_global_click oe_kanban_badge oe_kanban_color_white">
|
||||
<div class="oe_kanban_content">
|
||||
<div class="oe_kanban_left">
|
||||
<a type="open"><img t-att-src="kanban_image('gamification.badge', 'image', record.badge_id.raw_value)" t-att-title="record.badge_name.value" width="24" height="24" /></a>
|
||||
</div>
|
||||
<h4>
|
||||
<a type="open"><t t-esc="record.badge_name.raw_value" /></a>
|
||||
</h4>
|
||||
<t t-if="record.comment.raw_value">
|
||||
<p><em><field name="comment"/></em></p>
|
||||
</t>
|
||||
<p>Granted by <a type="open"><field name="create_uid" /></a> the <t t-esc="record.create_date.raw_value.toString(Date.CultureInfo.formatPatterns.shortDate)" /></p>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,289 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="challenge_list_view" model="ir.ui.view">
|
||||
<field name="name">Challenges List</field>
|
||||
<field name="model">gamification.challenge</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Goal definitions" colors="blue:state == 'draft';grey:state == 'done'">
|
||||
<field name="name"/>
|
||||
<field name="period"/>
|
||||
<field name="manager_id"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="goals_from_challenge_act" model="ir.actions.act_window">
|
||||
<field name="res_model">gamification.goal</field>
|
||||
<field name="name">Related Goals</field>
|
||||
<field name="view_mode">kanban,tree</field>
|
||||
<field name="context">{'search_default_group_by_definition': True, 'search_default_inprogress': True, 'search_default_challenge_id': active_id, 'default_challenge_id': active_id}</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
There is no goals associated to this challenge matching your search.
|
||||
Make sure that your challenge is active and assigned to at least one user.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="challenge_form_view" model="ir.ui.view">
|
||||
<field name="name">Challenge Form</field>
|
||||
<field name="model">gamification.challenge</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Goal definitions" version="7.0">
|
||||
<header>
|
||||
<button string="Refresh Challenge" type="object" name="action_check" states="inprogress"/>
|
||||
<button string="Send Report" type="object" name="action_report_progress" states="inprogress,done" groups="base.group_no_one"/>
|
||||
<field name="state" widget="statusbar" clickable="True"/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="name" placeholder="e.g. Monthly Sales Objectives"/>
|
||||
</h1>
|
||||
<label for="user_ids" class="oe_edit_only" string="Assign Challenge To"/>
|
||||
<div>
|
||||
<field name="user_ids" widget="many2many_tags" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- action buttons -->
|
||||
<div class="oe_right oe_button_box">
|
||||
<button type="action" name="%(goals_from_challenge_act)d" string="Related Goals" attrs="{'invisible': [('state','=','draft')]}" />
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="period" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="visibility_mode" widget="radio" colspan="1" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="manager_id"/>
|
||||
<field name="start_date" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="end_date" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Goals">
|
||||
<field name="line_ids" nolabel="1" colspan="4">
|
||||
<tree string="Line List" version="7.0" editable="bottom" >
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="definition_id" on_change="on_change_definition_id(definition_id)" />
|
||||
<field name="condition"/>
|
||||
<field name="target_goal"/>
|
||||
<field name="definition_full_suffix"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="description" placeholder="Describe the challenge: what is does, who it targets, why it matters..."/>
|
||||
</page>
|
||||
<page string="Reward">
|
||||
<group>
|
||||
<field name="reward_id"/>
|
||||
<field name="reward_first_id" />
|
||||
<field name="reward_second_id" attrs="{'invisible': [('reward_first_id','=', False)]}" />
|
||||
<field name="reward_third_id" attrs="{'invisible': ['|',('reward_first_id','=', False),('reward_second_id','=', False)]}" />
|
||||
<field name="reward_failure" attrs="{'invisible': [('reward_first_id','=', False)]}" />
|
||||
</group>
|
||||
<div class="oe_grey">
|
||||
<p>Badges are granted when a challenge is finished. This is either at the end of a running period (eg: end of the month for a monthly challenge), at the end date of a challenge (if no periodicity is set) or when the challenge is manually closed.</p>
|
||||
</div>
|
||||
</page>
|
||||
<page string="Advanced Options">
|
||||
<group string="Subscriptions">
|
||||
<field name="autojoin_group_id" />
|
||||
<field name="invited_user_ids" widget="many2many_tags" />
|
||||
</group>
|
||||
<group string="Notification Messages">
|
||||
<div class="oe_grey" colspan="4">
|
||||
<p>Depending on the Display mode, reports will be individual or shared.</p>
|
||||
</div>
|
||||
<field name="report_message_frequency" />
|
||||
<field name="report_template_id" attrs="{'invisible': [('report_message_frequency','=','never')]}" />
|
||||
<field name="report_message_group_id" attrs="{'invisible': [('report_message_frequency','=','never')]}" />
|
||||
</group>
|
||||
<group string="Reminders for Manual Goals">
|
||||
<label for="remind_update_delay" />
|
||||
<div>
|
||||
<field name="remind_update_delay" class="oe_inline"/> days
|
||||
</div>
|
||||
</group>
|
||||
<group string="Category" groups="base.group_no_one">
|
||||
<field name="category" widget="radio" />
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_challenge_kanban">
|
||||
<field name="name">Challenge Kanban</field>
|
||||
<field name="model">gamification.challenge</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban string="Challenges" class="oe_background_grey" version="7.0">
|
||||
<field name="line_ids"/>
|
||||
<field name="user_ids"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_card oe_kanban_goal oe_kanban_global_click">
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<span class="oe_e">í</span>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<li><a type="edit">Configure Challenge</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="oe_kanban_content">
|
||||
|
||||
<h4><field name="name"/></h4>
|
||||
<div class="oe_kanban_project_list">
|
||||
<a type="action" name="%(goals_from_challenge_act)d" style="margin-right: 10px">
|
||||
<span t-if="record.line_ids.raw_value.length gt 1"><t t-esc="record.line_ids.raw_value.length"/> Goals</span>
|
||||
<span t-if="record.line_ids.raw_value.length lt 2"><t t-esc="record.line_ids.raw_value.length"/> Goal</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="oe_kanban_badge_avatars">
|
||||
<t t-foreach="record.user_ids.raw_value.slice(0,11)" t-as="member">
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', member)" t-att-data-member_id="member"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="challenge_list_action" model="ir.actions.act_window">
|
||||
<field name="name">Challenges</field>
|
||||
<field name="res_model">gamification.challenge</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="context">{'search_default_inprogress':True, 'default_inprogress':True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a challenge.
|
||||
</p>
|
||||
<p>
|
||||
Assign a list of goals to chosen users to evaluate them.
|
||||
The challenge can use a period (weekly, monthly...) for automatic creation of goals.
|
||||
The goals are created for the specified users or member of the group.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<!-- Specify form view ID to avoid selecting view_challenge_wizard -->
|
||||
<record id="challenge_list_action_view1" model="ir.actions.act_window.view">
|
||||
<field eval="1" name="sequence"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="act_window_id" ref="challenge_list_action"/>
|
||||
<field name="view_id" ref="view_challenge_kanban"/>
|
||||
</record>
|
||||
<record id="challenge_list_action_view2" model="ir.actions.act_window.view">
|
||||
<field eval="10" name="sequence"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="act_window_id" ref="challenge_list_action"/>
|
||||
<field name="view_id" ref="challenge_form_view"/>
|
||||
</record>
|
||||
|
||||
<!-- Line -->
|
||||
<record id="challenge_line_list_view" model="ir.ui.view">
|
||||
<field name="name">Challenge line list</field>
|
||||
<field name="model">gamification.challenge.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Challenge Lines" >
|
||||
<field name="definition_id"/>
|
||||
<field name="target_goal"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="challenge_search_view" model="ir.ui.view">
|
||||
<field name="name">Challenge Search</field>
|
||||
<field name="model">gamification.challenge</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Challenges">
|
||||
<filter name="inprogress" string="Running Challenges"
|
||||
domain="[('state', '=', 'inprogress')]"/>
|
||||
<filter name="hr_challenges" string="HR Challenges"
|
||||
domain="[('category', '=', 'hr')]"/>
|
||||
<field name="name"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="State" domain="[]" context="{'group_by':'state'}"/>
|
||||
<filter string="Period" domain="[]" context="{'group_by':'period'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="view_challenge_wizard" model="ir.ui.view">
|
||||
<field name="name">Challenge Wizard</field>
|
||||
<field name="model">gamification.challenge</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Challenge" version="7.0">
|
||||
<field name="reward_failure" invisible="1"/>
|
||||
<div class="oe_title">
|
||||
<h1><field name="name" nolabel="1" readonly="1"/></h1>
|
||||
</div>
|
||||
<field name="description" nolabel="1" readonly="1" />
|
||||
<group>
|
||||
<field name="start_date" readonly="1" />
|
||||
<field name="end_date" readonly="1" />
|
||||
<field name="user_ids" string="Participating" readonly="1" widget="many2many_tags" />
|
||||
<field name="invited_user_ids" string="Invited" readonly="1" widget="many2many_tags" />
|
||||
</group>
|
||||
<group string="Goals">
|
||||
<field name="line_ids" nolabel="1" readonly="1" colspan="4">
|
||||
<tree string="Challenge Lines" version="7.0" editable="bottom" >
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="definition_id"/>
|
||||
<field name="condition"/>
|
||||
<field name="target_goal"/>
|
||||
<field name="definition_full_suffix"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group string="Reward">
|
||||
<div class="oe_grey" attrs="{'invisible': ['|',('reward_id','!=',False),('reward_first_id','!=',False)]}">
|
||||
There is no reward upon completion of this challenge.
|
||||
</div>
|
||||
<group attrs="{'invisible': [('reward_id','=',False),('reward_first_id','=',False)]}">
|
||||
<field name="reward_id" readonly="1" attrs="{'invisible': [('reward_first_id','=', False)]}" />
|
||||
<field name="reward_first_id" readonly="1" attrs="{'invisible': [('reward_first_id','=', False)]}" />
|
||||
<field name="reward_second_id" readonly="1" attrs="{'invisible': [('reward_second_id','=', False)]}" />
|
||||
<field name="reward_third_id" readonly="1" attrs="{'invisible': [('reward_third_id','=', False)]}" />
|
||||
</group>
|
||||
<div class="oe_grey" attrs="{'invisible': [('reward_failure','=',False)]}">
|
||||
Even if the challenge is failed, best challengers will be rewarded
|
||||
</div>
|
||||
</group>
|
||||
<footer>
|
||||
<center>
|
||||
<button string="Accept" type="object" name="accept_challenge" class="oe_highlight" />
|
||||
<button string="Reject" type="object" name="discard_challenge"/> or
|
||||
<button string="reply later" special="cancel" class="oe_link"/>
|
||||
</center>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="challenge_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Challenge Description</field>
|
||||
<field name="res_model">gamification.challenge</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_challenge_wizard"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,289 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Goal views -->
|
||||
<record id="goal_list_action" model="ir.actions.act_window">
|
||||
<field name="name">Goals</field>
|
||||
<field name="res_model">gamification.goal</field>
|
||||
<field name="view_mode">tree,form,kanban</field>
|
||||
<field name="context">{'search_default_group_by_user': True, 'search_default_group_by_definition': True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a goal.
|
||||
</p>
|
||||
<p>
|
||||
A goal is defined by a user and a goal definition.
|
||||
Goals can be created automatically by using challenges.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="goal_list_view" model="ir.ui.view">
|
||||
<field name="name">Goal List</field>
|
||||
<field name="model">gamification.goal</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Goal List" colors="red:state == 'failed';green:state == 'reached';grey:state == 'canceled'">
|
||||
<field name="definition_id" invisible="1" />
|
||||
<field name="user_id" invisible="1" />
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
<field name="current"/>
|
||||
<field name="target_goal"/>
|
||||
<field name="completeness" widget="progressbar"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="line_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="goal_form_view" model="ir.ui.view">
|
||||
<field name="name">Goal Form</field>
|
||||
<field name="model">gamification.goal</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Goal" version="7.0">
|
||||
<header>
|
||||
<button string="Start goal" type="object" name="action_start" states="draft" class="oe_highlight"/>
|
||||
|
||||
<button string="Goal Reached" type="object" name="action_reach" states="inprogress,inprogress_update" />
|
||||
<button string="Goal Failed" type="object" name="action_fail" states="inprogress,inprogress_update"/>
|
||||
<button string="Reset Completion" type="object" name="action_cancel" states="failed,reached" groups="base.group_no_one" />
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,inprogress,reached" />
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<group string="Reference">
|
||||
<field name="definition_id" on_change="on_change_definition_id(definition_id)" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="user_id" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="challenge_id" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
</group>
|
||||
<group string="Schedule">
|
||||
<field name="start_date" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="end_date" />
|
||||
<field name="computation_mode" invisible="1"/>
|
||||
|
||||
<label for="remind_update_delay" attrs="{'invisible':[('computation_mode','!=', 'manually')]}"/>
|
||||
<div attrs="{'invisible':[('computation_mode','!=', 'manually')]}">
|
||||
<field name="remind_update_delay" class="oe_inline"/>
|
||||
days
|
||||
</div>
|
||||
<field name="last_update" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group string="Data" colspan="4">
|
||||
<label for="target_goal" />
|
||||
<div>
|
||||
<field name="target_goal" attrs="{'readonly':[('state','!=','draft')]}" class="oe_inline"/>
|
||||
<field name="definition_suffix" class="oe_inline"/>
|
||||
</div>
|
||||
<label for="current" />
|
||||
<div>
|
||||
<field name="current" class="oe_inline"/>
|
||||
<button string="refresh" type="object" name="update" class="oe_link" attrs="{'invisible':['|',('computation_mode', '=', 'manually'),('state', '=', 'draft')]}" />
|
||||
<div class="oe_grey" attrs="{'invisible':[('definition_id', '=', False)]}">
|
||||
Reached when current value is <strong><field name="definition_condition" class="oe_inline"/></strong> than the target.
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="goal_search_view" model="ir.ui.view">
|
||||
<field name="name">Goal Search</field>
|
||||
<field name="model">gamification.goal</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Goals">
|
||||
<filter name="my" string="My Goals" domain="[('user_id', '=', uid)]"/>
|
||||
<separator/>
|
||||
<filter name="draft" string="Draft" domain="[('state', '=', 'draft')]"/>
|
||||
<filter name="inprogress" string="Current"
|
||||
domain="[
|
||||
'|',
|
||||
('state', 'in', ('inprogress', 'inprogress_update')),
|
||||
('end_date', '>=', context_today().strftime('%%Y-%%m-%%d'))
|
||||
]"/>
|
||||
<filter name="closed" string="Passed" domain="[('state', 'in', ('reached', 'failed'))]"/>
|
||||
<separator/>
|
||||
|
||||
<field name="user_id"/>
|
||||
<field name="definition_id"/>
|
||||
<field name="challenge_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter name="group_by_user" string="User" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter name="group_by_definition" string="Goal Definition" domain="[]" context="{'group_by':'definition_id'}"/>
|
||||
<filter string="State" domain="[]" context="{'group_by':'state'}"/>
|
||||
<filter string="End Date" domain="[]" context="{'group_by':'end_date'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="goal_kanban_view" model="ir.ui.view" >
|
||||
<field name="name">Goal Kanban View</field>
|
||||
<field name="model">gamification.goal</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban version="7.0" class="oe_background_grey">
|
||||
<field name="definition_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="current"/>
|
||||
<field name="completeness"/>
|
||||
<field name="state"/>
|
||||
<field name="target_goal"/>
|
||||
<field name="definition_condition"/>
|
||||
<field name="definition_suffix"/>
|
||||
<field name="definition_display"/>
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
<field name="last_update"/>
|
||||
<templates>
|
||||
<t t-name="kanban-tooltip">
|
||||
<field name="definition_description"/>
|
||||
</t>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_card oe_gamification_goal oe_kanban_goal #{record.end_date.raw_value < record.last_update.raw_value & record.state.raw_value == 'failed' ? 'oe_kanban_color_2' : ''} #{record.end_date.raw_value < record.last_update.raw_value & record.state.raw_value == 'reached' ? 'oe_kanban_color_5' : ''}">
|
||||
<div class="oe_kanban_content">
|
||||
<p><h4 class="oe_goal_name" tooltip="kanban-tooltip"><field name="definition_id" /></h4></p>
|
||||
<div class="oe_kanban_left">
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" width="24" height="24" />
|
||||
</div>
|
||||
<field name="user_id" />
|
||||
<div class="oe_goal_state_block">
|
||||
<t t-if="record.definition_display.raw_value == 'boolean'">
|
||||
<div class="oe_goal_state oe_e">
|
||||
<t t-if="record.state.raw_value=='reached'"><span class="oe_green" title="Goal Reached">W</span></t>
|
||||
<t t-if="record.state.raw_value=='inprogress' || record.state.raw_value=='inprogress_update'"><span title="Goal in Progress">N</span></t>
|
||||
<t t-if="record.state.raw_value=='failed'"><span class="oe_red" title="Goal Failed">X</span></t>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="record.definition_display.raw_value == 'progress'">
|
||||
<t t-if="record.definition_condition.raw_value =='higher'">
|
||||
<field name="current" widget="gauge" style="width:160px; height: 120px;" options="{'max_field': 'target_goal', 'label_field': 'definition_suffix'}" />
|
||||
</t>
|
||||
<t t-if="record.definition_condition.raw_value != 'higher'">
|
||||
<div t-attf-class="oe_goal_state #{record.current.raw_value == record.target_goal.raw_value+1 ? 'oe_orange' : record.current.raw_value > record.target_goal.raw_value ? 'oe_red' : 'oe_green'}">
|
||||
<t t-esc="record.current.raw_value" />
|
||||
</div>
|
||||
<em>Target: less than <t t-esc="record.target_goal.raw_value" /></em>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
</div>
|
||||
<p>
|
||||
<t t-if="record.start_date.value">
|
||||
From <t t-esc="record.start_date.value" />
|
||||
</t>
|
||||
<t t-if="record.end_date.value">
|
||||
To <t t-esc="record.end_date.value" />
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Goal definitions view -->
|
||||
|
||||
<record id="goal_definition_list_action" model="ir.actions.act_window">
|
||||
<field name="name">Goal Definitions</field>
|
||||
<field name="res_model">gamification.goal.definition</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a goal definition.
|
||||
</p>
|
||||
<p>
|
||||
A goal definition is a technical model of goal defining a condition to reach.
|
||||
The dates, values to reach or users are defined in goal instance.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="goal_definition_list_view" model="ir.ui.view">
|
||||
<field name="name">Goal Definitions List</field>
|
||||
<field name="model">gamification.goal.definition</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Goal Definitions">
|
||||
<field name="name"/>
|
||||
<field name="computation_mode"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="goal_definition_form_view" model="ir.ui.view">
|
||||
<field name="name">Goal Definitions Form</field>
|
||||
<field name="model">gamification.goal.definition</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Goal definitions" version="7.0">
|
||||
<sheet>
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="name" class="oe_inline"/>
|
||||
</h1>
|
||||
<label for="description" class="oe_edit_only"/>
|
||||
<div>
|
||||
<field name="description" class="oe_inline"/>
|
||||
</div>
|
||||
|
||||
<group string="How to compute the goal?">
|
||||
|
||||
<field widget="radio" name="computation_mode"/>
|
||||
|
||||
<!-- Hide the fields below if manually -->
|
||||
<field name="model_id" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))], 'required':[('computation_mode','in',('sum', 'count'))]}" class="oe_inline"/>
|
||||
<field name="field_id" attrs="{'invisible':[('computation_mode','!=','sum')], 'required':[('computation_mode','=','sum')]}" domain="[('model_id','=',model_id)]" class="oe_inline"/>
|
||||
<field name="field_date_id" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))]}" domain="[('ttype', 'in', ('date', 'datetime')), ('model_id','=',model_id)]" class="oe_inline"/>
|
||||
<field name="domain" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))], 'required':[('computation_mode','in',('sum', 'count'))]}" class="oe_inline"/>
|
||||
<field name="compute_code" attrs="{'invisible':[('computation_mode','!=','python')], 'required':[('computation_mode','=','python')]}" placeholder="e.g. result = pool.get('mail.followers').search(cr, uid, [('res_model', '=', 'mail.group'), ('partner_id', '=', object.user_id.partner_id.id)], count=True, context=context)"/>
|
||||
<field name="condition" widget="radio"/>
|
||||
</group>
|
||||
<group string="Formating Options">
|
||||
<field name="display_mode" widget="radio" />
|
||||
<field name="suffix" placeholder="e.g. days"/>
|
||||
<field name="monetary"/>
|
||||
</group>
|
||||
<group string="Clickable Goals" attrs="{'invisible': [('computation_mode', '=', 'manually')]}">
|
||||
<field name="action_id" class="oe_inline"/>
|
||||
<field name="res_id_field" attrs="{'invisible': [('action_id', '=', False)]}" class="oe_inline"/>
|
||||
</group>
|
||||
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="goal_definition_search_view" model="ir.ui.view">
|
||||
<field name="name">Goal Definition Search</field>
|
||||
<field name="model">gamification.goal.definition</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Goal Definitions">
|
||||
<field name="name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="field_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Model" domain="[]" context="{'group_by':'model_id'}"/>
|
||||
<filter string="Computation Mode" domain="[]" context="{'group_by':'computation_mode'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- menus in settings - technical feature required -->
|
||||
<menuitem id="gamification_menu" name="Gamification Tools" parent="base.menu_administration" groups="base.group_no_one" />
|
||||
<menuitem id="gamification_goal_menu" parent="gamification_menu" action="goal_list_action" sequence="0"/>
|
||||
<menuitem id="gamification_challenge_menu" parent="gamification_menu" action="challenge_list_action" sequence="10"/>
|
||||
<menuitem id="gamification_definition_menu" parent="gamification_menu" action="goal_definition_list_action" sequence="20"/>
|
||||
<menuitem id="gamification_badge_menu" parent="gamification_menu" action="badge_list_action" sequence="30"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://openerp.com>).
|
||||
#
|
||||
# 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 update_goal
|
||||
import grant_badge
|
||||
@@ -0,0 +1,56 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
||||
class grant_badge_wizard(osv.TransientModel):
|
||||
""" Wizard allowing to grant a badge to a user"""
|
||||
|
||||
_name = 'gamification.badge.user.wizard'
|
||||
_columns = {
|
||||
'user_id': fields.many2one("res.users", string='User', required=True),
|
||||
'badge_id': fields.many2one("gamification.badge", string='Badge', required=True),
|
||||
'comment': fields.text('Comment'),
|
||||
}
|
||||
|
||||
def action_grant_badge(self, cr, uid, ids, context=None):
|
||||
"""Wizard action for sending a badge to a chosen user"""
|
||||
|
||||
badge_obj = self.pool.get('gamification.badge')
|
||||
badge_user_obj = self.pool.get('gamification.badge.user')
|
||||
|
||||
for wiz in self.browse(cr, uid, ids, context=context):
|
||||
if uid == wiz.user_id.id:
|
||||
raise osv.except_osv(_('Warning!'), _('You can not grant a badge to yourself'))
|
||||
|
||||
#create the badge
|
||||
values = {
|
||||
'user_id': wiz.user_id.id,
|
||||
'sender_id': uid,
|
||||
'badge_id': wiz.badge_id.id,
|
||||
'comment': wiz.comment,
|
||||
}
|
||||
badge_user = badge_user_obj.create(cr, uid, values, context=context)
|
||||
result = badge_obj._send_badge(cr, uid, badge_user, context=context)
|
||||
|
||||
return result
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_badge_wizard_grant" model="ir.ui.view">
|
||||
<field name="name">Grant Badge User Form</field>
|
||||
<field name="model">gamification.badge.user.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Grant Badge To" version="7.0">
|
||||
Who would you like to reward?
|
||||
<group>
|
||||
<field name="user_id" nolabel="1" />
|
||||
<field name="badge_id" invisible="1"/>
|
||||
<field name="comment" nolabel="1" placeholder="Describe what they did and why it matters (will be public)" class="oe_no_padding" />
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Grant Badge" type="object" name="action_grant_badge" class="oe_highlight" /> or
|
||||
<button string="Cancel" special="cancel" class="oe_link"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window domain="[]" id="action_grant_wizard"
|
||||
name="Grant Badge"
|
||||
target="new"
|
||||
res_model="gamification.badge.user.wizard"
|
||||
context="{'default_badge_id': active_id, 'badge_id': active_id}"
|
||||
view_type="form" view_mode="form"
|
||||
view_id="gamification.view_badge_wizard_grant" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
class goal_manual_wizard(osv.TransientModel):
|
||||
"""Wizard to update a manual goal"""
|
||||
_name = 'gamification.goal.wizard'
|
||||
_columns = {
|
||||
'goal_id': fields.many2one("gamification.goal", string='Goal', required=True),
|
||||
'current': fields.float('Current'),
|
||||
}
|
||||
|
||||
def action_update_current(self, cr, uid, ids, context=None):
|
||||
"""Wizard action for updating the current value"""
|
||||
|
||||
goal_obj = self.pool.get('gamification.goal')
|
||||
|
||||
for wiz in self.browse(cr, uid, ids, context=context):
|
||||
towrite = {
|
||||
'current': wiz.current,
|
||||
'goal_id': wiz.goal_id.id,
|
||||
}
|
||||
goal_obj.write(cr, uid, [wiz.goal_id.id], towrite, context=context)
|
||||
goal_obj.update(cr, uid, [wiz.goal_id.id], context=context)
|
||||
return {}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_goal_wizard_update_current" model="ir.ui.view">
|
||||
<field name="name">Update the current value of the Goal</field>
|
||||
<field name="model">gamification.goal.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Grant Badge To" version="7.0">
|
||||
Set the current value you have reached for this goal
|
||||
<group>
|
||||
<field name="goal_id" invisible="1"/>
|
||||
<field name="current" />
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Update" type="object" name="action_update_current" class="oe_highlight" /> or
|
||||
<button string="Cancel" special="cancel" class="oe_link"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://openerp.com>).
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
@@ -0,0 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013 OpenERP SA (<http://openerp.com>).
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
{
|
||||
'name': 'CRM Gamification',
|
||||
'version': '1.0',
|
||||
'author': 'OpenERP SA',
|
||||
'category': 'hidden',
|
||||
'depends': ['gamification','sale_crm'],
|
||||
'description': """Example of goal definitions and challenges that can be used related to the usage of the CRM Sale module.""",
|
||||
|
||||
'data': ['sale_crm_goals.xml'],
|
||||
'demo': ['sale_crm_goals_demo.xml'],
|
||||
'auto_install': True,
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- goal definitions -->
|
||||
<record model="gamification.goal.definition" id="definition_crm_tot_invoices">
|
||||
<field name="name">Total Invoiced</field>
|
||||
<field name="description"></field>
|
||||
<field name="computation_mode">sum</field>
|
||||
<field name="monetary">True</field>
|
||||
<field name="model_id" eval="ref('account.model_account_invoice_report')" />
|
||||
<field name="field_id" eval="ref('account.field_account_invoice_report_price_total')" />
|
||||
<field name="field_date_id" eval="ref('account.field_account_invoice_report_day')" />
|
||||
<field name="domain">[('state','!=','cancel'),('user_id','=',user.id),('type','=','out_invoice')]</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_crm_nbr_new_leads">
|
||||
<field name="name">New Leads</field>
|
||||
<field name="description">Based on the creation date</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="suffix">leads</field>
|
||||
<field name="model_id" eval="ref('crm.model_crm_lead')" />
|
||||
<field name="field_date_id" eval="ref('crm.field_crm_lead_create_date')" />
|
||||
<!-- lead AND opportunity as don't want to be penalised for lead converted to opportunity -->
|
||||
<field name="domain">[('user_id','=',user.id), '|', ('type', '=', 'lead'), ('type', '=', 'opportunity')]</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_crm_lead_delay_open">
|
||||
<field name="name">Time to Qualify a Lead</field>
|
||||
<field name="description">The average number of days to open the case (lower than)</field>
|
||||
<field name="computation_mode">sum</field>
|
||||
<field name="condition">lower</field>
|
||||
<field name="suffix">days</field>
|
||||
<field name="model_id" eval="ref('crm.model_crm_lead_report')" />
|
||||
<field name="field_id" eval="ref('crm.field_crm_lead_report_delay_close')" />
|
||||
<field name="field_date_id" eval="ref('crm.field_crm_lead_report_date_closed')" />
|
||||
<field name="domain">[('user_id','=',user.id),('type', '=', 'lead')]</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_crm_lead_delay_close">
|
||||
<field name="name">Days to Close a Deal</field>
|
||||
<field name="description">The average number of days to close the case (lower than)</field>
|
||||
<field name="computation_mode">sum</field>
|
||||
<field name="condition">lower</field>
|
||||
<field name="suffix">days</field>
|
||||
<field name="model_id" eval="ref('crm.model_crm_lead_report')" />
|
||||
<field name="field_id" eval="ref('crm.field_crm_lead_report_delay_open')" />
|
||||
<field name="field_date_id" eval="ref('crm.field_crm_lead_report_opening_date')" />
|
||||
<field name="domain">[('user_id','=',user.id)]</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_crm_nbr_call">
|
||||
<field name="name">Logged Calls</field>
|
||||
<field name="description">Log a certain number of calls to reach this goal</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="suffix">calls</field>
|
||||
<field name="model_id" eval="ref('crm.model_crm_phonecall')" />
|
||||
<field name="field_date_id" eval="ref('crm.field_crm_phonecall_date_closed')" />
|
||||
<field name="domain">[('user_id','=',user.id),('state','=','done')]</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_crm_nbr_new_opportunities">
|
||||
<field name="name">New Opportunities</field>
|
||||
<field name="description">Based on the opening date</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="suffix">opportunities</field>
|
||||
<field name="model_id" eval="ref('crm.model_crm_lead')" />
|
||||
<field name="field_date_id" eval="ref('crm.field_crm_lead_date_open')" />
|
||||
<field name="domain">[('user_id','=',user.id),('type','=','opportunity')]</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_crm_nbr_sale_order_created">
|
||||
<field name="name">New Sales Orders</field>
|
||||
<field name="description">Based on the creation date</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="suffix">orders</field>
|
||||
<field name="model_id" eval="ref('sale.model_sale_order')" />
|
||||
<field name="field_date_id" eval="ref('sale.field_sale_order_date_order')" />
|
||||
<field name="domain">[('user_id','=',user.id),('state','not in',('draft', 'sent', 'cancel'))]</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_crm_nbr_paid_sale_order">
|
||||
<field name="name">Paid Sales Orders</field>
|
||||
<field name="description">Based on the invoice date</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="suffix">orders</field>
|
||||
<field name="model_id" eval="ref('account.model_account_invoice_report')" />
|
||||
<field name="field_date_id" eval="ref('account.field_account_invoice_report_day')" />
|
||||
<field name="domain">[('state','=','paid'),('user_id','=',user.id),('type','=','out_invoice')]</field>
|
||||
</record>
|
||||
<record model="gamification.goal.definition" id="definition_crm_tot_paid_sale_order">
|
||||
<field name="name">Total Paid Sales Orders</field>
|
||||
<field name="description">Based on the invoice date</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="monetary">True</field>
|
||||
<field name="model_id" eval="ref('account.model_account_invoice_report')" />
|
||||
<field name="field_id" eval="ref('account.field_account_invoice_report_price_total')" />
|
||||
<field name="field_date_id" eval="ref('account.field_account_invoice_report_day')" />
|
||||
<field name="domain">[('state','=','paid'),('user_id','=',user.id),('type','=','out_invoice')]</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_crm_nbr_customer_refunds">
|
||||
<field name="name">Customer Refunds</field>
|
||||
<field name="description">Refund the least customers (lower than)</field>
|
||||
<field name="computation_mode">count</field>
|
||||
<field name="condition">lower</field>
|
||||
<field name="suffix">invoices</field>
|
||||
<field name="model_id" eval="ref('account.model_account_invoice_report')" />
|
||||
<field name="field_date_id" eval="ref('account.field_account_invoice_report_day')" />
|
||||
<field name="domain">[('state','!=','cancel'),('user_id','=',user.id),('type','=','out_refund')]</field>
|
||||
</record>
|
||||
<record model="gamification.goal.definition" id="definition_crm_tot_customer_refunds">
|
||||
<field name="name">Total Customer Refunds</field>
|
||||
<field name="description">The total refunded value is a negative value. Validated when higher (min refunded).</field>
|
||||
<field name="computation_mode">sum</field>
|
||||
<field name="condition">higher</field>
|
||||
<field name="monetary">True</field>
|
||||
<field name="model_id" eval="ref('account.model_account_invoice_report')" />
|
||||
<field name="field_id" eval="ref('account.field_account_invoice_report_price_total')" />
|
||||
<field name="field_date_id" eval="ref('account.field_account_invoice_report_day')" />
|
||||
<field name="domain">[('state','!=','cancel'),('user_id','=',user.id),('type','=','out_refund')]</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<!-- challenges -->
|
||||
<record model="gamification.challenge" id="challenge_crm_sale">
|
||||
<field name="name">Monthly Sales Targets</field>
|
||||
<field name="period">monthly</field>
|
||||
<field name="visibility_mode">ranking</field>
|
||||
<field name="autojoin_group_id" eval="ref('base.group_sale_salesman')" />
|
||||
<field name="report_message_frequency">weekly</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.challenge" id="challenge_crm_marketing">
|
||||
<field name="name">Lead Acquisition</field>
|
||||
<field name="period">monthly</field>
|
||||
<field name="visibility_mode">ranking</field>
|
||||
<field name="autojoin_group_id" eval="ref('base.group_sale_salesman')" />
|
||||
<field name="report_message_frequency">weekly</field>
|
||||
</record>
|
||||
|
||||
<!-- lines -->
|
||||
<record model="gamification.challenge.line" id="line_crm_sale1">
|
||||
<field name="definition_id" eval="ref('definition_crm_tot_invoices')" />
|
||||
<field name="target_goal">20000</field>
|
||||
<field name="challenge_id" eval="ref('challenge_crm_sale')" />
|
||||
</record>
|
||||
|
||||
|
||||
<record model="gamification.challenge.line" id="line_crm_marketing1">
|
||||
<field name="definition_id" eval="ref('definition_crm_nbr_new_leads')" />
|
||||
<field name="target_goal">7</field>
|
||||
<field name="challenge_id" eval="ref('challenge_crm_marketing')" />
|
||||
<field name="sequence">1</field>
|
||||
</record>
|
||||
<record model="gamification.challenge.line" id="line_crm_marketing2">
|
||||
<field name="definition_id" eval="ref('definition_crm_lead_delay_open')" />
|
||||
<field name="target_goal">15</field>
|
||||
<field name="challenge_id" eval="ref('challenge_crm_marketing')" />
|
||||
<field name="sequence">2</field>
|
||||
</record>
|
||||
<record model="gamification.challenge.line" id="line_crm_marketing3">
|
||||
<field name="definition_id" eval="ref('definition_crm_nbr_new_opportunities')" />
|
||||
<field name="target_goal">5</field>
|
||||
<field name="challenge_id" eval="ref('challenge_crm_marketing')" />
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- challenges -->
|
||||
<record model="gamification.challenge" id="challenge_crm_sale">
|
||||
<field name="user_ids" eval="[(4,ref('base.user_demo'))]" />
|
||||
<field name="state">inprogress</field>
|
||||
</record>
|
||||
|
||||
<!-- goals -->
|
||||
<record model="gamification.goal" id="goal_crm_sale1">
|
||||
<field name="definition_id" eval="ref('definition_crm_tot_invoices')" />
|
||||
<field name="user_id" eval="ref('base.user_demo')" />
|
||||
<field name="line_id" eval="ref('line_crm_sale1')" />
|
||||
<field name="start_date" eval="time.strftime('%Y-%m-01')" />
|
||||
<field name="end_date" eval="time.strftime('%Y-%m-31')" />
|
||||
<field name="target_goal">2000</field>
|
||||
<field name="state">inprogress</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,963 @@
|
||||
# Hebrew translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-12-30 19:04+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hebrew <he@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: 2013-12-31 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,name:hr.process_node_openerpuser0
|
||||
msgid "Openerp user"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_timesheet_sheet:0
|
||||
msgid "Allow timesheets validation by managers"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,requirements:0
|
||||
msgid "Requirements"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,name:hr.process_transition_contactofemployee0
|
||||
msgid "Link the employee to information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,sinid:0
|
||||
msgid "SIN No"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_board_hr
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_dashboard
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_main
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_reporting
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_root
|
||||
#: model:ir.ui.menu,name:hr.menu_human_resources_configuration
|
||||
msgid "Human Resources"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,image_medium:0
|
||||
msgid ""
|
||||
"Medium-sized photo of the employee. It is automatically resized as a "
|
||||
"128x128px image, with aspect ratio preserved. Use this field in form views "
|
||||
"or some kanban views."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Time Tracking"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: view:hr.job:0
|
||||
msgid "Group By..."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.view_department_form_installer
|
||||
msgid "Create Your Departments"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,no_of_employee:0
|
||||
msgid "Number of employees currently occupying this job position."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_evaluation:0
|
||||
msgid "Organize employees periodic evaluation"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee,department_id:0
|
||||
#: view:hr.job:0
|
||||
#: field:hr.job,department_id:0
|
||||
#: model:ir.model,name:hr.model_hr_department
|
||||
msgid "Department"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_email:0
|
||||
msgid "Work Email"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,image:0
|
||||
msgid ""
|
||||
"This field holds the image used as photo for the employee, limited to "
|
||||
"1024x1024px."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_holidays:0
|
||||
msgid "This installs the module hr_holidays."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "Jobs"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "In Recruitment"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_unread:0
|
||||
msgid "Unread Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,company_id:0
|
||||
#: view:hr.employee:0
|
||||
#: view:hr.job:0
|
||||
#: field:hr.job,company_id:0
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,no_of_recruitment:0
|
||||
msgid "Expected in Recruitment"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:res.users,employee_ids:0
|
||||
msgid "Related employees"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.employee.category:0
|
||||
msgid "Error! You cannot create recursive Categories."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_recruitment:0
|
||||
msgid "This installs the module hr_recruitment."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Birth"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_view_categ_form
|
||||
#: model:ir.ui.menu,name:hr.menu_view_employee_category_form
|
||||
msgid "Employee Tags"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "Launch Recruitement"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,name:hr.process_transition_employeeuser0
|
||||
msgid "Link a user to an employee"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,parent_id:0
|
||||
msgid "Parent Department"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_config
|
||||
msgid "Leaves"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Married"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_ids:0
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Talent Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_timesheet_sheet:0
|
||||
msgid "This installs the module hr_timesheet_sheet."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Mobile:"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Position"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_unread:0
|
||||
msgid "If checked new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,color:0
|
||||
msgid "Color Index"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,note:hr.process_transition_employeeuser0
|
||||
msgid ""
|
||||
"The Related user field on the Employee form allows to link the OpenERP user "
|
||||
"(and her rights) to the employee."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,image_medium:0
|
||||
msgid "Medium-sized photo"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,identification_id:0
|
||||
msgid "Identification No"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,gender:0
|
||||
msgid "Female"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_new_config
|
||||
msgid "Attendance"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_phone:0
|
||||
msgid "Work Phone"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee.category,child_ids:0
|
||||
msgid "Child Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,description:0
|
||||
#: model:ir.model,name:hr.model_hr_job
|
||||
msgid "Job Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_location:0
|
||||
msgid "Office Location"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_follower_ids:0
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: model:ir.model,name:hr.model_hr_employee
|
||||
#: model:process.node,name:hr.process_node_employee0
|
||||
msgid "Employee"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,note:hr.process_node_employeecontact0
|
||||
msgid "Other information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,image_small:0
|
||||
msgid ""
|
||||
"Small-sized photo of the employee. It is automatically resized as a 64x64px "
|
||||
"image, with aspect ratio preserved. Use this field anywhere a small image is "
|
||||
"required."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,birthday:0
|
||||
msgid "Date of Birth"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,no_of_recruitment:0
|
||||
msgid "Number of new employees you expect to recruit."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.client,name:hr.action_client_hr_menu
|
||||
msgid "Open HR Menu"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_summary:0
|
||||
msgid ""
|
||||
"Holds the Chatter summary (number of messages, ...). This summary is "
|
||||
"directly in html format in order to be inserted in kanban views."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_account_analytic_analysis:0
|
||||
msgid ""
|
||||
"This installs the module account_analytic_analysis, which will install sales "
|
||||
"management too."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:board.board:0
|
||||
msgid "Human Resources Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee,job_id:0
|
||||
#: view:hr.job:0
|
||||
msgid "Job"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,no_of_employee:0
|
||||
msgid "Current Number of Employees"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,member_ids:0
|
||||
msgid "Members"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_configuration
|
||||
msgid "Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,note:hr.process_node_employee0
|
||||
msgid "Employee form and structure"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_expense:0
|
||||
msgid "Manage employees expenses"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Tel:"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Divorced"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee.category,parent_id:0
|
||||
msgid "Parent Category"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
#: model:ir.actions.act_window,name:hr.open_module_tree_department
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_department_tree
|
||||
msgid "Departments"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,name:hr.process_node_employeecontact0
|
||||
msgid "Employee Contact"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.action_hr_job
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to define a new job position.\n"
|
||||
" </p><p>\n"
|
||||
" Job Positions are used to define jobs and their "
|
||||
"requirements.\n"
|
||||
" You can keep track of the number of employees you have per "
|
||||
"job\n"
|
||||
" position and follow the evolution according to what you "
|
||||
"planned\n"
|
||||
" for the future.\n"
|
||||
" </p><p>\n"
|
||||
" You can attach a survey to a job position. It will be used "
|
||||
"in\n"
|
||||
" the recruitment process to evaluate the applicants for this "
|
||||
"job\n"
|
||||
" position.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,gender:0
|
||||
msgid "Male"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid ""
|
||||
"$('.oe_employee_picture').load(function() { if($(this).width() > "
|
||||
"$(this).height()) { $(this).addClass('oe_employee_picture_wide') } });"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_evaluation:0
|
||||
msgid "This installs the module hr_evaluation."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.employee:0
|
||||
msgid "Error! You cannot create recursive hierarchy of Employee(s)."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_attendance:0
|
||||
msgid "This installs the module hr_attendance."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,image_small:0
|
||||
msgid "Smal-sized photo"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee.category:0
|
||||
#: model:ir.model,name:hr.model_hr_employee_category
|
||||
msgid "Employee Category"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,category_ids:0
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_contract:0
|
||||
msgid "This installs the module hr_contract."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Related User"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee.category,name:0
|
||||
msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "Stop Recruitment"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_attendance:0
|
||||
msgid "Install attendances feature"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,bank_account_id:0
|
||||
msgid "Employee bank salary account"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,note:0
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_view_employee_tree
|
||||
msgid "Employees Structure"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Contact Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_holidays:0
|
||||
msgid "Manage holidays, leaves and allocation requests"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,child_ids:0
|
||||
msgid "Child Departments"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: view:hr.job:0
|
||||
#: field:hr.job,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,otherid:0
|
||||
msgid "Other Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.process,name:hr.process_process_employeecontractprocess0
|
||||
msgid "Employee Contract"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Contracts"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_ids:0
|
||||
msgid "Messages and communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,ssnid:0
|
||||
msgid "SSN No"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_is_follower:0
|
||||
msgid "Is a Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_recruitment:0
|
||||
msgid "Manage the recruitment process"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Human Resources Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Install your country's payroll"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,bank_account_id:0
|
||||
msgid "Bank Account Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_summary:0
|
||||
msgid "Summary"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,note:hr.process_transition_contactofemployee0
|
||||
msgid ""
|
||||
"In the Employee form, there are different kind of information like Contact "
|
||||
"information."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.open_view_employee_list_my
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to add a new employee.\n"
|
||||
" </p><p>\n"
|
||||
" With just a quick glance on the OpenERP employee screen, "
|
||||
"you\n"
|
||||
" can easily find all the information you need for each "
|
||||
"person;\n"
|
||||
" contact data, job position, availability, etc.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "HR Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Citizenship & Other Info"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.department:0
|
||||
msgid "Error! You cannot create recursive departments."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,address_id:0
|
||||
msgid "Working Address"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Public Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,marital:0
|
||||
msgid "Marital Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.model,name:hr.model_ir_actions_act_window
|
||||
msgid "ir.actions.act_window"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,last_login:0
|
||||
msgid "Latest Connection"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,image:0
|
||||
msgid "Photo"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.open_module_tree_department
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to create a department.\n"
|
||||
" </p><p>\n"
|
||||
" OpenERP's department structure is used to manage all "
|
||||
"documents\n"
|
||||
" related to employees by departments: expenses, timesheets,\n"
|
||||
" leaves and holidays, recruitments, etc.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_timesheet:0
|
||||
msgid "This installs the module hr_timesheet."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,expected_employees:0
|
||||
msgid ""
|
||||
"Expected number of employees for this job position after new recruitment."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.view_department_form_installer
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to define a new department.\n"
|
||||
" </p><p>\n"
|
||||
" Your departments structure is used to manage all documents\n"
|
||||
" related to employees by departments: expenses and "
|
||||
"timesheets,\n"
|
||||
" leaves and holidays, recruitments, etc.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Personal Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,city:0
|
||||
msgid "City"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,passport_id:0
|
||||
msgid "Passport No"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,mobile_phone:0
|
||||
msgid "Work Mobile"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.job,state:0
|
||||
msgid "Recruitement in Progress"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_account_analytic_analysis:0
|
||||
msgid ""
|
||||
"Allow invoicing based on timesheets (the sale application will be installed)"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee.category:0
|
||||
msgid "Employees Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,address_home_id:0
|
||||
msgid "Home Address"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_timesheet:0
|
||||
msgid "Manage timesheets"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_payroll_modules
|
||||
msgid "Payroll"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Single"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,name:0
|
||||
msgid "Job Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "In Position"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_payroll:0
|
||||
msgid "This installs the module hr_payroll."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_contract:0
|
||||
msgid "Record contracts per employee"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
msgid "department"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,country_id:0
|
||||
msgid "Nationality"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Additional Features"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,notes:0
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.action2
|
||||
msgid "Subordinate Hierarchy"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,resource_id:0
|
||||
msgid "Resource"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,complete_name:0
|
||||
#: field:hr.employee,name_related:0
|
||||
#: field:hr.employee.category,complete_name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,gender:0
|
||||
msgid "Gender"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee.category,employee_ids:0
|
||||
#: field:hr.job,employee_ids:0
|
||||
#: model:ir.actions.act_window,name:hr.hr_employee_normal_action_tree
|
||||
#: model:ir.actions.act_window,name:hr.open_view_employee_list
|
||||
#: model:ir.actions.act_window,name:hr.open_view_employee_list_my
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_employee_list_my
|
||||
msgid "Employees"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,sinid:0
|
||||
msgid "Social Insurance Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,name:0
|
||||
msgid "Department Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_reporting_timesheet
|
||||
msgid "Reports"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_payroll:0
|
||||
msgid "Manage payroll"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
#: model:ir.actions.act_window,name:hr.action_human_resources_configuration
|
||||
msgid "Configure Human Resources"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.job,state:0
|
||||
msgid "No Recruitment"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,ssnid:0
|
||||
msgid "Social Security Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,note:hr.process_node_openerpuser0
|
||||
msgid "Creation of a OpenERP user"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,login:0
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,expected_employees:0
|
||||
msgid "Total Forecasted Employees"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,state:0
|
||||
msgid ""
|
||||
"By default 'In position', set it to 'In Recruitment' if recruitment process "
|
||||
"is going on for this job position."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.model,name:hr.model_res_users
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.action_hr_job
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_job
|
||||
msgid "Job Positions"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.open_board_hr
|
||||
msgid ""
|
||||
"<div class=\"oe_empty_custom_dashboard\">\n"
|
||||
" <p>\n"
|
||||
" <b>Human Resources dashboard is empty.</b>\n"
|
||||
" </p><p>\n"
|
||||
" To add your first report into this dashboard, go to any\n"
|
||||
" menu, switch to list or graph view, and click <i>'Add "
|
||||
"to\n"
|
||||
" Dashboard'</i> in the extended search options.\n"
|
||||
" </p><p>\n"
|
||||
" You can filter and group data before inserting into the\n"
|
||||
" dashboard using the search options.\n"
|
||||
" </p>\n"
|
||||
" </div>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee,coach_id:0
|
||||
msgid "Coach"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: sql_constraint:hr.job:0
|
||||
msgid "The name of the job position must be unique per company!"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_expense:0
|
||||
msgid "This installs the module hr_expense."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.model,name:hr.model_hr_config_settings
|
||||
msgid "hr.config.settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,manager_id:0
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee,parent_id:0
|
||||
msgid "Manager"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Widower"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,child_ids:0
|
||||
msgid "Subordinates"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Apply"
|
||||
msgstr ""
|
||||
+62
-62
@@ -7,24 +7,24 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2012-05-10 17:48+0000\n"
|
||||
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
|
||||
"PO-Revision-Date: 2013-12-27 05:02+0000\n"
|
||||
"Last-Translator: Andy Cheng <andy@dobtor.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: 2013-09-12 05:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16761)\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-28 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,name:hr.process_node_openerpuser0
|
||||
msgid "Openerp user"
|
||||
msgstr ""
|
||||
msgstr "Openerp 使用者"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_timesheet_sheet:0
|
||||
msgid "Allow timesheets validation by managers"
|
||||
msgstr ""
|
||||
msgstr "允許主管批准工時表"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,requirements:0
|
||||
@@ -62,7 +62,7 @@ msgstr ""
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Time Tracking"
|
||||
msgstr ""
|
||||
msgstr "追蹤時間"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
@@ -73,17 +73,17 @@ msgstr "分組根據..."
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.view_department_form_installer
|
||||
msgid "Create Your Departments"
|
||||
msgstr ""
|
||||
msgstr "建立您的部門"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,no_of_employee:0
|
||||
msgid "Number of employees currently occupying this job position."
|
||||
msgstr ""
|
||||
msgstr "從事此職位的現有員工數量。"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_evaluation:0
|
||||
msgid "Organize employees periodic evaluation"
|
||||
msgstr ""
|
||||
msgstr "安排員工定期考評"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
@@ -98,19 +98,19 @@ msgstr "部門"
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_email:0
|
||||
msgid "Work Email"
|
||||
msgstr ""
|
||||
msgstr "工作電子郵件"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,image:0
|
||||
msgid ""
|
||||
"This field holds the image used as photo for the employee, limited to "
|
||||
"1024x1024px."
|
||||
msgstr ""
|
||||
msgstr "此欄位存放圖片作為員工照片,限制大小為 1024*1024 像素。"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_holidays:0
|
||||
msgid "This installs the module hr_holidays."
|
||||
msgstr ""
|
||||
msgstr "此功能將安裝 hr_holidays 模組。"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
@@ -125,7 +125,7 @@ msgstr "正招聘"
|
||||
#. module: hr
|
||||
#: field:hr.job,message_unread:0
|
||||
msgid "Unread Messages"
|
||||
msgstr ""
|
||||
msgstr "未讀訊息"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,company_id:0
|
||||
@@ -143,7 +143,7 @@ msgstr ""
|
||||
#. module: hr
|
||||
#: field:res.users,employee_ids:0
|
||||
msgid "Related employees"
|
||||
msgstr ""
|
||||
msgstr "相關員工"
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.employee.category:0
|
||||
@@ -153,28 +153,28 @@ msgstr ""
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_recruitment:0
|
||||
msgid "This installs the module hr_recruitment."
|
||||
msgstr ""
|
||||
msgstr "此功能將安裝 hr_recruitment 模組。"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Birth"
|
||||
msgstr ""
|
||||
msgstr "生日"
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_view_categ_form
|
||||
#: model:ir.ui.menu,name:hr.menu_view_employee_category_form
|
||||
msgid "Employee Tags"
|
||||
msgstr ""
|
||||
msgstr "員工標籤"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "Launch Recruitement"
|
||||
msgstr ""
|
||||
msgstr "啟動招募"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,name:hr.process_transition_employeeuser0
|
||||
msgid "Link a user to an employee"
|
||||
msgstr ""
|
||||
msgstr "將一個使用者帳號連結到一位員工"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,parent_id:0
|
||||
@@ -184,7 +184,7 @@ msgstr "上級部門"
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_config
|
||||
msgid "Leaves"
|
||||
msgstr ""
|
||||
msgstr "休假"
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
@@ -194,37 +194,37 @@ msgstr "已婚"
|
||||
#. module: hr
|
||||
#: field:hr.job,message_ids:0
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
msgstr "訊息"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Talent Management"
|
||||
msgstr ""
|
||||
msgstr "人才管理"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_timesheet_sheet:0
|
||||
msgid "This installs the module hr_timesheet_sheet."
|
||||
msgstr ""
|
||||
msgstr "此功能將安裝 hr_timesheet_sheet 模組。"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Mobile:"
|
||||
msgstr ""
|
||||
msgstr "行動電話:"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Position"
|
||||
msgstr ""
|
||||
msgstr "職位"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_unread:0
|
||||
msgid "If checked new messages require your attention."
|
||||
msgstr ""
|
||||
msgstr "當有新訊息時通知您。"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,color:0
|
||||
msgid "Color Index"
|
||||
msgstr ""
|
||||
msgstr "顏色索引"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,note:hr.process_transition_employeeuser0
|
||||
@@ -236,7 +236,7 @@ msgstr ""
|
||||
#. module: hr
|
||||
#: field:hr.employee,image_medium:0
|
||||
msgid "Medium-sized photo"
|
||||
msgstr ""
|
||||
msgstr "中等尺寸照片"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,identification_id:0
|
||||
@@ -251,7 +251,7 @@ msgstr "女"
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_new_config
|
||||
msgid "Attendance"
|
||||
msgstr ""
|
||||
msgstr "出勤"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_phone:0
|
||||
@@ -277,7 +277,7 @@ msgstr "辦公室位置"
|
||||
#. module: hr
|
||||
#: field:hr.job,message_follower_ids:0
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
msgstr "關注者"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
@@ -307,12 +307,12 @@ msgstr "出生日期"
|
||||
#. module: hr
|
||||
#: help:hr.job,no_of_recruitment:0
|
||||
msgid "Number of new employees you expect to recruit."
|
||||
msgstr ""
|
||||
msgstr "您期望聘雇的新員工數量。"
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.client,name:hr.action_client_hr_menu
|
||||
msgid "Open HR Menu"
|
||||
msgstr ""
|
||||
msgstr "開啟人資選單"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_summary:0
|
||||
@@ -326,12 +326,12 @@ msgstr ""
|
||||
msgid ""
|
||||
"This installs the module account_analytic_analysis, which will install sales "
|
||||
"management too."
|
||||
msgstr ""
|
||||
msgstr "此功能將安裝 account_analytic_analysis 模組,同時也安裝業務銷售管理模組。"
|
||||
|
||||
#. module: hr
|
||||
#: view:board.board:0
|
||||
msgid "Human Resources Dashboard"
|
||||
msgstr ""
|
||||
msgstr "人力資源儀表板"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
@@ -343,7 +343,7 @@ msgstr "工作"
|
||||
#. module: hr
|
||||
#: field:hr.job,no_of_employee:0
|
||||
msgid "Current Number of Employees"
|
||||
msgstr ""
|
||||
msgstr "現有員工數目"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,member_ids:0
|
||||
@@ -353,22 +353,22 @@ msgstr "成員"
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_configuration
|
||||
msgid "Configuration"
|
||||
msgstr ""
|
||||
msgstr "組態設定"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,note:hr.process_node_employee0
|
||||
msgid "Employee form and structure"
|
||||
msgstr ""
|
||||
msgstr "員工表單與架構"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_expense:0
|
||||
msgid "Manage employees expenses"
|
||||
msgstr ""
|
||||
msgstr "管理員工費用報支"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Tel:"
|
||||
msgstr ""
|
||||
msgstr "電話:"
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
@@ -430,7 +430,7 @@ msgstr ""
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_evaluation:0
|
||||
msgid "This installs the module hr_evaluation."
|
||||
msgstr ""
|
||||
msgstr "此功能將安裝 hr_evaluation 模組。"
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.employee:0
|
||||
@@ -440,12 +440,12 @@ msgstr ""
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_attendance:0
|
||||
msgid "This installs the module hr_attendance."
|
||||
msgstr ""
|
||||
msgstr "此功能將安裝 hr_attendance 模組。"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,image_small:0
|
||||
msgid "Smal-sized photo"
|
||||
msgstr ""
|
||||
msgstr "小尺吋照片"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee.category:0
|
||||
@@ -456,22 +456,22 @@ msgstr "員工分類"
|
||||
#. module: hr
|
||||
#: field:hr.employee,category_ids:0
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
msgstr "標籤"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_contract:0
|
||||
msgid "This installs the module hr_contract."
|
||||
msgstr ""
|
||||
msgstr "此功能將安裝 hr_contract 模組。"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Related User"
|
||||
msgstr ""
|
||||
msgstr "相關使用者"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
msgstr "或"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee.category,name:0
|
||||
@@ -481,12 +481,12 @@ msgstr "分類"
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "Stop Recruitment"
|
||||
msgstr ""
|
||||
msgstr "停止招募"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_attendance:0
|
||||
msgid "Install attendances feature"
|
||||
msgstr ""
|
||||
msgstr "安裝出勤管理功能"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,bank_account_id:0
|
||||
@@ -501,7 +501,7 @@ msgstr "備註"
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_view_employee_tree
|
||||
msgid "Employees Structure"
|
||||
msgstr ""
|
||||
msgstr "員工架構"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
@@ -511,7 +511,7 @@ msgstr "聯絡資料"
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_holidays:0
|
||||
msgid "Manage holidays, leaves and allocation requests"
|
||||
msgstr ""
|
||||
msgstr "管理假日、請假及排假。"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,child_ids:0
|
||||
@@ -528,7 +528,7 @@ msgstr "狀況"
|
||||
#. module: hr
|
||||
#: field:hr.employee,otherid:0
|
||||
msgid "Other Id"
|
||||
msgstr ""
|
||||
msgstr "其他ID"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.process,name:hr.process_process_employeecontractprocess0
|
||||
@@ -538,12 +538,12 @@ msgstr "僱傭合約"
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Contracts"
|
||||
msgstr ""
|
||||
msgstr "合約"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_ids:0
|
||||
msgid "Messages and communication history"
|
||||
msgstr ""
|
||||
msgstr "訊息及聯絡紀錄"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,ssnid:0
|
||||
@@ -553,12 +553,12 @@ msgstr "社會保障號碼(美國)"
|
||||
#. module: hr
|
||||
#: field:hr.job,message_is_follower:0
|
||||
msgid "Is a Follower"
|
||||
msgstr ""
|
||||
msgstr "為關注者"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_recruitment:0
|
||||
msgid "Manage the recruitment process"
|
||||
msgstr ""
|
||||
msgstr "管理招募流程"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
@@ -568,12 +568,12 @@ msgstr "活躍"
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Human Resources Management"
|
||||
msgstr ""
|
||||
msgstr "人力資源管理"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Install your country's payroll"
|
||||
msgstr ""
|
||||
msgstr "安裝您國家的薪資模組"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,bank_account_id:0
|
||||
@@ -588,7 +588,7 @@ msgstr "公司"
|
||||
#. module: hr
|
||||
#: field:hr.job,message_summary:0
|
||||
msgid "Summary"
|
||||
msgstr ""
|
||||
msgstr "摘要"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,note:hr.process_transition_contactofemployee0
|
||||
@@ -615,12 +615,12 @@ msgstr ""
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "HR Settings"
|
||||
msgstr ""
|
||||
msgstr "人資設定"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Citizenship & Other Info"
|
||||
msgstr ""
|
||||
msgstr "公民與其他資訊"
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.department:0
|
||||
@@ -635,7 +635,7 @@ msgstr "辦公地址"
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Public Information"
|
||||
msgstr ""
|
||||
msgstr "公開資訊"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,marital:0
|
||||
|
||||
@@ -42,6 +42,8 @@ class hr_config_settings(osv.osv_memory):
|
||||
help ="""This installs the module hr_contract."""),
|
||||
'module_hr_evaluation': fields.boolean('Organize employees periodic evaluation',
|
||||
help ="""This installs the module hr_evaluation."""),
|
||||
'module_hr_gamification': fields.boolean('Drive engagement with challenges and badges',
|
||||
help ="""This installs the module hr_gamification."""),
|
||||
'module_account_analytic_analysis': fields.boolean('Allow invoicing based on timesheets (the sale application will be installed)',
|
||||
help ="""This installs the module account_analytic_analysis, which will install sales management too."""),
|
||||
'module_hr_payroll': fields.boolean('Manage payroll',
|
||||
|
||||
@@ -56,6 +56,10 @@
|
||||
<field name="module_hr_expense" class="oe_inline"/>
|
||||
<label for="module_hr_expense"/>
|
||||
</div>
|
||||
<div>
|
||||
<field name="module_hr_gamification" class="oe_inline"/>
|
||||
<label for="module_hr_gamification"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<group name="timesheet_grp">
|
||||
|
||||
@@ -57,9 +57,10 @@ class res_users(osv.Model):
|
||||
various mailboxes, we do not have access to the current partner_id. """
|
||||
if kwargs.get('type') == 'email':
|
||||
return super(res_users, self).message_post(cr, uid, thread_id, context=context, **kwargs)
|
||||
res = None
|
||||
employee_ids = self._message_post_get_eid(cr, uid, thread_id, context=context)
|
||||
if not employee_ids:
|
||||
pass # dpo something
|
||||
if not employee_ids: # no employee: fall back on previous behavior
|
||||
return super(res_users, self).message_post(cr, uid, thread_id, context=context, **kwargs)
|
||||
for employee_id in employee_ids:
|
||||
res = self.pool.get('hr.employee').message_post(cr, uid, employee_id, context=context, **kwargs)
|
||||
return res
|
||||
|
||||
@@ -72,4 +72,4 @@
|
||||
.openerp .oe_employee_vignette .oe_followers {
|
||||
width: auto;
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2010-today OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# 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 models
|
||||
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
{
|
||||
'name': 'Applicant Resumes and Letters',
|
||||
'version': '1.0',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 25,
|
||||
'summary': 'Search job applications by Index content.',
|
||||
'description': """This module allows you to search job applications by content
|
||||
of resumes and letters.""",
|
||||
'author': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': [
|
||||
'hr_recruitment',
|
||||
'document'
|
||||
],
|
||||
'data': [
|
||||
'views/hr_applicant.xml'
|
||||
],
|
||||
'demo': [
|
||||
'demo/hr_applicant.xml'
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': True,
|
||||
'application': True,
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -0,0 +1,257 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="applicant_attach1" model="ir.attachment">
|
||||
<field name="datas">JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURl
|
||||
Y29kZT4+CnN0cmVhbQp4nJ1UTWvDMAy951f4PKhnKbEdQyk0TXrYrRDYYey2D9hhsF7292fZtdJk
|
||||
djpG4REqS37vSbKSIL6rL6GE8l/aaYmibUC24vxaPd6Jzxjzv/N71Y2VNj5krRHji7g/ggAlxren
|
||||
rYIdbhUS1AQNgSYwBHb3PD5Uw1idsuU0Srss2FKeI9jHCh663cYSYglK4UP8KpAA7bz2LIueEgfW
|
||||
FhQdPYCKpNKFACx9SHQB11U3sLgNKB+aBPHKS6UAWXk3NPswEG0wHMGcgDo1Cyz7HQ620w09ezAw
|
||||
q5ZPTwFXEu5Q1sKik83S6BtiimGg6YBuNixwmNsFk+CrP3vOwXnbiuxj28AuxoTqjR/ZwUI6+zvj
|
||||
aUUfBAcDHFPbUEVe/mvaM5dYI/5hxZSRy3HDmm1xvKl6tr3IN8U+66sp34AtjBs5i00cqjVSpkWP
|
||||
uY3bM6nLG1La3GBwtk5xG27udHGbvSodM6jMwE7RQTRsVx3C+8ukrRrgHx69fAT6VBLslQGzZf3P
|
||||
I4BULQK1El0arvg6kAFItmMX5495n8QPLYlXWAplbmRzdHJlYW0KZW5kb2JqCgozIDAgb2JqCjQx
|
||||
MwplbmRvYmoKCjUgMCBvYmoKPDwvTGVuZ3RoIDYgMCBSL0ZpbHRlci9GbGF0ZURlY29kZS9MZW5n
|
||||
dGgxIDE4MjEyPj4Kc3RyZWFtCnic3XsJXFTXvf8599w7GwPMDDsIXAZxiQgI4hYThlVRtgBuSY2O
|
||||
zCBEYAgzuD4jxocbGJKagKiN1qbG2DRaaw3GFI1iE7PU2GjaxqapjWljQkyedUkNnLzfOfcOW0zS
|
||||
z+v//3mfz2PkzrnnnvNbvr/1XBJPXb0TGVEDIshWVm2vvf0+vYYQehMhbClb6pF9ta0/gfFfEBKS
|
||||
ymsXV3e7UD5CognWPL+4akX5uuXzcuH+ZYTCxAqn3dE4bkMCQpEn4PmECpiIpjVauP8S7odXVHuW
|
||||
/8b/EQmhqGFwf3+Vq8zesfb8Krhfzu6r7ctrP8LPsOfn4V6usVc7L60/dy/cX4fb67Uut+d+tPZr
|
||||
hNI+Zs9r65y1jZ2vdiFk0yGkjYA5DB/2Y4Shht0LRJQ0Wp3e4GP09fM3mS0BgUHBIaFh4RHDIqOi
|
||||
5Rhr7PC4ESNHjb5rDPq/+dOB3uC/+/ET8F3OZzYIa5DQ9+lAp+C5wNd14DfwJvwSjPeiHriuQ9ew
|
||||
gbyKJ8KoE/bOFWNgtgXt5DtbyN9RPXkZvYPOoIsw+jueTGAvfgfF4A+A2qZ+LqQT7k7BdRXpJHNx
|
||||
NK5Gz+AXgOIq4OlCawT4FoqB8lviOZh9C22Az1b0DHLBmEm2DuR/Hx1GTeg62iZcQffD+CV0GuSh
|
||||
yE/hgS+gm0Bpv3CPUA7rTgO17Wg7XocuILeIsAFWXpIuCGOA6mHQAKFFaKd0QdrG8IDvC9IX8ASc
|
||||
VdOhCdTGghYMt734ZTxOKEDvwP5VqJT8gDxMLuJGMVZcRq6gFgGRheghdFa6oAlELdpY1KIpxyvE
|
||||
hfyziuknLBMX4v3oCtBcRL6E+xiQbCfXGKHDQrFUIBWAzuUwt5NfW5SrxoTeIrcB9ycEiqeLOSQN
|
||||
nqwS89A2tAd2jgRkEHKRVODuQqukLcoH7YfPWGkLaQX6HA2cItyDdgrluAmkvQloukgWmgg8IqWr
|
||||
qBEfBrmRdjVySxcQCkQvajWSSASM4mXTQSEu13HQdt9c+bV5MWPjh9zKJq18EBUd9F0hd3z9ddFc
|
||||
MUKad1AadpDE6Q6KcbGXvu3hpbHxM4vmyh04JDtLJZu9MAsmS+bCkN3BNMxnZ/FnjOtBKQ7+5S48
|
||||
KJdVyJtNm2OnbDY5p4wFm1fQVrFCegaylxZFv4xEDMogDQ48gnXSOkFEiV3nu8ch0/nu891JAeYY
|
||||
c1yMOaZCRD1uEtHzEW3V+n15rU4zmsWJAFZBYj2goEMBaIwtFLeZUJt+o8Vk0AEhKdl3khlF6VMC
|
||||
TT3dyT3d5pDJ41DidUYXm1OSJ6SOHxEbF5MsBgWKY7A5Frd80vyjnVtoHj58Gwv0668+eV1K7D37
|
||||
ZGPj1r0fXnz/r737GE+MHwKe68BPzKjQFqDR+hBkJm1+nfqTWoNGg3QW0/mu7mRgdBk4vWmebJ6c
|
||||
ZIszIRM2mWUkY9mchJJwiinJbEM2nGmymYtQES4yFZkt83ECjrVqgsyx5pSge3FKcnCIuO7ulbnP
|
||||
Hzl6NOH4uqylE8iKhLv+8GbvO+LCi8vWWIcrGGz6+kNxOsjjg0JQLEjUbEHNxk5Le6je4p9FLEH3
|
||||
hpqud/cwSEEi09UkDCwCgxX9RyZbzCYh1iqYTRahovnxx5u3PP74liu3bn5y5eZN8sF77164ePHC
|
||||
u+/tpL+jf6WX6Dt4LKSBKJzAsvYpwGEkeGIAGm8Ll0zYqDuiwc1oh5/mpEEI0CK9pPH19wk0nZ/a
|
||||
1TO1K3kyA/8ymMF0NdkyeXISDgJdI3FMUAzoG5Makzp+Qoo48lxZPl5L13TQC3jMc7/UBLbft7is
|
||||
pSeRnGsp6HhB0fcQ8M0CvnrkixJsYbojyNhl2IFOaoQjIsnzwRopD800aP2A8eXunqmgeGJ38uUe
|
||||
rjq4UhDwMsfglKBYKDy/x9U9NbiaXsLRHR3iwp7ElhaSIWReYfrtBj4GTTRwGWEL0CNiOGI8TY5I
|
||||
RCMijU+eHuh397zJtQJ0zUyjwOC7mVYjUpk+wpoH5v3+yk9/Rf+IP8Ct//HIzvMnyT8fB/lXgb3m
|
||||
gr2C0DCUbRuBggk2NOm3aIKPYE2zL34lrDmg07c9kgjDTPpgDcodZjFNj+Qm7DJbGD9mx8umq/C5
|
||||
ftXC/AsHxSgWnRjkh2NlZDahlGSLlnuTVpzb8+HxF+aeqK489QD9ir6H5S/evdUhPrGx8XmT8OD9
|
||||
mhdfmzT5xTFj8GQcgI3YRv98es9zB3eC/k2gfw7Elh5V24ZpsYAFjVaToRUIOqyTNFgrmMVxWjNK
|
||||
MkB0cQAAiandYOckSAtak3iG/c6zHgrBGM+3jQgRQrWjhRHaSdo5gkN4SFsvrNQaQjUj8GhNDs7V
|
||||
zMGLcYVGNx/ND4iB6AQLmWObwEJfnvoaUd0p6cJXKeJbt8eIb32VAhg2Aoax3OdHoxrbXQYtCpeN
|
||||
of5adCRU22yJaZKPRzYPZzHgi0PFMD+Dxpgli5qge+8CHLsgGSQr4nZdvt7DYsJ0lcUpYGmBYI1M
|
||||
ik6Sk2KSrLvRbrxb2G3Y7bMneHfI7tDdYbvD/ebzEFXQTp1ojk0FxMHi4yfcjVMVwFOV0I3CQuc9
|
||||
P/7JyqptL+CjR+/+ZcPP3vzqH7fw+q0Pnnig/NjcptP3jJCFlIdrnbXvvDQ6r3ftXseCV/YcOxm5
|
||||
fsWE8R0jRxYXJ2/l+QZVgx1coKsV/cQ2MtTirxe1KDJCow0yNsukM+JkmEmLzP66fE2BOd+/YFho
|
||||
fnh2rOn6zIPG0pkHzaUPzD2Kwr8+MWlez1RuJgs309TL18FUTOnJkBWTbNOSxCQpSZOkTdIl6ZMM
|
||||
ST5pwWkhaaFpYWnhaRFpw9Ii06IaSIPYIDVoGrQNugZ9g6HBpyW4JaQltCWsJbwlomVYS2RLVCye
|
||||
j7n2YTjWDNlVSWZ9AzWrCc9YK2dscO1LzSm6e9/kGbmTn302piwtz0muTs8+Rz/oXSas/cy96qPe
|
||||
NcLaL2rZt7hw4dS0HIh9DIEpfCSO5LUjwuYr7EHPi3s0Eo4UkQ7inefd7uuQ31MYO8jpV3rgRxxJ
|
||||
z9HJ9KyCJ6sZBeDX4Du2YE2bKLShjbo28RcGLOnHaUkUSjHyetHVxYh185wZwNKU+nuaLO0tFR7r
|
||||
rROO9yyTLuynOft7P9yv0GY5MQJsFYDibaF6P4IIxLS503jSANGDZvjqNT45geCDySwfJ4IVWFGC
|
||||
AL4DSmLE0YceXtvU0TFun/tnzwlHemcIR9oee/FnvRvEhfsWll1Scj8tFqPFZaDLMJRiGxZq1JNm
|
||||
f31zUKd/e8SpsJORoUaNJnwasljuVTJIcjJLH5d5IVBTlloIrRrMPJkVAua9qQy8vA2NjZs2NTZu
|
||||
EMLHtjvPXPn4dUd7wtGjwph337t44cLF93o3l8zDE7EZB+Mpc0pa/nlTwQBiM0J8cAgG7QZ80sj0
|
||||
nwFAcAx6lCqZrGIQAPZSpGGGU8LqVMeS2kc3Hz067rmHn9+H9zEQGATCiq/27LM7Lqnx8fWH5GWw
|
||||
pxn4hRi1OowOiW3+ujbDRv92i14b5YNSLaae8z1d3gp487dM9YmpUZhzY/XApAFu1Q+crGh5mK4T
|
||||
pr1za2HnPd333ffUGyRrf4+F/u2TeIXXBdBNA/YdieptNl+j4OcTEh2l0wtaQ0hUdFRGZFSowScq
|
||||
WgxCTfiEGNgUdCK02Sw2x3Wa20dFGnyiI7SoMELjl6vVBFqzR5mudwEIl1lS96Z1E71x1XTjqiWE
|
||||
pyKeR/0+A3i0/DrPioMS1PzDynBQIBN7pKrI+EQhAbMqmhxM3ircXbJ61Q9enLFpS/fvSo48tPjl
|
||||
0pXrb+iyd/3wvdfv3ytOPpyQcF/JzBmxfuE7V+89FhvbmZpaNq9hnOAXvXXNjw/EcN+KA19+HnAV
|
||||
kAFts6WjOIxESRTiJFELv5o4SRL1ccSgg18cZyAGFAeNNTFkIKJtwwfJRr2k12k1vDHVS4kGH9Of
|
||||
unkDNhVqsVc53Wdak/SZVvk3YKT7DAqHlrDCEW5A/tBFtyCRYB9BJEZRr9Xo1uNNAisWmEApx7Ek
|
||||
hsQKFRfwfvqLG/jMuZreG1XnpNhekbxwewxupKuQWnct0DeYIFaSoGNBgeHNfoHNuna/TryDhEBV
|
||||
F6aZLT7T+yMlsbs/UPqcUo2QgZFD7u/oSGh3vHHlk9ed26n/xsbGpqbGxo3knJD5z+4tJXMwtAUQ
|
||||
JRPnUJ933/vTeYgc5ks31fpqgP4ikLA8JG3UQvuqi9VEERSLfaDB6OpR2hfetEIjLKXGpbAcBLE6
|
||||
hb6Ai17HE3pe2y/W53XMuH1BzUHbgG4snIuGoftso9GwOEkjwdmZhETEaTRShsn8rG9bYKuI2gRk
|
||||
MgjYEBViNZHhkaYe4HXihFIfGMPrbyomkrj/wVdI8jxrHGufJqCJ92JFc6XYQQet0fphXC+80FN/
|
||||
DIemOnK2NjzwWu3iV+0Xsc88x6QL+/fvP40T7l3ZVrj6sYzMN8clX/n1whOe9L8xu7zC+iGwi49i
|
||||
l74c1u7fGbEjDHLXNJ7FcphdkpXEOcAuStrkxuClR+lnR4wMgkRKWjc2rt+8eX3jxt4P43eUv/7x
|
||||
lTcggXV0CIksgZ3/03vC8uK59Az9nH5KT88p2cKOVRhOb0jUSU9D/hpnC/WTdP7kCDLjk7ojBp2P
|
||||
Ho4VGpPFb3BX2319aherpsxNWJEY1Aea4Ri3hz74YP3ZS2f3s7ZWepqebOnd/R+Ltu59Q1jYgu+F
|
||||
M8VWekm4hhORhEJtPuQnaI+GiDgSWMEp6E1IDT2spAWR2AB8s+f09jKceJauxWsUezcBfuPA3mHQ
|
||||
DYeH/RIdCm4jvr80HjK16VtJe3hAshGN0ySFs5qmHgJ4EryaFOdtFmMg4fPEovj2hIniuPw9D0C/
|
||||
fwqn4cgH9uTP2D/7dFfX6bnP5aaOHo1bcS2uwe2jR5+9x0bfpm/R39K3bff01z9+Jhhc/3bcuf51
|
||||
37H+mb+n/mkCe5/hBVBAnXS2WAr52KTUv76Y7vRrx6fIyUiI52k8sgd4z8D6F9dXb1W/GeRPy+Dc
|
||||
BWH9949fL2/HX2xQfGnDlt4zGkNLyRz6G/oJuM6ZOfiG6k6KPWYDBisgro2o0RavE4igJUQA/bFe
|
||||
EHCGgTXQOuihfSA9Qm6U4NAoJho0KMlX6aND1D66izVmSgSe8XbTbAyJ0d+A0XzbcEln0IfgUBKi
|
||||
C9VDG01G6EbrJ+DJZIJukt7PXwsfA5mPoZ/WY3bGwrEA82zIHAIWsf8xerOd3nhJutCrE768PUYa
|
||||
2fMZCbj9R7Xvnwjya1CqLUyKAwVIHCT+DAn6JCIR2GxF0VoTO45MVg7U3kTBfudZoVcCVjFN5Pne
|
||||
T94RdL2p0oXZt9dKY5i9ylkvy2uKL8qwRWNf4gs1wxdqho+2TcJQNLDRgKJ0osbfONzP1NNznrep
|
||||
rE9gI8uAswVDAhQjKWDAWH6EFD6go/HvYz559dUzvRukyJ5PyVs9Kc/QndhxHEHHyM4MeRAn/JyM
|
||||
DbZw8lO9pS3K2BbaGtU+PCgqQhODIqz+UTHRw0E5SLimq96O4fzVJNu7iSgRJwqJJFFMlBI1idpE
|
||||
XaI+0ZDok4bScJqQRtLENClNk6ZN06Xp0wxpPoWoEBcKhYZCnwVoAV4gLDAs8NmFduFdwi6yS9wl
|
||||
7dLs0u7S7dLvMuzyOYAO4APCAXJAPCAd0BzQHtAd0B8wHPA5jo7j48Jxclw8Lh3XHNce1x3XHzcc
|
||||
98n5NmFUVmSBuEBaoFmgXaBboGeMv43QcHAQzHsGpZkIUHMAC4eBLwfwh/kTJhUVTp40s3FLU9OW
|
||||
x5qaHvv8xo3PP79+Xbg6saho4qSCPGEnJIMz9HX6Nk7CE6AvTNpNl9O19FG6HG/Ej+A1eCOPD+jh
|
||||
xbn8XDncFqD23+IvdBLmzfd4g9J8K438wNY79gpx9f5AcPbueIN13dP3907s6zfjIAeEoURbuLHJ
|
||||
94QJNYWdCG4mpmZ9J0uAFiPS5IRDt+XNfyZ6nXVZd0iA3pOdGDfjR8W0h17EcVi8b3tB7tb5P3/p
|
||||
2PMLt6VPhqPyJBwIn0l3xb+SPuUvb5+9dPe9zLfr6TXxB+BfZhSJ7rHJKMpk9o9oI0E8DZujzKEm
|
||||
oz8KtSQbJ4Qma1KjvKdmdggDsbq4o8EZFHxcsmpiB9hBG6IN8NoBZoQWbbju9q1bPb23NjW91mba
|
||||
sL19w4b27RsiBNyA1+MNuIE20BX0Pdo+vdNBbuFcHE7/Rl+kHfRvOAziYC/g/zB/Z2ZGMkgaG4ba
|
||||
DPo2y0bcZvhFtNknLDpAJ0jILypYSh42To+iLEkxygu08zxbT+47Fk3uf49GBrxQY66kZd2pOBrj
|
||||
hz8/2Pr0vs8//eG6tU/SGfilj75ct27rs/Qm/SfNEc70vr9qyw83CeX03trVDzv2/uZXm54ODD67
|
||||
+42zgGcEfUXcLrkhXsejWtu4UWOGh4cQP6M+Yjw5EKI/YDSPHH5gTEjUgXFjUkf6akaBkccEonDf
|
||||
BGNgzBjj2IRU6Dd7ukx0aheken60ZyifZ1NdF7rgyD95sjLND/2+6tE2oCGwIUjDYqK/DgT0H/L5
|
||||
0Yg9UrxmwsSQfheyBIl+DUuWrF27ZElD8+Nx64p//M47Py5aP/zgEzfp+3gGtkyompyUtmoK3UHn
|
||||
4+V46rnbQszaHTvWPrpjB/3YlZZ17eWXr+Xck7azE2LmKNhrZWDQhrBQ/DvcDFb9Lb35F+gT+PkX
|
||||
jwMrmo6gPQK0CKLpPO+I+JGXHXfxOH7QFdAaiIscnu+Go7tt1gANagv+mcm3yfiYqc2qaRvWam2P
|
||||
C9AQHG3VRxlHhEXHmXoug0v2vSi8yWKEvV3ytrmABuFnDYuZN8Kp4y0psoXpbh0hlK7dunXt+o0b
|
||||
LqU9ln/idOL+mj989o8/Y/EafZ9+mvuk0PrSM8+89Iufv3Cwd9NLcSNxDA5zLMGG6/+F9XQzddEN
|
||||
1B2N1Pc6LEeHgszgmdrosDZDdJvJ8DMRN6HHxLbgVlN7nDUKjfC1ajXDcAATursb5O5rbD5S3uYk
|
||||
YbWh4bU9KFCIlQUl0Ae+/iQfMGl/k8Skvf4+7bkGhStwxpP0/bVPPgnKbJQOg7D0A/p3xxJ66x/X
|
||||
6E1cj5/AK/GW6N4qr0I8B7F3sBNB7lFoGvTcAW1Bhib9Xt82TXSTvHdYW2yrpj3oudHBAYgEhkWN
|
||||
MEURa3SgPno09NxdalSB/N19nRmPLB5AA493I8bg1L4jR3/jTXRbd9JPbyx+d3H5bxbtPXRo2/bt
|
||||
TTufWD+vs2LFr3Pfw9ImEj3y1ad+++mI4WdSx7duebR978pq96pRo16S5Yu/WvWM0rO0gPxjISew
|
||||
zGUVtZHhbVpzk+mxwDZflp1927X7oyA3h0RhgxWZoqPYYaFLrY9eX6FdEEc8WTPJUFAgGiQ8k/ms
|
||||
cL23a8yc+I+xiX54a9npgh+8ZH/2V8eevW97DsvoT5j86dVPuukXsvxW8riDe3YfiosDT18HshVw
|
||||
P45FiSjTFhdqRG0jNW1RY9ssULlHPpcUahx+V1TQ8Ch/fVRQhJVE+cdEJ4GI3VxG3uip8Jp42A96
|
||||
Ax7nPTP3Ja1Y63CYCRhwvhMqNmx9qnHj1qfo62ufuPb2uWtPrG3dRenly/TrXfkNK1Y2rFm1okE4
|
||||
3bZ5c3tb86ZtpTGH1xw6d+7QmsMxMa/tev3yh2d2n8GLlj/yyPKVDWsVvMHXS1ee+3PxuAX+U2+g
|
||||
aB3/s98bzz25o/+PgLRYfF4DQYF0fVOwT1tNIwf8pRAP+cshFs+hCnQaP8T+cocOod1oFfRzjewd
|
||||
IuSO0zDH5qvRBTjds781bUOvoHV4K6w5hTqhc22CDq0RKvQpVA91IgL2rIH7TXD6Xsfpj0AL0T50
|
||||
Gcu4FIrNecEqbCPgGcRGashe8oU4SnxQPC9Nlf5TOqjRaYo0mzX7NFe1I7S12re1VDdVj/Sj9FX6
|
||||
E4ZAw9OGwz5+Pg/5vG4MNT6qahKPUsHeylt+E2pnmktzsBlORSLMBWO/Pn0X9OmOYeUCdSzAOpc6
|
||||
hgyJ3OpYhPE6dSxBX75VHWuQH9qljlk1/Lk69oE46FTHvvqt6KI69oPupAYoY1EPd52GPeoYI9ln
|
||||
oToWkM6nQR0TmN+ojkUY71PHcMrzeU0da9Awn7+oYx2y+vSoYx80xRiljn0DRhjnqmM/VBH9SKar
|
||||
dkVd5eIKjzyqbLScnJSUIi9aIWdUetyeOqe9Ol7OrSlLkNOrquRitsotFzvdzrqlTkeCIcv5kH12
|
||||
vVxWYa9Z7HTL9jqnXFkj19Yvqqoskx2uantljXdNib3GLee7alwZLteSoXND72c769yVrho5OSEl
|
||||
RXnGHg1YWe6qAUE8IF6Fx1M7JTHRAfNL6xPcrvq6Mme5q26xM6HG6cnhy5hYTLU+leRRbqdTXuSs
|
||||
ci0bnSD/C0okGAz9m0E4u6xQ7oPOMPY7fwyG/znI8hDOlSCi7KmzO5zV9rolsqt8KBWDochZV13p
|
||||
5gjC6gpnnRN4La6z13icjni5vA6Uh22gMMAUL3tcsr1mhVwLmMMG1yIPKFxZsxi4lIHQbKWnwqki
|
||||
bi8rc1XXwnK2wFMB1AEkZ40bALZySKyjgZhDtrvdrrJKO/ADBMvqq501HruHyVNeWQUYj2IU+Qa5
|
||||
xFXuWQaYW0dzSeqctXUuR32Zk5NxVIJilYvqPU4uw6AN8WClsqp6B5NkWaWnwlXvAWGqK1VGbH2d
|
||||
AiWQrXfDeqZOvFzt5Fpz+7or4gfwiGc8E111stsJdoDVlSCqqv4Q1kw4IFvLgPao0HFGyypc1d/c
|
||||
wMxQXl9XAwydfKPDJbtd8bK7ftFDzjIPm1EwrgKXZAqVuWoclUwP9xSDoRQe2Re5ljq5BooXcQH6
|
||||
nKDG5QEzuJVZZpXafg9QnsnuCjsotcipogZigJPbB+npqgG/qJOrXXXOO6ote1bUOsvtwChBEWrw
|
||||
02r7Cka/2uWoLK9kjmav8oDrwQCI2h0OrrkCHYsvex3IVV9lr+OMHE535eIaLsbiqhW1FW62iXmo
|
||||
vQyIuNkOrzzuoZwUj3MogNmrBhAYQkTd55WlnyKIWFO1Qq4c5OqgUp2T/SdIfC0buBmYzDbeEHGC
|
||||
3zkVBZa56hxu2doXi1bG2/tAtrLQtXLYwDp5aswsckI0Mar1YAemxFJXZZ9gzuUeiBrZXlsLIWZf
|
||||
VOVkDxT9gfIQw1TYPXKF3Q0UnTWDcQF2/R7ukOtrHKrA1sF5xapo+F2WdbuqWGRz0zFD2eUqlkEg
|
||||
XrwLa+1lS+yLQTGIxRpXX/741x1rECtIWiCis6qcCTU9W84pLCiVSwpzSuekF2fLuSVyUXHh7Nys
|
||||
7CzZml4C99Z4eU5u6fTCWaUyrChOLyidJxfmyOkF8+SZuQVZ8XL23KLi7JISubBYzs0vysvNhrnc
|
||||
gsy8WVm5BdPkDNhXUFgq5+Xm55YC0dJCvlUllZtdwojlZxdnTofb9IzcvNzSefFyTm5pAaOZA0TT
|
||||
5aL04tLczFl56cVy0aziosKSbKCRBWQLcgtyioFLdn42KAGEMguL5hXnTpteGg+bSmEyXi4tTs/K
|
||||
zk8vnhnPJCwElYtlviQBpAQacvZstrlkenpenpyRW1pSWpydns/WMnSmFRTmM4xmFWSll+YWFsgZ
|
||||
2aBKekZetiIbqJKZl56bHy9npeenT8su6WfClqnq9MPBNkzLLsguTs+Ll0uKsjNz2QBwzC3Ozizl
|
||||
KwF7QCKPi5tZWFCSfd8smIB1XhZgkOnZnAUokA7/MrlkXP0CUJfRKS0sLu0TZU5uSXa8nF6cW8JE
|
||||
yCkuBHGZPWEH03EW4MmMV6DKy2zE5r7pHbCK7VYVzMpOzwOCJUyMb6wF78peXuas9TDfVoNbSY88
|
||||
lSr5M557rZIEwIWn1UDgKnN8CP4MkcUrj5Lh+oOLleR4Nf2y9AHeDdVISb+OpU7Igm6WSiA+XCyZ
|
||||
LKt080iHMljtUuue214FzGBX3yrIl/Yq2ObuE3NwQHkLYm1dJWxZVlfpgWQi2+thtq5ypVqK69RS
|
||||
NVQDxmWo/HVOdy1UqsqlzqoVCbC2jtUzLkllDbRb1arqHL4yzxRvDvXIizlxBygOTVmCbPjOfi1x
|
||||
WeWSysRKyFHLE2orahPVRIkyoROvRStQHapEi+FM4kEynI7L0Gj4TkZJ8EmB0SJYIaMMWOOBbt0D
|
||||
q53IDueTeJjNRTWwPgFG6agKPjIq7qPl5ndO+HbCnqVwdcBKA8qC0UNAYTacX2TYXQHjGtjj5Dvs
|
||||
nL4MVGrgWgtrFgHdSlgnw34X8LXzZ0PplHAqjEI+rKqB3wz4daEl37vu+57P5vK7gauLy5QMWqTA
|
||||
Z+A+76470yznswoiHhU9hpAH9JsC5+VE0ExZvxTWJ8A6F3zXgc5OvreOo5MANJywJ2cANS9aXqt9
|
||||
00rsGbOAk1vSCVi60DJYy2z2/8YSzKaGO3JWkLPDaKDM3/Q6Axr7b3wY9/8NT74z2v06V6ooyvy5
|
||||
ndu4mqO6BOZcYNnvk4VpVsTpVXNq/T6o0K7gz5yqXos5lxruYQ5Op5w/dfZxUyyseFM8l8vFJazh
|
||||
+2tVP1c4uICqR7VwJfcKRZcyFWkvTQ+XYrCP22FVGfeQWpW6lwJbrciueJKTR43iwdYBXmLllmN7
|
||||
HfzbzeUqgz12VT/FB8vAK6s5FQ9/4sWnHEZVqh+P6pOxnwOLcya/B2JB8XPGsR8TNlMLVxdwqedy
|
||||
9kvj4Bp4uK8tgqce/tTL49s5xKuxVAaS1XMqCibLuA9U8Jj3qMhU87mBGnnp1w3ySkXaeo5h/ADr
|
||||
sHE1t6fX1v3x64bd8d+iR3yfnok878icshIPCu1KFdXB1v9urb3IKdLW9nm0Z4jX9Wu0jONR/S9x
|
||||
8EZDOc+ZNaqGzgEcHfzKeMTzb4bEQ7CijNNT1gz04yo1S3otVMZ5O7jElaqkU3h0lqq77EDRxTND
|
||||
vw0G5qJ+BL6ZCVi98KjR4B601hsr/YgNzAED98lcZ7tqqUV9edvrawoaSia3f4c9XbzGyKrtq/l3
|
||||
f/74V2zhAc1red2yqxolDELqu/YyTFb0yV/No6+Sx7I3ozHZPWrWU2YUSRmmjgE2H+h13vrFuCh4
|
||||
1QMVO9/n1cjBJWX2qhmAxmJYx7SpUOfqBuRQO/cexXe9PIbi4/5enQbmOMcgD7NzG91Jgu+WZDC/
|
||||
objcScZ41e5VfF/ld2T1OjUDObl81YPoemfcfZ7pjZuhVcSp5jvnIAss41o5+H7rHeqitU/voTvY
|
||||
em/VtQ7wNiV28obUmUU87l0DZK1X48FriaXwtPIOiDnRco5zjRrRtfBRqpidZ1Zn346B9ldk/u6I
|
||||
qeCZXubfblVGJ/eob/cXRbs75XD2tJ6vGozwnVCVByA30Ib/05h18+zprdn9UeeNKNZBVPX1IHXq
|
||||
jsEUa7lHL4HrYtViSl2s4dgO7T/+f2Ssb9dqkRojHrUulvchNR1lcz6FqADuGJ9CuCtFc6CfLObP
|
||||
cmFOhn6uGJ7MhrssmM3idknnT9hzK4/GOTBmFAvRLE5LoVEMV0Z7Hsww2jK/Z3czYX0B0GJ7s9Fc
|
||||
ziMbqJXwlcWcdj7M5sF3trqO7ciEmVlwz8bTEOtGFX4FsKuUxw7bx2RRJC2F+X6ug6XK5Ry9kuXD
|
||||
XTHQn64+TQfauZwekz+eI8XGBX1y5qiSpnOMGGVGMxMkyuN3bHYWfBfBuhKOZzrXWZG2gOuQA88V
|
||||
XbK5BIolFIky4bsIeLMV00CuUi4F41SqroznGjJ9svh+xnUmn1UkK1StzMb9VBJULBU5GP6z+ziX
|
||||
cP3z4CNz/UthppTbJh3oe+l6fWcap5Df50ezuH7pHIdCziGDP2MoMjzz+lYWD7BKJseL2Y1JnsU5
|
||||
pXNESu6oiZfaYOvcyTu8HKZx/bI5Unl8dQngmA3rc/tmFH/M5bpmqtgqNBW/V3wibwC6mVxHZtn7
|
||||
gGu26lPpHLvBWigRwuTv10KxQLp6zRyAWb/1C1TrZvbZupB72TdRmcNjMZuvSue2LulDIYfHb74q
|
||||
+awBHua14yzVPwv7JBuMrzeOvOv+ldyh0PLyHmzBLO5PeaqEJX1ofD9dJXdlQ10r4+cdT1/eHly5
|
||||
B3aP/V3pwP4zfkCuHdgJKFl4Gl9bPWRd/6ySn5Wa1X/mGdjD3alyeU/JSk/f3/16uw8ldytno4Hd
|
||||
r4P36Uov6O7rSpT64errTJbxp/01XTkNVvMVA897bs5X0axe3TGUltJf2nm3wLi574Dmd1WooSfE
|
||||
Wl7vFS7L+NijdiZMv3p1LZtfOeRUXDfkVPV9NvDq8n3413F716pnqkqOMOsnE1S6dch7PuvHhCGg
|
||||
vN2qHmL1fu9j1KagoX0ow2DxAMkdqsWVN2WMp+HfeL+WyPFeAr+JXEYH7/wSeBdeC3ODO0rlv4VA
|
||||
Xz+C7kd3+DkqNOCgQ0/Ol9KH4SDUighcG/j/T0thHMCvFmSBq5mPTfzqj7bD1Y+PfQ99Ok1Kj8O+
|
||||
aDXcGVEcXH1QMlwNnJ6er9IhP7hq+VjD10h8LPJ5wmcEPoNt8yihlPSuJj2UfEXJ7WTyz2Pky9Xk
|
||||
1s1m6RYlt06IN2/Mk242k5sN4o3rI6Qb88gNm3h9BPnHtUTpH7fJtUTyX5R8QcnnyeRqIPmslXSD
|
||||
iN2UdHd8fc72tfjpNPLJFYf0SSu54iAfU/L3v0VIf6fkbxHkI0ouLyEfUvLXY+TSX8KkS7fJX8LI
|
||||
B63kz5S8T8mfLgZJf6LkYhB5r5X88Q9B0h8p+cMWH+kPQeT3q8m7U8gFuLkwhZyn5J3fGaR3KPmd
|
||||
gZyj5G1Kzm42S2eHkd8Gk7coebOVvNEUJ71ByeuUnFlNXqPkVUp+Q8np7b5SFyWnKDlJySuUnAB6
|
||||
JwLJcSPp/PUxqZOSX788X/r1MfLrBvHlY3HSy/PJyzbxWBx5iZKjraSjJV16kZIj8HXkNvkV0DpM
|
||||
yS8d5JCD/MKPHLSQA5S8QG295OeUPE/JzyxkPyXP7fOTnksm+/zIs3vN0rOjyF4z+ekzY6WfribP
|
||||
jCU/oWQPJT+mZPeuMGm3g+x62iTtCiNPm8iPDGQnJTuAyQ5KtvuS9m0JUjsl2xJIG/BvayWtTx2T
|
||||
Wil5CnzrqWPkqQbxycfjpCfnkydt4lZKfkjJE3D/xDHyeBxpATBa0sljoO1jgWSLD2mGiWYHaQLQ
|
||||
muLIZjPZRMlGSjZQsr7RLK2npNFM/pOSdZQ8as6QHi0haylpWE7WPLJaWkPJI6vJ6ijyH5Ss8iMr
|
||||
KVlGyVJK6j1Gqd6f1HdgZHtP9BiJ54TothC3Tayj5GFKailx1ZRIrlZSUz1Kqikh1aNIFSVLkslD
|
||||
lFQmk4rbZPExUk6JkxIHJWWLoqQyShYhk7QoitgpWUjJAkoevN9HetCPzHeQH7xGHoCbBwLJ/T4E
|
||||
PHpuIJlDyWxKZkWESbOSSSklJZQUU3LfalJESWEgKaAkH4+V8inJO0ZmjiIzckOlGRNJbqZFyg0l
|
||||
07NDpemUTIO7aQ6SA3c5x0h2KMmCiayJJDPDLGVaSGaHYLPpxYx0fynDTDI6BAR36TY/Kd2fpHfg
|
||||
E3BnSzNKNj9i68ANcJdm1EtpRpLWgW02h3gvJfeACPfcJlMpuXsUmULJZAB4soNMGhcuTZpJJlIy
|
||||
YWygNIGS1JlkfFK4NH4mSYGvFEqSYWEyJePg8bhwkhROEmGUGEoS9MFSwjEyNj5AGhtIxnYIjG28
|
||||
ySzFB5B4Jm6rOOauOGkMJXfByrviyGhhijSaklGUjKRkhD+JC86Q4rLJcH8SS4nV31+yUhIjj5Vi
|
||||
VhN5LImeSaKAcxQlkZQMA2yHURIBVokII+GUhFESSkkIUAjJIcFBY6XgDBIUaJKCxpJAEwmAdQGB
|
||||
xAL7LZSYQXNzBjEBB5OZmBTs/P2Mkr8/8Vew8/M1SH5G4qdg5wvY+RqIL2B3WDTqiZH51kTRhxID
|
||||
aGKgRB9MdCaipUQDpDWUSIGEgHLkNhFgQphCMAiAxxJkIrgDOxq34DH/d37Q/7YA/+ZPJPpvgO3r
|
||||
dQplbmRzdHJlYW0KZW5kb2JqCgo2IDAgb2JqCjEwNDEzCmVuZG9iagoKNyAwIG9iago8PC9UeXBl
|
||||
L0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL0JBQUFBQStEZWphVnVTYW5zTW9ubwovRmxhZ3MgNQov
|
||||
Rm9udEJCb3hbLTU1NyAtMzc0IDcxNiAxMDQxXS9JdGFsaWNBbmdsZSAwCi9Bc2NlbnQgOTI4Ci9E
|
||||
ZXNjZW50IC0yMzUKL0NhcEhlaWdodCAxMDQxCi9TdGVtViA4MAovRm9udEZpbGUyIDUgMCBSCj4+
|
||||
CmVuZG9iagoKOCAwIG9iago8PC9MZW5ndGggNDE2L0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVh
|
||||
bQp4nF2TzW7iMBSF93kKLzuLKvEPCZVQJAaKxKIz1dA+QEgME2lwIhMWvH197klbaRagz/G9l8/m
|
||||
JN/st/vQT/lrHNqDn9SpD1301+EWW6+O/tyHTBvV9e00r+S7vTRjlqfew/06+cs+nIbVKsv/pL3r
|
||||
FO/qYd0NR/8jy3/Hzsc+nNXD++aQ1ofbOP7zFx8mVWR1rTp/SnNemvFXc/G5dD3uu7TdT/fH1PJd
|
||||
8HYfvTKy1lRph85fx6b1sQlnn62Kolar3a7OfOj+23OWLcdT+7eJqVSn0qJYFHViI1wZsBUud2BH
|
||||
LsEL8hO4JG/AFXkBXgq7Z/ATn2vwmrwF/xQ28rsbYbsGb9krc55ZL3N2dMMcXZBRo+nv0Ktnfwum
|
||||
v5P62d+B6W/lOf0tzqtnf2H6V1JPf4Mzavo7mU//cgmmf4Wz6NkfZ9T0txWY/hYzDf0t6s3sj7s1
|
||||
9C8x39B/AU9Dfwc3Q38nvfQ3uB9Df4v/xdDfykz6W5lJf4t7M/S3SwnJnAbEBXn+jKFqbzGmCEro
|
||||
JXtIXR/813sxDiO65PMBZrbPkAplbmRzdHJlYW0KZW5kb2JqCgo5IDAgb2JqCjw8L1R5cGUvRm9u
|
||||
dC9TdWJ0eXBlL1RydWVUeXBlL0Jhc2VGb250L0JBQUFBQStEZWphVnVTYW5zTW9ubwovRmlyc3RD
|
||||
aGFyIDAKL0xhc3RDaGFyIDQzCi9XaWR0aHNbNjAyIDYwMiA2MDIgNjAyIDYwMiA2MDIgNjAyIDYw
|
||||
MiA2MDIgNjAyIDYwMiA2MDIgNjAyIDYwMiA2MDIgNjAyCjYwMiA2MDIgNjAyIDYwMiA2MDIgNjAy
|
||||
IDYwMiA2MDIgNjAyIDYwMiA2MDIgNjAyIDYwMiA2MDIgNjAyIDYwMgo2MDIgNjAyIDYwMiA2MDIg
|
||||
NjAyIDYwMiA2MDIgNjAyIDYwMiA2MDIgNjAyIDYwMiBdCi9Gb250RGVzY3JpcHRvciA3IDAgUgov
|
||||
VG9Vbmljb2RlIDggMCBSCj4+CmVuZG9iagoKMTAgMCBvYmoKPDwvRjEgOSAwIFIKPj4KZW5kb2Jq
|
||||
CgoxMSAwIG9iago8PC9Gb250IDEwIDAgUgovUHJvY1NldFsvUERGL1RleHRdCj4+CmVuZG9iagoK
|
||||
MSAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDQgMCBSL1Jlc291cmNlcyAxMSAwIFIvTWVkaWFC
|
||||
b3hbMCAwIDU5NSA4NDJdL0dyb3VwPDwvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCL0kgdHJ1
|
||||
ZT4+L0NvbnRlbnRzIDIgMCBSPj4KZW5kb2JqCgo0IDAgb2JqCjw8L1R5cGUvUGFnZXMKL1Jlc291
|
||||
cmNlcyAxMSAwIFIKL01lZGlhQm94WyAwIDAgNTk1IDg0MiBdCi9LaWRzWyAxIDAgUiBdCi9Db3Vu
|
||||
dCAxPj4KZW5kb2JqCgoxMiAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgNCAwIFIKL09wZW5B
|
||||
Y3Rpb25bMSAwIFIgL1hZWiBudWxsIG51bGwgMF0KL0xhbmcoZW4tSU4pCj4+CmVuZG9iagoKMTMg
|
||||
MCBvYmoKPDwvQ3JlYXRvcjxGRUZGMDA1NzAwNzIwMDY5MDA3NDAwNjUwMDcyPgovUHJvZHVjZXI8
|
||||
RkVGRjAwNEMwMDY5MDA2MjAwNzIwMDY1MDA0RjAwNjYwMDY2MDA2OTAwNjMwMDY1MDAyMDAwMzMw
|
||||
MDJFMDAzNj4KL0NyZWF0aW9uRGF0ZShEOjIwMTMwOTE3MTA1MjE5KzA1JzMwJyk+PgplbmRvYmoK
|
||||
CnhyZWYKMCAxNAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMTIxNDEgMDAwMDAgbiAKMDAwMDAw
|
||||
MDAxOSAwMDAwMCBuIAowMDAwMDAwNTAzIDAwMDAwIG4gCjAwMDAwMTIyODQgMDAwMDAgbiAKMDAw
|
||||
MDAwMDUyMyAwMDAwMCBuIAowMDAwMDExMDIxIDAwMDAwIG4gCjAwMDAwMTEwNDMgMDAwMDAgbiAK
|
||||
MDAwMDAxMTIzOCAwMDAwMCBuIAowMDAwMDExNzIzIDAwMDAwIG4gCjAwMDAwMTIwNTQgMDAwMDAg
|
||||
biAKMDAwMDAxMjA4NiAwMDAwMCBuIAowMDAwMDEyMzgzIDAwMDAwIG4gCjAwMDAwMTI0ODAgMDAw
|
||||
MDAgbiAKdHJhaWxlcgo8PC9TaXplIDE0L1Jvb3QgMTIgMCBSCi9JbmZvIDEzIDAgUgovSUQgWyA8
|
||||
MUQ3RURGOENDMTExODZGOUQwNERCQTNCNTIxRUIwRUQ+CjwxRDdFREY4Q0MxMTE4NkY5RDA0REJB
|
||||
M0I1MjFFQjBFRD4gXQovRG9jQ2hlY2tzdW0gL0FGQTcyQ0IwMzY4QzE1RjAyN0YxODgxNDAxQkM3
|
||||
QkQ0Cj4+CnN0YXJ0eHJlZgoxMjY1NQolJUVPRgo=</field>
|
||||
<field name="datas_fname">Jones_CV.pdf</field>
|
||||
<field name="name">Jones_CV.pdf</field>
|
||||
<field name="res_id" ref="hr_recruitment.hr_case_salesman0"/>
|
||||
<field name="res_model">hr.applicant</field>
|
||||
</record>
|
||||
<record id="applicant_attach2" model="ir.attachment">
|
||||
<field name="datas">UFJPRklMRSANCg0KTmFtZSAgICAgICAgICAgIDogU2hhbmUgV2lsbGlhbXMgIA0KQWRkcmVzcyAgICAgICAgIDogODEgQWNhZGVteSBBdmVudWUsIA0KICAgICAgICAgICAgICAgICAgICAgOkJpcm1pbmdoYW1CNDYgM0FHLCANCiAgICAgICAgICAgICAgICAgICAgIDpVbml0ZWQgS2luZ2RvbSwgDQpRdWFsaWZpY2F0aW9uICAgOiBNQ0EgDQpFbWFpbCAgICAgICAgICAgICA6IFNoYW5lV2lsbGlhbXNAaW5mby5jb20gDQpNb2JpbGUgICAgICAgICAgIDogOTk2MzIxNDU4NyA=</field>
|
||||
<field name="datas_fname">Williams_CV.doc</field>
|
||||
<field name="name">Williams_CV.doc</field>
|
||||
<field name="res_id" ref="hr_recruitment.hr_case_programmer"/>
|
||||
<field name="res_model">hr.applicant</field>
|
||||
</record>
|
||||
<record id="applicant_attach3" model="ir.attachment">
|
||||
<field name="datas">UHJvZmlsZQ0KDQpOYW1lICAgICAgICAgIDpKb3NlDQpBZGRyZXNzICAgICAgIDo5MywgUHJlc3MgQXZlbnVlDQogICAgICAgICAgICAgICAgICAgOkxlIEJvdXJnZXQgZHUgTGFjLCA3MzM3NywNCiAgICAgICAgICAgICAgICAgICA6IEZyYW5jZSANClF1YWxpZmljYXRpb24gOk1DQQ0KRW1haWwgICAgICAgICAgIDpKb3NlQGdtYWlsLmNvbQ0KTW9iaWxlICAgICAgICAgIDo5OTY4NTEzNTg3</field>
|
||||
<field name="datas_fname">Jose_CV.txt</field>
|
||||
<field name="name">Jose_CV.txt</field>
|
||||
<field name="res_id" ref="hr_recruitment.hr_case_fresher0"/>
|
||||
<field name="res_model">hr.applicant</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import hr_applicant
|
||||
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
|
||||
class hr_applicant(osv.Model):
|
||||
_inherit = 'hr.applicant'
|
||||
|
||||
def _get_index_content(self, cr, uid, ids, fields, args, context=None):
|
||||
res = dict.fromkeys(ids, '')
|
||||
Attachment = self.pool.get('ir.attachment')
|
||||
attachment_ids = Attachment.search(cr, uid, [('res_model', '=', 'hr.applicant'), ('res_id', 'in', ids)], context=context)
|
||||
for attachment in Attachment.browse(cr, uid, attachment_ids, context=context):
|
||||
res[attachment.res_id] += attachment.index_content or ''
|
||||
return res
|
||||
|
||||
def _content_search(self, cr, user, obj, name, args, context=None):
|
||||
record_ids = set()
|
||||
Attachment = self.pool.get('ir.attachment')
|
||||
args = ['&'] + args + [('res_model', '=', 'hr.applicant')]
|
||||
att_ids = Attachment.search(cr, user, args, context=context)
|
||||
record_ids = set(att.res_id for att in Attachment.browse(cr, user, att_ids, context=context))
|
||||
return [('id', 'in', list(record_ids))]
|
||||
|
||||
_columns = {
|
||||
'index_content': fields.function(
|
||||
_get_index_content, fnct_search=_content_search,
|
||||
string='Index Content', type="text"),
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user