[MERGE] forward port of branch saas-3 up to 21b1203

This commit is contained in:
Christophe Simonis 2014-10-29 19:33:02 +01:00
commit 8e637bac92
11 changed files with 148 additions and 74 deletions

View File

@ -318,16 +318,26 @@ class account_invoice(models.Model):
@api.model
def fields_view_get(self, view_id=None, view_type=False, toolbar=False, submenu=False):
context = self._context
def get_view_id(xid, name):
try:
return self.env['ir.model.data'].xmlid_to_res_id('account.' + xid, raise_if_not_found=True)
except ValueError:
try:
return self.env['ir.ui.view'].search([('name', '=', name)], limit=1).id
except Exception:
return False # view not found
if context.get('active_model') == 'res.partner' and context.get('active_ids'):
partner = self.env['res.partner'].browse(context['active_ids'])[0]
if not view_type:
view_id = self.env['ir.ui.view'].search([('name', '=', 'account.invoice.tree')]).id
view_id = get_view_id('invoice_tree', 'account.invoice.tree')
view_type = 'tree'
elif view_type == 'form':
if partner.supplier and not partner.customer:
view_id = self.env['ir.ui.view'].search([('name', '=', 'account.invoice.supplier.form')]).id
view_id = get_view_id('invoice_supplier_form', 'account.invoice.supplier.form')
elif partner.customer and not partner.supplier:
view_id = self.env['ir.ui.view'].search([('name', '=', 'account.invoice.form')]).id
view_id = get_view_id('invoice_form', 'account.invoice.form')
res = super(account_invoice, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)

View File

