From 34088c6031e1b18fc3403526d7e4a89d3a355712 Mon Sep 17 00:00:00 2001
From: Raphael Valyi
Date: Tue, 14 Apr 2015 21:24:05 +0200
Subject: [PATCH 01/21] [CLA] add akretion CLA
---
doc/cla/corporate/akretion.md | 43 +++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
create mode 100644 doc/cla/corporate/akretion.md
diff --git a/doc/cla/corporate/akretion.md b/doc/cla/corporate/akretion.md
new file mode 100644
index 00000000000..61932b3fe8b
--- /dev/null
+++ b/doc/cla/corporate/akretion.md
@@ -0,0 +1,43 @@
+Brazil, France, 2015-04-14
+
+Akretion France 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,
+
+Sébastien BEAU sebastien.beau@akretion.com https://github.com/akretion
+
+
+Akretion LTDA 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,
+Raphaël Valyi raphael.valyi@akretion.com https://github.com/akretion
+
+
+List of contributors:
+
+Abdessamad Hilali abdessamad.hilali@akretion.com https://github.com/ahilali
+Adrien Chaussende adrien.chaussende@akretion.com https://github.com/achaussende
+Alexis de Lattre alexis.delattre@akretion.com https://github.com/alexis-via
+Arthur Vuillard arthur.vuillard@akretion.com https://github.com/arthru
+Benoît Guillot benoit.guillot@akretion.com https://github.com/bguillot
+Chafique delli chafique.delli@akretion.com https://github.com/chafique-delli
+Cilene Oliveira cilene.oliveira@akretion.com https://github.com/cileneoliveira
+David Beal david.beal@akretion.com https://github.com/bealdav
+Florian da Costa florian.dacosta@akretion.com https://github.com/florian-dacosta
+Magno Barcelo da Costa magno.costa@akretion.com.br https://github.com/mbcosta
+Raphaël Valyi raphael.valyi@akretion.com https://github.com/rvalyi
+Renato Lima renato.lima@akretion.com https://github.com/renatonlima
+Sebastien Beau sebastien.beau@akretion.com https://github.com/sebastienbeau
+Sylvain Calador sylvain.calador@akretion.com https://github.com/sylvainc
+Sylvain Legal sylvain.legal@akretion.com https://github.com/legalsylvain
+Thiago Moreira de Souza Arrais thiago.moreira@akretion.com.br https://github.com/thiagomds
+Valentin Chemiere valentin.chemiere@akretion.com https://github.com/viggor
+Vianney da Costa vianney.dacosta@akretion.com.br https://launchpad.net/~vianneydc
From 7535eaaedc61d6121f3bd67267127a369eb74c93 Mon Sep 17 00:00:00 2001
From: xmo-odoo
Date: Wed, 15 Apr 2015 10:19:28 +0200
Subject: [PATCH 02/21] [IMP] doc: note that accounting memento is US GAAP
So as not to confuse people looking for EU/IFRS accounting.
---
doc/business.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/business.rst b/doc/business.rst
index 26d4dfdf97a..def762578f6 100644
--- a/doc/business.rst
+++ b/doc/business.rst
@@ -4,4 +4,4 @@ Business Mementoes
.. toctree::
- Accounting Memento
+ Accounting Memento (US GAAP)
From 4a7159ca7803ccd679cf613bd862d61bac3038ae Mon Sep 17 00:00:00 2001
From: Nicolas Martinelli
Date: Wed, 15 Apr 2015 14:10:27 +0200
Subject: [PATCH 03/21] [FIX] purchase: merge RFQ if same currency and merge
order lines in appropriate RFQ - RFQ of same currency are merged (fixes #5901
and opw: 632594) - Merge order lines in the appropriate RFQ
---
addons/purchase/purchase.py | 13 +++++++------
.../purchase/wizard/purchase_order_group_view.xml | 2 +-
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 213b7da9013..e0434e635eb 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -868,7 +868,7 @@ class purchase_order(osv.osv):
Orders will only be merged if:
* Purchase Orders are in draft
* Purchase Orders belong to the same partner
- * Purchase Orders are have same stock location, same pricelist
+ * Purchase Orders are have same stock location, same pricelist, same currency
Lines will only be merged if:
* Order lines are exactly the same except for the quantity and unit
@@ -904,12 +904,13 @@ class purchase_order(osv.osv):
# Compute what the new orders should contain
new_orders = {}
- order_lines_to_move = []
+ order_lines_to_move = {}
for porder in [order for order in self.browse(cr, uid, ids, context=context) if order.state == 'draft']:
- order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id'))
+ order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id', 'currency_id'))
new_order = new_orders.setdefault(order_key, ({}, []))
new_order[1].append(porder.id)
order_infos = new_order[0]
+ order_lines_to_move.setdefault(order_key, [])
if not order_infos:
order_infos.update({
@@ -920,6 +921,7 @@ class purchase_order(osv.osv):
'picking_type_id': porder.picking_type_id.id,
'location_id': porder.location_id.id,
'pricelist_id': porder.pricelist_id.id,
+ 'currency_id': porder.currency_id.id,
'state': 'draft',
'order_line': {},
'notes': '%s' % (porder.notes or '',),
@@ -933,8 +935,7 @@ class purchase_order(osv.osv):
if porder.origin:
order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin
- for order_line in porder.order_line:
- order_lines_to_move += [order_line.id]
+ order_lines_to_move[order_key] += [order_line.id for order_line in porder.order_line]
allorders = []
orders_info = {}
@@ -948,7 +949,7 @@ class purchase_order(osv.osv):
for key, value in order_data['order_line'].iteritems():
del value['uom_factor']
value.update(dict(key))
- order_data['order_line'] = [(6, 0, order_lines_to_move)]
+ order_data['order_line'] = [(6, 0, order_lines_to_move[order_key])]
# create the new order
context.update({'mail_create_nolog': True})
diff --git a/addons/purchase/wizard/purchase_order_group_view.xml b/addons/purchase/wizard/purchase_order_group_view.xml
index 83503380c61..56efe485ae5 100644
--- a/addons/purchase/wizard/purchase_order_group_view.xml
+++ b/addons/purchase/wizard/purchase_order_group_view.xml
@@ -13,7 +13,7 @@ Please note that:
Orders will only be merged if:
* Purchase Orders are in draft
* Purchase Orders belong to the same supplier
-* Purchase Orders are have same stock location, same pricelist
+* Purchase Orders are have same stock location, same pricelist, same currency
Lines will only be merged if:
* Order lines are exactly the same except for the product,quantity and unit
" colspan="4"/>
From 3f7d168130aff5f9018aca8f21bf00ae78a8f7f8 Mon Sep 17 00:00:00 2001
From: rmu-odoo
Date: Fri, 30 Jan 2015 15:05:07 +0530
Subject: [PATCH 04/21] [FIX] sotck: correctly set reference on internal move
When creating a chained picking, the first move has no sequence, this is because
there is no sequence for stock.picking.internal.
Set the sequence before the chained move so that the sequences are in the right
order. opw 621261
---
addons/stock/stock.py | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 998109635bc..5cd1b4f510a 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -2061,17 +2061,20 @@ class stock_move(osv.osv):
for todo in moves_by_type.values():
ptype = todo[0][1][5] and todo[0][1][5] or location_obj.picking_type_get(cr, uid, todo[0][0].location_dest_id, todo[0][1][0])
if picking:
+ # Need to check name of old picking because it always considers picking as "OUT" when created from Sales Order
+ old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
+ if old_ptype != picking.type:
+ if old_ptype == 'internal':
+ old_pick_name = seq_obj.get(cr, uid, 'stock.picking')
+ else:
+ old_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + old_ptype)
+ self.pool.get('stock.picking').write(cr, uid, [picking.id], {'name': old_pick_name, 'type': old_ptype}, context=context)
# name of new picking according to its type
if ptype == 'internal':
new_pick_name = seq_obj.get(cr, uid,'stock.picking')
else :
new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
pickid = self._create_chained_picking(cr, uid, new_pick_name, picking, ptype, todo, context=context)
- # Need to check name of old picking because it always considers picking as "OUT" when created from Sales Order
- old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
- if old_ptype != picking.type:
- old_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + old_ptype)
- self.pool.get('stock.picking').write(cr, uid, [picking.id], {'name': old_pick_name, 'type': old_ptype}, context=context)
else:
pickid = False
for move, (loc, dummy, delay, dummy, company_id, ptype, invoice_state) in todo:
From 51774f2a4569f4df672718e0c32f0023253d5fde Mon Sep 17 00:00:00 2001
From: Denis Ledoux
Date: Wed, 15 Apr 2015 16:00:44 +0200
Subject: [PATCH 05/21] [FIX] mrp_repair: missiing taxes field in invoicing
tab.
Taxes can be applied on the repair fees.
The field was defined in the model, it was just missing
in the view.
In addition, the product_id_change worked already for the
taxes.
opw-632898
---
addons/mrp_repair/mrp_repair_view.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/addons/mrp_repair/mrp_repair_view.xml b/addons/mrp_repair/mrp_repair_view.xml
index b7a667ce308..48692400422 100644
--- a/addons/mrp_repair/mrp_repair_view.xml
+++ b/addons/mrp_repair/mrp_repair_view.xml
@@ -164,6 +164,7 @@
+
From 6aba1ac0c32cc50de03d6585955209c5fc01483d Mon Sep 17 00:00:00 2001
From: Nicolas Lempereur
Date: Wed, 15 Apr 2015 14:07:25 +0200
Subject: [PATCH 06/21] [FIX] crm: lead to opportunity
When converting a lead to an opportunity, there is a difference in
context than when going to an opportunity via the interface.
This leads to a difference when displaying a kanban view.
This commit adds what is needed in the context.
opw-632640
---
addons/crm/crm_lead.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 5bc185550ce..222817ed179 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -883,6 +883,7 @@ class crm_lead(format_address, osv.osv):
(tree_view or False, 'tree'), (False, 'kanban'),
(False, 'calendar'), (False, 'graph')],
'type': 'ir.actions.act_window',
+ 'context': {'default_type': 'opportunity'}
}
def redirect_lead_view(self, cr, uid, lead_id, context=None):
From 57c97784a928d8fe5d70d0fd78d46b8c0f0887be Mon Sep 17 00:00:00 2001
From: Rucha Dave
Date: Thu, 20 Nov 2014 17:55:00 +0530
Subject: [PATCH 07/21] [IMP] Project: modified set_remaining_time function to
improve functionality of Initially Planned Hour(s)
---
addons/project/project.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/project/project.py b/addons/project/project.py
index 12551248c44..d062076181d 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -970,7 +970,7 @@ class task(osv.osv):
def set_remaining_time(self, cr, uid, ids, remaining_time=1.0, context=None):
for task in self.browse(cr, uid, ids, context=context):
if (task.stage_id and task.stage_id.sequence <= 1) or (task.planned_hours == 0.0):
- self.write(cr, uid, [task.id], {'planned_hours': remaining_time}, context=context)
+ self.write(cr, uid, [task.id], {'planned_hours': remaining_time + task.effective_hours}, context=context)
self.write(cr, uid, ids, {'remaining_hours': remaining_time}, context=context)
return True
From 5fb717a971888e105db22cbe54eb4eac49f34764 Mon Sep 17 00:00:00 2001
From: Denis Ledoux
Date: Wed, 15 Apr 2015 16:53:35 +0200
Subject: [PATCH 08/21] [FIX] account: display name field in supplier refunds
The name field contains the refund reason.
The reason is filled when you create the refund
from the refund wizard available when
pressing "Ask Refund" on a supplier invoice.
As this field wasn't visibile on the supplier
invoice form, this wasn't possible to change
the reason on draft supplier refunds after
having created them through the wizard, while
you could change your mind or having done a
silly mistake in the wizard, that you could
edit since the invoice is stil draft.
This was also not possible to set a reason
when creating the refunds without going through
by the wizard.
This was also not possible to change the reason
when you duplicated your supplier refunds.
opw-632756
closes #6301
---
addons/account/account_invoice_view.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml
index 1106bd532d9..19919e53877 100644
--- a/addons/account/account_invoice_view.xml
+++ b/addons/account/account_invoice_view.xml
@@ -253,7 +253,7 @@
-
+
From 884864c40fd6faa242a4bde3f055d0be59a9da12 Mon Sep 17 00:00:00 2001
From: Martin Trigaux
Date: Wed, 15 Apr 2015 16:31:29 +0200
Subject: [PATCH 09/21] [FIX] account: do not show empty partners in manual
reconciliation
When doing a manual reconciliation, the current filter could restrict the
visibility of move lines and show empty results for some partners (e.g. filter
the lists on only one partner will show empty list of moves for other partners).
This is also the case for multicompany restrictions.
Integrate the current filter to the search to only get results for displayed
lines.
Fixes #3817, opw 618134
Fixes #5221, opw 632095
---
addons/account/account_move_line.py | 10 ++++++++--
.../static/src/js/account_move_reconciliation.js | 2 +-
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index 9287ed239c4..6dacf1a2816 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -741,7 +741,11 @@ class account_move_line(osv.osv):
args.append(('partner_id', '=', partner[0]))
return super(account_move_line, self).search(cr, uid, args, offset, limit, order, context, count)
- def list_partners_to_reconcile(self, cr, uid, context=None):
+ def list_partners_to_reconcile(self, cr, uid, context=None, filter_domain=False):
+ line_ids = []
+ if filter_domain:
+ line_ids = self.search(cr, uid, filter_domain, context=context)
+ where_clause = filter_domain and "AND l.id = ANY(%s)" or ""
cr.execute(
"""SELECT partner_id FROM (
SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit, MAX(l.create_date) AS max_date
@@ -751,10 +755,12 @@ class account_move_line(osv.osv):
WHERE a.reconcile IS TRUE
AND l.reconcile_id IS NULL
AND l.state <> 'draft'
+ %s
GROUP BY l.partner_id, p.last_reconciliation_date
) AS s
WHERE debit > 0 AND credit > 0 AND (last_reconciliation_date IS NULL OR max_date > last_reconciliation_date)
- ORDER BY last_reconciliation_date""")
+ ORDER BY last_reconciliation_date"""
+ % where_clause, (line_ids,))
ids = [x[0] for x in cr.fetchall()]
if not ids:
return []
diff --git a/addons/account/static/src/js/account_move_reconciliation.js b/addons/account/static/src/js/account_move_reconciliation.js
index cbc0abc4f4d..1629a16f5b3 100644
--- a/addons/account/static/src/js/account_move_reconciliation.js
+++ b/addons/account/static/src/js/account_move_reconciliation.js
@@ -49,7 +49,7 @@ openerp.account = function (instance) {
this.last_group_by = group_by;
this.old_search = _.bind(this._super, this);
var mod = new instance.web.Model("account.move.line", context, domain);
- return mod.call("list_partners_to_reconcile", []).then(function(result) {
+ return mod.call("list_partners_to_reconcile", [context, domain]).then(function(result) {
var current = self.current_partner !== null ? self.partners[self.current_partner][0] : null;
self.partners = result;
var index = _.find(_.range(self.partners.length), function(el) {
From 3b58ee833e098b061f603fd8c31b4b42e9c0488c Mon Sep 17 00:00:00 2001
From: Rucha Dave
Date: Thu, 13 Nov 2014 18:18:19 +0530
Subject: [PATCH 10/21] [IMP] stock: description of serial numbers empty list
The description was still making reference to available filter which is no
longer present in version 8. opw 617807
---
addons/stock/stock_view.xml | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 266d825aad3..174483e54a1 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -263,12 +263,7 @@
Click to add a serial number.
This is the list of all the production lots you recorded. When
- you select a lot, you can get the
- traceability of the products contained in lot. By default, the
- list is filtered on the serial numbers that are available in
- your warehouse but you can uncheck the 'Available' button to
- get all the lots you produced, received or delivered to
- customers.
+ you select a lot, you can get the traceability of the products contained in lot.
From 58fab75208270020093e6de1d40ddb033a880ef3 Mon Sep 17 00:00:00 2001
From: Akash Balar
Date: Fri, 14 Nov 2014 16:51:14 +0530
Subject: [PATCH 11/21] [FIX] CRM : won and lost stages are not required to be
folded anymore
The domain was inconsistent with the error message.
---
addons/crm/crm_lead.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 222817ed179..fbb0a3951a6 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -388,7 +388,7 @@ class crm_lead(format_address, osv.osv):
"""
stages_leads = {}
for lead in self.browse(cr, uid, ids, context=context):
- stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 0.0), ('fold', '=', True), ('sequence', '>', 1)], context=context)
+ stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 0.0), ('on_change', '=', True), ('sequence', '>', 1)], context=context)
if stage_id:
if stages_leads.get(stage_id):
stages_leads[stage_id].append(lead.id)
@@ -408,7 +408,7 @@ class crm_lead(format_address, osv.osv):
"""
stages_leads = {}
for lead in self.browse(cr, uid, ids, context=context):
- stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 100.0), ('fold', '=', True)], context=context)
+ stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 100.0), ('on_change', '=', True)], context=context)
if stage_id:
if stages_leads.get(stage_id):
stages_leads[stage_id].append(lead.id)
From 3b6eae8b1eca3532be27ba1f7d9913619e8f2686 Mon Sep 17 00:00:00 2001
From: Goffin Simon
Date: Tue, 14 Apr 2015 17:32:49 +0200
Subject: [PATCH 12/21] [FIX] sale: Sales Team GaugeEq
In Sales Team, the value shown when the cursor is over the gauge for Sales Orders
must not include the taxes.
opw:632348
---
addons/sale/sales_team.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/addons/sale/sales_team.py b/addons/sale/sales_team.py
index ef4891de8e8..a9f8fa6b482 100644
--- a/addons/sale/sales_team.py
+++ b/addons/sale/sales_team.py
@@ -24,8 +24,7 @@ class crm_case_section(osv.osv):
created_domain = [('section_id', '=', id), ('state', '=', 'draft'), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
validated_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'sent', 'cancel']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
res[id]['monthly_quoted'] = json.dumps(self.__get_bar_values(cr, uid, obj, created_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context))
- res[id]['monthly_confirmed'] = json.dumps(self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context))
-
+ res[id]['monthly_confirmed'] = json.dumps(self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_untaxed', 'date_order'], 'amount_untaxed', 'date_order', context=context))
return res
def _get_invoices_data(self, cr, uid, ids, field_name, arg, context=None):
From a5a797d0a6f5b723141069c833894bee1d3d600e Mon Sep 17 00:00:00 2001
From: Goffin Simon
Date: Tue, 14 Apr 2015 17:38:11 +0200
Subject: [PATCH 13/21] [FIX] web_kanban_sparkline: Floating format
The format of a float value must consider the language of
the user.
opw:632348
---
.../static/src/js/kanban_sparkline.js | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/addons/web_kanban_sparkline/static/src/js/kanban_sparkline.js b/addons/web_kanban_sparkline/static/src/js/kanban_sparkline.js
index b8c7761d103..f5be348a8e7 100644
--- a/addons/web_kanban_sparkline/static/src/js/kanban_sparkline.js
+++ b/addons/web_kanban_sparkline/static/src/js/kanban_sparkline.js
@@ -11,6 +11,15 @@ instance.web_kanban.SparklineBarWidget = instance.web_kanban.AbstractField.exten
var self = this;
var title = this.$node.html() || this.field.string;
setTimeout(function () {
+ var tooltipFormatter = function(sp, options, fields) {
+ var format = $.spformat('
{{offset:offset}} {{formatted_value}}
');
+ var result = '';
+ $.each(fields, function(i, field) {
+ field.formatted_value = instance.web.format_value(field.value, { type : 'float' });
+ result += format.render(field, options.get('tooltipValueLookups'), options);
+ })
+ return result;
+ }
var field_value = JSON.parse(self.field.value);
var value = _.pluck(field_value, 'value');
var tooltips = _.pluck(field_value, 'tooltip');
@@ -24,6 +33,7 @@ instance.web_kanban.SparklineBarWidget = instance.web_kanban.AbstractField.exten
barSpacing: 1,
barColor: '#96d854',
tooltipFormat: tooltipFormat,
+ tooltipFormatter: self.options.type == 'tristate' ? undefined : tooltipFormatter,
chartRangeMin: 0,
tooltipValueLookups: {
'offset': tooltips
From 397892a6c83b60e062345fd269745799bae0517c Mon Sep 17 00:00:00 2001
From: Goffin Simon
Date: Wed, 15 Apr 2015 14:51:33 +0200
Subject: [PATCH 14/21] [FIX] account: invoice_form for button invoiced
Button "invoiced" only shows customer invoices. The form view used must be
"invoice_form".
opw:632853
---
addons/account/account_invoice_view.xml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml
index b692f4e55c2..bcdb0d725c9 100644
--- a/addons/account/account_invoice_view.xml
+++ b/addons/account/account_invoice_view.xml
@@ -508,6 +508,19 @@
+
+
+ tree
+
+
+
+
+
+ form
+
+
+
+
Pending Invoiceaccount.invoice
From 57c1b07ebf8e6ac6fdc34907eae25ead011c2633 Mon Sep 17 00:00:00 2001
From: Goffin Simon
Date: Thu, 2 Apr 2015 09:14:46 +0200
Subject: [PATCH 15/21] [FIX] sale: Wrong invoice settings
On a sale order for a customer A where the invoice address is the address of the customer B,
the payment term, the receivable account and the fiscal position must be set from customer B
which is the partner invoice.
opw:630962
---
addons/sale/sale.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index a669853287e..3fb5e1743bd 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -330,7 +330,8 @@ class sale_order(osv.osv):
part = self.pool.get('res.partner').browse(cr, uid, part, context=context)
addr = self.pool.get('res.partner').address_get(cr, uid, [part.id], ['delivery', 'invoice', 'contact'])
pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
- payment_term = part.property_payment_term and part.property_payment_term.id or False
+ invoice_part = self.pool.get('res.partner').browse(cr, uid, addr['invoice'], context=context)
+ payment_term = invoice_part.property_payment_term and invoice_part.property_payment_term.id or False
dedicated_salesman = part.user_id and part.user_id.id or uid
val = {
'partner_invoice_id': addr['invoice'],
@@ -394,14 +395,14 @@ class sale_order(osv.osv):
'origin': order.name,
'type': 'out_invoice',
'reference': order.client_order_ref or order.name,
- 'account_id': order.partner_id.property_account_receivable.id,
+ 'account_id': order.partner_invoice_id.property_account_receivable.id,
'partner_id': order.partner_invoice_id.id,
'journal_id': journal_ids[0],
'invoice_line': [(6, 0, lines)],
'currency_id': order.pricelist_id.currency_id.id,
'comment': order.note,
'payment_term': order.payment_term and order.payment_term.id or False,
- 'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
+ 'fiscal_position': order.fiscal_position.id or order.partner_invoice_id.property_account_position.id,
'date_invoice': context.get('date_invoice', False),
'company_id': order.company_id.id,
'user_id': order.user_id and order.user_id.id or False,
From a6ef1a7c723cbcbf2c868eb97ea52d46b5a639b9 Mon Sep 17 00:00:00 2001
From: Jean-Nicolas Brunet
Date: Thu, 16 Apr 2015 09:22:19 +0200
Subject: [PATCH 16/21] [ADD] CLA for jnbrunet
---
doc/cla/individual/jnbrunet.md | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 doc/cla/individual/jnbrunet.md
diff --git a/doc/cla/individual/jnbrunet.md b/doc/cla/individual/jnbrunet.md
new file mode 100644
index 00000000000..9c48a753205
--- /dev/null
+++ b/doc/cla/individual/jnbrunet.md
@@ -0,0 +1,11 @@
+Canada, March 21 2015
+
+I hereby agree to the terms of the Odoo Individual Contributor License
+Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this
+declaration.
+
+Signed,
+
+Jean-Nicolas Brunet jnbrunet2000@gmail.com https://github.com/jnbrunet
From 58a481329eb1ec4074a08e12b89fdbd2aaa35343 Mon Sep 17 00:00:00 2001
From: Martin Trigaux
Date: Thu, 16 Apr 2015 09:23:50 +0200
Subject: [PATCH 17/21] [FIX] point_of_sale: child taxes computation
The box "Tax on children" was ignored in the pos, leading to 100% taxes for these
taxes (as amount is 1.0 on these taxes).
Add child tax fields when loading the pos to be able to correctly compute
recusively the tax amount on children.
Courtesy of Jean-Nicolas Brunet
Fixes #1515, lp:1231574, opw 622143
---
addons/point_of_sale/static/src/js/models.js | 104 +++++++++++++------
1 file changed, 71 insertions(+), 33 deletions(-)
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index dc2557fa62d..13422c7f9e8 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -188,14 +188,20 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
},
},{
model: 'account.tax',
- fields: ['name','amount', 'price_include', 'include_base_amount', 'type'],
+ fields: ['name','amount', 'price_include', 'include_base_amount', 'type', 'child_ids', 'child_depend', 'include_base_amount'],
domain: null,
- loaded: function(self,taxes){
- self.taxes = taxes;
+ loaded: function(self, taxes){
+ self.taxes = taxes;
self.taxes_by_id = {};
- for (var i = 0; i < taxes.length; i++) {
- self.taxes_by_id[taxes[i].id] = taxes[i];
- }
+ _.each(taxes, function(tax){
+ self.taxes_by_id[tax.id] = tax;
+ });
+ _.each(self.taxes_by_id, function(tax) {
+ tax.child_taxes = {};
+ _.each(tax.child_ids, function(child_tax_id) {
+ tax.child_taxes[child_tax_id] = self.taxes_by_id[child_tax_id];
+ });
+ });
},
},{
model: 'pos.session',
@@ -851,52 +857,84 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
get_tax_details: function(){
return this.get_all_prices().taxDetails;
},
- get_all_prices: function(){
+ compute_all: function(taxes, price_unit) {
var self = this;
+ var res = [];
var currency_rounding = this.pos.currency.rounding;
- var base = this.get_base_price();
- var totalTax = base;
- var totalNoTax = base;
-
- var product = this.get_product();
- var taxes = this.get_applicable_taxes();
- var taxtotal = 0;
- var taxdetail = {};
- _.each(taxes, function(tax) {
+ var base = price_unit;
+ _(taxes).each(function(tax) {
if (tax.price_include) {
- var tmp;
if (tax.type === "percent") {
- tmp = base - round_pr(base / (1 + tax.amount),currency_rounding);
+ tmp = round_pr(base - round_pr(base / (1 + tax.amount),currency_rounding),currency_rounding);
+ data = {amount:tmp, price_include:true, id: tax.id};
+ res.push(data);
} else if (tax.type === "fixed") {
tmp = round_pr(tax.amount * self.get_quantity(),currency_rounding);
+ data = {amount:tmp, price_include:true, id: tax.id};
+ res.push(data);
} else {
throw "This type of tax is not supported by the point of sale: " + tax.type;
}
- tmp = round_pr(tmp,currency_rounding);
- taxtotal += tmp;
- totalNoTax -= tmp;
- taxdetail[tax.id] = tmp;
} else {
- var tmp;
if (tax.type === "percent") {
- tmp = tax.amount * base;
+ tmp = round_pr(tax.amount * base, currency_rounding);
+ data = {amount:tmp, price_include:false, id: tax.id};
+ res.push(data);
} else if (tax.type === "fixed") {
- tmp = tax.amount * self.get_quantity();
+ tmp = round_pr(tax.amount * self.get_quantity(), currency_rounding);
+ data = {amount:tmp, price_include:false, id: tax.id};
+ res.push(data);
} else {
throw "This type of tax is not supported by the point of sale: " + tax.type;
}
- tmp = round_pr(tmp,currency_rounding);
-
- if (tax.include_base_amount) {
- base += tmp;
+ var base_amount = data.amount;
+ var child_amount = 0.0;
+ if (tax.child_depend) {
+ res.pop(); // do not use parent tax
+ child_tax = self.compute_all(tax.child_taxes, base_amount);
+ res.push(child_tax);
+ _(child_tax).each(function(child) {
+ child_amount += child.amount;
+ });
+ }
+ if (tax.include_base_amount) {
+ base += base_amount + child_amount;
}
-
- taxtotal += tmp;
- totalTax += tmp;
- taxdetail[tax.id] = tmp;
}
});
+ return res;
+ },
+ get_all_prices: function(){
+ var base = round_pr(this.get_quantity() * this.get_unit_price() * (1.0 - (this.get_discount() / 100.0)), this.pos.currency.rounding);
+ var totalTax = base;
+ var totalNoTax = base;
+ var taxtotal = 0;
+
+ var product = this.get_product();
+ var taxes_ids = product.taxes_id;
+ var taxes = this.pos.taxes;
+ var taxdetail = {};
+ var product_taxes = [];
+
+ _(taxes_ids).each(function(el){
+ product_taxes.push(_.detect(taxes, function(t){
+ return t.id === el;
+ }));
+ });
+
+ var all_taxes = _(this.compute_all(product_taxes, base)).flatten();
+
+ _(all_taxes).each(function(tax) {
+ if (tax.price_include) {
+ totalNoTax -= tax.amount;
+ } else {
+ totalTax += tax.amount;
+ }
+ taxtotal += tax.amount;
+ taxdetail[tax.id] = tax.amount;
+ });
+
return {
"priceWithTax": totalTax,
"priceWithoutTax": totalNoTax,
From cd94f10e1dccec0fc17df61992f785514fe2204e Mon Sep 17 00:00:00 2001
From: David Monjoie
Date: Thu, 16 Apr 2015 14:12:05 +0200
Subject: [PATCH 18/21] [FIX] base: fixed display of address in IE11
Spiritual backport of 5de677208c8db5589f20727d987b729dc9545976
which should have been fixed in 7.0 back then.
---
openerp/addons/base/res/res_partner_view.xml | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml
index 2f442479434..09473c47de9 100644
--- a/openerp/addons/base/res/res_partner_view.xml
+++ b/openerp/addons/base/res/res_partner_view.xml
@@ -155,10 +155,12 @@
-
-
+
+
+
+
From 55f9cbf9c7331fdf14cc716768fef308181fc0fa Mon Sep 17 00:00:00 2001
From: Martin Trigaux
Date: Thu, 16 Apr 2015 13:46:09 +0200
Subject: [PATCH 19/21] [FIX] hr_timesheet_invoice: description of invoice
Partial backport of 4d912af without the group by partner part. Do not forward
port above saas-6.
The generation of invoices from analytic lines was messy and mixed the
description of lines (e.g. redundant message when same product is invoiced twice
with different user, see opw 633047). Grouping was not consistent.
In 4d912af, grouping by partner was added with a refactoring of the grouping
method. Backport the second part only to get cleaner grouping and avoid mixing
messages.
---
.../hr_timesheet_invoice.py | 266 ++++++++++--------
1 file changed, 144 insertions(+), 122 deletions(-)
diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
index 6e6393bced2..ac7c237d73c 100644
--- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
+++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
@@ -150,14 +150,106 @@ class account_analytic_line(osv.osv):
price = 0.0
return price
+ def _prepare_cost_invoice(self, cr, uid, partner, company_id, currency_id, analytic_lines, context=None):
+ """ returns values used to create main invoice from analytic lines"""
+ account_payment_term_obj = self.pool['account.payment.term']
+ invoice_name = analytic_lines[0].account_id.name
+
+ date_due = False
+ if partner.property_payment_term:
+ pterm_list = account_payment_term_obj.compute(cr, uid,
+ partner.property_payment_term.id, value=1,
+ date_ref=time.strftime('%Y-%m-%d'))
+ if pterm_list:
+ pterm_list = [line[0] for line in pterm_list]
+ pterm_list.sort()
+ date_due = pterm_list[-1]
+ return {
+ 'name': "%s - %s" % (time.strftime('%d/%m/%Y'), invoice_name),
+ 'partner_id': partner.id,
+ 'company_id': company_id,
+ 'payment_term': partner.property_payment_term.id or False,
+ 'account_id': partner.property_account_receivable.id,
+ 'currency_id': currency_id,
+ 'date_due': date_due,
+ 'fiscal_position': partner.property_account_position.id
+ }
+
+ def _prepare_cost_invoice_line(self, cr, uid, invoice_id, product_id, uom, user_id,
+ factor_id, account, analytic_lines, journal_type, data, context=None):
+ product_obj = self.pool['product.product']
+
+ uom_context = dict(context or {}, uom=uom)
+
+ total_price = sum(l.amount for l in analytic_lines)
+ total_qty = sum(l.unit_amount for l in analytic_lines)
+
+ if data.get('product'):
+ # force product, use its public price
+ if isinstance(data['product'], (tuple, list)):
+ product_id = data['product'][0]
+ else:
+ product_id = data['product']
+ unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, total_qty, uom_context)
+ elif journal_type == 'general' and product_id:
+ # timesheets, use sale price
+ unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, total_qty, uom_context)
+ else:
+ # expenses, using price from amount field
+ unit_price = total_price*-1.0 / total_qty
+
+ factor = self.pool['hr_timesheet_invoice.factor'].browse(cr, uid, factor_id, context=uom_context)
+ factor_name = factor.customer_name
+ curr_invoice_line = {
+ 'price_unit': unit_price,
+ 'quantity': total_qty,
+ 'product_id': product_id,
+ 'discount': factor.factor,
+ 'invoice_id': invoice_id,
+ 'name': factor_name,
+ 'uos_id': uom,
+ 'account_analytic_id': account.id,
+ }
+
+ if product_id:
+ product = product_obj.browse(cr, uid, product_id, context=uom_context)
+ factor_name = product_obj.name_get(cr, uid, [product_id], context=uom_context)[0][1]
+ if factor.customer_name:
+ factor_name += ' - ' + factor.customer_name
+
+ general_account = product.property_account_income or product.categ_id.property_account_income_categ
+ if not general_account:
+ raise osv.except_osv(_('Error!'), _("Configuration Error!") + '\n' + _("Please define income account for product '%s'.") % product.name)
+ taxes = product.taxes_id or general_account.tax_ids
+ tax = self.pool['account.fiscal.position'].map_tax(cr, uid, account.partner_id.property_account_position, taxes)
+ curr_invoice_line.update({
+ 'invoice_line_tax_id': [(6, 0, tax)],
+ 'name': factor_name,
+ 'invoice_line_tax_id': [(6, 0, tax)],
+ 'account_id': general_account.id,
+ })
+
+ note = []
+ for line in analytic_lines:
+ # set invoice_line_note
+ details = []
+ if data.get('date', False):
+ details.append(line['date'])
+ if data.get('time', False):
+ if line['product_uom_id']:
+ details.append("%s %s" % (line.unit_amount, line.product_uom_id.name))
+ else:
+ details.append("%s" % (line['unit_amount'], ))
+ if data.get('name', False):
+ details.append(line['name'])
+ if details:
+ note.append(u' - '.join(map(lambda x: unicode(x) or '', details)))
+ if note:
+ curr_invoice_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '', note)))
+ return curr_invoice_line
+
def invoice_cost_create(self, cr, uid, ids, data=None, context=None):
- analytic_account_obj = self.pool.get('account.analytic.account')
- account_payment_term_obj = self.pool.get('account.payment.term')
invoice_obj = self.pool.get('account.invoice')
- product_obj = self.pool.get('product.product')
- invoice_factor_obj = self.pool.get('hr_timesheet_invoice.factor')
- fiscal_pos_obj = self.pool.get('account.fiscal.position')
- product_uom_obj = self.pool.get('product.uom')
invoice_line_obj = self.pool.get('account.invoice.line')
invoices = []
if context is None:
@@ -165,132 +257,62 @@ class account_analytic_line(osv.osv):
if data is None:
data = {}
- journal_types = {}
+ # use key (partner/account, company, currency)
+ # creates one invoice per key
+ invoice_grouping = {}
+ currency_id = False
# prepare for iteration on journal and accounts
- for line in self.pool.get('account.analytic.line').browse(cr, uid, ids, context=context):
- if line.journal_id.type not in journal_types:
- journal_types[line.journal_id.type] = set()
- journal_types[line.journal_id.type].add(line.account_id.id)
- for journal_type, account_ids in journal_types.items():
- for account in analytic_account_obj.browse(cr, uid, list(account_ids), context=context):
- partner = account.partner_id
+ for line in self.browse(cr, uid, ids, context=context):
+
+ key = (line.account_id.id,
+ line.account_id.company_id.id,
+ line.account_id.pricelist_id.currency_id.id)
+ invoice_grouping.setdefault(key, []).append(line)
+
+ for (key_id, company_id, currency_id), analytic_lines in invoice_grouping.items():
+ # key_id is an account.analytic.account
+ partner = analytic_lines[0].account_id.partner_id # will be the same for every line
+
+ curr_invoice = self._prepare_cost_invoice(cr, uid, partner, company_id, currency_id, analytic_lines, context=context)
+ invoice_context = dict(context,
+ lang=partner.lang,
+ force_company=company_id, # set force_company in context so the correct product properties are selected (eg. income account)
+ company_id=company_id) # set company_id in context, so the correct default journal will be selected
+ last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=invoice_context)
+ invoices.append(last_invoice)
+
+ # use key (product, uom, user, invoiceable, analytic account, journal type)
+ # creates one invoice line per key
+ invoice_lines_grouping = {}
+ for analytic_line in analytic_lines:
+ account = analytic_line.account_id
if (not partner) or not (account.pricelist_id):
- raise osv.except_osv(_('Analytic Account Incomplete!'),
- _('Contract incomplete. Please fill in the Customer and Pricelist fields.'))
+ raise osv.except_osv(_('Error!'), _('Contract incomplete. Please fill in the Customer and Pricelist fields for %s.') % (account.name))
- date_due = False
- if partner.property_payment_term:
- pterm_list= account_payment_term_obj.compute(cr, uid,
- partner.property_payment_term.id, value=1,
- date_ref=time.strftime('%Y-%m-%d'))
- if pterm_list:
- pterm_list = [line[0] for line in pterm_list]
- pterm_list.sort()
- date_due = pterm_list[-1]
+ if not analytic_line.to_invoice:
+ raise osv.except_osv(_('Error!'), _('Trying to invoice non invoiceable line for %s.') % (analytic_line.product_id.name))
- curr_invoice = {
- 'name': time.strftime('%d/%m/%Y') + ' - '+account.name,
- 'partner_id': account.partner_id.id,
- 'company_id': account.company_id.id,
- 'payment_term': partner.property_payment_term.id or False,
- 'account_id': partner.property_account_receivable.id,
- 'currency_id': account.pricelist_id.currency_id.id,
- 'date_due': date_due,
- 'fiscal_position': account.partner_id.property_account_position.id
- }
- context2 = context.copy()
- context2['lang'] = partner.lang
- # set company_id in context, so the correct default journal will be selected
- context2['force_company'] = curr_invoice['company_id']
- # set force_company in context so the correct product properties are selected (eg. income account)
- context2['company_id'] = curr_invoice['company_id']
+ key = (analytic_line.product_id.id,
+ analytic_line.product_uom_id.id,
+ analytic_line.user_id.id,
+ analytic_line.to_invoice.id,
+ analytic_line.account_id,
+ analytic_line.journal_id.type)
+ invoice_lines_grouping.setdefault(key, []).append(analytic_line)
- last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2)
- invoices.append(last_invoice)
+ # finally creates the invoice line
+ for (product_id, uom, user_id, factor_id, account, journal_type), lines_to_invoice in invoice_lines_grouping.items():
+ curr_invoice_line = self._prepare_cost_invoice_line(cr, uid, last_invoice,
+ product_id, uom, user_id, factor_id, account, lines_to_invoice,
+ journal_type, data, context=context)
- cr.execute("""SELECT product_id, user_id, to_invoice, sum(amount), sum(unit_amount), product_uom_id
- FROM account_analytic_line as line LEFT JOIN account_analytic_journal journal ON (line.journal_id = journal.id)
- WHERE account_id = %s
- AND line.id IN %s AND journal.type = %s AND to_invoice IS NOT NULL
- GROUP BY product_id, user_id, to_invoice, product_uom_id""", (account.id, tuple(ids), journal_type))
-
- for product_id, user_id, factor_id, total_price, qty, uom in cr.fetchall():
- context2.update({'uom': uom})
-
- if data.get('product'):
- # force product, use its public price
- product_id = data['product'][0]
- unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, context2)
- elif journal_type == 'general' and product_id:
- # timesheets, use sale price
- unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, context2)
- else:
- # expenses, using price from amount field
- unit_price = total_price*-1.0 / qty
-
- factor = invoice_factor_obj.browse(cr, uid, factor_id, context=context2)
- # factor_name = factor.customer_name and line_name + ' - ' + factor.customer_name or line_name
- factor_name = factor.customer_name
- curr_line = {
- 'price_unit': unit_price,
- 'quantity': qty,
- 'product_id': product_id or False,
- 'discount': factor.factor,
- 'invoice_id': last_invoice,
- 'name': factor_name,
- 'uos_id': uom,
- 'account_analytic_id': account.id,
- }
- product = product_obj.browse(cr, uid, product_id, context=context2)
- if product:
- factor_name = product_obj.name_get(cr, uid, [product_id], context=context2)[0][1]
- if factor.customer_name:
- factor_name += ' - ' + factor.customer_name
-
- general_account = product.property_account_income or product.categ_id.property_account_income_categ
- if not general_account:
- raise osv.except_osv(_("Configuration Error!"), _("Please define income account for product '%s'.") % product.name)
- taxes = product.taxes_id or general_account.tax_ids
- tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes)
- curr_line.update({
- 'invoice_line_tax_id': [(6,0,tax )],
- 'name': factor_name,
- 'invoice_line_tax_id': [(6,0,tax)],
- 'account_id': general_account.id,
- })
- #
- # Compute for lines
- #
- cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id IN %s AND product_id=%s and to_invoice=%s ORDER BY account_analytic_line.date", (account.id, tuple(ids), product_id, factor_id))
-
- line_ids = cr.dictfetchall()
- note = []
- for line in line_ids:
- # set invoice_line_note
- details = []
- if data.get('date', False):
- details.append(line['date'])
- if data.get('time', False):
- if line['product_uom_id']:
- details.append("%s %s" % (line['unit_amount'], product_uom_obj.browse(cr, uid, [line['product_uom_id']],context2)[0].name))
- else:
- details.append("%s" % (line['unit_amount'], ))
- if data.get('name', False):
- details.append(line['name'])
- if details:
- note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
- if note:
- curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
- invoice_line_obj.create(cr, uid, curr_line, context=context)
- cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))
- self.invalidate_cache(cr, uid, ['invoice_id'], ids, context=context)
-
- invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
+ invoice_line_obj.create(cr, uid, curr_invoice_line, context=context)
+ self.write(cr, uid, [l.id for l in analytic_lines], {'invoice_id': last_invoice}, context=context)
+ invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
return invoices
-
class hr_analytic_timesheet(osv.osv):
_inherit = "hr.analytic.timesheet"
def on_change_account_id(self, cr, uid, ids, account_id, user_id=False):
From d0ef1b938d1525d994895b743f980c6ce1eb4e40 Mon Sep 17 00:00:00 2001
From: dhr-odoo
Date: Wed, 26 Nov 2014 10:24:58 +0530
Subject: [PATCH 20/21] [FIX] Fixed wrong digits format issue for float fields
when thousand separator is '.'
The function was returning the number value directly before proceeding to any formatting.
---
addons/web/static/src/js/formats.js | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js
index cddeced29ca..d9126184c38 100644
--- a/addons/web/static/src/js/formats.js
+++ b/addons/web/static/src/js/formats.js
@@ -233,10 +233,7 @@ instance.web.parse_value = function (value, descriptor, value_if_empty) {
throw new Error(_.str.sprintf(_t("'%s' is not a correct integer"), value));
return tmp;
case 'float':
- var tmp = Number(value);
- if (!isNaN(tmp))
- return tmp;
-
+ var tmp;
var tmp2 = value;
do {
tmp = tmp2;
From bd82569d512c37db6ff3a870e31d05ad7e8fb3a5 Mon Sep 17 00:00:00 2001
From: Goffin Simon
Date: Tue, 14 Apr 2015 16:58:39 +0200
Subject: [PATCH 21/21] [FIX] website_quote: online quotation
To show the translation linked to an order, the controller "/quote/" must consider the context to browse
the order_id.
opw:632349
---
addons/website_quote/controllers/main.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/website_quote/controllers/main.py b/addons/website_quote/controllers/main.py
index a6de9543e47..f8dc4bad961 100644
--- a/addons/website_quote/controllers/main.py
+++ b/addons/website_quote/controllers/main.py
@@ -36,7 +36,7 @@ class sale_quote(http.Controller):
def view(self, order_id, token=None, message=False, **post):
# use SUPERUSER_ID allow to access/view order for public user
# only if he knows the private token
- order = request.registry.get('sale.order').browse(request.cr, token and SUPERUSER_ID or request.uid, order_id)
+ order = request.registry.get('sale.order').browse(request.cr, token and SUPERUSER_ID or request.uid, order_id, request.context)
now = time.strftime('%Y-%m-%d')
if token:
if token != order.access_token: