From 9b1a9c95189d41c1cd6353063a89564f5c37c96d Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 29 Sep 2014 17:39:01 +0200 Subject: [PATCH 1/7] [FIX] tools: remove useless attributes --- openerp/tools/safe_eval.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openerp/tools/safe_eval.py b/openerp/tools/safe_eval.py index c317c9bea88..6c5bb88da4e 100644 --- a/openerp/tools/safe_eval.py +++ b/openerp/tools/safe_eval.py @@ -267,8 +267,6 @@ def safe_eval(expr, globals_dict=None, locals_dict=None, mode="eval", nocopy=Fal 'False': False, 'None': None, 'str': str, - 'globals': locals, - 'locals': locals, 'bool': bool, 'dict': dict, 'list': list, From fca2f5ce31f6d72faffcced9345ea87ebe8dddae Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Tue, 30 Sep 2014 14:05:02 +0200 Subject: [PATCH 2/7] [FIX] im_livechat: ir.config_parameter must be read as superuser As ir.config_parameter is restricted to employees in ACL, for security reasons --- addons/im_livechat/im_livechat.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/im_livechat/im_livechat.py b/addons/im_livechat/im_livechat.py index cfc6bb9ce8e..5925084f4ee 100644 --- a/addons/im_livechat/im_livechat.py +++ b/addons/im_livechat/im_livechat.py @@ -107,7 +107,7 @@ class im_livechat_channel(osv.osv): res = {} for record in self.browse(cr, uid, ids, context=context): res[record.id] = env.get_template("include.html").render({ - "url": self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'), + "url": self.pool.get('ir.config_parameter').get_param(cr, openerp.SUPERUSER_ID, 'web.base.url'), "parameters": {"db":cr.dbname, "channel":record.id}, }) return res @@ -115,7 +115,7 @@ class im_livechat_channel(osv.osv): def _web_page(self, cr, uid, ids, name, arg, context=None): res = {} for record in self.browse(cr, uid, ids, context=context): - res[record.id] = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') + \ + res[record.id] = self.pool.get('ir.config_parameter').get_param(cr, openerp.SUPERUSER_ID, 'web.base.url') + \ "/im_livechat/web_page?p=" + json.dumps({"db":cr.dbname, "channel":record.id}) return res From 419c439776e3c7ab8ad142fe000890675c6e7092 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Tue, 30 Sep 2014 15:44:53 +0200 Subject: [PATCH 3/7] [FIX] account: sort partner ledger report by partner ref, name --- addons/account/report/account_partner_ledger.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/account/report/account_partner_ledger.py b/addons/account/report/account_partner_ledger.py index d21323e02fc..6d5f4924968 100644 --- a/addons/account/report/account_partner_ledger.py +++ b/addons/account/report/account_partner_ledger.py @@ -109,6 +109,7 @@ class third_party_ledger(report_sxw.rml_parse, common_report_header): "AND account.active ", params) self.partner_ids = [res['partner_id'] for res in self.cr.dictfetchall()] objects = obj_partner.browse(self.cr, self.uid, self.partner_ids) + objects.sort(key=lambda x: (x.ref, x.name)) return super(third_party_ledger, self).set_context(objects, data, self.partner_ids, report_type) def lines(self, partner): From 937fb4aa1105dac22fda231d68d51257171e9623 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 30 Sep 2014 15:31:52 +0200 Subject: [PATCH 4/7] [FIX] hr_expense: computation of tax/base amount When computing the amount for a tax (included) with children, accumulate the included taxes to avoid taking only the last one (opw 614867). --- addons/hr_expense/hr_expense.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index 17547a57ce0..e14e79aaa32 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -303,6 +303,7 @@ class hr_expense_expense(osv.osv): if not taxes: continue tax_l = [] + base_tax_amount = line.total_amount #Calculating tax on the line and creating move? for tax in tax_obj.compute_all(cr, uid, taxes, line.unit_amount , @@ -318,10 +319,10 @@ class hr_expense_expense(osv.osv): ## We need to deduce the price for the tax res[-1]['price'] = res[-1]['price'] - (tax['amount'] * tax['base_sign'] or 0.0) # tax amount countains base amount without the tax - tax_amount = (line.total_amount - tax['amount']) * tax['base_sign'] + base_tax_amount = (base_tax_amount - tax['amount']) * tax['base_sign'] else: - tax_amount = line.total_amount * tax['base_sign'] - res[-1]['tax_amount'] = cur_obj.compute(cr, uid, exp.currency_id.id, company_currency, tax_amount, context={'date': exp.date_confirm}) + base_tax_amount = base_tax_amount * tax['base_sign'] + assoc_tax = { 'type':'tax', 'name':tax['name'], @@ -333,6 +334,8 @@ class hr_expense_expense(osv.osv): 'tax_amount': tax['amount'] * tax['base_sign'], } tax_l.append(assoc_tax) + + res[-1]['tax_amount'] = cur_obj.compute(cr, uid, exp.currency_id.id, company_currency, base_tax_amount, context={'date': exp.date_confirm}) res += tax_l return res From 7201bc0250e460e13698d453018c2a83b75cbc5e Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 30 Sep 2014 16:17:57 +0200 Subject: [PATCH 5/7] [FIX] hr_payroll_account: do not create entries with amount at 0 If the salary compuation gives a salary of zero, skip the creation of the account.move.line (not good to have lines at 0). Fixes lp:1298116, opw 605816 --- addons/hr_payroll_account/hr_payroll_account.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/hr_payroll_account/hr_payroll_account.py b/addons/hr_payroll_account/hr_payroll_account.py index 9e892682e96..d6385c6f92b 100644 --- a/addons/hr_payroll_account/hr_payroll_account.py +++ b/addons/hr_payroll_account/hr_payroll_account.py @@ -24,7 +24,7 @@ from openerp import netsvc from datetime import date, datetime, timedelta from openerp.osv import fields, osv -from openerp.tools import config, float_compare +from openerp.tools import float_compare, float_is_zero from openerp.tools.translate import _ class hr_payslip(osv.osv): @@ -112,6 +112,8 @@ class hr_payslip(osv.osv): } for line in slip.details_by_salary_rule_category: amt = slip.credit_note and -line.total or line.total + if float_is_zero(amt, precision_digits=precision): + continue partner_id = line.salary_rule_id.register_id.partner_id and line.salary_rule_id.register_id.partner_id.id or default_partner_id debit_account_id = line.salary_rule_id.account_debit.id credit_account_id = line.salary_rule_id.account_credit.id @@ -183,6 +185,7 @@ class hr_payslip(osv.osv): 'credit': 0.0, }) line_ids.append(adjust_debit) + move.update({'line_id': line_ids}) move_id = move_pool.create(cr, uid, move, context=context) self.write(cr, uid, [slip.id], {'move_id': move_id, 'period_id' : period_id}, context=context) From 3c9df6a71fd25040a3baf31c785bd20a88b44464 Mon Sep 17 00:00:00 2001 From: dhr-odoo Date: Wed, 16 Jul 2014 19:15:56 +0530 Subject: [PATCH 6/7] [FIX] purchase: minmum purchase quantity and float precision (opw 610557) --- addons/purchase/purchase.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 5d56d3cb31a..d1bb845e38d 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -32,6 +32,7 @@ from openerp.tools.translate import _ import openerp.addons.decimal_precision as dp from openerp.osv.orm import browse_record, browse_null from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP +from openerp.tools.float_utils import float_compare class purchase_order(osv.osv): @@ -1013,13 +1014,14 @@ class purchase_order_line(osv.osv): supplierinfo = False + precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Product Unit of Measure') for supplier in product.seller_ids: if partner_id and (supplier.name.id == partner_id): supplierinfo = supplier if supplierinfo.product_uom.id != uom_id: res['warning'] = {'title': _('Warning!'), 'message': _('The selected supplier only sells this product by %s') % supplierinfo.product_uom.name } min_qty = product_uom._compute_qty(cr, uid, supplierinfo.product_uom.id, supplierinfo.min_qty, to_uom_id=uom_id) - if (qty or 0.0) < min_qty: # If the supplier quantity is greater than entered from user, set minimal. + if float_compare(min_qty , qty, precision_digits=precision) == 1: # If the supplier quantity is greater than entered from user, set minimal. if qty: res['warning'] = {'title': _('Warning!'), 'message': _('The selected supplier has a minimal quantity set to %s %s, you should not purchase less.') % (supplierinfo.min_qty, supplierinfo.product_uom.name)} qty = min_qty From 9cc54dcd2c09610e95cd379d4b7e216630a72b51 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 1 Oct 2014 12:39:32 +0200 Subject: [PATCH 7/7] [FIX] product: name_search handles negative operators --- addons/product/product.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/addons/product/product.py b/addons/product/product.py index da0ce6f9040..124ce313f37 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -25,7 +25,7 @@ import re from _common import ceiling from openerp import tools, SUPERUSER_ID -from openerp.osv import osv, fields +from openerp.osv import osv, fields, expression from openerp.tools.translate import _ import openerp.addons.decimal_precision as dp @@ -672,10 +672,13 @@ class product_product(osv.osv): if not args: args = [] if name: - ids = self.search(cr, user, [('default_code','=',name)]+ args, limit=limit, context=context) - if not ids: - ids = self.search(cr, user, [('ean13','=',name)]+ args, limit=limit, context=context) - if not ids: + positive_operators = ['=', 'ilike', '=ilike', 'like', '=like'] + ids = [] + if operator in positive_operators: + ids = self.search(cr, user, [('default_code','=',name)]+ args, limit=limit, context=context) + if not ids: + ids = self.search(cr, user, [('ean13','=',name)]+ args, limit=limit, context=context) + if not ids and operator not in expression.NEGATIVE_TERM_OPERATORS: # Do not merge the 2 next lines into one single search, SQL search performance would be abysmal # on a database with thousands of matching products, due to the huge merge+unique needed for the # OR operator (and given the fact that the 'name' lookup results come from the ir.translation table @@ -686,7 +689,9 @@ class product_product(osv.osv): # we may underrun the limit because of dupes in the results, that's fine ids.update(self.search(cr, user, args + [('name',operator,name)], limit=(limit and (limit-len(ids)) or False) , context=context)) ids = list(ids) - if not ids: + elif not ids and operator in expression.NEGATIVE_TERM_OPERATORS: + ids = self.search(cr, user, args + ['&', ('default_code', operator, name), ('name', operator, name)], limit=limit, context=context) + if not ids and operator in positive_operators: ptrn = re.compile('(\[(.*?)\])') res = ptrn.search(name) if res: