diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py
index e5e13b33830..28fb8756616 100644
--- a/addons/account/models/account_invoice.py
+++ b/addons/account/models/account_invoice.py
@@ -1107,7 +1107,7 @@ class AccountInvoiceLine(models.Model):
default=0.0)
invoice_line_tax_ids = fields.Many2many('account.tax',
'account_invoice_line_tax', 'invoice_line_id', 'tax_id',
- string='Taxes', domain=[('type_tax_use','!=','none')], oldname='invoice_line_tax_id')
+ string='Taxes', domain=[('type_tax_use','!=','none'), '|', ('active', '=', False), ('active', '=', True)], oldname='invoice_line_tax_id')
account_analytic_id = fields.Many2one('account.analytic.account',
string='Analytic Account')
company_id = fields.Many2one('res.company', string='Company',
diff --git a/addons/account_asset/account_asset.py b/addons/account_asset/account_asset.py
index 749e3ec3289..e008e3d2d26 100644
--- a/addons/account_asset/account_asset.py
+++ b/addons/account_asset/account_asset.py
@@ -154,7 +154,7 @@ class AccountAssetAsset(models.Model):
def compute_depreciation_board(self):
self.ensure_one()
- posted_depreciation_line_ids = self.depreciation_line_ids.filtered(lambda x: x.move_check)
+ posted_depreciation_line_ids = self.depreciation_line_ids.filtered(lambda x: x.move_check).sorted(key=lambda l: l.depreciation_date, reverse=True)
unposted_depreciation_line_ids = self.depreciation_line_ids.filtered(lambda x: not x.move_check)
# Remove old unposted depreciation lines. We cannot use unlink() with One2many field
diff --git a/addons/crm/crm_action_rule_demo.xml b/addons/crm/crm_action_rule_demo.xml
index e7f05dca512..ff83639703a 100644
--- a/addons/crm/crm_action_rule_demo.xml
+++ b/addons/crm/crm_action_rule_demo.xml
@@ -22,7 +22,7 @@
1
on_time
[('stage_id.sequence', '=', 1)]
-
+
5
day
diff --git a/addons/gamification_sale_crm/sale_crm_goals.xml b/addons/gamification_sale_crm/sale_crm_goals.xml
index 684d2a51844..40e90cfa1a7 100644
--- a/addons/gamification_sale_crm/sale_crm_goals.xml
+++ b/addons/gamification_sale_crm/sale_crm_goals.xml
@@ -20,7 +20,7 @@
count
leads
-
+
[('user_id','=',user.id), '|', ('type', '=', 'lead'), ('type', '=', 'opportunity')]
diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py
index 16994c3ced6..cedce7f97f1 100644
--- a/addons/mrp_repair/mrp_repair.py
+++ b/addons/mrp_repair/mrp_repair.py
@@ -562,7 +562,8 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
'invoiced': fields.boolean('Invoiced', readonly=True, copy=False),
'price_unit': fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Product Price')),
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits=0),
- 'tax_id': fields.many2many('account.tax', 'repair_operation_line_tax', 'repair_operation_line_id', 'tax_id', 'Taxes'),
+ 'tax_id': fields.many2many('account.tax', 'repair_operation_line_tax', 'repair_operation_line_id', 'tax_id', 'Taxes',
+ domain=['|', ('active', '=', False), ('active', '=', True)]),
'product_uom_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True, copy=False),
@@ -656,7 +657,8 @@ class mrp_repair_fee(osv.osv, ProductChangeMixin):
'price_unit': fields.float('Unit Price', required=True),
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits=0),
- 'tax_id': fields.many2many('account.tax', 'repair_fee_line_tax', 'repair_fee_line_id', 'tax_id', 'Taxes'),
+ 'tax_id': fields.many2many('account.tax', 'repair_fee_line_tax', 'repair_fee_line_id', 'tax_id', 'Taxes',
+ domain=['|', ('active', '=', False), ('active', '=', True)]),
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True, copy=False),
'to_invoice': fields.boolean('To Invoice'),
'invoiced': fields.boolean('Invoiced', readonly=True, copy=False),
diff --git a/addons/payment_ogone/models/ogone.py b/addons/payment_ogone/models/ogone.py
index b1a90b64bf7..585ad5a09ba 100644
--- a/addons/payment_ogone/models/ogone.py
+++ b/addons/payment_ogone/models/ogone.py
@@ -129,6 +129,7 @@ class PaymentAcquirerOgone(osv.Model):
'NCERRORED',
'ORDERID',
'PAYID',
+ 'PAYIDSUB',
'PM',
'SCO_CATEGORY',
'SCORING',
diff --git a/addons/point_of_sale/report/pos_details.py b/addons/point_of_sale/report/pos_details.py
index 3e77f35a027..5107c26dc78 100644
--- a/addons/point_of_sale/report/pos_details.py
+++ b/addons/point_of_sale/report/pos_details.py
@@ -24,6 +24,19 @@ class pos_details(report_sxw.rml_parse):
user_obj = self.pool.get('res.users')
return user_obj.search(self.cr, self.uid, [])
+ def _get_utc_time_range(self, form):
+ user = self.pool['res.users'].browse(self.cr, self.uid, self.uid)
+ tz_name = user.tz or self.localcontext.get('tz') or 'UTC'
+ user_tz = pytz.timezone(tz_name)
+ between_dates = {}
+
+ for date_field, delta in {'date_start': {'days': 0}, 'date_end': {'days': 1}}.items():
+ timestamp = datetime.datetime.strptime(form[date_field] + ' 00:00:00', tools.DEFAULT_SERVER_DATETIME_FORMAT) + datetime.timedelta(**delta)
+ timestamp = user_tz.localize(timestamp).astimezone(pytz.utc)
+ between_dates[date_field] = timestamp.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
+
+ return between_dates['date_start'], between_dates['date_end']
+
def _pos_sales_details(self, form):
pos_obj = self.pool.get('pos.order')
user_obj = self.pool.get('res.users')
@@ -31,18 +44,11 @@ class pos_details(report_sxw.rml_parse):
result = {}
user_ids = form['user_ids'] or self._get_all_users()
company_id = user_obj.browse(self.cr, self.uid, self.uid).company_id.id
- user = self.pool['res.users'].browse(self.cr, self.uid, self.uid)
- tz_name = user.tz or self.localcontext.get('tz') or 'UTC'
- user_tz = pytz.timezone(tz_name)
- between_dates = {}
- for date_field, delta in {'date_start': {'days': 0}, 'date_end': {'days': 1}}.items():
- timestamp = datetime.datetime.strptime(form[date_field] + ' 00:00:00', tools.DEFAULT_SERVER_DATETIME_FORMAT) + datetime.timedelta(**delta)
- timestamp = user_tz.localize(timestamp).astimezone(pytz.utc)
- between_dates[date_field] = timestamp.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
+ date_start, date_end = self._get_utc_time_range(form)
pos_ids = pos_obj.search(self.cr, self.uid, [
- ('date_order', '>=', between_dates['date_start']),
- ('date_order', '<', between_dates['date_end']),
+ ('date_order', '>=', date_start),
+ ('date_order', '<', date_end),
('user_id', 'in', user_ids),
('state', 'in', ['done', 'paid', 'invoiced']),
('company_id', '=', company_id)
@@ -81,7 +87,8 @@ class pos_details(report_sxw.rml_parse):
user_obj = self.pool.get('res.users')
user_ids = form['user_ids'] or self._get_all_users()
company_id = user_obj.browse(self.cr, self.uid, self.uid).company_id.id
- pos_ids = pos_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('user_id','in',user_ids),('company_id','=',company_id),('invoice_id','<>',False)])
+ date_start, date_end = self._get_utc_time_range(form)
+ pos_ids = pos_obj.search(self.cr, self.uid, [('date_order','>=', date_start),('date_order','<=',date_end),('user_id','in',user_ids),('company_id','=',company_id),('invoice_id','<>',False)])
for pos in pos_obj.browse(self.cr, self.uid, pos_ids):
for pol in pos.lines:
self.total_invoiced += (pol.price_unit * pol.qty * (1 - (pol.discount) / 100.0))
@@ -99,7 +106,8 @@ class pos_details(report_sxw.rml_parse):
user_obj = self.pool.get('res.users')
user_ids = form['user_ids'] or self._get_all_users()
company_id = user_obj.browse(self.cr, self.uid, self.uid).company_id.id
- pos_ids = pos_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('user_id','in',user_ids),('company_id','=',company_id)])
+ date_start, date_end = self._get_utc_time_range(form)
+ pos_ids = pos_obj.search(self.cr, self.uid, [('date_order','>=',date_start),('date_order','<=',date_end),('user_id','in',user_ids),('company_id','=',company_id)])
for pos in pos_obj.browse(self.cr, self.uid, pos_ids):
for pol in pos.lines:
self.total_discount += ((pol.price_unit * pol.qty) * (pol.discount / 100))
@@ -110,7 +118,8 @@ class pos_details(report_sxw.rml_parse):
pos_order_obj = self.pool.get("pos.order")
user_ids = form['user_ids'] or self._get_all_users()
company_id = self.pool['res.users'].browse(self.cr, self.uid, self.uid).company_id.id
- pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('state','in',['paid','invoiced','done']),('user_id','in',user_ids), ('company_id', '=', company_id)])
+ date_start, date_end = self._get_utc_time_range(form)
+ pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',date_start),('date_order','<=',date_end),('state','in',['paid','invoiced','done']),('user_id','in',user_ids), ('company_id', '=', company_id)])
data={}
if pos_ids:
st_line_ids = statement_line_obj.search(self.cr, self.uid, [('pos_statement_id', 'in', pos_ids)])
@@ -153,7 +162,8 @@ class pos_details(report_sxw.rml_parse):
user_ids = form['user_ids'] or self._get_all_users()
pos_order_obj = self.pool.get('pos.order')
company_id = self.pool['res.users'].browse(self.cr, self.uid, self.uid).company_id.id
- pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('state','in',['paid','invoiced','done']),('user_id','in',user_ids), ('company_id', '=', company_id)])
+ date_start, date_end = self._get_utc_time_range(form)
+ pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',date_start),('date_order','<=',date_end),('state','in',['paid','invoiced','done']),('user_id','in',user_ids), ('company_id', '=', company_id)])
for order in pos_order_obj.browse(self.cr, self.uid, pos_ids):
currency = order.session_id.currency_id
for line in order.lines:
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 50fcd79c8dc..ad5cbf7907d 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -1662,8 +1662,6 @@ exports.Order = Backbone.Model.extend({
client: client ? client.name : null ,
invoice_id: null, //TODO
cashier: cashier ? cashier.name : null,
- header: this.pos.config.receipt_header || '',
- footer: this.pos.config.receipt_footer || '',
precision: {
price: 2,
money: 2,
@@ -1696,11 +1694,17 @@ exports.Order = Backbone.Model.extend({
};
if (is_xml(this.pos.config.receipt_header)){
+ receipt.header = '';
receipt.header_xml = render_xml(this.pos.config.receipt_header);
+ } else {
+ receipt.header = this.pos.config.receipt_header || '';
}
if (is_xml(this.pos.config.receipt_footer)){
+ receipt.footer = '';
receipt.footer_xml = render_xml(this.pos.config.receipt_footer);
+ } else {
+ receipt.footer = this.pos.config.receipt_footer || '';
}
return receipt;
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 0a31e36a896..007d410bcf3 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -514,7 +514,7 @@ class PurchaseOrderLine(models.Model):
name = fields.Text(string='Description', required=True)
product_qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True)
date_planned = fields.Datetime(string='Scheduled Date', required=True, select=True)
- taxes_id = fields.Many2many('account.tax', string='Taxes')
+ taxes_id = fields.Many2many('account.tax', string='Taxes', domain=['|', ('active', '=', False), ('active', '=', True)])
product_uom = fields.Many2one('product.uom', string='Product Unit of Measure', required=True)
product_id = fields.Many2one('product.product', string='Product', domain=[('purchase_ok', '=', True)], change_default=True, required=True)
move_ids = fields.One2many('stock.move', 'purchase_line_id', string='Reservation', readonly=True, ondelete='set null', copy=False)
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index c25eff9f74c..d5ec1833bab 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -652,7 +652,7 @@ class SaleOrderLine(models.Model):
price_total = fields.Monetary(compute='_compute_amount', string='Total', readonly=True, store=True)
price_reduce = fields.Monetary(compute='_get_price_reduce', string='Price Reduce', readonly=True, store=True)
- tax_id = fields.Many2many('account.tax', string='Taxes')
+ tax_id = fields.Many2many('account.tax', string='Taxes', domain=['|', ('active', '=', False), ('active', '=', True)])
discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'), default=0.0)
diff --git a/addons/web/static/src/js/views/graph_widget.js b/addons/web/static/src/js/views/graph_widget.js
index e458cc483ed..599899dd32f 100644
--- a/addons/web/static/src/js/views/graph_widget.js
+++ b/addons/web/static/src/js/views/graph_widget.js
@@ -164,7 +164,7 @@ return Widget.extend({
var chart = nv.models.multiBarChart();
var maxVal = _.max(values, function(v) {return v.y})
chart.options({
- margin: {left: 12 * String(maxVal && maxVal.y || 0).length},
+ margin: {left: 12 * String(maxVal && maxVal.y || 10000000).length},
delay: 250,
transition: 10,
showLegend: _.size(data) <= MAX_LEGEND_LENGTH,
@@ -296,7 +296,7 @@ return Widget.extend({
var chart = nv.models.lineChart();
var maxVal = _.max(values, function(v) {return v.y})
chart.options({
- margin: {left: 12 * String(maxVal && maxVal.y || 0).length, right: 50},
+ margin: {left: 12 * String(maxVal && maxVal.y || 10000000).length, right: 50},
useInteractiveGuideline: true,
showLegend: _.size(data) <= MAX_LEGEND_LENGTH,
showXAxis: true,
diff --git a/addons/website_mass_mailing/controllers/main.py b/addons/website_mass_mailing/controllers/main.py
index 2a7596104a8..3deaedbf1cb 100644
--- a/addons/website_mass_mailing/controllers/main.py
+++ b/addons/website_mass_mailing/controllers/main.py
@@ -51,8 +51,12 @@ class MassMailController(MassMailController):
def subscribe(self, list_id, email, **post):
cr, uid, context = request.cr, request.uid, request.context
Contacts = request.registry['mail.mass_mailing.contact']
+ parsed_email = Contacts.get_name_email(email, context=context)[1]
- contact_ids = Contacts.search_read(cr, SUPERUSER_ID, [('list_id', '=', int(list_id)), ('email', '=', email)], ['opt_out'], context=context)
+ contact_ids = Contacts.search_read(
+ cr, SUPERUSER_ID,
+ [('list_id', '=', int(list_id)), ('email', '=', parsed_email)],
+ ['opt_out'], context=context)
if not contact_ids:
Contacts.add_to_list(cr, SUPERUSER_ID, email, int(list_id), context=context)
else:
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index c791cbdd2a5..d384c1d064d 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -132,6 +132,10 @@ class website_sale(http.Controller):
for p in product.product_variant_ids]
return attribute_value_ids
+ def _get_search_order(self, post):
+ # OrderBy will be parsed in orm and so no direct sql injection
+ return 'website_published desc,%s' % post.get('order', 'website_sequence desc')
+
@http.route(['/shop/change_pricelist/'], type='http', auth="public", website=True)
def pricelist_change(self, pl_id, **post):
if request.website.is_pricelist_available(pl_id.id, context=request.context):
@@ -230,7 +234,7 @@ class website_sale(http.Controller):
product_count = product_obj.search_count(cr, uid, domain, context=context)
pager = request.website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post)
- product_ids = product_obj.search(cr, uid, domain, limit=ppg, offset=pager['offset'], order='website_published desc, website_sequence desc', context=context)
+ product_ids = product_obj.search(cr, uid, domain, limit=ppg, offset=pager['offset'], order=self._get_search_order(post), context=context)
products = product_obj.browse(cr, uid, product_ids, context=context)
attributes_obj = request.registry['product.attribute']
diff --git a/addons/website_sale/data/demo.xml b/addons/website_sale/data/demo.xml
index 6a94c31f0b1..9126fc0f167 100644
--- a/addons/website_sale/data/demo.xml
+++ b/addons/website_sale/data/demo.xml
@@ -781,6 +781,12 @@ Weight: 31 grams
+
+ #FFFFFF
+
+
+ #000000
+
diff --git a/doc/cla/corporate/AetnaSoftwares.md b/doc/cla/corporate/AetnaSoftwares.md
new file mode 100644
index 00000000000..406727bfb04
--- /dev/null
+++ b/doc/cla/corporate/AetnaSoftwares.md
@@ -0,0 +1,13 @@
+France, 2016-05-30
+
+Aetna Softwares. agrees to the terms of the Odoo Corporate Contributor License Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this declaration.
+
+Signed,
+
+Olivier Oriol aetna.softwares@gmail.com https://github.com/aetna-softwares
+
+List of contributors:
+
+Olivier Oriol aetna.softwares@gmail.com https://github.com/aetna-softwares
diff --git a/doc/cla/corporate/devcocolombia.md b/doc/cla/corporate/devcocolombia.md
new file mode 100644
index 00000000000..3ef6e397168
--- /dev/null
+++ b/doc/cla/corporate/devcocolombia.md
@@ -0,0 +1,15 @@
+Colombia, 2016-04-20
+
+DevCO Colombia agrees to the terms of the Odoo Corporate Contributor License
+Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this
+declaration.
+
+Signed,
+
+David Arnold dar@devco.co https://github.com/blaggacao
+
+List of contributors:
+
+Juan Pablo Arias jpa@devco.co https://github.com/kurkop
diff --git a/doc/cla/corporate/therp.md b/doc/cla/corporate/therp.md
index 428ecb2b411..e9f7dfae3ba 100644
--- a/doc/cla/corporate/therp.md
+++ b/doc/cla/corporate/therp.md
@@ -1,5 +1,7 @@
Netherlands, 2015-03-09
+Updated 2016-05-27
+
Therp BV agrees to the terms of the Odoo Corporate
Contributor License Agreement v1.0.
@@ -8,14 +10,12 @@ this declaration.
Signed,
-* Ronald Portier rportier@therp.nl https://github.com/nl66278
-* Stefan Rijnhart stefan@therp.nl https://github.com/stefanrijnhart
+* Ronald Portier ronald@therp.nl https://github.com/nl66278
List of contributors:
* Giovanni Capalbo giovanni@therp.nl https://github.com/gfcapalbo
* Holger Brunn hbrunn@therp.nl https://github.com/hbrunn
* Lara Freeke lfreeke@therp.nl https://github.com/lfreeke
-* Ronald Portier rportier@therp.nl https://github.com/nl66278
-* Stefan Rijnhart stefan@therp.nl https://github.com/stefanrijnhart
+* Ronald Portier ronald@therp.nl https://github.com/nl66278