diff --git a/addons/account/wizard/account_invoice_refund.py b/addons/account/wizard/account_invoice_refund.py
index b7d278b8849..38a22baa9f1 100644
--- a/addons/account/wizard/account_invoice_refund.py
+++ b/addons/account/wizard/account_invoice_refund.py
@@ -32,11 +32,11 @@ class account_invoice_refund(osv.osv_memory):
_name = "account.invoice.refund"
_description = "Invoice Refund"
_columns = {
- 'date': fields.date('Operation Date', help='This date will be used as the invoice date for credit note and period will be chosen accordingly!'),
+ 'date': fields.date('Date', help='This date will be used as the invoice date for credit note and period will be chosen accordingly!'),
'period': fields.many2one('account.period', 'Force period'),
'journal_id': fields.many2one('account.journal', 'Refund Journal', help='You can select here the journal to use for the credit note that will be created. If you leave that field empty, it will use the same journal as the current invoice.'),
- 'description': fields.char('Description', size=128, required=True),
- 'filter_refund': fields.selection([('refund', 'Create a draft refund'), ('cancel', 'Cancel: create credit note and reconcile'),('modify', 'Modify: create credit note, reconcile and create a new draft invoice')], "Refund Method", required=True, help='Credit note base on this type. You can not Modify and Cancel if the invoice is already reconciled'),
+ 'description': fields.char('Reason', size=128, required=True),
+ 'filter_refund': fields.selection([('refund', 'Create a draft credit note'), ('cancel', 'Cancel: create credit note and reconcile'),('modify', 'Modify: create credit note, reconcile and create a new draft invoice')], "Refund Method", required=True, help='Credit note base on this type. You can not Modify and Cancel if the invoice is already reconciled'),
}
def _get_journal(self, cr, uid, context=None):
diff --git a/addons/account/wizard/account_invoice_refund_view.xml b/addons/account/wizard/account_invoice_refund_view.xml
index 78a9b085bf1..3945a6f57e6 100644
--- a/addons/account/wizard/account_invoice_refund_view.xml
+++ b/addons/account/wizard/account_invoice_refund_view.xml
@@ -7,19 +7,40 @@
account.invoice.refund
+
+
+
+ Status Change
+ account.voucher
+
+
diff --git a/addons/account_voucher/report/__init__.py b/addons/account_voucher/report/__init__.py
index caeb155adbe..862843352a8 100644
--- a/addons/account_voucher/report/__init__.py
+++ b/addons/account_voucher/report/__init__.py
@@ -23,4 +23,4 @@ import account_voucher
import account_voucher_print
import account_voucher_sales_receipt
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/analytic/__openerp__.py b/addons/analytic/__openerp__.py
index 417d2b29b20..6227cd369d3 100644
--- a/addons/analytic/__openerp__.py
+++ b/addons/analytic/__openerp__.py
@@ -38,7 +38,8 @@ that have no counterpart in the general financial accounts.
'security/analytic_security.xml',
'security/ir.model.access.csv',
'analytic_sequence.xml',
- 'analytic_view.xml'
+ 'analytic_view.xml',
+ 'analytic_data.xml'
],
'demo': [],
'installable': True,
diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py
index 269bf24ed61..ff09349b8a2 100644
--- a/addons/analytic/analytic.py
+++ b/addons/analytic/analytic.py
@@ -284,7 +284,8 @@ class account_analytic_account(osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
- self.message_post(cr, uid, [obj.id], body=_("Contract for
%s has been
created.") % (obj.partner_id.name), context=context)
+ self.message_post(cr, uid, [obj.id], body=_("Contract for
%s has been
created.") % (obj.partner_id.name),
+ subtype="analytic.mt_account_status", context=context)
account_analytic_account()
diff --git a/addons/analytic/analytic_data.xml b/addons/analytic/analytic_data.xml
new file mode 100644
index 00000000000..67940fb2063
--- /dev/null
+++ b/addons/analytic/analytic_data.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ Status Change
+ account.analytic.account
+
+
+
+
diff --git a/addons/analytic_user_function/i18n/nl_BE.po b/addons/analytic_user_function/i18n/nl_BE.po
index 979cef10b2c..04943a48f1d 100644
--- a/addons/analytic_user_function/i18n/nl_BE.po
+++ b/addons/analytic_user_function/i18n/nl_BE.po
@@ -1,63 +1,86 @@
-# Translation of OpenERP Server.
-# This file contains the translation of the following modules:
-# * analytic_user_function
+# Dutch (Belgium) translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR
, 2012.
#
msgid ""
msgstr ""
-"Project-Id-Version: OpenERP Server 6.0dev\n"
-"Report-Msgid-Bugs-To: support@openerp.com\n"
-"POT-Creation-Date: 2009-08-28 15:34:14+0000\n"
-"PO-Revision-Date: 2009-08-28 15:34:14+0000\n"
-"Last-Translator: <>\n"
-"Language-Team: \n"
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-02-08 00:35+0000\n"
+"PO-Revision-Date: 2012-10-02 07:35+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
+"Language-Team: Dutch (Belgium) \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: \n"
-"Plural-Forms: \n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-10-03 05:09+0000\n"
+"X-Generator: Launchpad (build 16061)\n"
#. module: analytic_user_function
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr ""
+#: field:analytic.user.funct.grid,product_id:0
+msgid "Product"
+msgstr "Product"
#. module: analytic_user_function
#: model:ir.model,name:analytic_user_function.model_analytic_user_funct_grid
msgid "Relation table between users and products on a analytic account"
msgstr ""
+"Relatietabel tussen gebruikers en producten van een analytische rekening"
#. module: analytic_user_function
-#: field:analytic_user_funct_grid,product_id:0
-msgid "Product"
-msgstr ""
+#: constraint:hr.analytic.timesheet:0
+msgid "You cannot modify an entry in a Confirmed/Done timesheet !."
+msgstr "In een bevestigde/afgesloten uurrooster kunt u geen regels wijzigen."
#. module: analytic_user_function
-#: field:analytic_user_funct_grid,account_id:0
+#: field:analytic.user.funct.grid,account_id:0
+#: model:ir.model,name:analytic_user_function.model_account_analytic_account
msgid "Analytic Account"
-msgstr ""
+msgstr "Analytische rekening"
#. module: analytic_user_function
#: view:account.analytic.account:0
#: field:account.analytic.account,user_product_ids:0
msgid "Users/Products Rel."
-msgstr ""
+msgstr "Rel. gebruikers/producten"
#. module: analytic_user_function
-#: field:analytic_user_funct_grid,user_id:0
+#: field:analytic.user.funct.grid,user_id:0
msgid "User"
+msgstr "Gebruiker"
+
+#. module: analytic_user_function
+#: code:addons/analytic_user_function/analytic_user_function.py:96
+#: code:addons/analytic_user_function/analytic_user_function.py:131
+#, python-format
+msgid "There is no expense account define for this product: \"%s\" (id:%d)"
msgstr ""
+"Er is geen kostenrekening gedefinieerd voor dit product: \"%s\" (id:%d)"
#. module: analytic_user_function
-#: constraint:ir.model:0
-msgid "The Object name must start with x_ and not contain any special character !"
-msgstr "De objectnaam moet beginnen met x_ en mag geen speciale karakters bevatten !"
+#: code:addons/analytic_user_function/analytic_user_function.py:95
+#: code:addons/analytic_user_function/analytic_user_function.py:130
+#, python-format
+msgid "Error !"
+msgstr "Fout"
#. module: analytic_user_function
-#: model:ir.module.module,shortdesc:analytic_user_function.module_meta_information
-msgid "Analytic User Function"
-msgstr ""
+#: constraint:account.analytic.account:0
+msgid "Error! You can not create recursive analytic accounts."
+msgstr "U kunt niet dezelfde analytische rekeningen maken."
#. module: analytic_user_function
-#: view:analytic_user_funct_grid:0
+#: model:ir.model,name:analytic_user_function.model_hr_analytic_timesheet
+msgid "Timesheet Line"
+msgstr "Uurroosterlijn"
+
+#. module: analytic_user_function
+#: view:analytic.user.funct.grid:0
msgid "User's Product for this Analytic Account"
-msgstr ""
+msgstr "Product van gebruiker voor deze analytische rekening"
+#~ msgid ""
+#~ "The Object name must start with x_ and not contain any special character !"
+#~ msgstr ""
+#~ "De objectnaam moet beginnen met x_ en mag geen speciale karakters bevatten !"
diff --git a/addons/anonymization/anonymization.py b/addons/anonymization/anonymization.py
index 43d198b27e2..8834645c460 100644
--- a/addons/anonymization/anonymization.py
+++ b/addons/anonymization/anonymization.py
@@ -363,7 +363,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
})
raise osv.except_osv(error_type, error_msg)
- def anonymize_database(self,cr, uid, ids, context=None):
+ def anonymize_database(self, cr, uid, ids, context=None):
"""Sets the 'anonymized' state to defined fields"""
# create a new history record:
@@ -498,7 +498,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
'target':'new',
}
- def reverse_anonymize_database(self,cr, uid, ids, context=None):
+ def reverse_anonymize_database(self, cr, uid, ids, context=None):
"""Set the 'clear' state to defined fields"""
ir_model_fields_anonymization_model = self.pool.get('ir.model.fields.anonymization')
diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py
index 3dff7c1cb00..9232a696da8 100644
--- a/addons/audittrail/audittrail.py
+++ b/addons/audittrail/audittrail.py
@@ -202,7 +202,7 @@ class audittrail_objects_proxy(object_proxy):
res = value
return res
- def create_log_line(self, cr, uid, log_id, model, lines=[]):
+ def create_log_line(self, cr, uid, log_id, model, lines=None):
"""
Creates lines for changed fields with its old and new values
@@ -211,6 +211,8 @@ class audittrail_objects_proxy(object_proxy):
@param model: Object which values are being changed
@param lines: List of values for line is to be created
"""
+ if lines is None:
+ lines = []
pool = pooler.get_pool(cr.dbname)
obj_pool = pool.get(model.model)
model_pool = pool.get('ir.model')
@@ -349,9 +351,9 @@ class audittrail_objects_proxy(object_proxy):
data[(model.id, resource_id)] = {'text':values_text, 'value': values}
return data
- def prepare_audittrail_log_line(self, cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=[]):
+ def prepare_audittrail_log_line(self, cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=None):
"""
- This function compares the old data (i.e before the method was executed) and the new data
+ This function compares the old data (i.e before the method was executed) and the new data
(after the method was executed) and returns a structure with all the needed information to
log those differences.
@@ -375,9 +377,11 @@ class audittrail_objects_proxy(object_proxy):
(model.id, resource_id): []
}
- The reason why the structure returned is build as above is because when modifying an existing
+ The reason why the structure returned is build as above is because when modifying an existing
record, we may have to log a change done in a x2many field of that object
"""
+ if field_list is None:
+ field_list = []
key = (model.id, resource_id)
lines = {
key: []
@@ -416,7 +420,7 @@ class audittrail_objects_proxy(object_proxy):
lines[key].append(data)
return lines
- def process_data(self, cr, uid, pool, res_ids, model, method, old_values={}, new_values={}, field_list=[]):
+ def process_data(self, cr, uid, pool, res_ids, model, method, old_values=None, new_values=None, field_list=None):
"""
This function processes and iterates recursively to log the difference between the old
data (i.e before the method was executed) and the new data and creates audittrail log
@@ -435,6 +439,8 @@ class audittrail_objects_proxy(object_proxy):
on specific fields only.
:return: True
"""
+ if field_list is None:
+ field_list = []
# loop on all the given ids
for res_id in res_ids:
# compare old and new values and get audittrail log lines accordingly
@@ -442,11 +448,13 @@ class audittrail_objects_proxy(object_proxy):
# if at least one modification has been found
for model_id, resource_id in lines:
+ name = pool.get(model.model).name_get(cr, uid, [resource_id])[0][1]
vals = {
'method': method,
'object_id': model_id,
'user_id': uid,
'res_id': resource_id,
+ 'name': name,
}
if (model_id, resource_id) not in old_values and method not in ('copy', 'read'):
# the resource was not existing so we are forcing the method to 'create'
@@ -484,7 +492,7 @@ class audittrail_objects_proxy(object_proxy):
if len(rule['user_id']) == 0 or uid in rule['user_id']:
if rule.get('log_'+method,0):
return True
- elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create'):
+ elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create', 'read_group', 'import_data'):
if rule['log_action']:
return True
diff --git a/addons/auth_ldap/users_ldap.py b/addons/auth_ldap/users_ldap.py
index 47fc41c3645..c2c0ac557bf 100644
--- a/addons/auth_ldap/users_ldap.py
+++ b/addons/auth_ldap/users_ldap.py
@@ -180,8 +180,8 @@ class CompanyLDAP(osv.osv):
"""
user_id = False
- login = tools.ustr(login)
- cr.execute("SELECT id, active FROM res_users WHERE login=%s", (login,))
+ login = tools.ustr(login.lower())
+ cr.execute("SELECT id, active FROM res_users WHERE lower(login)=%s", (login,))
res = cr.fetchone()
if res:
if res[1]:
diff --git a/addons/auth_ldap/users_ldap_view.xml b/addons/auth_ldap/users_ldap_view.xml
index c4fc7cebbbe..47c15badd7c 100644
--- a/addons/auth_ldap/users_ldap_view.xml
+++ b/addons/auth_ldap/users_ldap_view.xml
@@ -14,7 +14,7 @@
-
+
diff --git a/addons/auth_oauth/__openerp__.py b/addons/auth_oauth/__openerp__.py
index d43815e8018..1c29ca8c093 100644
--- a/addons/auth_oauth/__openerp__.py
+++ b/addons/auth_oauth/__openerp__.py
@@ -34,11 +34,15 @@ Allow users to login through Google OAuth2.
'depends': ['base', 'web', 'base_setup'],
'data': [
'auth_oauth_data.xml',
+ 'auth_oauth_data.yml',
'auth_oauth_view.xml',
'security/ir.model.access.csv'
],
'js': ['static/src/js/auth_oauth.js'],
- 'css': ['static/lib/zocial/css/zocial.css'],
+ 'css': [
+ 'static/lib/zocial/css/zocial.css',
+ 'static/src/css/auth_oauth.css',
+ ],
'qweb': ['static/src/xml/auth_oauth.xml'],
'installable': True,
'auto_install': False,
diff --git a/addons/auth_oauth/auth_oauth_data.xml b/addons/auth_oauth/auth_oauth_data.xml
index 7bb95192e5d..83e9df2e44d 100644
--- a/addons/auth_oauth/auth_oauth_data.xml
+++ b/addons/auth_oauth/auth_oauth_data.xml
@@ -2,6 +2,15 @@
+
+ OpenERP Accounts
+ https://accounts.openerp.com/oauth2/auth
+ userinfo
+ https://accounts.openerp.com/oauth2/tokeninfo
+
+ zocial openerp
+ Sign in with OpenERP account
+
Facebook Graph
https://www.facebook.com/dialog/oauth
diff --git a/addons/auth_oauth/auth_oauth_data.yml b/addons/auth_oauth/auth_oauth_data.yml
new file mode 100644
index 00000000000..af43811a560
--- /dev/null
+++ b/addons/auth_oauth/auth_oauth_data.yml
@@ -0,0 +1,6 @@
+-
+ Use database uuid as client_id for OpenERP oauth provider
+-
+ !python {model: ir.config_parameter}: |
+ oauth = self.pool.get('auth.oauth.provider')
+ oauth.write(cr, uid, [ref('provider_openerp')], {'client_id': self.get_param(cr, uid, 'database.uuid')})
diff --git a/addons/auth_oauth/controllers/main.py b/addons/auth_oauth/controllers/main.py
index 5d939f19db1..ae01df5f6f7 100644
--- a/addons/auth_oauth/controllers/main.py
+++ b/addons/auth_oauth/controllers/main.py
@@ -16,10 +16,13 @@ class OAuthController(openerpweb.Controller):
@openerpweb.jsonrequest
def list_providers(self, req, dbname):
- registry = openerp.modules.registry.RegistryManager.get(dbname)
- with registry.cursor() as cr:
- providers = registry.get('auth.oauth.provider')
- l = providers.read(cr, SUPERUSER_ID, providers.search(cr, SUPERUSER_ID, [('enabled','=',True)]))
+ try:
+ registry = openerp.modules.registry.RegistryManager.get(dbname)
+ with registry.cursor() as cr:
+ providers = registry.get('auth.oauth.provider')
+ l = providers.read(cr, SUPERUSER_ID, providers.search(cr, SUPERUSER_ID, [('enabled','=',True)]))
+ except Exception:
+ l = []
return l
@openerpweb.httprequest
diff --git a/addons/auth_oauth/res_users.py b/addons/auth_oauth/res_users.py
index b4f62612746..fd26e89c2e3 100644
--- a/addons/auth_oauth/res_users.py
+++ b/addons/auth_oauth/res_users.py
@@ -1,6 +1,7 @@
import logging
import urllib
+import urlparse
import urllib2
import simplejson
@@ -20,8 +21,11 @@ class res_users(osv.Model):
}
def auth_oauth_rpc(self, cr, uid, endpoint, access_token, context=None):
- params = urllib.urlencode({'access_token':access_token})
- url = endpoint + '?' + params
+ params = urllib.urlencode({ 'access_token': access_token })
+ if urlparse.urlparse(endpoint)[4]:
+ url = endpoint + '&' + params
+ else:
+ url = endpoint + '?' + params
f = urllib2.urlopen(url)
response = f.read()
return simplejson.loads(response)
@@ -38,26 +42,32 @@ class res_users(osv.Model):
validation = self.auth_oauth_rpc(cr, uid, p.validation_endpoint, access_token)
if validation.get("error"):
raise openerp.exceptions.AccessDenied
- login = validation['email']
+ if p.data_endpoint:
+ data = self.auth_oauth_rpc(cr, uid, p.data_endpoint, access_token)
+ validation.update(data)
+ # required
oauth_uid = validation['user_id']
- name = self.auth_oauth_rpc(cr, uid, p.data_endpoint, access_token)['name']
-
- credentials = (cr.dbname, login, access_token)
+ if not oauth_uid:
+ raise openerp.exceptions.AccessDenied
+ email = validation.get('email', 'provider_%d_user_%d' % (p.id, oauth_uid))
+ # optional
+ name = validation.get('name', email)
res = self.search(cr, uid, [("oauth_uid", "=", oauth_uid)])
if res:
- self.write(cr, uid, res[0], {'oauth_access_token':access_token})
+ self.write(cr, uid, res[0], { 'oauth_access_token': access_token })
else:
# New user
new_user = {
'name': name,
- 'login': login,
- 'user_email': login,
- 'oauth_provider_id': 1,
+ 'login': email,
+ 'user_email': email,
+ 'oauth_provider_id': p.id,
'oauth_uid': oauth_uid,
'oauth_access_token': access_token,
'active': True,
}
self.auth_signup_create(cr, uid, new_user)
+ credentials = (cr.dbname, email, access_token)
return credentials
def check_credentials(self, cr, uid, password):
diff --git a/addons/auth_oauth/static/src/css/auth_oauth.css b/addons/auth_oauth/static/src/css/auth_oauth.css
new file mode 100644
index 00000000000..ed6130e3123
--- /dev/null
+++ b/addons/auth_oauth/static/src/css/auth_oauth.css
@@ -0,0 +1,35 @@
+.openerp .oe_application .zocial {
+ font: white;
+}
+
+.openerp .zocial.openerp:before {
+ content: "\E02E";
+ font-style: italic;
+ text-shadow: 0 1px 1px black;
+}
+
+.openerp a.zocial.openerp {
+ float: right;
+ border: 1px solid #222222;
+ color: white;
+ margin: 0;
+ background-color: #b92020;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#b92020), to(#600606));
+ background-image: -webkit-linear-gradient(top, #b92020, #600606);
+ background-image: -moz-linear-gradient(top, #b92020, #600606);
+ background-image: -ms-linear-gradient(top, #b92020, #600606);
+ background-image: -o-linear-gradient(top, #b92020, #600606);
+ background-image: linear-gradient(to bottom, #b92020, #600606);
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
+ text-shadow: none;
+ font-weight: normal;
+}
+
+.openerp .oe_login .oe_oauth_provider_login_button {
+ margin-top: 4px;
+}
diff --git a/addons/auth_oauth/static/src/js/auth_oauth.js b/addons/auth_oauth/static/src/js/auth_oauth.js
index 4a41e720726..5c80d29f4e9 100644
--- a/addons/auth_oauth/static/src/js/auth_oauth.js
+++ b/addons/auth_oauth/static/src/js/auth_oauth.js
@@ -1,8 +1,9 @@
openerp.auth_oauth = function(instance) {
var QWeb = instance.web.qweb;
- instance.web.Login = instance.web.Login.extend({
+ instance.web.Login.include({
start: function(parent, params) {
+ var self = this;
var d = this._super.apply(this, arguments);
this.$el.on('click', 'a.zocial', this.on_oauth_sign_in);
this.oauth_providers = [];
@@ -11,7 +12,13 @@ openerp.auth_oauth = function(instance) {
} else if(this.params.oauth_error === 2) {
this.do_warn("Authentication error","");
}
- return d.then(this.do_oauth_load);
+ return d.then(this.do_oauth_load).fail(function() {
+ self.do_oauth_load([]);
+ });
+ },
+ on_db_loaded: function(result) {
+ this._super.apply(this, arguments);
+ this.$("form [name=db]").change(this.do_oauth_load);
},
do_oauth_load: function() {
var db = this.$("form [name=db]").val();
@@ -21,6 +28,7 @@ openerp.auth_oauth = function(instance) {
},
on_oauth_loaded: function(result) {
this.oauth_providers = result;
+ this.$('.oe_oauth_provider_login_button').remove();
var buttons = QWeb.render("auth_oauth.Login.button",{"widget":this});
this.$(".oe_login_pane form ul").after(buttons);
},
@@ -33,7 +41,7 @@ openerp.auth_oauth = function(instance) {
var state_object = {
d: dbname,
p: p.id
- }
+ };
var state = JSON.stringify(state_object);
var params = {
response_type: 'token',
diff --git a/addons/auth_oauth/static/src/xml/auth_oauth.xml b/addons/auth_oauth/static/src/xml/auth_oauth.xml
index c2693804e59..76c71b83f10 100644
--- a/addons/auth_oauth/static/src/xml/auth_oauth.xml
+++ b/addons/auth_oauth/static/src/xml/auth_oauth.xml
@@ -2,8 +2,7 @@
-
-
+
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index 7555621945d..5b8c41787d4 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -971,8 +971,8 @@ class calendar_event(osv.osv):
event = datas['id']
if datas.get('interval', 0) < 0:
raise osv.except_osv(_('Warning!'), _('Interval cannot be negative.'))
- if datas.get('count', 0) < 0:
- raise osv.except_osv(_('Warning!'), _('Count cannot be negative.'))
+ if datas.get('count', 0) <= 0:
+ raise osv.except_osv(_('Warning!'), _('Count cannot be negative or 0.'))
if datas['recurrency']:
result[event] = self.compute_rule_string(datas)
else:
@@ -1113,6 +1113,16 @@ rule or repeating pattern of time to exclude from the recurring rule."),
'user_id': lambda self, cr, uid, ctx: uid,
'organizer': default_organizer,
}
+
+ def _check_closing_date(self, cr, uid, ids, context=None):
+ for event in self.browse(cr, uid, ids, context=context):
+ if event.date_deadline < event.date:
+ return False
+ return True
+
+ _constraints = [
+ (_check_closing_date, 'Error ! End date cannot be set before start date.', ['date_deadline']),
+ ]
def get_recurrent_ids(self, cr, uid, select, domain, limit=100, context=None):
"""Gives virtual event ids for recurring events based on value of Recurrence Rule
diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml
index 2da18447820..adcfc23a520 100644
--- a/addons/base_calendar/crm_meeting_view.xml
+++ b/addons/base_calendar/crm_meeting_view.xml
@@ -182,13 +182,14 @@
+ type="object" icon="gtk-apply"/>
+ type="object" icon="gtk-cancel"/>