[MERGE] Merged with addons/trunk.

bzr revid: tde@openerp.com-20120821150936-0pvvttbq6w3t2byi
This commit is contained in:
Thibault Delavallée 2012-08-21 17:09:36 +02:00
commit eeb7878d43
48 changed files with 584 additions and 322 deletions

View File

@ -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-02-08 00:35+0000\n"
"PO-Revision-Date: 2012-05-10 17:32+0000\n"
"Last-Translator: Michael Otcheskih <otma@mail.ru>\n"
"PO-Revision-Date: 2012-08-17 11:07+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: 2012-08-07 05:06+0000\n"
"X-Generator: Launchpad (build 15745)\n"
"X-Launchpad-Export-Date: 2012-08-18 04:58+0000\n"
"X-Generator: Launchpad (build 15810)\n"
#. module: account
#: view:account.invoice.report:0
@ -9872,7 +9872,7 @@ msgstr "Не определен счет доходов для ТМЦ: \"%s\" (i
#. module: account
#: constraint:account.move.line:0
msgid "You can not create journal items on closed account."
msgstr ""
msgstr "Нельзя создать элемент журнала по закрытому счету ."
#. module: account
#: field:account.account,unrealized_gain_loss:0

View File

@ -7,19 +7,19 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev_rc3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
"PO-Revision-Date: 2011-01-13 18:03+0000\n"
"Last-Translator: Nicola Riolini - Micronaet <Unknown>\n"
"PO-Revision-Date: 2012-08-16 09:05+0000\n"
"Last-Translator: gagarin <Unknown>\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: 2012-08-07 05:14+0000\n"
"X-Generator: Launchpad (build 15745)\n"
"X-Launchpad-Export-Date: 2012-08-17 04:38+0000\n"
"X-Generator: Launchpad (build 15810)\n"
#. module: account_analytic_analysis
#: field:account.analytic.account,revenue_per_hour:0
msgid "Revenue per Time (real)"
msgstr ""
msgstr "Ricavo orario (reale)"
#. module: account_analytic_analysis
#: help:account.analytic.account,remaining_ca:0
@ -38,11 +38,13 @@ msgid ""
"The contracts to be renewed because the deadline is passed or the working "
"hours are higher than the allocated hours"
msgstr ""
"I contratti da rinnovare perchè la scadenza è passata o le ore lavorate sono "
"maggiori delle ore allocate"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Pending contracts to renew with your customer"
msgstr ""
msgstr "Contratti in sospeso da rinnovare con il cliente"
#. module: account_analytic_analysis
#: help:account.analytic.account,hours_qtt_non_invoiced:0
@ -50,6 +52,8 @@ msgid ""
"Number of time (hours/days) (from journal of type 'general') that can be "
"invoiced if you invoice based on analytic account."
msgstr ""
"Tempo fatturabile (in ore/giorni, dal giornale di tipo 'generale') se si "
"fattura tramite conto analitico"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
@ -59,17 +63,17 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Group By..."
msgstr ""
msgstr "Raggruppa per..."
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "End Date"
msgstr ""
msgstr "Data fine"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Create Invoice"
msgstr ""
msgstr "Crea Fattura"
#. module: account_analytic_analysis
#: field:account.analytic.account,last_invoice_date:0
@ -87,16 +91,18 @@ msgid ""
"Number of time you spent on the analytic account (from timesheet). It "
"computes quantities on all journal of type 'general'."
msgstr ""
"Costi orari da attribuire al conto analitico (da timesheet). Calcola "
"quantità su tutti i sezionali di tipo 'generale'."
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Contracts in progress"
msgstr ""
msgstr "Contratti attivi"
#. module: account_analytic_analysis
#: field:account.analytic.account,is_overdue_quantity:0
msgid "Overdue Quantity"
msgstr ""
msgstr "Quantità Scadute"
#. module: account_analytic_analysis
#: model:ir.actions.act_window,help:account_analytic_analysis.action_account_analytic_overdue
@ -108,16 +114,22 @@ msgid ""
"pending accounts and reopen or close the according to the negotiation with "
"the customer."
msgstr ""
"Qui troverai i contratti da rinnovare in quanto scaduti o le ore lavorate "
"sono maggiori di quelle allocate. OpenERP imposta automaticamente questi "
"conti analitici in stato sospeso, in modo da notificare un avviso durante la "
"fase di inserimento dei timesheet. I commerciali dovrebbero ricontrollare "
"tutti i contratti sospesi e riaprirli/chiuderli coerentemente con quanto il "
"cliente vuole rinegoziare."
#. module: account_analytic_analysis
#: field:account.analytic.account,ca_theorical:0
msgid "Theoretical Revenue"
msgstr "Ricavo teorico"
msgstr "Ricavo Teorico"
#. module: account_analytic_analysis
#: field:account.analytic.account,hours_qtt_non_invoiced:0
msgid "Uninvoiced Time"
msgstr ""
msgstr "Tempo non fatturato"
#. module: account_analytic_analysis
#: help:account.analytic.account,last_worked_invoiced_date:0
@ -131,7 +143,7 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "To Renew"
msgstr ""
msgstr "Da Rinnovare"
#. module: account_analytic_analysis
#: field:account.analytic.account,last_worked_date:0
@ -141,24 +153,25 @@ msgstr "Data dell'ultimo costo/lavoro"
#. module: account_analytic_analysis
#: field:account.analytic.account,hours_qtt_invoiced:0
msgid "Invoiced Time"
msgstr ""
msgstr "Tempo Fatturato"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid ""
"A contract in OpenERP is an analytic account having a partner set on it."
msgstr ""
"Un contratto in OpenERP è un conto analitico associato ad un partner."
#. module: account_analytic_analysis
#: field:account.analytic.account,remaining_hours:0
msgid "Remaining Time"
msgstr ""
msgstr "Tempo rimanente"
#. module: account_analytic_analysis
#: model:ir.actions.act_window,name:account_analytic_analysis.action_account_analytic_overdue
#: model:ir.ui.menu,name:account_analytic_analysis.menu_action_account_analytic_overdue
msgid "Contracts to Renew"
msgstr ""
msgstr "Contratti da Rinnovare"
#. module: account_analytic_analysis
#: field:account.analytic.account,theorical_margin:0
@ -168,7 +181,7 @@ msgstr "Margine teorico"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid " +1 Month"
msgstr ""
msgstr " +1 Mese"
#. module: account_analytic_analysis
#: help:account.analytic.account,ca_theorical:0
@ -184,7 +197,7 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Pending"
msgstr ""
msgstr "In sospeso"
#. module: account_analytic_analysis
#: field:account.analytic.account,ca_to_invoice:0
@ -199,7 +212,7 @@ msgstr "Calcolato utilizzando la formula: importo fatturato - totale costi"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Parent"
msgstr ""
msgstr "Mastro"
#. module: account_analytic_analysis
#: field:account.analytic.account,user_ids:0
@ -231,7 +244,7 @@ msgstr "Data dell'ultimo costo fatturato"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Contract"
msgstr ""
msgstr "Contratto"
#. module: account_analytic_analysis
#: field:account.analytic.account,real_margin_rate:0
@ -266,14 +279,14 @@ msgstr "Reddito rimanente"
#. module: account_analytic_analysis
#: help:account.analytic.account,remaining_hours:0
msgid "Computed using the formula: Maximum Time - Total Time"
msgstr ""
msgstr "Calcolato usando la formula: Tempo Massimo - Tempo Totale"
#. module: account_analytic_analysis
#: help:account.analytic.account,hours_qtt_invoiced:0
msgid ""
"Number of time (hours/days) that can be invoiced plus those that already "
"have been invoiced."
msgstr ""
msgstr "Tempo (ore/giorni) fatturabile più tempo già fatturato."
#. module: account_analytic_analysis
#: help:account.analytic.account,ca_to_invoice:0
@ -287,7 +300,7 @@ msgstr ""
#. module: account_analytic_analysis
#: help:account.analytic.account,revenue_per_hour:0
msgid "Computed using the formula: Invoiced Amount / Total Time"
msgstr ""
msgstr "Calcolato usando la formula: Fatturato / Tempo Totale"
#. module: account_analytic_analysis
#: field:account.analytic.account,total_cost:0
@ -312,12 +325,12 @@ msgstr "Contabilità Analitica"
#: model:ir.actions.act_window,name:account_analytic_analysis.action_account_analytic_overdue_all
#: model:ir.ui.menu,name:account_analytic_analysis.menu_action_account_analytic_overdue_all
msgid "Contracts"
msgstr ""
msgstr "Contratti"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Manager"
msgstr ""
msgstr "Manager"
#. module: account_analytic_analysis
#: model:ir.actions.act_window,name:account_analytic_analysis.action_hr_tree_invoiced_all
@ -328,12 +341,12 @@ msgstr "Voci da Fatturare"
#. module: account_analytic_analysis
#: help:account.analytic.account,last_invoice_date:0
msgid "If invoice from the costs, this is the date of the latest invoiced."
msgstr ""
msgstr "Se si fattura dai costi, questa è la data dell'ultima fattura."
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Associated Partner"
msgstr ""
msgstr "Partner Associato"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
@ -343,7 +356,7 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Contracts that are not assigned to an account manager."
msgstr ""
msgstr "Contratti non assegnati ad un responsabile del cliente"
#. module: account_analytic_analysis
#: field:account.analytic.account,hours_quantity:0

View File

@ -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-02-08 00:35+0000\n"
"PO-Revision-Date: 2010-12-23 13:10+0000\n"
"PO-Revision-Date: 2012-08-17 10:54+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: 2012-08-07 05:17+0000\n"
"X-Generator: Launchpad (build 15745)\n"
"X-Launchpad-Export-Date: 2012-08-18 04:58+0000\n"
"X-Generator: Launchpad (build 15810)\n"
#. module: account_analytic_default
#: help:account.analytic.default,partner_id:0
@ -133,7 +133,7 @@ msgstr "Аналитика по умолчанию"
#. module: account_analytic_default
#: sql_constraint:stock.picking:0
msgid "Reference must be unique per Company!"
msgstr ""
msgstr "Ссылка должна быть уникальна для каждой компании!"
#. module: account_analytic_default
#: view:account.analytic.default:0

View File

@ -1106,7 +1106,8 @@ class account_voucher(osv.osv):
# otherwise we use the rates of the system (giving the voucher date in the context)
amount_currency = currency_obj.compute(cr, uid, company_currency, line.move_line_id.currency_id.id, move_line['debit']-move_line['credit'], context=ctx)
if line.amount == line.amount_unreconciled and line.move_line_id.currency_id.id == voucher_currency:
foreign_currency_diff = line.move_line_id.amount_residual_currency + amount_currency
sign = voucher_brw.type in ('payment', 'purchase') and -1 or 1
foreign_currency_diff = sign * line.move_line_id.amount_residual_currency + amount_currency
move_line['amount_currency'] = amount_currency
voucher_line = move_line_obj.create(cr, uid, move_line)

View File

@ -1,3 +1,4 @@
import controllers
import auth_oauth
import res_users
import res_config

View File

@ -28,12 +28,13 @@
'author': 'Victor Tabuenca',
'maintainer': 'OpenERP s.a.',
'website': 'http://www.openerp.com',
'depends': ['base', 'web'],
'depends': ['base', 'web', 'base_setup'],
'data': [
'auth_oauth_data.xml'
'auth_oauth_data.xml',
],
'update_xml': [
'auth_oauth_view.xml'
'auth_oauth_view.xml',
'res_config.xml',
],
'js': [
'static/src/js/auth_oauth.js',

View File

@ -1,6 +1,6 @@
from openerp.osv import osv, fields
class auth_oauth_providers(osv.osv):
class auth_oauth_provider(osv.osv):
"""Class defining the configuration values of an OAuth2 provider"""
_name = 'auth.oauth.provider'
@ -8,15 +8,17 @@ class auth_oauth_providers(osv.osv):
_order = 'name'
_columns = {
'name' : fields.char('Provider name', required=True), # Name of the OAuth2 entity, Google, LinkedIn, etc
'client_id' : fields.char('Client ID', required=True), # Our identifier
'auth_endpoint' : fields.char('Authentication URL', required=True), # OAuth provider URL to authenticate users
'name' : fields.char('Provider name'), # Name of the OAuth2 entity, Google, LinkedIn, etc
'client_id' : fields.char('Client ID'), # Our identifier
'auth_endpoint' : fields.char('Authentication URL'), # OAuth provider URL to authenticate users
'scope' : fields.char('Scope'), # OAUth user data desired to access
'validation_endpoint' : fields.char('Validation URL'), # OAuth provider URL to validate tokens
'data_endpoint' : fields.char('Data URL'),
'enabled' : fields.boolean('Allowed'),
'css_class' : fields.char('CSS class'),
'body' : fields.char('Body'),
'active' : fields.boolean('Active'),
'sequence' : fields.integer(),
}
_defaults = {
'enabled' : False,
}

View File

@ -1,38 +1,34 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<data>
<record id="provider_facebook" model="auth.oauth.provider">
<field name="name">Facebook Graph</field>
<field name="client_id">facebook_client_id</field>
<field name="auth_endpoint">https://www.facebook.com/dialog/oauth</field>
<field name="scope"></field>
<field name="validation_endpoint">https://graph.facebook.com/me/permissions</field>
<field name="data_endpoint"></field>
<field name="css_class">zocial facebook</field>
<field name="body">Sign in with facebook</field>
<field name="active">True</field>
</record>
<record id="provider_google" model="auth.oauth.provider">
<field name="name">Google OAuth2</field>
<field name="client_id">108010644258-duuhmp6pu7li4tsmnqg7j9rvdeklg0ki.apps.googleusercontent.com</field>
<field name="auth_endpoint">https://accounts.google.com/o/oauth2/auth</field>
<field name="scope">https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile</field>
<field name="validation_endpoint">https://www.googleapis.com/oauth2/v1/tokeninfo</field>
<field name="data_endpoint">https://www.googleapis.com/oauth2/v1/userinfo</field>
<field name="css_class">zocial google</field>
<field name="body">Sign in with google</field>
<field name="active">True</field>
</record>
<record id="provider_twitter" model="auth.oauth.provider">
<field name="name">Twitter OAuth2</field>
<field name="client_id">108010644258-duuhmp6pu7li4tsmnqg7j9rvdeklg0ki.apps.twitterusercontent.com</field>
<!-- <record id="provider_twitter" model="auth.oauth.provider">
<field name="name">Twitter OAuth</field>
<field name="auth_endpoint">https://api.twitter.com/oauth/request_token</field>
<field name="scope"></field>
<field name="validation_endpoint">https://api.twitter.com/oauth/authorize</field>
<field name="data_endpoint"></field>
<field name="css_class">zocial twitter</field>
<field name="body">Sign in with twitter</field>
<field name="active">True</field>
</record>
</record> -->
</data>
</openerp>

View File

@ -11,7 +11,7 @@
<group>
<field name="name" />
<field name="client_id" />
<field name="active" />
<field name="enabled" />
</group>
<group>
<field name="auth_endpoint" />
@ -22,7 +22,7 @@
</sheet>
</form>
</field>
</record>
</record>
<record model="ir.ui.view" id="view_oauth_provider_list">
<field name="name">auth.oauth.provider.list</field>
<field name="model">auth.oauth.provider</field>
@ -31,7 +31,7 @@
<tree string="arch" version="7.0">
<field name="name" />
<field name="client_id" />
<field name="active" />
<field name="enabled" />
</tree>
</field>
</record>

View File

@ -18,7 +18,7 @@ class OAuthController(openerpweb.Controller):
registry = openerp.modules.registry.RegistryManager.get(dbname)
with registry.cursor() as cr:
providers = registry.get('auth.oauth.provider')
l = providers.read(cr, 1, providers.search(cr, 1, []))
l = providers.read(cr, 1, providers.search(cr, 1, [('enabled','=',True)]))
return l
@openerpweb.httprequest

View File

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012-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 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, fields
import logging
_logger = logging.getLogger(__name__)
class base_config_settings(osv.TransientModel):
_inherit = 'base.config.settings'
_columns = {
'auth_oauth_google_enabled' : fields.boolean('Allow users to sign in with Google'),
'auth_oauth_google_client_id' : fields.char('Client ID'),
'auth_oauth_facebook_enabled' : fields.boolean('Allow users to sign in with Facebook'),
'auth_oauth_facebook_client_id' : fields.char('Client ID'),
}
def get_oauth_providers(self, cr, uid, fields, context=None):
google_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'auth_oauth', 'provider_google')[1]
facebook_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'auth_oauth', 'provider_facebook')[1]
rg = self.pool.get('auth.oauth.provider').read(cr, uid, [google_id], ['enabled','client_id'], context=context)
rf = self.pool.get('auth.oauth.provider').read(cr, uid, [facebook_id], ['enabled','client_id'], context=context)
return {
'auth_oauth_google_enabled': rg[0]['enabled'],
'auth_oauth_google_client_id': rg[0]['client_id'],
'auth_oauth_facebook_enabled': rf[0]['enabled'],
'auth_oauth_facebook_client_id': rf[0]['client_id'],
}
def set_oauth_providers(self, cr, uid, ids, context=None):
google_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'auth_oauth', 'provider_google')[1]
facebook_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'auth_oauth', 'provider_facebook')[1]
config = self.browse(cr, uid, ids[0], context=context)
rg = {
'enabled':config.auth_oauth_google_enabled,
'client_id':config.auth_oauth_google_client_id,
}
rf = {
'enabled':config.auth_oauth_facebook_enabled,
'client_id':config.auth_oauth_facebook_client_id,
}
self.pool.get('auth.oauth.provider').write(cr, uid, [google_id], rg)
self.pool.get('auth.oauth.provider').write(cr, uid, [facebook_id], rf)

View File

@ -0,0 +1,50 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_general_configuration">
<field name="name">base.config.settings.oauth</field>
<field name="model">base.config.settings</field>
<field name="inherit_id" ref="base_setup.view_general_configuration"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='module_auth_oauth']/.." position="after">
<div attrs="{'invisible':[('module_auth_oauth','=',False)]}">
<div name="google">
<div>
<field name="auth_oauth_google_enabled" class="oe_inline"/>
<label for="auth_oauth_google_enabled"/>
</div>
<div attrs="{'invisible':[('auth_oauth_google_enabled','=',False)]}">
<blockquote>
To setup the signin process with Google, first you have to perform the following steps:<br/>
<br/>
- Go to the <a href="https://code.google.com/apis/console/">Google APIs console</a><br/>
- Ceate a new project<br/>
- Go to Api Access<br/>
- Create an oauth client_id<br/>
- Edit settings and set both Authorized Redirect URIs and Authorized JavaScript Origins to your hostname.<br/>
<br/>
Now copy paste the client_id here: <field name="auth_oauth_google_client_id" class="oe_inline" placeholder="e.g. 1234-xyz.apps.googleusercontent.com"/>
</blockquote>
</div>
</div>
<div name="facebook">
<div>
<field name="auth_oauth_facebook_enabled" class="oe_inline"/>
<label for="auth_oauth_facebook_enabled"/>
</div>
<div attrs="{'invisible':[('auth_oauth_facebook_enabled','=',False)]}">
<blockquote>
To setup the signin process with Google, first you have to perform the following steps:<br/>
<br/>
Now copy paste the client_id here: <field name="auth_oauth_facebook_client_id" class="oe_inline" placeholder="e.g. 1234-xyz.apps.googleusercontent.com"/>
</blockquote>
</div>
</div>
</div>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -21,9 +21,7 @@ openerp.auth_oauth = function(instance) {
},
on_oauth_loaded: function(result) {
this.oauth_providers = result;
console.log(result);
var buttons = QWeb.render("auth_oauth.Login.button",{"widget":this});
console.log(buttons);
this.$(".oe_login_pane form ul").after(buttons);
},
on_oauth_sign_in: function(ev) {

View File

@ -25,7 +25,8 @@ class base_config_settings(osv.TransientModel):
_inherit = 'base.config.settings'
_columns = {
'auth_signup_template_user_id': fields.many2one('res.users', 'Template user for new users created through signup')
'auth_signup_uninvited': fields.boolean('allow public users to sign up', help="If unchecked only invited users may sign up"),
'auth_signup_template_user_id': fields.many2one('res.users', 'Template user for new users created through signup'),
}
def get_default_signup(self, cr, uid, fields, context=None):

View File

@ -7,16 +7,15 @@
<field name="model">base.config.settings</field>
<field name="inherit_id" ref="base_setup.view_general_configuration"/>
<field name="arch" type="xml">
<xpath expr="//group[last()]" position="after">
<group>
<label for="id" string="External Users"/>
<div>
<div>
<label for="auth_signup_template_user_id"/>
<field name="auth_signup_template_user_id" class="oe_inline"/>
</div>
</div>
</group>
<xpath expr="//field[@name='module_auth_anonymous']/.." position="after">
<div>
<field name="auth_signup_uninvited" class="oe_inline"/>
<label for="auth_signup_uninvited"/>
</div>
<div>
<label for="auth_signup_template_user_id"/>
<field name="auth_signup_template_user_id" class="oe_inline"/>
</div>
</xpath>
</field>
</record>

View File

@ -28,10 +28,13 @@ class base_config_settings(osv.osv_memory):
'module_multi_company': fields.boolean('manage multiple companies',
help="""Work in multi-company environments, with appropriate security access between companies.
This installs the module multi_company."""),
'module_portal': fields.boolean('activate customer portal',
help="""The portal will give access to a series of documents for your customers; his quotations, his invoices, his projects, etc."""),
'module_share': fields.boolean('allow documents sharing',
help="""As an example, you will be able to share a project or some tasks to your customers, or quotes/sales to several persons at your customer company, or your agenda availabilities to your contacts."""),
help="""Share or embbed any screen of openerp."""),
'module_portal': fields.boolean('activate the customer/supplier portal',
help="""Give access your customers and suppliers to their documents."""),
'module_auth_anonymous': fields.boolean('activate the public portal',
help="""Enable the public part of openerp, openerp becomes a public website."""),
'module_auth_oauth': fields.boolean('use external authentication providers, sign in with google, facebook, ...'),
}
def open_company(self, cr, uid, ids, context=None):

View File

@ -28,20 +28,34 @@
</div>
</group>
<group>
<label for="id" string="Share Data"/>
<div>
<label for="id" string="Email"/>
<div name="email">
<div>
<field name="module_share" class="oe_inline"/>
<label for="module_share"/>
<button type="action"
name="%(base.action_ir_mail_server_list)d"
string="Configure outgoing email servers" class="oe_link"/>
</div>
</div>
</group>
<group>
<label for="id" string="Portal access"/>
<div>
<div>
<field name="module_portal" class="oe_inline"/>
<label for="module_portal"/>
</div>
<div>
<button type="action"
name="%(base.action_ir_mail_server_list)d"
string="Configure outgoing email servers" class="oe_link"/>
<field name="module_auth_anonymous" class="oe_inline"/>
<label for="module_auth_anonymous"/>
</div>
</div>
</group>
<group>
<label for="id" string="Authentication"/>
<div>
<div>
<field name="module_auth_oauth" class="oe_inline"/>
<label for="module_auth_oauth"/>
</div>
</div>
</group>

View File

@ -287,6 +287,7 @@
<field name="arch" type="xml">
<kanban default_group_by="stage_id">
<field name="state" groups="base.group_no_one"/>
<field name="stage_id"/>
<field name="color"/>
<field name="priority"/>
<field name="planned_revenue" sum="Expected Revenues"/>

View File

