[MERGE] Forward-port of latest saas-2 bugfixes, up to rev. 9144 revid:dle@openerp.com-20140310133913-465x5t3n1bo7fu98
bzr revid: dle@openerp.com-20140310143600-kz7qjfe4p63s0a34
This commit is contained in:
commit
74af3ac0fe
|
@ -1601,7 +1601,6 @@
|
||||||
<label for="value_amount" string="Amount To Pay" attrs="{'invisible':[('value','=','balance')]}"/>
|
<label for="value_amount" string="Amount To Pay" attrs="{'invisible':[('value','=','balance')]}"/>
|
||||||
<div attrs="{'invisible':[('value','=','balance')]}">
|
<div attrs="{'invisible':[('value','=','balance')]}">
|
||||||
<field name="value_amount" class="oe_inline"/>
|
<field name="value_amount" class="oe_inline"/>
|
||||||
<label string="%%" class="oe_inline" attrs="{'invisible':['!',('value','=','procent')]}" />
|
|
||||||
</div>
|
</div>
|
||||||
</group>
|
</group>
|
||||||
<group string="Due Date Computation">
|
<group string="Due Date Computation">
|
||||||
|
|
|
@ -407,7 +407,7 @@ class crm_lead(format_address, osv.osv):
|
||||||
'probability = 0 %, select "Change Probability Automatically".\n'
|
'probability = 0 %, select "Change Probability Automatically".\n'
|
||||||
'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
|
'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
|
||||||
for stage_id, lead_ids in stages_leads.items():
|
for stage_id, lead_ids in stages_leads.items():
|
||||||
self.write(cr, uid, lead_ids, {'stage_id': stage_id}, context=context)
|
self.write(cr, uid, lead_ids, {'stage_id': stage_id, 'date_closed': fields.datetime.now()}, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def case_mark_won(self, cr, uid, ids, context=None):
|
def case_mark_won(self, cr, uid, ids, context=None):
|
||||||
|
@ -428,7 +428,7 @@ class crm_lead(format_address, osv.osv):
|
||||||
'probability = 100 % and select "Change Probability Automatically".\n'
|
'probability = 100 % and select "Change Probability Automatically".\n'
|
||||||
'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
|
'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
|
||||||
for stage_id, lead_ids in stages_leads.items():
|
for stage_id, lead_ids in stages_leads.items():
|
||||||
self.write(cr, uid, lead_ids, {'stage_id': stage_id}, context=context)
|
self.write(cr, uid, lead_ids, {'stage_id': stage_id, 'date_closed': fields.datetime.now()}, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def case_escalate(self, cr, uid, ids, context=None):
|
def case_escalate(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
<field name="view_mode">tree,calendar</field>
|
<field name="view_mode">tree,calendar</field>
|
||||||
<field name="view_id" ref="crm_case_inbound_phone_tree_view"/>
|
<field name="view_id" ref="crm_case_inbound_phone_tree_view"/>
|
||||||
<field name="domain">[]</field>
|
<field name="domain">[]</field>
|
||||||
<field name="context">{'default_state': 'done'}</field>
|
<field name="context">{'search_default_state': 'done', 'default_state': 'done'}</field>
|
||||||
<field name="search_view_id" ref="crm.view_crm_case_phonecalls_filter"/>
|
<field name="search_view_id" ref="crm.view_crm_case_phonecalls_filter"/>
|
||||||
<field name="help" type="html">
|
<field name="help" type="html">
|
||||||
<p class="oe_view_nocontent_create">
|
<p class="oe_view_nocontent_create">
|
||||||
|
|
|
@ -167,6 +167,7 @@
|
||||||
<search string="Search Phonecalls">
|
<search string="Search Phonecalls">
|
||||||
<field name="name" string="Phonecalls"/>
|
<field name="name" string="Phonecalls"/>
|
||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
|
<field name="state"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<filter icon="terp-gtk-go-back-rtl" string="To Do" name="current" domain="[('state','=','open')]"/>
|
<filter icon="terp-gtk-go-back-rtl" string="To Do" name="current" domain="[('state','=','open')]"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
|
|
|
@ -52,7 +52,7 @@ class report_event_registration(osv.osv):
|
||||||
# TOFIX this request won't select events that have no registration
|
# TOFIX this request won't select events that have no registration
|
||||||
cr.execute(""" CREATE VIEW report_event_registration AS (
|
cr.execute(""" CREATE VIEW report_event_registration AS (
|
||||||
SELECT
|
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.id AS event_id,
|
||||||
e.user_id AS user_id,
|
e.user_id AS user_id,
|
||||||
r.user_id AS user_id_registration,
|
r.user_id AS user_id_registration,
|
||||||
|
|
|
@ -263,6 +263,10 @@ class hr_expense_expense(osv.osv):
|
||||||
|
|
||||||
#convert eml into an osv-valid format
|
#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)
|
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)
|
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)
|
self.write(cr, uid, ids, {'account_move_id': move_id, 'state': 'done'}, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -23,7 +23,7 @@ import time
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
from openerp.tools import config
|
from openerp.tools import config, float_compare
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
class hr_payslip(osv.osv):
|
class hr_payslip(osv.osv):
|
||||||
|
@ -86,6 +86,7 @@ class hr_payslip(osv.osv):
|
||||||
def process_sheet(self, cr, uid, ids, context=None):
|
def process_sheet(self, cr, uid, ids, context=None):
|
||||||
move_pool = self.pool.get('account.move')
|
move_pool = self.pool.get('account.move')
|
||||||
period_pool = self.pool.get('account.period')
|
period_pool = self.pool.get('account.period')
|
||||||
|
precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Payroll')
|
||||||
timenow = time.strftime('%Y-%m-%d')
|
timenow = time.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
for slip in self.browse(cr, uid, ids, context=context):
|
for slip in self.browse(cr, uid, ids, context=context):
|
||||||
|
@ -149,7 +150,7 @@ class hr_payslip(osv.osv):
|
||||||
line_ids.append(credit_line)
|
line_ids.append(credit_line)
|
||||||
credit_sum += credit_line[2]['credit'] - credit_line[2]['debit']
|
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
|
acc_id = slip.journal_id.default_credit_account_id.id
|
||||||
if not acc_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))
|
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)
|
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
|
acc_id = slip.journal_id.default_debit_account_id.id
|
||||||
if not acc_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))
|
raise osv.except_osv(_('Configuration Error!'),_('The Expense Journal "%s" has not properly configured the Debit Account!')%(slip.journal_id.name))
|
||||||
|
|
|
@ -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):
|
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_template = self.pool.get('account.tax.template')
|
||||||
obj_tax = self.pool.get('account.tax')
|
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')
|
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)
|
return self.process_translations(cr, uid, langs, obj_tax_template, field, in_ids, obj_tax, out_ids, context=context)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<record id="membership_0" model="product.product">
|
<record id="membership_0" model="product.product">
|
||||||
<field name="membership">True</field>
|
<field name="membership">True</field>
|
||||||
<field eval="time.strftime('%Y-01-01')" name="membership_date_from"/>
|
<field eval="time.strftime('%Y-01-01')" name="membership_date_from"/>
|
||||||
<field eval="time.strftime('%Y-12-01')" name="membership_date_to"/>
|
<field eval="time.strftime('%Y-12-31')" name="membership_date_to"/>
|
||||||
<field name="name">Gold Membership</field>
|
<field name="name">Gold Membership</field>
|
||||||
<field name="list_price">180</field>
|
<field name="list_price">180</field>
|
||||||
<field name="categ_id" ref="product.product_category_1"/>
|
<field name="categ_id" ref="product.product_category_1"/>
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
<record id="membership_1" model="product.product">
|
<record id="membership_1" model="product.product">
|
||||||
<field name="membership">True</field>
|
<field name="membership">True</field>
|
||||||
<field eval="time.strftime('%Y-01-01')" name="membership_date_from"/>
|
<field eval="time.strftime('%Y-01-01')" name="membership_date_from"/>
|
||||||
<field eval="time.strftime('%Y-12-01')" name="membership_date_to"/>
|
<field eval="time.strftime('%Y-12-31')" name="membership_date_to"/>
|
||||||
<field name="name">Silver Membership</field>
|
<field name="name">Silver Membership</field>
|
||||||
<field name="categ_id" ref="product.product_category_1"/>
|
<field name="categ_id" ref="product.product_category_1"/>
|
||||||
<field name="list_price">80</field>
|
<field name="list_price">80</field>
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
<record id="membership_2" model="product.product">
|
<record id="membership_2" model="product.product">
|
||||||
<field name="membership">True</field>
|
<field name="membership">True</field>
|
||||||
<field eval="time.strftime('%Y-01-01')" name="membership_date_from"/>
|
<field eval="time.strftime('%Y-01-01')" name="membership_date_from"/>
|
||||||
<field eval="time.strftime('%Y-12-01')" name="membership_date_to"/>
|
<field eval="time.strftime('%Y-12-31')" name="membership_date_to"/>
|
||||||
<field name="name">Basic Membership</field>
|
<field name="name">Basic Membership</field>
|
||||||
<field name="categ_id" ref="product.product_category_1"/>
|
<field name="categ_id" ref="product.product_category_1"/>
|
||||||
<field name="list_price">40</field>
|
<field name="list_price">40</field>
|
||||||
|
|
|
@ -29,6 +29,7 @@ from openerp.tools import float_compare
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
from openerp import tools, SUPERUSER_ID
|
from openerp import tools, SUPERUSER_ID
|
||||||
from openerp import SUPERUSER_ID
|
from openerp import SUPERUSER_ID
|
||||||
|
from openerp.addons.product import _common
|
||||||
|
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
# Work Centers
|
# Work Centers
|
||||||
|
@ -320,7 +321,7 @@ class mrp_bom(osv.osv):
|
||||||
"""
|
"""
|
||||||
routing_obj = self.pool.get('mrp.routing')
|
routing_obj = self.pool.get('mrp.routing')
|
||||||
factor = factor / (bom.product_efficiency or 1.0)
|
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:
|
if factor < bom.product_rounding:
|
||||||
factor = bom.product_rounding
|
factor = bom.product_rounding
|
||||||
result = []
|
result = []
|
||||||
|
@ -376,6 +377,8 @@ class mrp_bom(osv.osv):
|
||||||
|
|
||||||
|
|
||||||
def rounding(f, r):
|
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
|
import math
|
||||||
if not r:
|
if not r:
|
||||||
return f
|
return f
|
||||||
|
|
|
@ -57,7 +57,8 @@ The following topics should be covered by this module:
|
||||||
'test/test_mrp_repair_b4inv.yml',
|
'test/test_mrp_repair_b4inv.yml',
|
||||||
'test/test_mrp_repair_afterinv.yml',
|
'test/test_mrp_repair_afterinv.yml',
|
||||||
'test/test_mrp_repair_cancel.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,
|
'installable': True,
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
|
|
|
@ -108,10 +108,12 @@ class mrp_repair(osv.osv):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _get_lines(self, cr, uid, ids, context=None):
|
def _get_lines(self, cr, uid, ids, context=None):
|
||||||
result = {}
|
return self.pool['mrp.repair'].search(
|
||||||
for line in self.pool.get('mrp.repair.line').browse(cr, uid, ids, context=context):
|
cr, uid, [('operations', 'in', ids)], context=context)
|
||||||
result[line.repair_id.id] = True
|
|
||||||
return result.keys()
|
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 = {
|
_columns = {
|
||||||
'name': fields.char('Repair Reference',size=24, required=True, states={'confirmed':[('readonly',True)]}),
|
'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),
|
'repaired': fields.boolean('Repaired', readonly=True),
|
||||||
'amount_untaxed': fields.function(_amount_untaxed, string='Untaxed Amount',
|
'amount_untaxed': fields.function(_amount_untaxed, string='Untaxed Amount',
|
||||||
store={
|
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.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',
|
'amount_tax': fields.function(_amount_tax, string='Taxes',
|
||||||
store={
|
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.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',
|
'amount_total': fields.function(_amount_total, string='Total',
|
||||||
store={
|
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.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),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -63,7 +63,6 @@ Print product labels with barcode.
|
||||||
],
|
],
|
||||||
'test': [
|
'test': [
|
||||||
'product_pricelist_demo.yml',
|
'product_pricelist_demo.yml',
|
||||||
'test/product_uom.yml',
|
|
||||||
'test/product_pricelist.yml',
|
'test/product_pricelist.yml',
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
|
|
|
@ -18,12 +18,18 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
from openerp import tools
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
def rounding(f, r):
|
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:
|
if not r:
|
||||||
return f
|
return f
|
||||||
return round(f / r) * r
|
return math.ceil(f / r) * r
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from _common import rounding
|
from openerp import tools
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
@ -270,7 +269,8 @@ class product_pricelist(osv.osv):
|
||||||
if price is not False:
|
if price is not False:
|
||||||
price_limit = price
|
price_limit = price
|
||||||
price = price * (1.0+(rule.price_discount or 0.0))
|
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)
|
price += (rule.price_surcharge or 0.0)
|
||||||
if rule.price_min_margin:
|
if rule.price_min_margin:
|
||||||
price = max(price, price_limit+rule.price_min_margin)
|
price = max(price, price_limit+rule.price_min_margin)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from _common import rounding
|
from _common import ceiling
|
||||||
|
|
||||||
from openerp import SUPERUSER_ID
|
from openerp import SUPERUSER_ID
|
||||||
from openerp import tools
|
from openerp import tools
|
||||||
|
@ -178,7 +178,7 @@ class product_uom(osv.osv):
|
||||||
return qty
|
return qty
|
||||||
amount = qty / from_unit.factor
|
amount = qty / from_unit.factor
|
||||||
if to_unit:
|
if to_unit:
|
||||||
amount = rounding(amount * to_unit.factor, to_unit.rounding)
|
amount = ceiling(amount * to_unit.factor, to_unit.rounding)
|
||||||
return amount
|
return amount
|
||||||
|
|
||||||
def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False):
|
def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False):
|
||||||
|
|
|
@ -221,7 +221,6 @@
|
||||||
<kanban>
|
<kanban>
|
||||||
<field name="color"/>
|
<field name="color"/>
|
||||||
<field name="type"/>
|
<field name="type"/>
|
||||||
<field name="image_small"/>
|
|
||||||
<field name="list_price"/>
|
<field name="list_price"/>
|
||||||
<templates>
|
<templates>
|
||||||
<t t-name="kanban-box">
|
<t t-name="kanban-box">
|
||||||
|
|
|
@ -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."
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
from . import test_uom
|
||||||
|
|
||||||
|
fast_suite = [
|
||||||
|
test_uom,
|
||||||
|
]
|
|
@ -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.")
|
|
@ -53,9 +53,9 @@ class product_product(osv.osv):
|
||||||
states = ('draft', 'open', 'paid')
|
states = ('draft', 'open', 'paid')
|
||||||
|
|
||||||
sqlstr="""select
|
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) 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.list_price) as sale_expected,
|
||||||
sum(l.quantity * pt.standard_price) as normal_cost
|
sum(l.quantity * pt.standard_price) as normal_cost
|
||||||
from account_invoice_line l
|
from account_invoice_line l
|
||||||
|
|
Loading…
Reference in New Issue