diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml
index 9675913a0b5..60b5934ac53 100644
--- a/addons/crm/crm_phonecall_view.xml
+++ b/addons/crm/crm_phonecall_view.xml
@@ -167,6 +167,7 @@
+
diff --git a/addons/event/report/report_event_registration.py b/addons/event/report/report_event_registration.py
index ca78412bd8e..e76b5c60d1f 100644
--- a/addons/event/report/report_event_registration.py
+++ b/addons/event/report/report_event_registration.py
@@ -52,7 +52,7 @@ class report_event_registration(osv.osv):
# TOFIX this request won't select events that have no registration
cr.execute(""" CREATE VIEW report_event_registration AS (
SELECT
- e.id::char || '/' || coalesce(r.id::char,'') AS id,
+ e.id::varchar || '/' || coalesce(r.id::varchar,'') AS id,
e.id AS event_id,
e.user_id AS user_id,
r.user_id AS user_id_registration,
diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py
index e25b5ac0894..f57b142cae9 100644
--- a/addons/hr_expense/hr_expense.py
+++ b/addons/hr_expense/hr_expense.py
@@ -263,6 +263,10 @@ class hr_expense_expense(osv.osv):
#convert eml into an osv-valid format
lines = map(lambda x:(0,0,self.line_get_convert(cr, uid, x, exp.employee_id.address_home_id, exp.date_confirm, context=context)), eml)
+ journal_id = move_obj.browse(cr, uid, move_id, context).journal_id
+ # post the journal entry if 'Skip 'Draft' State for Manual Entries' is checked
+ if journal_id.entry_posted:
+ move_obj.button_validate(cr, uid, [move_id], context)
move_obj.write(cr, uid, [move_id], {'line_id': lines}, context=context)
self.write(cr, uid, ids, {'account_move_id': move_id, 'state': 'done'}, context=context)
return True
diff --git a/addons/hr_payroll_account/hr_payroll_account.py b/addons/hr_payroll_account/hr_payroll_account.py
index ccab06c0dc1..ad8527fce43 100644
--- a/addons/hr_payroll_account/hr_payroll_account.py
+++ b/addons/hr_payroll_account/hr_payroll_account.py
@@ -23,7 +23,7 @@ import time
from datetime import date, datetime, timedelta
from openerp.osv import fields, osv
-from openerp.tools import config
+from openerp.tools import config, float_compare
from openerp.tools.translate import _
class hr_payslip(osv.osv):
@@ -86,6 +86,7 @@ class hr_payslip(osv.osv):
def process_sheet(self, cr, uid, ids, context=None):
move_pool = self.pool.get('account.move')
period_pool = self.pool.get('account.period')
+ precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Payroll')
timenow = time.strftime('%Y-%m-%d')
for slip in self.browse(cr, uid, ids, context=context):
@@ -149,7 +150,7 @@ class hr_payslip(osv.osv):
line_ids.append(credit_line)
credit_sum += credit_line[2]['credit'] - credit_line[2]['debit']
- if debit_sum > credit_sum:
+ if float_compare(credit_sum, debit_sum, precision_digits=precision) == -1:
acc_id = slip.journal_id.default_credit_account_id.id
if not acc_id:
raise osv.except_osv(_('Configuration Error!'),_('The Expense Journal "%s" has not properly configured the Credit Account!')%(slip.journal_id.name))
@@ -165,7 +166,7 @@ class hr_payslip(osv.osv):
})
line_ids.append(adjust_credit)
- elif debit_sum < credit_sum:
+ elif float_compare(debit_sum, credit_sum, precision_digits=precision) == -1:
acc_id = slip.journal_id.default_debit_account_id.id
if not acc_id:
raise osv.except_osv(_('Configuration Error!'),_('The Expense Journal "%s" has not properly configured the Debit Account!')%(slip.journal_id.name))
diff --git a/addons/l10n_multilang/l10n_multilang.py b/addons/l10n_multilang/l10n_multilang.py
index 937ba332694..4d70d2f40e7 100644
--- a/addons/l10n_multilang/l10n_multilang.py
+++ b/addons/l10n_multilang/l10n_multilang.py
@@ -138,7 +138,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
def _process_taxes_translations(self, cr, uid, obj_multi, company_id, langs, field, context=None):
obj_tax_template = self.pool.get('account.tax.template')
obj_tax = self.pool.get('account.tax')
- in_ids = sorted([x.id for x in obj_multi.chart_template_id.tax_template_ids])
+ in_ids = [x.id for x in obj_multi.chart_template_id.tax_template_ids]
out_ids = obj_tax.search(cr, uid, [('company_id', '=', company_id)], order='id')
return self.process_translations(cr, uid, langs, obj_tax_template, field, in_ids, obj_tax, out_ids, context=context)
diff --git a/addons/membership/membership_demo.xml b/addons/membership/membership_demo.xml
index 379eaf0c1e3..219e4c50e23 100644
--- a/addons/membership/membership_demo.xml
+++ b/addons/membership/membership_demo.xml
@@ -6,7 +6,7 @@
True
-
+
Gold Membership
180
@@ -16,7 +16,7 @@
True
-
+
Silver Membership
80
@@ -26,7 +26,7 @@
True
-
+
Basic Membership
40
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index e3271f3f947..6b629a16bc6 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -29,6 +29,7 @@ from openerp.tools import float_compare
from openerp.tools.translate import _
from openerp import tools, SUPERUSER_ID
from openerp import SUPERUSER_ID
+from openerp.addons.product import _common
#----------------------------------------------------------
# Work Centers
@@ -320,7 +321,7 @@ class mrp_bom(osv.osv):
"""
routing_obj = self.pool.get('mrp.routing')
factor = factor / (bom.product_efficiency or 1.0)
- factor = rounding(factor, bom.product_rounding)
+ factor = _common.ceiling(factor, bom.product_rounding)
if factor < bom.product_rounding:
factor = bom.product_rounding
result = []
@@ -376,6 +377,8 @@ class mrp_bom(osv.osv):
def rounding(f, r):
+ # TODO for trunk: log deprecation warning
+ # _logger.warning("Deprecated rounding method, please use tools.float_round to round floats.")
import math
if not r:
return f
diff --git a/addons/mrp_repair/__openerp__.py b/addons/mrp_repair/__openerp__.py
index a274cbc3ef4..ad20feb39b0 100644
--- a/addons/mrp_repair/__openerp__.py
+++ b/addons/mrp_repair/__openerp__.py
@@ -57,7 +57,8 @@ The following topics should be covered by this module:
'test/test_mrp_repair_b4inv.yml',
'test/test_mrp_repair_afterinv.yml',
'test/test_mrp_repair_cancel.yml',
- 'test/mrp_repair_report.yml'
+ 'test/mrp_repair_report.yml',
+ 'test/test_mrp_repair_fee.yml',
],
'installable': True,
'auto_install': False,
diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py
index f04aa68ca6a..b1aec60a4f4 100644
--- a/addons/mrp_repair/mrp_repair.py
+++ b/addons/mrp_repair/mrp_repair.py
@@ -108,10 +108,12 @@ class mrp_repair(osv.osv):
return res
def _get_lines(self, cr, uid, ids, context=None):
- result = {}
- for line in self.pool.get('mrp.repair.line').browse(cr, uid, ids, context=context):
- result[line.repair_id.id] = True
- return result.keys()
+ return self.pool['mrp.repair'].search(
+ cr, uid, [('operations', 'in', ids)], context=context)
+
+ def _get_fee_lines(self, cr, uid, ids, context=None):
+ return self.pool['mrp.repair'].search(
+ cr, uid, [('fees_lines', 'in', ids)], context=context)
_columns = {
'name': fields.char('Repair Reference',size=24, required=True, states={'confirmed':[('readonly',True)]}),
@@ -160,18 +162,21 @@ class mrp_repair(osv.osv):
'repaired': fields.boolean('Repaired', readonly=True),
'amount_untaxed': fields.function(_amount_untaxed, string='Untaxed Amount',
store={
- 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations'], 10),
+ 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations', 'fees_lines'], 10),
'mrp.repair.line': (_get_lines, ['price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom'], 10),
+ 'mrp.repair.fee': (_get_fee_lines, ['price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom'], 10),
}),
'amount_tax': fields.function(_amount_tax, string='Taxes',
store={
- 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations'], 10),
+ 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations', 'fees_lines'], 10),
'mrp.repair.line': (_get_lines, ['price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom'], 10),
+ 'mrp.repair.fee': (_get_fee_lines, ['price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom'], 10),
}),
'amount_total': fields.function(_amount_total, string='Total',
store={
- 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations'], 10),
+ 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations', 'fees_lines'], 10),
'mrp.repair.line': (_get_lines, ['price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom'], 10),
+ 'mrp.repair.fee': (_get_fee_lines, ['price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom'], 10),
}),
}
diff --git a/addons/mrp_repair/test/test_mrp_repair_fee.yml b/addons/mrp_repair/test/test_mrp_repair_fee.yml
new file mode 100644
index 00000000000..6aac605d0d9
--- /dev/null
+++ b/addons/mrp_repair/test/test_mrp_repair_fee.yml
@@ -0,0 +1,23 @@
+-
+ Testing total amount update function
+-
+ I check the total amount of mrp_repair_rmrp1 is 100
+-
+ !assert {model: mrp.repair, id: mrp_repair_rmrp1, string=amount_total should be 100}:
+ - amount_total == 100
+-
+ I add a new fee line
+-
+ !record {model: mrp.repair, id: mrp_repair_rmrp1}:
+ fees_lines:
+ - name: 'Assembly Service Cost'
+ product_id: product.product_assembly
+ product_uom_qty: 1.0
+ product_uom: product.product_uom_hour
+ price_unit: 12.0
+ to_invoice: True
+-
+ I check the total amount of mrp_repair_rmrp1 is now 112
+-
+ !assert {model: mrp.repair, id: mrp_repair_rmrp1, string=amount_total should be 112}:
+ - amount_total == 112
diff --git a/addons/product/__openerp__.py b/addons/product/__openerp__.py
index 194cc91b019..c628fca6aa8 100644
--- a/addons/product/__openerp__.py
+++ b/addons/product/__openerp__.py
@@ -63,7 +63,6 @@ Print product labels with barcode.
],
'test': [
'product_pricelist_demo.yml',
- 'test/product_uom.yml',
'test/product_pricelist.yml',
],
'installable': True,
diff --git a/addons/product/_common.py b/addons/product/_common.py
index f5f53fe8689..c05dcee66a2 100644
--- a/addons/product/_common.py
+++ b/addons/product/_common.py
@@ -18,12 +18,18 @@
# along with this program. If not, see .
#
##############################################################################
+from openerp import tools
+
+import math
+
+
def rounding(f, r):
+ # TODO for trunk: log deprecation warning
+ # _logger.warning("Deprecated rounding method, please use tools.float_round to round floats.")
+ return tools.float_round(f, precision_rounding=r)
+
+# TODO for trunk: add rounding method parameter to tools.float_round and use this method as hook
+def ceiling(f, r):
if not r:
return f
- return round(f / r) * r
-
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+ return math.ceil(f / r) * r
diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py
index 67ab3649b3b..3c2edf74ea3 100644
--- a/addons/product/pricelist.py
+++ b/addons/product/pricelist.py
@@ -21,8 +21,7 @@
import time
-from _common import rounding
-
+from openerp import tools
from openerp.osv import fields, osv
from openerp.tools.translate import _
@@ -270,7 +269,8 @@ class product_pricelist(osv.osv):
if price is not False:
price_limit = price
price = price * (1.0+(rule.price_discount or 0.0))
- price = rounding(price, rule.price_round) #TOFIX: rounding with tools.float_rouding
+ if rule.price_round:
+ price = tools.float_round(price, precision_rounding=rule.price_round)
price += (rule.price_surcharge or 0.0)
if rule.price_min_margin:
price = max(price, price_limit+rule.price_min_margin)
diff --git a/addons/product/product.py b/addons/product/product.py
index 3380db5a4aa..6b0e22238cd 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -22,7 +22,7 @@
import math
import re
-from _common import rounding
+from _common import ceiling
from openerp import SUPERUSER_ID
from openerp import tools
@@ -178,7 +178,7 @@ class product_uom(osv.osv):
return qty
amount = qty / from_unit.factor
if to_unit:
- amount = rounding(amount * to_unit.factor, to_unit.rounding)
+ amount = ceiling(amount * to_unit.factor, to_unit.rounding)
return amount
def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False):
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index c0798aa74dd..4946a71f80b 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -221,7 +221,6 @@
-
diff --git a/addons/product/test/product_uom.yml b/addons/product/test/product_uom.yml
deleted file mode 100644
index 04928d43d87..00000000000
--- a/addons/product/test/product_uom.yml
+++ /dev/null
@@ -1,15 +0,0 @@
--
- In order to test conversation of UOM,
--
- I convert Grams into TON with price.
--
- !python {model: product.uom}: |
- from_uom_id = ref("product_uom_gram")
- to_uom_id = ref("product_uom_ton")
- price = 2
- qty = 1020000
- price = self._compute_price(cr, uid, from_uom_id, price, to_uom_id)
- qty = self._compute_qty(cr, uid, from_uom_id, qty, to_uom_id)
- assert qty == 1.02, "Qty is not correspond."
- assert price == 2000000.0, "Price is not correspond."
-
diff --git a/addons/product/tests/__init__.py b/addons/product/tests/__init__.py
new file mode 100644
index 00000000000..850189ac0f4
--- /dev/null
+++ b/addons/product/tests/__init__.py
@@ -0,0 +1,5 @@
+from . import test_uom
+
+fast_suite = [
+ test_uom,
+]
diff --git a/addons/product/tests/test_uom.py b/addons/product/tests/test_uom.py
new file mode 100644
index 00000000000..3d3ba04b689
--- /dev/null
+++ b/addons/product/tests/test_uom.py
@@ -0,0 +1,37 @@
+from openerp.tests.common import TransactionCase
+
+class TestUom(TransactionCase):
+ """Tests for unit of measure conversion"""
+
+ def setUp(self):
+ super(TestUom, self).setUp()
+ self.product = self.registry('product.product')
+ self.uom = self.registry('product.uom')
+ self.imd = self.registry('ir.model.data')
+
+ def test_10_conversion(self):
+ cr, uid = self.cr, self.uid
+ gram_id = self.imd.get_object_reference(cr, uid, 'product', 'product_uom_gram')[1]
+ tonne_id = self.imd.get_object_reference(cr, uid, 'product', 'product_uom_ton')[1]
+
+ qty = self.uom._compute_qty(cr, uid, gram_id, 1020000, tonne_id)
+ self.assertEquals(qty, 1.02, "Converted quantity does not correspond.")
+
+ price = self.uom._compute_price(cr, uid, gram_id, 2, tonne_id)
+ self.assertEquals(price, 2000000.0, "Converted price does not correspond.")
+
+ def test_20_rounding(self):
+ cr, uid = self.cr, self.uid
+ unit_id = self.imd.get_object_reference(cr, uid, 'product', 'product_uom_unit')[1]
+ categ_unit_id = self.imd.get_object_reference(cr, uid, 'product', 'product_uom_categ_unit')[1]
+
+ score_id = self.uom.create(cr, uid, {
+ 'name': 'Score',
+ 'factor_inv': 20,
+ 'uom_type': 'bigger',
+ 'rounding': 1.0,
+ 'category_id': categ_unit_id
+ })
+
+ qty = self.uom._compute_qty(cr, uid, unit_id, 2, score_id)
+ self.assertEquals(qty, 1, "Converted quantity should be rounded up.")
diff --git a/addons/product_margin/product_margin.py b/addons/product_margin/product_margin.py
index 1bbfe8c285b..c344abb3410 100644
--- a/addons/product_margin/product_margin.py
+++ b/addons/product_margin/product_margin.py
@@ -53,9 +53,9 @@ class product_product(osv.osv):
states = ('draft', 'open', 'paid')
sqlstr="""select
- sum(l.price_unit * l.quantity)/sum(l.quantity) as avg_unit_price,
+ sum(l.price_unit * l.quantity)/sum(nullif(l.quantity,0)) as avg_unit_price,
sum(l.quantity) as num_qty,
- sum(l.quantity * (l.price_subtotal/l.quantity)) as total,
+ sum(l.quantity * (l.price_subtotal/(nullif(l.quantity,0)))) as total,
sum(l.quantity * pt.list_price) as sale_expected,
sum(l.quantity * pt.standard_price) as normal_cost
from account_invoice_line l