[MERGE] forward port of branch saas-3 up to 3d80dc2
This commit is contained in:
commit
9363bc9182
|
@ -51,7 +51,7 @@ class account_move_line(osv.osv):
|
||||||
if bank.state in bank_type:
|
if bank.state in bank_type:
|
||||||
line2bank[line.id] = bank.id
|
line2bank[line.id] = bank.id
|
||||||
break
|
break
|
||||||
if line.id not in line2bank and line.partner_id.bank_ids:
|
if not line2bank.get(line.id) and line.partner_id.bank_ids:
|
||||||
line2bank[line.id] = line.partner_id.bank_ids[0].id
|
line2bank[line.id] = line.partner_id.bank_ids[0].id
|
||||||
else:
|
else:
|
||||||
raise osv.except_osv(_('Error!'), _('There is no partner defined on the entry line.'))
|
raise osv.except_osv(_('Error!'), _('There is no partner defined on the entry line.'))
|
||||||
|
|
|
@ -37,9 +37,9 @@ trigger an automatic reminder email.
|
||||||
'website': 'http://www.openerp.com',
|
'website': 'http://www.openerp.com',
|
||||||
'depends': ['base', 'resource', 'mail'],
|
'depends': ['base', 'resource', 'mail'],
|
||||||
'data': [
|
'data': [
|
||||||
|
'base_action_rule_data.xml',
|
||||||
'base_action_rule_view.xml',
|
'base_action_rule_view.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'base_action_rule_data.xml'
|
|
||||||
],
|
],
|
||||||
'demo': [],
|
'demo': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
|
|
|
@ -227,10 +227,20 @@ class base_action_rule(osv.osv):
|
||||||
updated = True
|
updated = True
|
||||||
return updated
|
return updated
|
||||||
|
|
||||||
|
def _update_cron(self, cr, uid, context=None):
|
||||||
|
try:
|
||||||
|
cron = self.pool['ir.model.data'].get_object(
|
||||||
|
cr, uid, 'base_action_rule', 'ir_cron_crm_action', context=context)
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return cron.toggle(model=self._name, domain=[('kind', '=', 'on_time')])
|
||||||
|
|
||||||
def create(self, cr, uid, vals, context=None):
|
def create(self, cr, uid, vals, context=None):
|
||||||
res_id = super(base_action_rule, self).create(cr, uid, vals, context=context)
|
res_id = super(base_action_rule, self).create(cr, uid, vals, context=context)
|
||||||
if self._register_hook(cr, [res_id]):
|
if self._register_hook(cr, [res_id]):
|
||||||
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
|
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
|
||||||
|
self._update_cron(cr, uid, context=context)
|
||||||
return res_id
|
return res_id
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
|
@ -239,8 +249,14 @@ class base_action_rule(osv.osv):
|
||||||
super(base_action_rule, self).write(cr, uid, ids, vals, context=context)
|
super(base_action_rule, self).write(cr, uid, ids, vals, context=context)
|
||||||
if self._register_hook(cr, ids):
|
if self._register_hook(cr, ids):
|
||||||
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
|
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
|
||||||
|
self._update_cron(cr, uid, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def unlink(self, cr, uid, ids, context=None):
|
||||||
|
res = super(base_action_rule, self).unlink(cr, uid, ids, context=context)
|
||||||
|
self._update_cron(cr, uid, context=context)
|
||||||
|
return res
|
||||||
|
|
||||||
def onchange_model_id(self, cr, uid, ids, model_id, context=None):
|
def onchange_model_id(self, cr, uid, ids, model_id, context=None):
|
||||||
data = {'model': False, 'filter_pre_id': False, 'filter_id': False}
|
data = {'model': False, 'filter_pre_id': False, 'filter_id': False}
|
||||||
if model_id:
|
if model_id:
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<field eval="'base.action.rule'" name="model"/>
|
<field eval="'base.action.rule'" name="model"/>
|
||||||
<field eval="'_check'" name="function"/>
|
<field eval="'_check'" name="function"/>
|
||||||
<field eval="'(True,)'" name="args"/>
|
<field eval="'(True,)'" name="args"/>
|
||||||
|
<field name="active" eval="False" />
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -40,6 +40,7 @@ If you need to manage your meetings, you should install the CRM module.
|
||||||
'website': 'http://www.openerp.com',
|
'website': 'http://www.openerp.com',
|
||||||
'demo': ['calendar_demo.xml'],
|
'demo': ['calendar_demo.xml'],
|
||||||
'data': [
|
'data': [
|
||||||
|
'calendar_cron.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'security/calendar_security.xml',
|
'security/calendar_security.xml',
|
||||||
'calendar_view.xml',
|
'calendar_view.xml',
|
||||||
|
|
|
@ -415,11 +415,12 @@ class calendar_alarm_manager(osv.AbstractModel):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_next_mail(self, cr, uid, context=None):
|
def get_next_mail(self, cr, uid, context=None):
|
||||||
cron = self.pool.get('ir.cron').search(cr, uid, [('model', 'ilike', self._name)], context=context)
|
try:
|
||||||
if cron and len(cron) == 1:
|
cron = self.pool['ir.model.data'].get_object(
|
||||||
cron = self.pool.get('ir.cron').browse(cr, uid, cron[0], context=context)
|
cr, uid, 'calendar', 'ir_cron_scheduler_alarm', context=context)
|
||||||
else:
|
except ValueError:
|
||||||
_logger.exception("Cron for " + self._name + " can not be identified !")
|
_logger.error("Cron for " + self._name + " can not be identified !")
|
||||||
|
return False
|
||||||
|
|
||||||
if cron.interval_type == "weeks":
|
if cron.interval_type == "weeks":
|
||||||
cron_interval = cron.interval_number * 7 * 24 * 60 * 60
|
cron_interval = cron.interval_number * 7 * 24 * 60 * 60
|
||||||
|
@ -431,9 +432,12 @@ class calendar_alarm_manager(osv.AbstractModel):
|
||||||
cron_interval = cron.interval_number * 60
|
cron_interval = cron.interval_number * 60
|
||||||
elif cron.interval_type == "seconds":
|
elif cron.interval_type == "seconds":
|
||||||
cron_interval = cron.interval_number
|
cron_interval = cron.interval_number
|
||||||
|
else:
|
||||||
|
cron_interval = False
|
||||||
|
|
||||||
if not cron_interval:
|
if not cron_interval:
|
||||||
_logger.exception("Cron delay can not be computed !")
|
_logger.error("Cron delay can not be computed !")
|
||||||
|
return False
|
||||||
|
|
||||||
all_events = self.get_next_potential_limit_alarm(cr, uid, cron_interval, notif=False, context=context)
|
all_events = self.get_next_potential_limit_alarm(cr, uid, cron_interval, notif=False, context=context)
|
||||||
|
|
||||||
|
@ -558,6 +562,35 @@ class calendar_alarm(osv.Model):
|
||||||
'interval': 'hours',
|
'interval': 'hours',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _update_cron(self, cr, uid, context=None):
|
||||||
|
try:
|
||||||
|
cron = self.pool['ir.model.data'].get_object(
|
||||||
|
cr, uid, 'calendar', 'ir_cron_scheduler_alarm', context=context)
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
return cron.toggle(model=self._name, domain=[('type', '=', 'email')])
|
||||||
|
|
||||||
|
def create(self, cr, uid, values, context=None):
|
||||||
|
res = super(calendar_alarm, self).create(cr, uid, values, context=context)
|
||||||
|
|
||||||
|
self._update_cron(cr, uid, context=context)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
def write(self, cr, uid, ids, values, context=None):
|
||||||
|
res = super(calendar_alarm, self).write(cr, uid, ids, values, context=context)
|
||||||
|
|
||||||
|
self._update_cron(cr, uid, context=context)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
def unlink(self, cr, uid, ids, context=None):
|
||||||
|
res = super(calendar_alarm, self).unlink(cr, uid, ids, context=context)
|
||||||
|
|
||||||
|
self._update_cron(cr, uid, context=context)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
class ir_values(osv.Model):
|
class ir_values(osv.Model):
|
||||||
_inherit = 'ir.values'
|
_inherit = 'ir.values'
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<openerp>
|
||||||
|
<data noupdate="1">
|
||||||
|
<!-- Scheduler for Event Alarm-->
|
||||||
|
<record forcecreate="True" id="ir_cron_scheduler_alarm" model="ir.cron">
|
||||||
|
<field name="name">Run Event Reminder</field>
|
||||||
|
<field eval="False" name="active" />
|
||||||
|
<field name="user_id" ref="base.user_root" />
|
||||||
|
<field name="interval_number">30</field>
|
||||||
|
<field name="interval_type">minutes</field>
|
||||||
|
<field name="numbercall">-1</field>
|
||||||
|
<field eval="False" name="doall" />
|
||||||
|
<field eval="'calendar.alarm_manager'" name="model" />
|
||||||
|
<field eval="'get_next_mail'" name="function" />
|
||||||
|
<!--<field eval="'(False,)'" name="args" />-->
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</openerp>
|
|
@ -72,21 +72,6 @@
|
||||||
<field name="type">email</field>
|
<field name="type">email</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
<!-- Scheduler for Event Alarm-->
|
|
||||||
<record forcecreate="True" id="ir_cron_scheduler_alarm" model="ir.cron">
|
|
||||||
<field name="name">Run Event Reminder</field>
|
|
||||||
<field eval="True" name="active" />
|
|
||||||
<field name="user_id" ref="base.user_root" />
|
|
||||||
<field name="interval_number">30</field>
|
|
||||||
<field name="interval_type">minutes</field>
|
|
||||||
<field name="numbercall">-1</field>
|
|
||||||
<field eval="False" name="doall" />
|
|
||||||
<field eval="'calendar.alarm_manager'" name="model" />
|
|
||||||
<field eval="'get_next_mail'" name="function" />
|
|
||||||
<!--<field eval="'(False,)'" name="args" />-->
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record model="calendar.event.type" id="categ_meet1">
|
<record model="calendar.event.type" id="categ_meet1">
|
||||||
<field name="name">Customer Meeting</field>
|
<field name="name">Customer Meeting</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -114,7 +114,7 @@
|
||||||
<separator string="Contact" colspan="2"/>
|
<separator string="Contact" colspan="2"/>
|
||||||
<group col="2">
|
<group col="2">
|
||||||
<field name="partner_id" select="1"
|
<field name="partner_id" select="1"
|
||||||
on_change="onchange_partner_id(partner_id, email_from)" string="Customer"
|
string="Customer"
|
||||||
colspan="2" readonly="1"/>
|
colspan="2" readonly="1"/>
|
||||||
<field name="partner_name" string="Customer Name" readonly="1"/>
|
<field name="partner_name" string="Customer Name" readonly="1"/>
|
||||||
<field domain="[('domain', '=', 'contact')]" name="title" widget="selection" readonly="1"/>
|
<field domain="[('domain', '=', 'contact')]" name="title" widget="selection" readonly="1"/>
|
||||||
|
|
|
@ -3,8 +3,10 @@ openerp.document = function (instance) {
|
||||||
instance.web.Sidebar.include({
|
instance.web.Sidebar.include({
|
||||||
init : function(){
|
init : function(){
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
this.sections.splice(1, 0, { 'name' : 'files', 'label' : _t('Attachment(s)'), });
|
if (this.getParent().view_type == "form"){
|
||||||
this.items['files'] = [];
|
this.sections.splice(1, 0, { 'name' : 'files', 'label' : _t('Attachment(s)'), });
|
||||||
|
this.items['files'] = [];
|
||||||
|
}
|
||||||
},
|
},
|
||||||
on_attachments_loaded: function(attachments) {
|
on_attachments_loaded: function(attachments) {
|
||||||
//to display number in name if more then one attachment which has same name.
|
//to display number in name if more then one attachment which has same name.
|
||||||
|
|
|
@ -56,8 +56,8 @@ For more specific needs, you may also assign custom-defined actions
|
||||||
""",
|
""",
|
||||||
'website': 'http://www.openerp.com',
|
'website': 'http://www.openerp.com',
|
||||||
'data': [
|
'data': [
|
||||||
'fetchmail_view.xml',
|
|
||||||
'fetchmail_data.xml',
|
'fetchmail_data.xml',
|
||||||
|
'fetchmail_view.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'fetchmail_installer_view.xml'
|
'fetchmail_installer_view.xml'
|
||||||
],
|
],
|
||||||
|
|
|
@ -251,27 +251,33 @@ openerp_mailgate: "|/path/to/openerp-mailgate.py --host=localhost -u %(uid)d -p
|
||||||
server.write({'date': time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)})
|
server.write({'date': time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def cron_update(self, cr, uid, context=None):
|
def _update_cron(self, cr, uid, context=None):
|
||||||
if context is None:
|
if context and context.get('fetchmail_cron_running'):
|
||||||
context = {}
|
return
|
||||||
if not context.get('fetchmail_cron_running'):
|
|
||||||
# Enabled/Disable cron based on the number of 'done' server of type pop or imap
|
try:
|
||||||
ids = self.search(cr, uid, [('state','=','done'),('type','in',['pop','imap'])])
|
cron = self.pool['ir.model.data'].get_object(
|
||||||
try:
|
cr, uid, 'fetchmail', 'ir_cron_mail_gateway_action', context=context)
|
||||||
cron_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fetchmail', 'ir_cron_mail_gateway_action')[1]
|
except ValueError:
|
||||||
self.pool.get('ir.cron').write(cr, 1, [cron_id], {'active': bool(ids)})
|
# Nevermind if default cron cannot be found
|
||||||
except ValueError:
|
return
|
||||||
# Nevermind if default cron cannot be found
|
|
||||||
pass
|
# Enabled/Disable cron based on the number of 'done' server of type pop or imap
|
||||||
|
cron.toggle(model=self._name, domain=[('state','=','done'), ('type','in',['pop','imap'])])
|
||||||
|
|
||||||
def create(self, cr, uid, values, context=None):
|
def create(self, cr, uid, values, context=None):
|
||||||
res = super(fetchmail_server, self).create(cr, uid, values, context=context)
|
res = super(fetchmail_server, self).create(cr, uid, values, context=context)
|
||||||
self.cron_update(cr, uid, context=context)
|
self._update_cron(cr, uid, context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def write(self, cr, uid, ids, values, context=None):
|
def write(self, cr, uid, ids, values, context=None):
|
||||||
res = super(fetchmail_server, self).write(cr, uid, ids, values, context=context)
|
res = super(fetchmail_server, self).write(cr, uid, ids, values, context=context)
|
||||||
self.cron_update(cr, uid, context=context)
|
self._update_cron(cr, uid, context=context)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def unlink(self, cr, uid, ids, context=None):
|
||||||
|
res = super(fetchmail_server, self).unlink(cr, uid, ids, context=context)
|
||||||
|
self._update_cron(cr, uid, context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
class mail_mail(osv.osv):
|
class mail_mail(osv.osv):
|
||||||
|
|
|
@ -24,7 +24,7 @@ class PaypalController(http.Controller):
|
||||||
""" Extract the return URL from the data coming from paypal. """
|
""" Extract the return URL from the data coming from paypal. """
|
||||||
return_url = post.pop('return_url', '')
|
return_url = post.pop('return_url', '')
|
||||||
if not return_url:
|
if not return_url:
|
||||||
custom = json.loads(post.pop('custom', '{}'))
|
custom = json.loads(post.pop('custom', False) or '{}')
|
||||||
return_url = custom.get('return_url', '/')
|
return_url = custom.get('return_url', '/')
|
||||||
return return_url
|
return return_url
|
||||||
|
|
||||||
|
|
|
@ -597,21 +597,7 @@ class sale_order(osv.osv):
|
||||||
def action_button_confirm(self, cr, uid, ids, context=None):
|
def action_button_confirm(self, cr, uid, ids, context=None):
|
||||||
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
|
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
|
||||||
self.signal_order_confirm(cr, uid, ids)
|
self.signal_order_confirm(cr, uid, ids)
|
||||||
|
return True
|
||||||
# redisplay the record as a sales order
|
|
||||||
view_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale', 'view_order_form')
|
|
||||||
view_id = view_ref and view_ref[1] or False,
|
|
||||||
return {
|
|
||||||
'type': 'ir.actions.act_window',
|
|
||||||
'name': _('Sales Order'),
|
|
||||||
'res_model': 'sale.order',
|
|
||||||
'res_id': ids[0],
|
|
||||||
'view_type': 'form',
|
|
||||||
'view_mode': 'form',
|
|
||||||
'view_id': view_id,
|
|
||||||
'target': 'current',
|
|
||||||
'nodestroy': True,
|
|
||||||
}
|
|
||||||
|
|
||||||
def action_wait(self, cr, uid, ids, context=None):
|
def action_wait(self, cr, uid, ids, context=None):
|
||||||
context = context or {}
|
context = context or {}
|
||||||
|
|
|
@ -405,15 +405,36 @@ instance.web.ActionManager = instance.web.Widget.extend({
|
||||||
}
|
}
|
||||||
var widget = executor.widget();
|
var widget = executor.widget();
|
||||||
if (executor.action.target === 'new') {
|
if (executor.action.target === 'new') {
|
||||||
|
var pre_dialog = this.dialog;
|
||||||
|
if (pre_dialog){
|
||||||
|
// prevent previous dialog to consider itself closed,
|
||||||
|
// right now, as we're opening a new one (prevents
|
||||||
|
// reload of original form view)
|
||||||
|
pre_dialog.off('closing', null, pre_dialog.on_close);
|
||||||
|
}
|
||||||
if (this.dialog_widget && !this.dialog_widget.isDestroyed()) {
|
if (this.dialog_widget && !this.dialog_widget.isDestroyed()) {
|
||||||
this.dialog_widget.destroy();
|
this.dialog_widget.destroy();
|
||||||
}
|
}
|
||||||
|
// explicitly passing a closing action to dialog_stop() prevents
|
||||||
|
// it from reloading the original form view
|
||||||
this.dialog_stop(executor.action);
|
this.dialog_stop(executor.action);
|
||||||
this.dialog = new instance.web.Dialog(this, {
|
this.dialog = new instance.web.Dialog(this, {
|
||||||
title: executor.action.name,
|
title: executor.action.name,
|
||||||
dialogClass: executor.klass,
|
dialogClass: executor.klass,
|
||||||
});
|
});
|
||||||
this.dialog.on("closing", null, options.on_close);
|
|
||||||
|
// chain on_close triggers with previous dialog, if any
|
||||||
|
this.dialog.on_close = function(){
|
||||||
|
options.on_close.apply(null, arguments);
|
||||||
|
if (pre_dialog && pre_dialog.on_close){
|
||||||
|
// no parameter passed to on_close as this will
|
||||||
|
// only be called when the last dialog is truly
|
||||||
|
// closing, and *should* trigger a reload of the
|
||||||
|
// underlying form view (see comments above)
|
||||||
|
pre_dialog.on_close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.dialog.on("closing", null, this.dialog.on_close);
|
||||||
if (widget instanceof instance.web.ViewManager) {
|
if (widget instanceof instance.web.ViewManager) {
|
||||||
_.extend(widget.flags, {
|
_.extend(widget.flags, {
|
||||||
$buttons: this.dialog.$buttons,
|
$buttons: this.dialog.$buttons,
|
||||||
|
@ -426,6 +447,9 @@ instance.web.ActionManager = instance.web.Widget.extend({
|
||||||
this.dialog.open();
|
this.dialog.open();
|
||||||
return initialized;
|
return initialized;
|
||||||
} else {
|
} else {
|
||||||
|
// explicitly passing a closing action to dialog_stop() prevents
|
||||||
|
// it from reloading the original form view - we're opening a
|
||||||
|
// completely new action anyway
|
||||||
this.dialog_stop(executor.action);
|
this.dialog_stop(executor.action);
|
||||||
this.inner_action = executor.action;
|
this.inner_action = executor.action;
|
||||||
this.inner_widget = widget;
|
this.inner_widget = widget;
|
||||||
|
|
|
@ -294,4 +294,20 @@ class ir_cron(osv.osv):
|
||||||
res = super(ir_cron, self).unlink(cr, uid, ids, context=context)
|
res = super(ir_cron, self).unlink(cr, uid, ids, context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def try_write(self, cr, uid, ids, values, context=None):
|
||||||
|
try:
|
||||||
|
with cr.savepoint():
|
||||||
|
cr.execute("""SELECT id FROM "%s" WHERE id IN %%s FOR UPDATE NOWAIT""" % self._table,
|
||||||
|
(tuple(ids),), log_exceptions=False)
|
||||||
|
except psycopg2.OperationalError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return super(ir_cron, self).write(cr, uid, ids, values, context=context)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def toggle(self, cr, uid, ids, model, domain, context=None):
|
||||||
|
active = bool(self.pool[model].search_count(cr, uid, domain, context=context))
|
||||||
|
|
||||||
|
return self.try_write(cr, uid, ids, {'active': active}, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
Loading…
Reference in New Issue