@ -33,10 +33,6 @@ class partner_balance(report_sxw.rml_parse, common_report_header):
self.account_ids = []
self.localcontext.update( {
'time': time,
'lines': self.lines,
'sum_debit': self._sum_debit,
'sum_credit': self._sum_credit,
'sum_litige': self._sum_litige,
'get_fiscalyear': self._get_fiscalyear,
'get_journal': self._get_journal,
'get_filter': self._get_filter,
@ -70,7 +66,20 @@ class partner_balance(report_sxw.rml_parse, common_report_header):
"WHERE a.type IN %s " \
"AND a.active", (self.ACCOUNT_TYPE,))
self.account_ids = [a for (a,) in self.cr.fetchall()]
return super(partner_balance, self).set_context(objects, data, ids, report_type=report_type)
res = super(partner_balance, self).set_context(objects, data, ids, report_type=report_type)
lines = self.lines()
sum_debit = sum_credit = sum_litige = 0
for line in filter(lambda x: x['type'] == 3, lines):
sum_debit += line['debit'] or 0
sum_credit += line['credit'] or 0
sum_litige += line['enlitige'] or 0
self.localcontext.update({
'lines': lambda: lines,
'sum_debit': lambda: sum_debit,
'sum_credit': lambda: sum_credit,
'sum_litige': lambda: sum_litige,
})
return res
def lines(self):
move_state = ['draft','posted']
@ -236,62 +245,6 @@ class partner_balance(report_sxw.rml_parse, common_report_header):
i = i + 1
return completearray
def _sum_debit(self):
move_state = ['draft','posted']
if self.target_move == 'posted':
move_state = ['posted']
if not self.ids:
return 0.0
self.cr.execute(
"SELECT sum(debit) " \
"FROM account_move_line AS l " \
"JOIN account_move am ON (am.id = l.move_id)" \
"WHERE l.account_id IN %s" \
"AND am.state IN %s" \
"AND " + self.query + "",
(tuple(self.account_ids), tuple(move_state)))
temp_res = float(self.cr.fetchone()[0] or 0.0)
return temp_res
def _sum_credit(self):
move_state = ['draft','posted']
if self.target_move == 'posted':
move_state = ['posted']
if not self.ids:
return 0.0
self.cr.execute(
"SELECT sum(credit) " \
"FROM account_move_line AS l " \
"JOIN account_move am ON (am.id = l.move_id)" \
"WHERE l.account_id IN %s" \
"AND am.state IN %s" \
"AND " + self.query + "",
(tuple(self.account_ids), tuple(move_state)))
temp_res = float(self.cr.fetchone()[0] or 0.0)
return temp_res
def _sum_litige(self):
#gives the total of move lines with blocked boolean set to TRUE for the report selection
move_state = ['draft','posted']
if self.target_move == 'posted':
move_state = ['posted']
if not self.ids:
return 0.0
self.cr.execute(
"SELECT sum(debit-credit) " \
"FROM account_move_line AS l " \
"JOIN account_move am ON (am.id = l.move_id)" \
"WHERE l.account_id IN %s" \
"AND am.state IN %s" \
"AND " + self.query + " " \
"AND l.blocked=TRUE ",
(tuple(self.account_ids), tuple(move_state), ))
temp_res = float(self.cr.fetchone()[0] or 0.0)
return temp_res
def _get_partners(self):
if self.result_selection == 'customer':

View File

@ -39,13 +39,15 @@ class account_analytic_profit(report_sxw.rml_parse):
return user_obj.browse(self.cr, self.uid, ids)
def _journal_ids(self, form, user_id):
if isinstance(user_id, (int, long)):
user_id = [user_id]
line_obj = self.pool['account.analytic.line']
journal_obj = self.pool['account.analytic.journal']
line_ids=line_obj.search(self.cr, self.uid, [
('date', '>=', form['date_from']),
('date', '<=', form['date_to']),
('journal_id', 'in', form['journal_ids'][0][2]),
('user_id', '=', user_id),
('user_id', 'in', user_id),
])
ids=list(set([b.journal_id.id for b in line_obj.browse(self.cr, self.uid, line_ids)]))
return journal_obj.browse(self.cr, self.uid, ids)

View File

@ -315,7 +315,12 @@ class product_pricelist(osv.osv):
price = price * (1.0+(rule.price_discount or 0.0))
if rule.price_round:
price = tools.float_round(price, precision_rounding=rule.price_round)
price += (rule.price_surcharge or 0.0)
if context.get('uom'):
# compute price_surcharge based on reference uom
factor = product_uom_obj.browse(cr, uid, context.get('uom'), context=context).factor
else:
factor = 1.0
price += (rule.price_surcharge or 0.0) / factor
if rule.price_min_margin:
price = max(price, price_limit+rule.price_min_margin)
if rule.price_max_margin:

View File

@ -1118,6 +1118,34 @@ class product_product(osv.osv):
def need_procurement(self, cr, uid, ids, context=None):
return False
def _compute_uos_qty(self, cr, uid, ids, uom, qty, uos, context=None):
'''
Computes product's invoicing quantity in UoS from quantity in UoM.
Takes into account the
:param uom: Source unit
:param qty: Source quantity
:param uos: Target UoS unit.
'''
if not uom or not qty or not uos:
return qty
uom_obj = self.pool['product.uom']
product_id = ids[0] if isinstance(ids, (list, tuple)) else ids
product = self.browse(cr, uid, product_id, context=context)
if isinstance(uos, (int, long)):
uos = uom_obj.browse(cr, uid, uos, context=context)
if isinstance(uom, (int, long)):
uom = uom_obj.browse(cr, uid, uom, context=context)
if product.uos_id: # Product has UoS defined
# We cannot convert directly between units even if the units are of the same category
# as we need to apply the conversion coefficient which is valid only between quantities
# in product's default UoM/UoS
qty_default_uom = uom_obj._compute_qty_obj(cr, uid, uom, qty, product.uom_id) # qty in product's default UoM
qty_default_uos = qty_default_uom * product.uos_coeff
return uom_obj._compute_qty_obj(cr, uid, product.uos_id, qty_default_uos, uos)
else:
return uom_obj._compute_qty_obj(cr, uid, uom, qty, uos)
class product_packaging(osv.osv):
_name = "product.packaging"

View File

@ -1,5 +1,6 @@
from . import test_uom
from . import test_uom, test_pricelist
fast_suite = [
test_uom,
test_pricelist
]

View File

@ -0,0 +1,70 @@
from openerp.tests.common import TransactionCase
class TestPricelist(TransactionCase):
"""Tests for unit of measure conversion"""
def setUp(self):
super(TestPricelist, self).setUp()
cr, uid, context = self.cr, self.uid, {}
self.ir_model_data = self.registry('ir.model.data')
self.product_product = self.registry('product.product')
self.product_pricelist = self.registry('product.pricelist')
self.uom = self.registry('product.uom')
self.usb_adapter_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_product_48')[1]
self.datacard_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_product_46')[1]
self.unit_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_uom_unit')[1]
self.dozen_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_uom_dozen')[1]
self.public_pricelist_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'list0')[1]
self.sale_pricelist_id = self.product_pricelist.create(cr, uid, {
'name': 'Sale pricelist',
'type': 'sale',
'version_id': [(0, 0, {
'name': 'v1.0',
'items_id': [(0, 0, {
'name': 'Discount 10%',
'base': 1, # based on public price
'price_discount': -0.1,
'product_id': self.usb_adapter_id
}), (0, 0, {
'name': 'Discount -0.5',
'base': 1, # based on public price
'price_surcharge': -0.5,
'product_id': self.datacard_id
})]
})]
}, context=context)
def test_10_discount(self):
# Make sure the price using a pricelist is the same than without after
# applying the computation manually
cr, uid, context = self.cr, self.uid, {}
public_context = dict(context, pricelist=self.public_pricelist_id)
pricelist_context = dict(context, pricelist=self.sale_pricelist_id)
usb_adapter_without_pricelist = self.product_product.browse(cr, uid, self.usb_adapter_id, context=public_context)
usb_adapter_with_pricelist = self.product_product.browse(cr, uid, self.usb_adapter_id, context=pricelist_context)
self.assertEqual(usb_adapter_with_pricelist.price, usb_adapter_without_pricelist.price*0.9)
datacard_without_pricelist = self.product_product.browse(cr, uid, self.datacard_id, context=public_context)
datacard_with_pricelist = self.product_product.browse(cr, uid, self.datacard_id, context=pricelist_context)
self.assertEqual(datacard_with_pricelist.price, datacard_without_pricelist.price-0.5)
# Make sure that changing the unit of measure does not break the unit
# price (after converting)
unit_context = dict(context,
pricelist=self.sale_pricelist_id,
uom=self.unit_id)
dozen_context = dict(context,
pricelist=self.sale_pricelist_id,
uom=self.dozen_id)
usb_adapter_unit = self.product_product.browse(cr, uid, self.usb_adapter_id, context=unit_context)
usb_adapter_dozen = self.product_product.browse(cr, uid, self.usb_adapter_id, context=dozen_context)
self.assertAlmostEqual(usb_adapter_unit.price*12, usb_adapter_dozen.price)
datacard_unit = self.product_product.browse(cr, uid, self.datacard_id, context=unit_context)
datacard_dozen = self.product_product.browse(cr, uid, self.datacard_id, context=dozen_context)
self.assertAlmostEqual(datacard_unit.price*12, datacard_dozen.price)