@ -32,7 +32,7 @@ class report_document_user(osv.osv):
'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':fields.char('User',size=64,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),
'create_date': fields.datetime('Date Created', readonly=True),
@ -50,7 +50,6 @@ class report_document_user(osv.osv):
to_char(f.create_date, 'YYYY') as name,
to_char(f.create_date, 'MM') as month,
f.user_id as user_id,
u.name as user,
count(*) as nbr,
d.name as directory,
f.datas_fname as datas_fname,
@ -60,8 +59,7 @@ class report_document_user(osv.osv):
f.write_date as change_date
FROM ir_attachment f
left join document_directory d on (f.parent_id=d.id and d.name<>'')
inner join res_users u on (f.user_id=u.id)
group by to_char(f.create_date, 'YYYY'), to_char(f.create_date, 'MM'),d.name,f.parent_id,d.type,f.create_date,f.user_id,f.file_size,u.name,d.type,f.write_date,f.datas_fname
group by to_char(f.create_date, 'YYYY'), to_char(f.create_date, 'MM'),d.name,f.parent_id,d.type,f.create_date,f.user_id,f.file_size,d.type,f.write_date,f.datas_fname
)
""")

View File

@ -34,8 +34,7 @@ The whole workflow is implemented:
* Draft expense
* Confirmation of the sheet by the employee
* Validation by his manager
* Validation by the accountant and invoice creation
* Payment of the invoice to the employee
* Validation by the accountant and receipt creation
This module also uses the analytic accounting and is compatible with
the invoice on timesheet module so that you will be able to automatically
@ -44,7 +43,7 @@ re-invoice your customer's expenses if your work by project.
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
'images': ['images/hr_expenses_analysis.jpeg', 'images/hr_expenses.jpeg'],
'depends': ['hr', 'account'],
'depends': ['hr', 'account_voucher'],
'init_xml': [],
'update_xml': [
'security/ir.model.access.csv',

View File

@ -40,12 +40,16 @@ class hr_expense_expense(osv.osv):
if context is None:
context = {}
if not default: default = {}
default.update({'invoice_id': False, 'date_confirm': False, 'date_valid': False, 'user_valid': False})
default.update({'voucher_id': False, 'date_confirm': False, 'date_valid': False, 'user_valid': False})
return super(hr_expense_expense, self).copy(cr, uid, id, default, context=context)
def _amount(self, cr, uid, ids, field_name, arg, context=None):
cr.execute("SELECT s.id,COALESCE(SUM(l.unit_amount*l.unit_quantity),0) AS amount FROM hr_expense_expense s LEFT OUTER JOIN hr_expense_line l ON (s.id=l.expense_id) WHERE s.id IN %s GROUP BY s.id ", (tuple(ids),))
res = dict(cr.fetchall())
res= {}
for expense in self.browse(cr, uid, ids, context=context):
total = 0.0
for line in expense.line_ids:
total += line.unit_amount * line.unit_quantity
res[expense.id] = total
return res
def _get_currency(self, cr, uid, context=None):
@ -63,7 +67,7 @@ class hr_expense_expense(osv.osv):
'name': fields.char('Description', size=128, required=True),
'id': fields.integer('Sheet ID', readonly=True),
'date': fields.date('Date', select=True),
'journal_id': fields.many2one('account.journal', 'Force Journal', help = "The journal used when the expense is invoiced"),
'journal_id': fields.many2one('account.journal', 'Force Journal', help = "The journal used when the expense is done."),
'employee_id': fields.many2one('hr.employee', "Employee", required=True),
'user_id': fields.many2one('res.users', 'User', required=True),
'date_confirm': fields.date('Confirmation Date', select=True, help = "Date of the confirmation of the sheet expense. It's filled when the button Confirm is pressed."),
@ -73,7 +77,7 @@ class hr_expense_expense(osv.osv):
'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines', readonly=True, states={'draft':[('readonly',False)]} ),
'note': fields.text('Note'),
'amount': fields.function(_amount, string='Total Amount', digits_compute= dp.get_precision('Account')),
'invoice_id': fields.many2one('account.invoice', "Employee's Invoice"),
'voucher_id': fields.many2one('account.voucher', "Employee's Receipt"),
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
'department_id':fields.many2one('hr.department','Department'),
'company_id': fields.many2one('res.company', 'Company', required=True),
@ -82,11 +86,10 @@ class hr_expense_expense(osv.osv):
('cancelled', 'Refused'),
('confirm', 'Waiting Approval'),
('accepted', 'Approved'),
('invoiced', 'Invoiced'),
('paid', 'Reimbursed')
('done', 'Done'),
],
'Status', readonly=True, help='When the expense request is created the status is \'Draft\'.\n It is confirmed by the user and request is sent to admin, the status is \'Waiting Confirmation\'.\
\nIf the admin accepts it, the status is \'Accepted\'.\n If an invoice is made for the expense request, the status is \'Invoiced\'.\n If the expense is paid to user, the status is \'Reimbursed\'.'),
\nIf the admin accepts it, the status is \'Accepted\'.\n If a receipt is made for the expense request, the status is \'Done\'.'),
}
_defaults = {
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'hr.employee', context=c),
@ -97,6 +100,13 @@ class hr_expense_expense(osv.osv):
'currency_id': _get_currency,
}
def onchange_currency_id(self, cr, uid, ids, currency_id=False, company_id=False, context=None):
res = {'value': {'journal_id': False}}
journal_ids = self.pool.get('account.journal').search(cr, uid, [('type','=','purchase'), ('currency','=',currency_id), ('company_id', '=', company_id)], context=context)
if journal_ids:
res['value']['journal_id'] = journal_ids[0]
return res
def onchange_employee_id(self, cr, uid, ids, employee_id, context=None):
emp_obj = self.pool.get('hr.employee')
department_id = False
@ -126,101 +136,94 @@ class hr_expense_expense(osv.osv):
self.write(cr, uid, ids, {'state':'cancelled'})
return True
def expense_paid(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state':'paid'})
return True
def invoice(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService("workflow")
mod_obj = self.pool.get('ir.model.data')
res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_supplier_form')
inv_ids = []
for id in ids:
wf_service.trg_validate(uid, 'hr.expense.expense', id, 'invoice', cr)
inv_ids.append(self.browse(cr, uid, id).invoice_id.id)
return {
'name': _('Supplier Invoices'),
'view_type': 'form',
'view_mode': 'form',
'view_id': [res and res[1] or False],
'res_model': 'account.invoice',
'context': "{'type':'out_invoice', 'journal_type': 'purchase'}",
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'current',
'res_id': inv_ids and inv_ids[0] or False,
}
def action_invoice_create(self, cr, uid, ids):
res = False
invoice_obj = self.pool.get('account.invoice')
def action_receipt_create(self, cr, uid, ids, context=None):
property_obj = self.pool.get('ir.property')
sequence_obj = self.pool.get('ir.sequence')
analytic_journal_obj = self.pool.get('account.analytic.journal')
account_journal = self.pool.get('account.journal')
for exp in self.browse(cr, uid, ids):
voucher_obj = self.pool.get('account.voucher')
currency_obj = self.pool.get('res.currency')
wkf_service = netsvc.LocalService("workflow")
if context is None:
context = {}
for exp in self.browse(cr, uid, ids, context=context):
company_id = exp.company_id.id
lines = []
for l in exp.line_ids:
tax_id = []
if l.product_id:
acc = l.product_id.product_tmpl_id.property_account_expense
total = 0.0
ctx = context.copy()
ctx.update({'date': exp.date})
journal = False
if exp.journal_id:
journal = exp.journal_id
else:
journal_id = voucher_obj._get_journal(cr, uid, context={'type': 'purchase', 'company_id': company_id})
if journal_id:
journal = account_journal.browse(cr, uid, journal_id, context=context)
for line in exp.line_ids:
if line.product_id:
acc = line.product_id.product_tmpl_id.property_account_expense
if not acc:
acc = l.product_id.categ_id.property_account_expense_categ
tax_id = [x.id for x in l.product_id.supplier_taxes_id]
acc = line.product_id.categ_id.property_account_expense_categ
else:
acc = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category', context={'force_company': company_id})
if not acc:
raise osv.except_osv(_('Error!'), _('Please configure Default Expense account for Product purchase: `property_account_expense_categ`.'))
total_amount = line.total_amount
if journal.currency:
if exp.currency_id != journal.currency:
total_amount = currency_obj.compute(cr, uid, exp.currency_id.id, journal.currency.id, total_amount, context=ctx)
elif exp.currency_id != exp.company_id.currency_id:
total_amount = currency_obj.compute(cr, uid, exp.currency_id.id, exp.company_id.currency_id.id, total_amount, context=ctx)
lines.append((0, False, {
'name': l.name,
'name': line.name,
'account_id': acc.id,
'price_unit': l.unit_amount,
'quantity': l.unit_quantity,
'uos_id': l.uom_id.id,
'product_id': l.product_id and l.product_id.id or False,
'invoice_line_tax_id': tax_id and [(6, 0, tax_id)] or False,
'account_analytic_id': l.analytic_account.id,
'account_analytic_id': line.analytic_account.id,
'amount': total_amount,
'type': 'dr'
}))
total += total_amount
if not exp.employee_id.address_home_id:
raise osv.except_osv(_('Error!'), _('The employee must have a home address.'))
acc = exp.employee_id.address_home_id.property_account_payable.id
payment_term_id = exp.employee_id.address_home_id.property_payment_term.id
inv = {
voucher = {
'name': exp.name,
'reference': sequence_obj.get(cr, uid, 'hr.expense.invoice'),
'account_id': acc,
'type': 'in_invoice',
'type': 'purchase',
'partner_id': exp.employee_id.address_home_id.id,
'company_id': company_id,
'origin': exp.name,
'invoice_line': lines,
'currency_id': exp.currency_id.id,
'payment_term': payment_term_id,
'fiscal_position': exp.employee_id.address_home_id.property_account_position.id
'line_ids': lines,
'amount': total,
'journal_id': journal.id,
}
if payment_term_id:
to_update = invoice_obj.onchange_payment_term_date_invoice(cr, uid, [], payment_term_id, None)
if to_update:
inv.update(to_update['value'])
journal = False
if exp.journal_id:
inv['journal_id']=exp.journal_id.id
journal = exp.journal_id
else:
journal_id = invoice_obj._get_journal(cr, uid, context={'type': 'in_invoice', 'company_id': company_id})
if journal_id:
inv['journal_id'] = journal_id
journal = account_journal.browse(cr, uid, journal_id)
if journal and not journal.analytic_journal_id:
analytic_journal_ids = analytic_journal_obj.search(cr, uid, [('type','=','purchase')])
analytic_journal_ids = analytic_journal_obj.search(cr, uid, [('type','=','purchase')], context=context)
if analytic_journal_ids:
account_journal.write(cr, uid, [journal.id],{'analytic_journal_id':analytic_journal_ids[0]})
inv_id = invoice_obj.create(cr, uid, inv, {'type': 'in_invoice'})
invoice_obj.button_compute(cr, uid, [inv_id], {'type': 'in_invoice'}, set_total=True)
self.write(cr, uid, [exp.id], {'invoice_id': inv_id, 'state': 'invoiced'})
res = inv_id
return res
account_journal.write(cr, uid, [journal.id], {'analytic_journal_id': analytic_journal_ids[0]}, context=context)
voucher_id = voucher_obj.create(cr, uid, voucher, context=context)
wkf_service.trg_validate(uid, 'account.voucher', voucher_id, 'proforma_voucher', cr)
self.write(cr, uid, [exp.id], {'voucher_id': voucher_id, 'state': 'done'}, context=context)
return True
def action_view_receipt(self, cr, uid, ids, context=None):
'''
This function returns an action that display existing receipt of given expense ids.
'''
assert len(ids) == 1, 'This option should only be used for a single id at a time'
voucher_id = self.browse(cr, uid, ids[0], context=context).voucher_id.id
res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_voucher', 'view_purchase_receipt_form')
result = {
'name': _('Expense Receipt'),
'view_type': 'form',
'view_mode': 'form',
'view_id': res and res[1] or False,
'res_model': 'account.voucher',
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'current',
'res_id': voucher_id,
}
return result
hr_expense_expense()

View File

@ -31,7 +31,7 @@
<field name="date"/>
<field name="user_id" invisible="1"/>
<field name="name"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="amount"/>
<field name="state"/>
</tree>
@ -42,7 +42,7 @@
<field name="name">hr.expense.expense.tree</field>
<field name="model">hr.expense.expense</field>
<field name="arch" type="xml">
<tree colors="blue:state == 'draft';black:state in ('confirm','accepted','invoiced','paid');gray:state == 'cancelled'" string="Expenses" editable="top">
<tree colors="blue:state == 'draft';black:state in ('confirm','accepted','done');gray:state == 'cancelled'" string="Expenses" editable="top">
<field name="employee_id"/>
<field name="date"/>
<field name="department_id"/>
@ -64,9 +64,10 @@
<button name="confirm" states="draft" string="Submit to Manager" type="workflow" class="oe_highlight"/>
<button name="validate" states="confirm" string="Approve" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button name="draft" states="confirm,cancelled" string="Set to Draft" type="workflow" groups="base.group_hr_user" />
<button name="invoice" states="accepted" string="Invoice" type="object" groups="base.group_hr_user" class="oe_highlight"/>
<button name="done" states="accepted" string="Generate Accounting Entries" type="workflow" groups="account.group_account_invoice" class="oe_highlight"/>
<button name="action_view_receipt" states="done" string="Open Receipt" type="object"/>
<button name="refuse" states="confirm,accepted" string="Refuse" type="workflow" groups="base.group_hr_user" />
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,accepted" statusbar_colors='{"confirm":"blue","cancelled":"red"}'/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,accepted,done" statusbar_colors='{"confirm":"blue","cancelled":"red"}'/>
</header>
<sheet>
<group>
@ -79,7 +80,7 @@
<group>
<field name="name"/>
<field name="user_valid"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency" on_change="onchange_currency_id(currency_id, company_id)"/>
</group>
</group>
<notebook>
@ -105,14 +106,21 @@
</group>
</form>
</field>
<separator string="Notes"/>
<field name="note" placeholder="Free Notes"/>
<group>
<div>
<separator string="Notes"/>
<field name="note" placeholder="Free Notes"/>
</div>
<group class="oe_subtotal_footer">
<field name="amount"/>
</group>
</group>
</page>
<page string="Other Info">
<group>
<group string="Accounting Data">
<field name="journal_id"/>
<field name="invoice_id" context="{'type':'in_invoice', 'journal_type': 'purchase'}"/>
<field name="journal_id" widget="selection" domain="[('type', '=', 'purchase')]"/>
<field name="voucher_id" context="{'form_view_ref': 'account_voucher.view_purchase_receipt_form'}"/>
</group>
</group>
</page>

View File

@ -32,14 +32,6 @@
<field name="action">expense_accept()</field>
</record>
<record id="act_paid" model="workflow.activity">
<field name="wkf_id" ref="wkf_expenses"/>
<field name="name">paid</field>
<field name="kind">function</field>
<field name="action">expense_paid()</field>
<field name="flow_stop">True</field>
</record>
<record id="act_refused" model="workflow.activity">
<field name="wkf_id" ref="wkf_expenses"/>
<field name="name">refused</field>
@ -47,12 +39,11 @@
<field name="action">expense_canceled()</field>
</record>
<record id="act_invoice" model="workflow.activity">
<record id="act_done" model="workflow.activity">
<field name="wkf_id" ref="wkf_expenses"/>
<field name="name">invoice</field>
<field name="kind">subflow</field>
<field name="subflow_id" ref="account.wkf"/>
<field name="action">action_invoice_create()</field>
<field name="name">done</field>
<field name="kind">function</field>
<field name="action">action_receipt_create()</field>
</record>
<record id="t1" model="workflow.transition">
@ -91,15 +82,8 @@
<record id="t8" model="workflow.transition">
<field name="act_from" ref="act_accepted"/>
<field name="act_to" ref="act_invoice"/>
<field name="signal">invoice</field>
<field name="group_id" ref="base.group_hr_user"/>
</record>
<record id="t9" model="workflow.transition">
<field name="act_from" ref="act_invoice"/>
<field name="act_to" ref="act_paid"/>
<field name="signal">subflow.paid</field>
<field name="act_to" ref="act_done"/>
<field name="signal">done</field>
<field name="group_id" ref="base.group_hr_user"/>
</record>

View File

@ -39,11 +39,10 @@ class hr_expense_report(osv.osv):
'product_id':fields.many2one('product.product', 'Product', readonly=True),
'journal_id': fields.many2one('account.journal', 'Force Journal', readonly=True),
'product_qty':fields.float('Qty', readonly=True),
'invoiced':fields.integer('# of Invoiced Lines', readonly=True),
'employee_id': fields.many2one('hr.employee', "Employee's Name", readonly=True),
'date_confirm': fields.date('Confirmation Date', readonly=True),
'date_valid': fields.date('Validation Date', readonly=True),
'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True),
'voucher_id': fields.many2one('account.voucher', 'Receipt', readonly=True),
'department_id':fields.many2one('hr.department','Department', readonly=True),
'company_id':fields.many2one('res.company', 'Company', readonly=True),
'user_id':fields.many2one('res.users', 'Validation User', readonly=True),
@ -60,8 +59,7 @@ class hr_expense_report(osv.osv):
('draft', 'Draft'),
('confirm', 'Waiting confirmation'),
('accepted', 'Accepted'),
('invoiced', 'Invoiced'),
('paid', 'Reimbursed'),
('done', 'Done'),
('cancelled', 'Cancelled')],
'Status', readonly=True),
}
@ -78,8 +76,7 @@ class hr_expense_report(osv.osv):
s.currency_id,
to_date(to_char(s.date_confirm, 'dd-MM-YYYY'),'dd-MM-YYYY') as date_confirm,
to_date(to_char(s.date_valid, 'dd-MM-YYYY'),'dd-MM-YYYY') as date_valid,
s.invoice_id,
count(s.invoice_id) as invoiced,
s.voucher_id,
s.user_valid as user_id,
s.department_id,
to_char(date_trunc('day',s.create_date), 'YYYY') as year,
@ -109,7 +106,7 @@ class hr_expense_report(osv.osv):
to_date(to_char(s.date_valid, 'dd-MM-YYYY'),'dd-MM-YYYY'),
l.product_id,
l.analytic_account,
s.invoice_id,
s.voucher_id,
s.currency_id,
s.user_valid,
s.department_id,

View File

@ -6,13 +6,13 @@
<field name="name">hr.expense.report.tree</field>
<field name="model">hr.expense.report</field>
<field name="arch" type="xml">
<tree colors="blue:state == 'draft';black:state in ('confirm','accepted','invoiced','paid');gray:state == 'cancelled'" string="Expenses Analysis">
<tree colors="blue:state == 'draft';black:state in ('confirm','accepted','done');gray:state == 'cancelled'" string="Expenses Analysis">
<field name="employee_id" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="year" invisible="1"/>
<field name="month" invisible="1"/>
<field name="day" invisible="1"/>
<field name="invoice_id" invisible="1"/>
<field name="voucher_id" invisible="1"/>
<field name="analytic_account" invisible="1" groups="analytic.group_analytic_accounting"/>
<field name="department_id" invisible="1"/>
<field name="company_id" invisible="1"/>
@ -22,7 +22,6 @@
<field name="state" invisible="1"/>
<field name="nbr" sum="# of Lines"/>
<field name="no_of_products" sum="# of Products"/>
<field name="invoiced" sum="Total Invoiced Lines"/>
<field name="price_average" avg="Average Price"/>
<field name="price_total" sum="Total Price"/>
<field name="delay_confirm"/>
@ -50,7 +49,7 @@
<search string="Expenses Analysis">
<filter string="Waiting" icon="terp-gtk-media-pause" domain="[('state', '=' ,'confirm')]" help = "Confirm Expenses"/>
<filter string="Approved" icon="terp-check" domain="[('state','=','accepted')]" help = "Approved Expenses"/>
<filter string="Invoiced" icon="terp-dolar" domain="[('state','in', ('invoiced', 'paid'))]" help = "Invoiced Expenses"/>
<filter string="Done" icon="terp-dolar" domain="[('state','=', 'done')]" help = "Done Expenses"/>
<field name="employee_id"/>
<field name="department_id"/>
<group expand="0" string="Extended Filters...">

View File

@ -17,33 +17,20 @@
!assert {model: hr.expense.expense, id: sep_expenses, severity: error, string: Expense should be in Approved state}:
- state == 'accepted'
-
I make Invoice for the expense.
I make Receipt for the expense.
-
!python {model: hr.expense.expense}: |
self.invoice(cr, uid, [ref('sep_expenses')])
!workflow {model: hr.expense.expense, action: done, ref: sep_expenses}
-
I check invoice details.
I check receipt details.
-
!python {model: hr.expense.expense}: |
sep_expenses = self.browse(cr, uid, ref("sep_expenses"), context=context)
assert sep_expenses.state == 'invoiced', "Expense should be in 'Invoiced' state."
assert sep_expenses.invoice_id, "Expense should have link of Invoice."
assert sep_expenses.invoice_id.currency_id == sep_expenses.currency_id,"Invoice currency is not correspond with supplier invoice currency"
assert sep_expenses.invoice_id.origin == sep_expenses.name,"Invoice origin is not correspond with supplier invoice"
assert sep_expenses.invoice_id.type == 'in_invoice', "Invoice type is not supplier invoice"
assert sep_expenses.invoice_id.amount_total == sep_expenses.amount,"Invoice total amount is not correspond with supplier invoice total"
assert len(sep_expenses.invoice_id.invoice_line) == len(sep_expenses.line_ids),"Lines of Invoice and supplier invoice Line are not correspond"
#TODO: check invoice line details with Expenses lines
-
I pay the expenses.
-
!python {model: hr.expense.expense}: |
self.expense_paid(cr, uid, [ref('sep_expenses')])
-
I check that state of expenses is 'Paid'.
-
!assert {model: hr.expense.expense, id: sep_expenses, severity: error, string: Expense should be in Paid state}:
- state == 'paid'
assert sep_expenses.state == 'done', "Expense should be in 'Done' state."
assert sep_expenses.voucher_id, "Expense should have link of Purchase Receipt."
assert sep_expenses.voucher_id.type == 'purchase', "Receipt type is not purchase receipt."
assert sep_expenses.voucher_id.amount == sep_expenses.amount,"Receipt total amount is not correspond with expense total."
assert len(sep_expenses.voucher_id.line_dr_ids) == len(sep_expenses.line_ids),"Lines of Receipt and expense line are not correspond."
-
I duplicate the expenses and cancel duplicated.
-

View File

@ -19,12 +19,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Recruitment Process',
'version': '1.0',
'category': 'Human Resources',
"sequence": 24,
"summary": "Recruitment Process, Job Descriptions",
'sequence': 24,
'summary': 'Recruitment Process, Job Descriptions',
'description': """
Manages job positions and the recruitment process.
==================================================
@ -46,7 +47,7 @@ system to store and search in your CV base.
'base_calendar',
'fetchmail',
],
'update_xml': [
'data': [
'wizard/hr_recruitment_employee_hired.xml',
'wizard/hr_recruitment_create_partner_job_view.xml',
'hr_recruitment_view.xml',
@ -57,19 +58,18 @@ system to store and search in your CV base.
'board_hr_recruitment_statistical_view.xml',
'hr_recruitment_installer_view.xml',
'res_config_view.xml',
],
'init_xml': [
'hr_recruitment_data.xml'
],
'demo_xml': [
'demo': [
'hr_recruitment_demo.yml',
],
'test':[
'test/recruitment_process.yml',
],
'js': ['static/src/js/hr_recruitment.js'],
'test': [
'test/recruitment_process.yml',
],
'installable': True,
'auto_install': False,
'certificate' : '001073437025460275621',
'certificate': '001073437025460275621',
'application': True,
}

View File

@ -197,6 +197,7 @@ class hr_applicant(base_stage, osv.Model):
When the case is over, the state is set to \'Done\'.\
If the case needs to be reviewed then the state is \
set to \'Pending\'.'),
'categ_ids': fields.many2many('hr.applicant_category', string='Categories'),
'company_id': fields.many2one('res.company', 'Company'),
'user_id': fields.many2one('res.users', 'Responsible'),
# Applicant Columns
@ -348,7 +349,7 @@ class hr_applicant(base_stage, osv.Model):
if isinstance(ids, (str, int, long)):
ids = [ids]
if update_vals is None: vals = {}
update_vals.update({
'description': msg.get('body'),
'email_from': msg.get('from'),
@ -503,7 +504,7 @@ class hr_job(osv.osv):
_inherits = {'mail.alias': 'alias_id'}
_columns = {
'survey_id': fields.many2one('survey', 'Interview Form', help="Choose an interview form for this job position and you will be able to print/answer this interview from all applicants who apply for this job"),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
help="Email alias for this job position. New emails will automatically "
"create new applicants for this job position."),
}
@ -514,13 +515,13 @@ class hr_job(osv.osv):
def _auto_init(self, cr, context=None):
"""Installation hook to create aliases for all jobs and avoid constraint errors."""
# disable the unique alias_id not null constraint, to avoid spurious warning during
# disable the unique alias_id not null constraint, to avoid spurious warning during
# super.auto_init. We'll reinstall it afterwards.
self._columns['alias_id'].required = False
super(hr_job,self)._auto_init(cr, context=context)
registry = RegistryManager.get(cr.dbname)
mail_alias = registry.get('mail.alias')
hr_jobs = registry.get('hr.job')
@ -548,7 +549,7 @@ class hr_job(osv.osv):
mail_alias = self.pool.get('mail.alias')
if not vals.get('alias_id'):
vals.pop('alias_name', None) # prevent errors during copy()
alias_id = mail_alias.create_unique_alias(cr, uid,
alias_id = mail_alias.create_unique_alias(cr, uid,
# Using '+' allows using subaddressing for those who don't
# have a catchall domain setup.
{'alias_name': 'jobs+'+vals['name']},
@ -566,7 +567,7 @@ class hr_job(osv.osv):
res = super(hr_job, self).unlink(cr, uid, ids, context=context)
mail_alias.unlink(cr, uid, alias_ids, context=context)
return res
def action_print_survey(self, cr, uid, ids, context=None):
if context is None:
context = {}
@ -584,4 +585,12 @@ class hr_job(osv.osv):
'nodestroy':True,
}
class applicant_category(osv.osv):
""" Category of applicant """
_name = "hr.applicant_category"
_description = "Category of applicant"
_columns = {
'name': fields.char('Name', size=64, required=True, translate=True),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -176,6 +176,9 @@
</div>
</group>
</group>
<group>
<field name="categ_ids" widget="many2many_tags"/>
</group>
<separator string="Application Summary"/>
<field name="description" placeholder="Feedback of interviews..."/>
</sheet>
@ -254,6 +257,7 @@
<field name="model">hr.applicant</field>
<field name="arch" type="xml">
<kanban default_group_by="stage_id">
<field name="stage_id"/>
<field name="color"/>
<field name="priority"/>
<field name="survey"/>
@ -264,6 +268,7 @@
<field name="job_id"/>
<field name="title_action"/>
<field name="department_id"/>
<field name="categ_ids"/>
<templates>
<t t-name="kanban-tooltip">
<ul class="oe_kanban_tooltip">
@ -308,6 +313,13 @@
<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" class="oe_kanban_avatar"/>
</div>
<div class="oe_kanban_footer_left" style="margin-top:5px;">
<div class="oe_left oe_tags">
<t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
<span class="oe_tag" t-att-data-categ_id="categ_id"></span>
</t>
</div>
</div>
</div>
<div class="oe_clear"></div>
</div>

View File

@ -8,3 +8,5 @@ access_survey_hr_user,survey.hr.user,survey.model_survey,base.group_hr_user,1,1,
access_crm_meeting_hruser,crm.meeting.hruser,base_calendar.model_crm_meeting,base.group_hr_user,1,1,1,1
access_hr_recruitment_source_hr_officer,hr.recruitment.source,model_hr_recruitment_source,base.group_hr_user,1,1,1,1
access_hr_recruitment_source_all,hr.recruitment.source,model_hr_recruitment_source,,1,0,0,0
access_hr_applicant_category,hr.applicant_category,model_hr_applicant_category,,1,0,0,0
access_hr_applicant_category_manager,hr.applicant_category,model_hr_applicant_category,base.group_hr_manager,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
8 access_crm_meeting_hruser crm.meeting.hruser base_calendar.model_crm_meeting base.group_hr_user 1 1 1 1
9 access_hr_recruitment_source_hr_officer hr.recruitment.source model_hr_recruitment_source base.group_hr_user 1 1 1 1
10 access_hr_recruitment_source_all hr.recruitment.source model_hr_recruitment_source 1 0 0 0
11 access_hr_applicant_category hr.applicant_category model_hr_applicant_category 1 0 0 0
12 access_hr_applicant_category_manager hr.applicant_category model_hr_applicant_category base.group_hr_manager 1 1 1 1

View File

@ -0,0 +1,35 @@
openerp.hr_recruitment = function(openerp) {
openerp.web_kanban.KanbanView.include({
applicant_display_categ_names: function() {
/*
* Set proper names to applicant categories.
* In kanban views, many2many fields only return a list of ids.
* Therefore, we have to fetch the matching data by ourselves.
*/
var self = this;
var categ_ids = [];
// Collect categories ids
self.$element.find('span[data-categ_id]').each(function() {
categ_ids.push($(this).data('categ_id'));
});
// Find their matching names
var dataset = new openerp.web.DataSetSearch(self, 'hr.applicant_category', self.session.context, [['id', 'in', _.uniq(categ_ids)]]);
dataset.read_slice(['id', 'name']).then(function(result) {
_.each(result, function(v, k) {
// Set the proper value in the DOM and display the element
self.$element.find('span[data-categ_id=' + v.id + ']').text(v.name);
});
});
},
on_groups_started: function() {
var self = this;
self._super.apply(self, arguments);
if (self.dataset.model === 'hr.applicant') {
self.applicant_display_categ_names();
}
}
});
};

View File

@ -6,9 +6,10 @@
<field name="model">base.config.settings</field>
<field name="inherit_id" ref="base_setup.view_general_configuration"/>
<field name="arch" type="xml">
<xpath expr="/form/group[last()]/div[last()]/div[last()]" position='after' version="7.0">
<xpath expr="//div[@name='email']" position='inside'>
<div>
<label for="alias_domain" class="oe_inline"/><field name="alias_domain" placeholder="mycompany.my.openerp.com" class="oe_inline"/>
<label for="alias_domain" class="oe_inline"/>
<field name="alias_domain" placeholder="mycompany.my.openerp.com" class="oe_inline"/>
</div>
</xpath>
</field>

View File

@ -46,7 +46,7 @@
width: 486px;
}
.openerp div.oe_mail_msg_content li {
.openerp div.oe_mail_msg_content > li {
float: left;
margin-right: 3px;
}
@ -320,6 +320,11 @@
color: #888;
}
.openerp .oe_mail_msg_footer li {
float: left;
margin-right: 3px;
}
.openerp .oe_mail_msg_body {
margin-bottom: .5em;
text-align: justify;

View File

@ -617,7 +617,7 @@ openerp.mail = function(session) {
this.options.thread_level = this.options.thread_level || 0;
this.thread_list = [];
},
start: function() {
// this._super.apply(this, arguments);
// NB: all the widget should be modified to check the actual_mode property on view, not use

View File

@ -97,7 +97,7 @@
<!-- default layout -->
<li t-name="mail.thread.message" class="oe_mail oe_mail_thread_msg">
<div t-attf-class="oe_mail_msg_#{record.type}">
<img class="oe_mail_icon oe_left" t-att-src="record.avatar"/>
<img class="oe_mail_icon oe_mail_frame oe_left" t-att-src="record.avatar"/>
<div class="oe_mail_msg_content">
<!-- dropdown menu with message options and actions -->
<span class="oe_dropdown_toggle oe_dropdown_arrow">

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2010-10-26 08:32+0000\n"
"PO-Revision-Date: 2012-08-17 11:09+0000\n"
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n"
"Language-Team: Russian <ru@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-08-07 05:25+0000\n"
"X-Generator: Launchpad (build 15745)\n"
"X-Launchpad-Export-Date: 2012-08-18 04:58+0000\n"
"X-Generator: Launchpad (build 15810)\n"
#. module: multi_company
#: model:res.company,overdue_msg:multi_company.res_company_odoo
@ -68,7 +68,7 @@ msgstr "Возвращаемое"
#. module: multi_company
#: model:ir.ui.menu,name:multi_company.menu_custom_multicompany
msgid "Multi-Companies"
msgstr ""
msgstr "Холдинги"
#. module: multi_company
#: view:multi_company.default:0

View File

@ -20,10 +20,15 @@
##############################################################################
{
'name' : "Portal",
'version' : "1.0",
'depends' : ["base", "share", "auth_anonymous"],
'author' : "OpenERP SA",
'name' : 'Portal',
'version' : '1.0',
'depends' : [
'base',
'share',
'auth_anonymous',
'auth_signup',
],
'author' : 'OpenERP SA',
'category': 'Portal',
'description': """
Customize access to your OpenERP database to external users by creating portals.
@ -41,8 +46,8 @@ very handy when used in combination with the module 'share'.
'data': [
'security/portal_security.xml',
'security/ir.model.access.csv',
'portal_view.xml',
'portal_data.xml',
'portal_view.xml',
'wizard/portal_wizard_view.xml',
'wizard/share_wizard_view.xml',
],

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<data noupdate="1">
<record id="portal" model="res.portal">
<field name="name">Portal</field>
@ -10,7 +10,7 @@
<!-- Mail group for the company's news -->
<record id="company_news_feed" model="mail.group">
<field name="name">Company's news feed</field>
<field name="name">Company's news</field>
</record>
<record id="action_news" model="ir.actions.act_window">
@ -32,24 +32,5 @@
<field name="view_mode">form</field>
</record>
<!-- Top menu item -->
<menuitem name="Portal"
id="portal_menu"
groups="base.group_no_one,portal.group_portal_member,auth_anonymous.group_anonymous"
sequence="20"/>
<menuitem name="Our company" id="portal_company" parent="portal_menu" sequence="10"/>
<menuitem name="News" id="portal_company_news" parent="portal_company" sequence="10" action="action_news"/>
<menuitem name="Jobs" id="portal_jobs" parent="portal_company" sequence="20" action="action_jobs"/>
<!--
Create menu items that we'll leave empty for now - they'll be
filled up by other portal modules.
-->
<menuitem name="Orders" id="portal_orders" parent="portal_menu" sequence="20"/>
<menuitem name="Invoices and Payments" id="portal_invoices_payements" parent="portal_menu" sequence="30"/>
<menuitem name="Projects" id="portal_projects" parent="portal_menu" sequence="40"/>
<menuitem name="After Sale Services" id="portal_after_sales" parent="portal_menu" sequence="50"/>
</data>
</openerp>

View File

@ -2,6 +2,25 @@
<openerp>
<data>
<!-- Top menu item -->
<menuitem name="Portal"
id="portal_menu"
groups="base.group_no_one,portal.group_portal_member,auth_anonymous.group_anonymous"
sequence="20"/>
<menuitem name="Our company" id="portal_company" parent="portal_menu" sequence="10"/>
<menuitem name="News" id="portal_company_news" parent="portal_company" sequence="10" action="action_news"/>
<menuitem name="Jobs" id="portal_jobs" parent="portal_company" sequence="20" action="action_jobs"/>
<!--
Create menu items that we'll leave empty for now - they'll be
filled up by other portal modules.
-->
<menuitem name="Orders" id="portal_orders" parent="portal_menu" sequence="20"/>
<menuitem name="Invoices and Payments" id="portal_invoices_payements" parent="portal_menu" sequence="30"/>
<menuitem name="Projects" id="portal_projects" parent="portal_menu" sequence="40"/>
<menuitem name="After Sale Services" id="portal_after_sales" parent="portal_menu" sequence="50"/>
<!-- portal tree view -->
<record id="portal_list_view" model="ir.ui.view">
<field name="name">Portal List</field>

16
addons/portal_event/portal_event_view.xml Normal file → Executable file
View File

@ -2,8 +2,22 @@
<openerp>
<data>
<!--
Override the original action to set another help field and/or
another context field, more suited for portal members
-->
<record model="ir.actions.act_window" id="action_event_view">
<field name="name">Events</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">event.event</field>
<field name="view_mode">kanban,calendar,tree,form,graph</field>
<field name="context">{"search_default_upcoming":1}</field>
<field name="search_view_id" ref="event.view_event_search"/>
<field name="help">No public events.</field>
</record>
<menuitem name="Events" id="portal_company_events" parent="portal.portal_company"
action="event.action_event_view" sequence="40"/>
action="action_event_view" sequence="40"/>
</data>
</openerp>

View File

@ -2,16 +2,39 @@
<openerp>
<data>
<!--
Override the original action to set another help field and/or
another context field, more suited for portal members
-->
<record id="action_order_tree5" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="context">{"search_default_draft":1}</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="help">You dont have any quotation.</field>
</record>
<record id="action_order_form" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="context">{"search_default_sales":1}</field>
<field name="help">You dont have any sale order.</field>
</record>
<record id="action_picking_tree" model="ir.actions.act_window">
<field name="name">Delivery Orders</field>
<field name="res_model">stock.picking.out</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('type','=','out')]</field>
<field name="context">{'default_type': 'out', 'contact_display': 'partner_address'}</field>
<field name="search_view_id" ref="stock.view_picking_out_search"/>
<field name="help">This is the list of all delivery orders that have to be prepared, according to your different orders.</field>
<field name="help">You dont have any delivery order.</field>
</record>
<record id="product_normal_action" model="ir.actions.act_window">
@ -22,21 +45,42 @@
<field name="view_mode">kanban,tree,form</field>
<field name="view_id" ref="product.product_kanban_view"/>
<field name="search_view_id" ref="product.product_search_form_view"/>
<field name="help">No public products.</field>
</record>
<record id="action_invoice_tree1" model="ir.actions.act_window">
<field name="name">Customer Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('type','=','out_invoice')]</field>
<field name="context">{'default_type':'out_invoice', 'type':'out_invoice', 'journal_type': 'sale'}</field>
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
<field name="help">You dont have any invoice.</field>
</record>
<record id="action_vendor_receipt" model="ir.actions.act_window">
<field name="name">Customer Payment</field>
<field name="res_model">account.voucher</field>
<field name="domain">[('journal_id.type', 'in', ['bank', 'cash']), ('type','=','receipt')]</field>
<field name="context">{'type':'receipt'}</field>
<field name="search_view_id" ref="account_voucher.view_voucher_filter_customer_pay"/>
<field name="target">current</field>
<field name="help">You dont have any payment.</field>
</record>
<menuitem name="Quotations" id="portal_quotations" parent="portal.portal_orders"
action="sale.action_order_tree5" sequence="10"/>
action="action_order_tree5" sequence="10"/>
<menuitem name="Sales Orders" id="portal_sales_orders" parent="portal.portal_orders"
action="sale.action_order_form" sequence="20"/>
action="action_order_form" sequence="20"/>
<menuitem name="Delivery Orders" id="portal_delivery" parent="portal.portal_orders"
action="action_picking_tree" sequence="30"/>
<menuitem name="Products" id="portal_products" parent="portal.portal_orders"
action="product_normal_action" sequence="40"/>
<menuitem name="Invoice" id="portal_invoices" parent="portal.portal_invoices_payements"
action="account.action_invoice_tree1" sequence="10"/>
action="action_invoice_tree1" sequence="10"/>
<menuitem name="Refund/Payments" id="portal_payments" parent="portal.portal_invoices_payements"
action="account_voucher.action_vendor_receipt" sequence="20"/>
action="action_vendor_receipt" sequence="20"/>
</data>
</openerp>

View File

@ -19,18 +19,33 @@
#
##############################################################################
{
"name": "Project Management",
"version": "1.1",
"author": "OpenERP SA",
"website": "http://www.openerp.com",
"category": "Project Management",
"sequence": 8,
"summary": "Projects, Tasks",
"images": ["images/gantt.png", "images/project_dashboard.jpeg","images/project_task_tree.jpeg","images/project_task.jpeg","images/project.jpeg","images/task_analysis.jpeg"],
"depends": ["base_setup", "base_status", "product", "analytic", "board", "mail", "resource","web_kanban"],
"description": """
'name': 'Project Management',
'version': '1.1',
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
'category': 'Project Management',
'sequence': 8,
'summary': 'Projects, Tasks',
'images': [
'images/gantt.png',
'images/project_dashboard.jpeg',
'images/project_task_tree.jpeg',
'images/project_task.jpeg',
'images/project.jpeg',
'images/task_analysis.jpeg'
],
'depends': [
'base_setup',
'base_status',
'product',
'analytic',
'board',
'mail',
'resource',
'web_kanban'
],
'description': """
Project Management module tracks multi-level projects, tasks, work done on tasks.
=================================================================================
@ -41,22 +56,21 @@ Dashboard for project management that includes:
* List of My Open Tasks
* Graph of My Remaining Hours by Project
""",
"init_xml": [],
"update_xml": [
"security/project_security.xml",
"wizard/project_task_delegate_view.xml",
"wizard/project_task_reevaluate_view.xml",
"security/ir.model.access.csv",
"project_data.xml",
"project_view.xml",
"process/task_process.xml",
"res_partner_view.xml",
"report/project_report_view.xml",
'data': [
'security/project_security.xml',
'wizard/project_task_delegate_view.xml',
'wizard/project_task_reevaluate_view.xml',
'security/ir.model.access.csv',
'project_data.xml',
'project_view.xml',
'process/task_process.xml',
'res_partner_view.xml',
'report/project_report_view.xml',
'report/project_cumulative.xml',
"board_project_view.xml",
'board_project_view.xml',
'res_config_view.xml',
],
'demo_xml': [
'demo': [
'project_demo.xml',
],
'test':[

View File

@ -229,7 +229,7 @@
<field name="alias_domain"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_project oe_kanban_auto_height oe_kanban_global_click">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_project oe_kanban_global_click">
<div class="oe_dropdown_toggle oe_dropdown_kanban">
<span class="oe_e">í</span>
<ul class="oe_dropdown_menu">

View File

@ -18,3 +18,5 @@ access_account_analytic_line_project,account.analytic.line project,analytic.mode
access_project_task_history,project.task.history project,project.model_project_task_history,project.group_project_user,1,1,1,0
access_project_task_history_cumulative,project.task.history project,project.model_project_task_history_cumulative,project.group_project_manager,1,0,0,0
access_resource_calendar,project.resource_calendar manager,resource.model_resource_calendar,project.group_project_manager,1,0,0,0
access_project_category,project.project_category,model_project_category,,1,0,0,0
access_project_category_manager,project.project_category,model_project_category,project.group_project_manager,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
18 access_project_task_history project.task.history project project.model_project_task_history project.group_project_user 1 1 1 0
19 access_project_task_history_cumulative project.task.history project project.model_project_task_history_cumulative project.group_project_manager 1 0 0 0
20 access_resource_calendar project.resource_calendar manager resource.model_resource_calendar project.group_project_manager 1 0 0 0
21 access_project_category project.project_category model_project_category 1 0 0 0
22 access_project_category_manager project.project_category model_project_category project.group_project_manager 1 1 1 1

View File

@ -239,6 +239,7 @@
<field name="model">project.issue</field>
<field name="arch" type="xml">
<kanban default_group_by="stage_id">
<field name="stage_id"/>
<field name="color"/>
<field name="priority"/>
<field name="user_email"/>

View File

@ -186,9 +186,9 @@
<para style="terp_default_9">
<font color="white"> </font>
</para>
<para style="terp_default_9">Tél. : [[ (o.partner_id.phone) or removeParentNode('para') ]]</para>
<para style="terp_default_9">Tel : [[ (o.partner_id.phone) or removeParentNode('para') ]]</para>
<para style="terp_default_9">Fax : [[ (o.partner_id.fax) or removeParentNode('para') ]]</para>
<para style="terp_default_9">TVA : [[ (o.partner_id.vat) or removeParentNode('para') ]]</para>
<para style="terp_default_9">TIN : [[ (o.partner_id.vat) or removeParentNode('para') ]]</para>
</td>
</tr>
</blockTable>

View File

@ -270,6 +270,7 @@ openerp.web_linkedin = function(instance) {
template: "LinkedIn.KeyWizard",
init: function(parent, text) {
this._super(parent, {title:_t("LinkedIn API Key")});
this.api_domain = window.location.origin;
},
start: function() {
this._super();

View File

@ -41,8 +41,7 @@
<li>Log into LinkedIn.</li>
<li>Add a new application and fill the form:
<ul>
<li>JavaScript API Domain is Your domain name (e.g. https://yourcompany.my.openerp.com)</li>
<li>You can give multiple domain (e.g. yourcompany.my.openerp.com)</li>
<li>JavaScript API Domain: <t t-esc="widget.api_domain"/></li>
<li>The programming tool is Javascript</li>
</ul>
</li>