[MERGE] forward port of branch saas-4 up to 6b8e972
This commit is contained in:
commit
a7c2125735
|
@ -77,7 +77,7 @@ class account_analytic_invoice_line(osv.osv):
|
|||
price = price_unit
|
||||
elif pricelist_id:
|
||||
price = res.price
|
||||
else:
|
||||
if price is False:
|
||||
price = res.list_price
|
||||
if not name:
|
||||
name = self.pool.get('product.product').name_get(cr, uid, [res.id], context=local_context)[0][1]
|
||||
|
|
|
@ -139,7 +139,8 @@
|
|||
<group>
|
||||
<field name="pricelist_id"
|
||||
class="oe_inline"
|
||||
attrs="{'required': [('invoice_on_timesheets', '=', True)]}"/>
|
||||
attrs="{'required': [('invoice_on_timesheets', '=', True)]}"
|
||||
domain="[('type', '=', 'sale')]"/>
|
||||
<field name="to_invoice"
|
||||
class="oe_inline"
|
||||
widget="selection"
|
||||
|
|
|
@ -123,7 +123,7 @@ class pos_make_payment(osv.osv_memory):
|
|||
}
|
||||
_defaults = {
|
||||
'journal_id' : _default_journal,
|
||||
'payment_date': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'payment_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'amount': _default_amount,
|
||||
}
|
||||
|
||||
|
|
|
@ -198,6 +198,7 @@ class project_work(osv.osv):
|
|||
if amount_unit and 'amount' in amount_unit.get('value',{}):
|
||||
vals_line['amount'] = amount_unit['value']['amount']
|
||||
|
||||
if vals_line:
|
||||
self.pool.get('hr.analytic.timesheet').write(cr, uid, [line_id.id], vals_line, context=context)
|
||||
|
||||
return super(project_work,self).write(cr, uid, ids, vals, context)
|
||||
|
|
|
@ -37,6 +37,7 @@ from openerp import report
|
|||
import tempfile
|
||||
import time
|
||||
import logging
|
||||
from functools import partial
|
||||
|
||||
from report_helper import WebKitHelper
|
||||
import openerp
|
||||
|
@ -119,7 +120,6 @@ class WebKitParser(report_sxw):
|
|||
"""
|
||||
def __init__(self, name, table, rml=False, parser=rml_parse,
|
||||
header=True, store=False, register=True):
|
||||
self.parser_instance = False
|
||||
self.localcontext = {}
|
||||
report_sxw.__init__(self, name, table, rml, parser,
|
||||
header, store, register=register)
|
||||
|
@ -230,16 +230,16 @@ class WebKitParser(report_sxw):
|
|||
_logger.error('cannot remove file %s: %s', f_to_del, exc)
|
||||
return pdf
|
||||
|
||||
def translate_call(self, src):
|
||||
def translate_call(self, parser_instance, src):
|
||||
"""Translate String."""
|
||||
ir_translation = self.pool['ir.translation']
|
||||
name = self.tmpl and 'addons/' + self.tmpl or None
|
||||
res = ir_translation._get_source(self.parser_instance.cr, self.parser_instance.uid,
|
||||
name, 'report', self.parser_instance.localcontext.get('lang', 'en_US'), src)
|
||||
res = ir_translation._get_source(parser_instance.cr, parser_instance.uid,
|
||||
name, 'report', parser_instance.localcontext.get('lang', 'en_US'), src)
|
||||
if res == src:
|
||||
# no translation defined, fallback on None (backward compatibility)
|
||||
res = ir_translation._get_source(self.parser_instance.cr, self.parser_instance.uid,
|
||||
None, 'report', self.parser_instance.localcontext.get('lang', 'en_US'), src)
|
||||
res = ir_translation._get_source(parser_instance.cr, parser_instance.uid,
|
||||
None, 'report', parser_instance.localcontext.get('lang', 'en_US'), src)
|
||||
if not res :
|
||||
return src
|
||||
return res
|
||||
|
@ -264,14 +264,14 @@ class WebKitParser(report_sxw):
|
|||
if report_xml.report_type != 'webkit':
|
||||
return super(WebKitParser,self).create_single_pdf(cursor, uid, ids, data, report_xml, context=context)
|
||||
|
||||
self.parser_instance = self.parser(cursor,
|
||||
parser_instance = self.parser(cursor,
|
||||
uid,
|
||||
self.name2,
|
||||
context=context)
|
||||
|
||||
self.pool = pool
|
||||
objs = self.getObjects(cursor, uid, ids, context)
|
||||
self.parser_instance.set_context(objs, data, ids, report_xml.report_type)
|
||||
parser_instance.set_context(objs, data, ids, report_xml.report_type)
|
||||
|
||||
template = False
|
||||
|
||||
|
@ -299,21 +299,22 @@ class WebKitParser(report_sxw):
|
|||
if not css :
|
||||
css = ''
|
||||
|
||||
translate_call = partial(self.translate_call, parser_instance)
|
||||
body_mako_tpl = mako_template(template)
|
||||
helper = WebKitHelper(cursor, uid, report_xml.id, context)
|
||||
self.parser_instance.localcontext['helper'] = helper
|
||||
self.parser_instance.localcontext['css'] = css
|
||||
self.parser_instance.localcontext['_'] = self.translate_call
|
||||
parser_instance.localcontext['helper'] = helper
|
||||
parser_instance.localcontext['css'] = css
|
||||
parser_instance.localcontext['_'] = translate_call
|
||||
|
||||
# apply extender functions
|
||||
additional = {}
|
||||
if xml_id in _extender_functions:
|
||||
for fct in _extender_functions[xml_id]:
|
||||
fct(pool, cr, uid, self.parser_instance.localcontext, context)
|
||||
fct(pool, cr, uid, parser_instance.localcontext, context)
|
||||
|
||||
if report_xml.precise_mode:
|
||||
ctx = dict(self.parser_instance.localcontext)
|
||||
for obj in self.parser_instance.localcontext['objects']:
|
||||
ctx = dict(parser_instance.localcontext)
|
||||
for obj in parser_instance.localcontext['objects']:
|
||||
ctx['objects'] = [obj]
|
||||
try :
|
||||
html = body_mako_tpl.render(dict(ctx))
|
||||
|
@ -324,7 +325,7 @@ class WebKitParser(report_sxw):
|
|||
raise except_osv(_('Webkit render!'), msg)
|
||||
else:
|
||||
try :
|
||||
html = body_mako_tpl.render(dict(self.parser_instance.localcontext))
|
||||
html = body_mako_tpl.render(dict(parser_instance.localcontext))
|
||||
htmls.append(html)
|
||||
except Exception, e:
|
||||
msg = u"%s" % e
|
||||
|
@ -332,22 +333,21 @@ class WebKitParser(report_sxw):
|
|||
raise except_osv(_('Webkit render!'), msg)
|
||||
head_mako_tpl = mako_template(header)
|
||||
try :
|
||||
head = head_mako_tpl.render(dict(self.parser_instance.localcontext, _debug=False))
|
||||
head = head_mako_tpl.render(dict(parser_instance.localcontext, _debug=False))
|
||||
except Exception, e:
|
||||
raise except_osv(_('Webkit render!'), u"%s" % e)
|
||||
foot = False
|
||||
if footer :
|
||||
foot_mako_tpl = mako_template(footer)
|
||||
try :
|
||||
foot = foot_mako_tpl.render(dict({},
|
||||
**self.parser_instance.localcontext))
|
||||
foot = foot_mako_tpl.render(dict(parser_instance.localcontext))
|
||||
except Exception, e:
|
||||
msg = u"%s" % e
|
||||
_logger.error(msg)
|
||||
raise except_osv(_('Webkit render!'), msg)
|
||||
if report_xml.webkit_debug :
|
||||
try :
|
||||
deb = head_mako_tpl.render(dict(self.parser_instance.localcontext, _debug=tools.ustr("\n".join(htmls))))
|
||||
deb = head_mako_tpl.render(dict(parser_instance.localcontext, _debug=tools.ustr("\n".join(htmls))))
|
||||
except Exception, e:
|
||||
msg = u"%s" % e
|
||||
_logger.error(msg)
|
||||
|
|
|
@ -4858,7 +4858,8 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in
|
|||
pop.select_element(
|
||||
this.model,
|
||||
{
|
||||
title: _t("Add: ") + this.m2m_field.string
|
||||
title: _t("Add: ") + this.m2m_field.string,
|
||||
no_create: this.m2m_field.options.no_create,
|
||||
},
|
||||
new instance.web.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]),
|
||||
this.m2m_field.build_context()
|
||||
|
|
|
@ -1504,8 +1504,9 @@
|
|||
<t t-if="! widget.options.disable_multiple_selection">
|
||||
<button type="button" class="oe_button oe_selectcreatepopup-search-select oe_highlight" disabled="disabled">Select</button>
|
||||
</t>
|
||||
<t t-if="!widget.options.no_create">
|
||||
<button type="button" class="oe_button oe_selectcreatepopup-search-create">Create</button>
|
||||
or <a class="oe_selectcreatepopup-search-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Cancel</a>
|
||||
or </t><a class="oe_selectcreatepopup-search-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Cancel</a>
|
||||
</t>
|
||||
<t t-name="AbstractFormPopup.buttons">
|
||||
<t t-if="! readonly">
|
||||
|
|
|
@ -93,6 +93,9 @@
|
|||
.openerp .oe_kanban_view .oe_kanban_groups {
|
||||
height: inherit;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_groups_records {
|
||||
height: 100%;
|
||||
}
|
||||
.openerp .oe_kanban_view.oe_kanban_grouped_by_m2o .oe_kanban_group_title {
|
||||
cursor: move;
|
||||
}
|
||||
|
@ -160,7 +163,7 @@
|
|||
padding: 0px;
|
||||
background: white;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_column, .openerp .oe_kanban_view .oe_kanban_column_cards {
|
||||
.openerp .oe_kanban_view.oe_kanban_grouped .oe_kanban_column, .openerp .oe_kanban_view.oe_kanban_grouped .oe_kanban_column_cards {
|
||||
height: 100%;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_aggregates {
|
||||
|
|
|
@ -119,6 +119,8 @@
|
|||
// KanbanGroups {{{
|
||||
.oe_kanban_groups
|
||||
height: inherit
|
||||
.oe_kanban_groups_records
|
||||
height: 100%
|
||||
&.oe_kanban_grouped_by_m2o .oe_kanban_group_title
|
||||
cursor: move
|
||||
.oe_kanban_header
|
||||
|
@ -178,7 +180,7 @@
|
|||
.oe_kanban_column
|
||||
padding: 0px
|
||||
background: #ffffff
|
||||
|
||||
&.oe_kanban_grouped
|
||||
.oe_kanban_column, .oe_kanban_column_cards
|
||||
height: 100%
|
||||
.oe_kanban_aggregates
|
||||
|
|
|
@ -977,6 +977,8 @@
|
|||
clean_for_save: function () {
|
||||
this._super();
|
||||
$(".carousel").find(".item").removeClass("next prev left right active");
|
||||
this.$indicators.find('li').removeClass('active');
|
||||
this.$indicators.find('li:first').addClass('active');
|
||||
if(!this.$target.find(".item.active").length) {
|
||||
this.$target.find(".item:first").addClass("active");
|
||||
}
|
||||
|
|
|
@ -214,7 +214,8 @@
|
|||
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
|
||||
e.src='//www.google-analytics.com/analytics.js';
|
||||
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
|
||||
ga('create','<t t-esc="website.google_analytics_key"/>');ga('send','pageview');
|
||||
ga('create',_.str.trim('<t t-esc="website.google_analytics_key"/>'));
|
||||
ga('send','pageview');
|
||||
</script>
|
||||
</t>
|
||||
</body>
|
||||
|
|
|
@ -134,9 +134,7 @@
|
|||
</h3>
|
||||
<ul class="list-inline mb0">
|
||||
<li t-if="track.speaker_ids" class="text-muted fa fa-user">
|
||||
<t t-foreach="track.speaker_ids" t-as="speaker">
|
||||
<t t-esc="speaker.name"/>,
|
||||
</t>
|
||||
<t t-esc="', '.join([speaker.name for speaker in track.speaker_ids])"></t>
|
||||
</li>
|
||||
<li class="text-muted fa fa-calendar"> <span t-field="track.date" t-field-options='{"hide_seconds":"True"}'/></li>
|
||||
<li class="text-muted fa fa-map-marker" t-if="track.location_id">
|
||||
|
|
|
@ -238,7 +238,7 @@ class ir_cron(osv.osv):
|
|||
|
||||
locked_job = lock_cr.fetchone()
|
||||
if not locked_job:
|
||||
# job was already executed by another parallel process/thread, skipping it.
|
||||
_logger.debug("Job `%s` already executed by another process/thread. skipping it", job['name'])
|
||||
continue
|
||||
# Got the lock on the job row, run its code
|
||||
_logger.debug('Starting job `%s`.', job['name'])
|
||||
|
|
|
@ -1141,13 +1141,20 @@ class ir_model_data(osv.osv):
|
|||
|
||||
# Remove non-model records first, then model fields, and finish with models
|
||||
unlink_if_refcount((model, res_id) for model, res_id in to_unlink
|
||||
if model not in ('ir.model','ir.model.fields'))
|
||||
if model not in ('ir.model','ir.model.fields','ir.model.constraint'))
|
||||
unlink_if_refcount((model, res_id) for model, res_id in to_unlink
|
||||
if model == 'ir.model.constraint')
|
||||
|
||||
ir_module_module = self.pool['ir.module.module']
|
||||
ir_model_constraint = self.pool['ir.model.constraint']
|
||||
modules_to_remove_ids = ir_module_module.search(cr, uid, [('name', 'in', modules_to_remove)], context=context)
|
||||
constraint_ids = ir_model_constraint.search(cr, uid, [('module', 'in', modules_to_remove_ids)], context=context)
|
||||
ir_model_constraint._module_data_uninstall(cr, uid, constraint_ids, context)
|
||||
|
||||
unlink_if_refcount((model, res_id) for model, res_id in to_unlink
|
||||
if model == 'ir.model.fields')
|
||||
|
||||
ir_model_relation = self.pool['ir.model.relation']
|
||||
ir_module_module = self.pool['ir.module.module']
|
||||
modules_to_remove_ids = ir_module_module.search(cr, uid, [('name', 'in', modules_to_remove)])
|
||||
relation_ids = ir_model_relation.search(cr, uid, [('module', 'in', modules_to_remove_ids)])
|
||||
ir_model_relation._module_data_uninstall(cr, uid, relation_ids, context)
|
||||
|
||||
|
|
|
@ -445,11 +445,7 @@ class module(osv.osv):
|
|||
including the deletion of all database structures created by the module:
|
||||
tables, columns, constraints, etc."""
|
||||
ir_model_data = self.pool.get('ir.model.data')
|
||||
ir_model_constraint = self.pool.get('ir.model.constraint')
|
||||
modules_to_remove = [m.name for m in self.browse(cr, uid, ids, context)]
|
||||
modules_to_remove_ids = [m.id for m in self.browse(cr, uid, ids, context)]
|
||||
constraint_ids = ir_model_constraint.search(cr, uid, [('module', 'in', modules_to_remove_ids)])
|
||||
ir_model_constraint._module_data_uninstall(cr, uid, constraint_ids, context)
|
||||
ir_model_data._module_data_uninstall(cr, uid, modules_to_remove, context)
|
||||
self.write(cr, uid, ids, {'state': 'uninstalled'})
|
||||
return True
|
||||
|
|
|
@ -75,7 +75,6 @@ class PostgreSQLHandler(logging.Handler):
|
|||
def emit(self, record):
|
||||
ct = threading.current_thread()
|
||||
ct_db = getattr(ct, 'dbname', None)
|
||||
ct_uid = getattr(ct, 'uid', None)
|
||||
dbname = tools.config['log_db'] or ct_db
|
||||
if not dbname:
|
||||
return
|
||||
|
@ -88,10 +87,10 @@ class PostgreSQLHandler(logging.Handler):
|
|||
msg = "%s\n%s" % (msg, traceback)
|
||||
# we do not use record.levelname because it may have been changed by ColoredFormatter.
|
||||
levelname = logging.getLevelName(record.levelno)
|
||||
val = (ct_uid, ct_uid, 'server', ct_db, record.name, levelname, msg, record.pathname, record.lineno, record.funcName)
|
||||
val = ('server', ct_db, record.name, levelname, msg, record.pathname, record.lineno, record.funcName)
|
||||
cr.execute("""
|
||||
INSERT INTO ir_logging(create_date, write_date, create_uid, write_uid, type, dbname, name, level, message, path, line, func)
|
||||
VALUES (NOW() at time zone 'UTC', NOW() at time zone 'UTC', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
INSERT INTO ir_logging(create_date, type, dbname, name, level, message, path, line, func)
|
||||
VALUES (NOW() at time zone 'UTC', %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
""", val)
|
||||
|
||||
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10)
|
||||
|
|
|
@ -1261,8 +1261,16 @@ class function(_column):
|
|||
return new_values
|
||||
|
||||
def get(self, cr, obj, ids, name, uid=False, context=None, values=None):
|
||||
multi = self._multi
|
||||
# if we already have a value, don't recompute it.
|
||||
# This happen if case of stored many2one fields
|
||||
if values and not multi and name in values[0]:
|
||||
result = {v['id']: v[name] for v in values}
|
||||
elif values and multi and all(n in values[0] for n in name):
|
||||
result = {v['id']: dict({n: v[n]} for n in name) for v in values}
|
||||
else:
|
||||
result = self._fnct(obj, cr, uid, ids, name, self._arg, context)
|
||||
if self._multi:
|
||||
if multi:
|
||||
swap = {}
|
||||
for rid, values in result.iteritems():
|
||||
for f, v in values.iteritems():
|
||||
|
|
|
@ -2806,7 +2806,7 @@ class BaseModel(object):
|
|||
('numeric', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
|
||||
('float8', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
|
||||
]
|
||||
if f_pg_type == 'varchar' and f._type == 'char' and ((f.size is None and f_pg_size) or f_pg_size < f.size):
|
||||
if f_pg_type == 'varchar' and f._type == 'char' and f_pg_size and (f.size is None or f_pg_size < f.size):
|
||||
try:
|
||||
with cr.savepoint():
|
||||
cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" TYPE %s' % (self._table, k, pg_varchar(f.size)))
|
||||
|
|
Loading…
Reference in New Issue