View File

@ -43,6 +43,7 @@ class sale_order_line(osv.osv):
fiscal_position=False, flag=False, context=None):
def get_real_price(res_dict, product_id, qty, uom, pricelist):
"""Retrieve the price before applying the pricelist"""
item_obj = self.pool.get('product.pricelist.item')
price_type_obj = self.pool.get('product.price.type')
product_obj = self.pool.get('product.product')
@ -58,9 +59,8 @@ class sale_order_line(osv.osv):
factor = 1.0
if uom and uom != product.uom_id.id:
product_uom_obj = self.pool.get('product.uom')
uom_data = product_uom_obj.browse(cr, uid, product.uom_id.id)
factor = uom_data.factor
# the unit price is in a different uom
factor = self.pool['product.uom']._compute_qty(cr, uid, uom, 1.0, product.uom_id.id)
return product_read[field_name] * factor
@ -77,7 +77,7 @@ class sale_order_line(osv.osv):
price=result['price_unit']
else:
return res
uom = result.get('product_uom', uom)
product = product_obj.browse(cr, uid, product, context)
pricelist_context = dict(context, uom=uom, date=date_order)
list_price = pricelist_obj.price_rule_get(cr, uid, [pricelist],

View File

@ -101,7 +101,8 @@ class sale_order_line_make_invoice(osv.osv_memory):
flag = False
break
if flag:
workflow.trg_validate(uid, 'sale.order', order.id, 'manual_invoice', cr)
line.order_id.write({'state': 'progress'})
workflow.trg_validate(uid, 'sale.order', order.id, 'all_lines', cr)
if not invoices:
raise osv.except_osv(_('Warning!'), _('Invoice cannot be created for this Sales Order Line due to one of the following reasons:\n1.The state of this sales order line is either "draft" or "cancel"!\n2.The Sales Order Line is Invoiced!'))

View File

@ -36,7 +36,11 @@ class sale_order_line(osv.osv):
frm_cur = self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id
to_cur = self.pool.get('product.pricelist').browse(cr, uid, [pricelist])[0].currency_id.id
if product:
purchase_price = self.pool.get('product.product').browse(cr, uid, product).standard_price
product = self.pool['product.product'].browse(cr, uid, product, context=context)
purchase_price = product.standard_price
to_uom = res.get('product_uom', uom)
if to_uom != product.uom_id.id:
purchase_price = self.pool['product.uom']._compute_price(cr, uid, product.uom_id.id, purchase_price, to_uom)
ctx = context.copy()
ctx['date'] = date_order
price = self.pool.get('res.currency').compute(cr, uid, frm_cur, to_cur, purchase_price, round=False, context=ctx)

View File

@ -820,7 +820,7 @@ openerp.web_calendar = function(instance) {
}
else {
var pop = new instance.web.form.FormOpenPopup(this);
pop.show_element(this.dataset.model, id, this.dataset.get_context(), {
pop.show_element(this.dataset.model, parseInt(id), this.dataset.get_context(), {
title: _.str.sprintf(_t("View: %s"),title),
view_id: +this.open_popup_action,
res_id: id,