[MERGE] forward port of branch 8.0 up to 42ecf5e
This commit is contained in:
@@ -2163,6 +2163,13 @@ class account_tax(osv.osv):
|
|||||||
total += r['amount']
|
total += r['amount']
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def _fix_tax_included_price(self, cr, uid, price, prod_taxes, line_taxes):
|
||||||
|
"""Subtract tax amount from price when corresponding "price included" taxes do not apply"""
|
||||||
|
incl_tax = [tax for tax in prod_taxes if tax.id not in line_taxes and tax.price_include]
|
||||||
|
if incl_tax:
|
||||||
|
return self._unit_compute_inv(cr, uid, incl_tax, price)[0]['price_unit']
|
||||||
|
return price
|
||||||
|
|
||||||
def _unit_compute_inv(self, cr, uid, taxes, price_unit, product=None, partner=None):
|
def _unit_compute_inv(self, cr, uid, taxes, price_unit, product=None, partner=None):
|
||||||
taxes = self._applicable(cr, uid, taxes, price_unit, product, partner)
|
taxes = self._applicable(cr, uid, taxes, price_unit, product, partner)
|
||||||
res = []
|
res = []
|
||||||
|
|||||||
@@ -737,7 +737,7 @@ class account_invoice(models.Model):
|
|||||||
if self.currency_id != company_currency:
|
if self.currency_id != company_currency:
|
||||||
currency = self.currency_id.with_context(date=self.date_invoice or fields.Date.context_today(self))
|
currency = self.currency_id.with_context(date=self.date_invoice or fields.Date.context_today(self))
|
||||||
line['currency_id'] = currency.id
|
line['currency_id'] = currency.id
|
||||||
line['amount_currency'] = line['price']
|
line['amount_currency'] = currency.round(line['price'])
|
||||||
line['price'] = currency.compute(line['price'], company_currency)
|
line['price'] = currency.compute(line['price'], company_currency)
|
||||||
else:
|
else:
|
||||||
line['currency_id'] = False
|
line['currency_id'] = False
|
||||||
|
|||||||
@@ -23,11 +23,11 @@
|
|||||||
<field name="tax_ids" widget="one2many_list">
|
<field name="tax_ids" widget="one2many_list">
|
||||||
<tree string="Tax Mapping" editable="bottom">
|
<tree string="Tax Mapping" editable="bottom">
|
||||||
<field name="tax_src_id" domain="[('parent_id','=',False)]"/>
|
<field name="tax_src_id" domain="[('parent_id','=',False)]"/>
|
||||||
<field name="tax_dest_id" domain="[('parent_id','=',False)]"/>
|
<field name="tax_dest_id" domain="[('parent_id','=',False), ('price_include', '=', False)]"/>
|
||||||
</tree>
|
</tree>
|
||||||
<form string="Tax Mapping">
|
<form string="Tax Mapping">
|
||||||
<field name="tax_src_id" domain="[('parent_id','=',False)]"/>
|
<field name="tax_src_id" domain="[('parent_id','=',False)]"/>
|
||||||
<field name="tax_dest_id" domain="[('parent_id','=',False)]"/>
|
<field name="tax_dest_id" domain="[('parent_id','=',False), ('price_include', '=', False)]"/>
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
<separator string="Accounts Mapping"/>
|
<separator string="Accounts Mapping"/>
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ class pos_session(osv.osv):
|
|||||||
bank_statement_ids.append(statement_id)
|
bank_statement_ids.append(statement_id)
|
||||||
|
|
||||||
values.update({
|
values.update({
|
||||||
'name': self.pool['ir.sequence'].next_by_code(cr, uid, 'pos.session'),
|
'name': self.pool['ir.sequence'].next_by_code(cr, uid, 'pos.session', context=context),
|
||||||
'statement_ids' : [(6, 0, bank_statement_ids)],
|
'statement_ids' : [(6, 0, bank_statement_ids)],
|
||||||
'config_id': config_id
|
'config_id': config_id
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class pos_details(report_sxw.rml_parse):
|
|||||||
user_ids = form['user_ids'] or self._get_all_users()
|
user_ids = form['user_ids'] or self._get_all_users()
|
||||||
company_id = user_obj.browse(self.cr, self.uid, self.uid).company_id.id
|
company_id = user_obj.browse(self.cr, self.uid, self.uid).company_id.id
|
||||||
pos_ids = pos_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('user_id','in',user_ids),('state','in',['done','paid','invoiced']),('company_id','=',company_id)])
|
pos_ids = pos_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('user_id','in',user_ids),('state','in',['done','paid','invoiced']),('company_id','=',company_id)])
|
||||||
for pos in pos_obj.browse(self.cr, self.uid, pos_ids):
|
for pos in pos_obj.browse(self.cr, self.uid, pos_ids, context=self.localcontext):
|
||||||
for pol in pos.lines:
|
for pol in pos.lines:
|
||||||
result = {
|
result = {
|
||||||
'code': pol.product_id.default_code,
|
'code': pol.product_id.default_code,
|
||||||
|
|||||||
@@ -1217,6 +1217,7 @@ class purchase_order_line(osv.osv):
|
|||||||
taxes = account_tax.browse(cr, uid, map(lambda x: x.id, product.supplier_taxes_id))
|
taxes = account_tax.browse(cr, uid, map(lambda x: x.id, product.supplier_taxes_id))
|
||||||
fpos = fiscal_position_id and account_fiscal_position.browse(cr, uid, fiscal_position_id, context=context) or False
|
fpos = fiscal_position_id and account_fiscal_position.browse(cr, uid, fiscal_position_id, context=context) or False
|
||||||
taxes_ids = account_fiscal_position.map_tax(cr, uid, fpos, taxes)
|
taxes_ids = account_fiscal_position.map_tax(cr, uid, fpos, taxes)
|
||||||
|
price = self.pool['account.tax']._fix_tax_included_price(cr, uid, price, product.supplier_taxes_id, taxes_ids)
|
||||||
res['value'].update({'price_unit': price, 'taxes_id': taxes_ids})
|
res['value'].update({'price_unit': price, 'taxes_id': taxes_ids})
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -20,3 +20,4 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from . import test_purchase_to_invoice
|
from . import test_purchase_to_invoice
|
||||||
|
from . import test_onchange_product_id
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
from openerp.tests.common import TransactionCase
|
||||||
|
|
||||||
|
class TestOnchangeProductId(TransactionCase):
|
||||||
|
"""Test that when an included tax is mapped by a fiscal position, the included tax must be
|
||||||
|
subtracted to the price of the product.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestOnchangeProductId, self).setUp()
|
||||||
|
self.fiscal_position_model = self.registry('account.fiscal.position')
|
||||||
|
self.fiscal_position_tax_model = self.registry('account.fiscal.position.tax')
|
||||||
|
self.tax_model = self.registry('account.tax')
|
||||||
|
self.pricelist_model = self.registry('product.pricelist')
|
||||||
|
self.res_partner_model = self.registry('res.partner')
|
||||||
|
self.product_tmpl_model = self.registry('product.template')
|
||||||
|
self.product_model = self.registry('product.product')
|
||||||
|
self.product_uom_model = self.registry('product.uom')
|
||||||
|
self.so_line_model = self.registry('purchase.order.line')
|
||||||
|
|
||||||
|
def test_onchange_product_id(self):
|
||||||
|
cr, uid = self.cr, self.uid
|
||||||
|
uom_id = self.product_uom_model.search(cr, uid, [('name', '=', 'Unit(s)')])[0]
|
||||||
|
pricelist = self.pricelist_model.search(cr, uid, [('name', '=', 'Public Pricelist')])[0]
|
||||||
|
partner_id = self.res_partner_model.create(cr, uid, dict(name="George"))
|
||||||
|
tax_include_id = self.tax_model.create(cr, uid, dict(name="Include tax",
|
||||||
|
type='percent',
|
||||||
|
amount='0.21',
|
||||||
|
price_include=True))
|
||||||
|
tax_exclude_id = self.tax_model.create(cr, uid, dict(name="Exclude tax",
|
||||||
|
type='percent',
|
||||||
|
amount='0.00'))
|
||||||
|
product_tmpl_id = self.product_tmpl_model.create(cr, uid, dict(name="Voiture",
|
||||||
|
list_price='121',
|
||||||
|
supplier_taxes_id=[(6, 0, [tax_include_id])]))
|
||||||
|
product_id = self.product_model.create(cr, uid, dict(product_tmpl_id=product_tmpl_id))
|
||||||
|
fp_id = self.fiscal_position_model.create(cr, uid, dict(name="fiscal position",
|
||||||
|
sequence=1))
|
||||||
|
fp_tax_id = self.fiscal_position_tax_model.create(cr, uid, dict(position_id=fp_id,
|
||||||
|
tax_src_id=tax_include_id,
|
||||||
|
tax_dest_id=tax_exclude_id))
|
||||||
|
res = self.so_line_model.onchange_product_id(cr, uid, [], pricelist, product_id, 1.0, uom_id, partner_id,
|
||||||
|
fiscal_position_id=fp_id)
|
||||||
|
|
||||||
|
self.assertEquals(100, res['value']['price_unit'], "The included tax must be subtracted to the price")
|
||||||
+5
-3
@@ -1052,7 +1052,7 @@ class sale_order_line(osv.osv):
|
|||||||
date_order=order['date_order'],
|
date_order=order['date_order'],
|
||||||
fiscal_position=order['fiscal_position'][0] if order['fiscal_position'] else False,
|
fiscal_position=order['fiscal_position'][0] if order['fiscal_position'] else False,
|
||||||
flag=False, # Force name update
|
flag=False, # Force name update
|
||||||
context=context
|
context=dict(context or {}, company_id=values.get('company_id'))
|
||||||
)['value']
|
)['value']
|
||||||
if defaults.get('tax_id'):
|
if defaults.get('tax_id'):
|
||||||
defaults['tax_id'] = [[6, 0, defaults['tax_id']]]
|
defaults['tax_id'] = [[6, 0, defaults['tax_id']]]
|
||||||
@@ -1108,8 +1108,8 @@ class sale_order_line(osv.osv):
|
|||||||
# The superuser is used by website_sale in order to create a sale order. We need to make
|
# The superuser is used by website_sale in order to create a sale order. We need to make
|
||||||
# sure we only select the taxes related to the company of the partner. This should only
|
# sure we only select the taxes related to the company of the partner. This should only
|
||||||
# apply if the partner is linked to a company.
|
# apply if the partner is linked to a company.
|
||||||
if uid == SUPERUSER_ID and partner.company_id:
|
if uid == SUPERUSER_ID and context.get('company_id'):
|
||||||
taxes = product_obj.taxes_id.filtered(lambda r: r.company_id == partner.company_id)
|
taxes = product_obj.taxes_id.filtered(lambda r: r.company_id.id == context['company_id'])
|
||||||
else:
|
else:
|
||||||
taxes = product_obj.taxes_id
|
taxes = product_obj.taxes_id
|
||||||
result['tax_id'] = self.pool['account.fiscal.position'].map_tax(cr, uid, fpos, taxes)
|
result['tax_id'] = self.pool['account.fiscal.position'].map_tax(cr, uid, fpos, taxes)
|
||||||
@@ -1162,6 +1162,8 @@ class sale_order_line(osv.osv):
|
|||||||
product, qty or 1.0, partner_id, ctx)[pricelist]
|
product, qty or 1.0, partner_id, ctx)[pricelist]
|
||||||
else:
|
else:
|
||||||
price = Product.price_get(cr, uid, [product], ptype='list_price', context=ctx_product)[product] or False
|
price = Product.price_get(cr, uid, [product], ptype='list_price', context=ctx_product)[product] or False
|
||||||
|
if update_tax:
|
||||||
|
price = self.pool['account.tax']._fix_tax_included_price(cr, uid, price, product_obj.taxes_id, result['tax_id'])
|
||||||
if context.get('uom_qty_change', False):
|
if context.get('uom_qty_change', False):
|
||||||
result, domain = {}, {}
|
result, domain = {}, {}
|
||||||
result.update({'price_unit': price})
|
result.update({'price_unit': price})
|
||||||
|
|||||||
@@ -141,17 +141,17 @@
|
|||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="product_id"
|
<field name="product_id"
|
||||||
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
|
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'company_id': parent.company_id}"
|
||||||
groups="base.group_user"
|
groups="base.group_user"
|
||||||
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, False, product_uos_qty, False, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
|
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, False, product_uos_qty, False, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
|
||||||
<label for="product_uom_qty"/>
|
<label for="product_uom_qty"/>
|
||||||
<div>
|
<div>
|
||||||
<field
|
<field
|
||||||
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'uom_qty_change':True}"
|
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'uom_qty_change':True, 'company_id': parent.company-id}"
|
||||||
name="product_uom_qty" class="oe_inline"
|
name="product_uom_qty" class="oe_inline"
|
||||||
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, False, parent.date_order, False, parent.fiscal_position, True, context)"/>
|
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, False, parent.date_order, False, parent.fiscal_position, True, context)"/>
|
||||||
<field name="product_uom" groups="product.group_uom" class="oe_inline oe_no_button"
|
<field name="product_uom" groups="product.group_uom" class="oe_inline oe_no_button"
|
||||||
|
context="{'company_id': parent.company_id}"
|
||||||
on_change="product_uom_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, False, parent.date_order, context)"/>
|
on_change="product_uom_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, False, parent.date_order, context)"/>
|
||||||
</div>
|
</div>
|
||||||
<label for="product_uos_qty" groups="product.group_uos"/>
|
<label for="product_uos_qty" groups="product.group_uos"/>
|
||||||
@@ -184,14 +184,15 @@
|
|||||||
<field name="state" invisible="1"/>
|
<field name="state" invisible="1"/>
|
||||||
<field name="th_weight" invisible="1"/>
|
<field name="th_weight" invisible="1"/>
|
||||||
<field name="product_id"
|
<field name="product_id"
|
||||||
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
|
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'company_id': parent.company_id}"
|
||||||
groups="base.group_user"
|
groups="base.group_user"
|
||||||
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, False, product_uos_qty, False, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
|
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, False, product_uos_qty, False, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="product_uom_qty"
|
<field name="product_uom_qty"
|
||||||
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
|
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'company_id': parent.company_id}"
|
||||||
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, product_uos_qty, product_uos, name, parent.partner_id, False, False, parent.date_order, False, parent.fiscal_position, True, context)"/>
|
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, product_uos_qty, product_uos, name, parent.partner_id, False, False, parent.date_order, False, parent.fiscal_position, True, context)"/>
|
||||||
<field name="product_uom"
|
<field name="product_uom"
|
||||||
|
context="{'company_id': parent.company_id}"
|
||||||
on_change="product_uom_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, product_uos_qty, product_uos, name, parent.partner_id, False, False, parent.date_order, context)"
|
on_change="product_uom_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, product_uos_qty, product_uos, name, parent.partner_id, False, False, parent.date_order, context)"
|
||||||
groups="product.group_uom" options='{"no_open": True}'/>
|
groups="product.group_uom" options='{"no_open": True}'/>
|
||||||
<field name="product_uos_qty" groups="product.group_uos" invisible="1"/>
|
<field name="product_uos_qty" groups="product.group_uos" invisible="1"/>
|
||||||
|
|||||||
@@ -20,3 +20,4 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from . import test_sale_to_invoice
|
from . import test_sale_to_invoice
|
||||||
|
from . import test_product_id_change
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
from openerp.tests.common import TransactionCase
|
||||||
|
|
||||||
|
class TestProductIdChange(TransactionCase):
|
||||||
|
"""Test that when an included tax is mapped by a fiscal position, the included tax must be
|
||||||
|
subtracted to the price of the product.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestProductIdChange, self).setUp()
|
||||||
|
self.fiscal_position_model = self.registry('account.fiscal.position')
|
||||||
|
self.fiscal_position_tax_model = self.registry('account.fiscal.position.tax')
|
||||||
|
self.tax_model = self.registry('account.tax')
|
||||||
|
self.pricelist_model = self.registry('product.pricelist')
|
||||||
|
self.res_partner_model = self.registry('res.partner')
|
||||||
|
self.product_tmpl_model = self.registry('product.template')
|
||||||
|
self.product_model = self.registry('product.product')
|
||||||
|
self.so_line_model = self.registry('sale.order.line')
|
||||||
|
|
||||||
|
def test_product_id_change(self):
|
||||||
|
cr, uid = self.cr, self.uid
|
||||||
|
pricelist = self.pricelist_model.search(cr, uid, [('name', '=', 'Public Pricelist')])[0]
|
||||||
|
partner_id = self.res_partner_model.create(cr, uid, dict(name="George"))
|
||||||
|
tax_include_id = self.tax_model.create(cr, uid, dict(name="Include tax",
|
||||||
|
type='percent',
|
||||||
|
amount='0.21',
|
||||||
|
price_include=True))
|
||||||
|
tax_exclude_id = self.tax_model.create(cr, uid, dict(name="Exclude tax",
|
||||||
|
type='percent',
|
||||||
|
amount='0.00'))
|
||||||
|
product_tmpl_id = self.product_tmpl_model.create(cr, uid, dict(name="Voiture",
|
||||||
|
list_price='121',
|
||||||
|
taxes_id=[(6, 0, [tax_include_id])]))
|
||||||
|
product_id = self.product_model.create(cr, uid, dict(product_tmpl_id=product_tmpl_id))
|
||||||
|
fp_id = self.fiscal_position_model.create(cr, uid, dict(name="fiscal position",
|
||||||
|
sequence=1))
|
||||||
|
fp_tax_id = self.fiscal_position_tax_model.create(cr, uid, dict(position_id=fp_id,
|
||||||
|
tax_src_id=tax_include_id,
|
||||||
|
tax_dest_id=tax_exclude_id))
|
||||||
|
res = self.so_line_model.product_id_change(cr, uid, [], pricelist, product_id, partner_id=partner_id,
|
||||||
|
fiscal_position=fp_id)
|
||||||
|
self.assertEquals(100, res['value']['price_unit'], "The included tax must be subtracted to the price")
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
parent.partner_id, False, True, parent.date_order, product_packaging, parent.fiscal_position,
|
parent.partner_id, False, True, parent.date_order, product_packaging, parent.fiscal_position,
|
||||||
False, parent.warehouse_id, context)
|
False, parent.warehouse_id, context)
|
||||||
</attribute>
|
</attribute>
|
||||||
<attribute name="context">{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':False}</attribute>
|
<attribute name="context">{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':False, 'company_id': parent.company_id}</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="attributes">
|
<xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="attributes">
|
||||||
<attribute name="on_change">product_id_change_with_wh(
|
<attribute name="on_change">product_id_change_with_wh(
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/form[@string='Sales Order Lines']/group/group/field[@name='tax_id']" position="before">
|
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/form[@string='Sales Order Lines']/group/group/field[@name='tax_id']" position="before">
|
||||||
<field name="product_tmpl_id" invisible="1"/>
|
<field name="product_tmpl_id" invisible="1"/>
|
||||||
<field name="product_packaging" context="{'default_product_tmpl_id': product_tmpl_id, 'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}" on_change="product_packaging_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, parent.partner_id, product_packaging, True, context)" domain="[('product_tmpl_id','=',product_tmpl_id)]" groups="product.group_stock_packaging" />
|
<field name="product_packaging" context="{'default_product_tmpl_id': product_tmpl_id, 'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'company_id': parent.company_id}" on_change="product_packaging_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, parent.partner_id, product_packaging, True, context)" domain="[('product_tmpl_id','=',product_tmpl_id)]" groups="product.group_stock_packaging" />
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/tree[@string='Sales Order Lines']/field[@name='sequence']" position="after">
|
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/tree[@string='Sales Order Lines']/field[@name='sequence']" position="after">
|
||||||
<field name="delay" invisible="1"/>
|
<field name="delay" invisible="1"/>
|
||||||
|
|||||||
@@ -848,7 +848,7 @@ class survey_user_input(osv.Model):
|
|||||||
'survey_id': fields.many2one('survey.survey', 'Survey', required=True,
|
'survey_id': fields.many2one('survey.survey', 'Survey', required=True,
|
||||||
readonly=1, ondelete='restrict'),
|
readonly=1, ondelete='restrict'),
|
||||||
'date_create': fields.datetime('Creation Date', required=True,
|
'date_create': fields.datetime('Creation Date', required=True,
|
||||||
readonly=1),
|
readonly=1, copy=False),
|
||||||
'deadline': fields.datetime("Deadline",
|
'deadline': fields.datetime("Deadline",
|
||||||
help="Date by which the person can open the survey and submit answers",
|
help="Date by which the person can open the survey and submit answers",
|
||||||
oldname="date_deadline"),
|
oldname="date_deadline"),
|
||||||
@@ -861,7 +861,7 @@ class survey_user_input(osv.Model):
|
|||||||
'Status',
|
'Status',
|
||||||
readonly=True),
|
readonly=True),
|
||||||
'test_entry': fields.boolean('Test entry', readonly=1),
|
'test_entry': fields.boolean('Test entry', readonly=1),
|
||||||
'token': fields.char("Identification token", readonly=1, required=1),
|
'token': fields.char("Identification token", readonly=1, required=1, copy=False),
|
||||||
|
|
||||||
# Optional Identification data
|
# Optional Identification data
|
||||||
'partner_id': fields.many2one('res.partner', 'Partner', readonly=1),
|
'partner_id': fields.many2one('res.partner', 'Partner', readonly=1),
|
||||||
@@ -872,7 +872,7 @@ class survey_user_input(osv.Model):
|
|||||||
'Last displayed page'),
|
'Last displayed page'),
|
||||||
# The answers !
|
# The answers !
|
||||||
'user_input_line_ids': fields.one2many('survey.user_input_line',
|
'user_input_line_ids': fields.one2many('survey.user_input_line',
|
||||||
'user_input_id', 'Answers'),
|
'user_input_id', 'Answers', copy=True),
|
||||||
|
|
||||||
# URLs used to display the answers
|
# URLs used to display the answers
|
||||||
'result_url': fields.related('survey_id', 'result_url', type='char',
|
'result_url': fields.related('survey_id', 'result_url', type='char',
|
||||||
@@ -895,9 +895,6 @@ class survey_user_input(osv.Model):
|
|||||||
('deadline_in_the_past', 'CHECK (deadline >= date_create)', 'The deadline cannot be in the past')
|
('deadline_in_the_past', 'CHECK (deadline >= date_create)', 'The deadline cannot be in the past')
|
||||||
]
|
]
|
||||||
|
|
||||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
|
||||||
raise UserError(_('You cannot duplicate this element!'))
|
|
||||||
|
|
||||||
def do_clean_emptys(self, cr, uid, automatic=False, context=None):
|
def do_clean_emptys(self, cr, uid, automatic=False, context=None):
|
||||||
''' Remove empty user inputs that have been created manually
|
''' Remove empty user inputs that have been created manually
|
||||||
(used as a cronjob declared in data/survey_cron.xml) '''
|
(used as a cronjob declared in data/survey_cron.xml) '''
|
||||||
@@ -1026,9 +1023,6 @@ class survey_user_input_line(osv.Model):
|
|||||||
vals.update({'quizz_mark': self.__get_mark(cr, uid, value_suggested)})
|
vals.update({'quizz_mark': self.__get_mark(cr, uid, value_suggested)})
|
||||||
return super(survey_user_input_line, self).write(cr, uid, ids, vals, context=context)
|
return super(survey_user_input_line, self).write(cr, uid, ids, vals, context=context)
|
||||||
|
|
||||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
|
||||||
raise UserError(_('You cannot duplicate this element!'))
|
|
||||||
|
|
||||||
def save_lines(self, cr, uid, user_input_id, question, post, answer_tag,
|
def save_lines(self, cr, uid, user_input_id, question, post, answer_tag,
|
||||||
context=None):
|
context=None):
|
||||||
''' Save answers to questions, depending on question type
|
''' Save answers to questions, depending on question type
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ class WebsiteMail(http.Controller):
|
|||||||
partner_ids = _object._find_partner_from_emails(
|
partner_ids = _object._find_partner_from_emails(
|
||||||
cr, SUPERUSER_ID, _id, [email], context=context, check_followers=True)
|
cr, SUPERUSER_ID, _id, [email], context=context, check_followers=True)
|
||||||
if not partner_ids or not partner_ids[0]:
|
if not partner_ids or not partner_ids[0]:
|
||||||
partner_ids = [partner_obj.create(cr, SUPERUSER_ID, {'name': email, 'email': email}, context=context)]
|
name = email.split('@')[0]
|
||||||
|
partner_ids = [partner_obj.create(cr, SUPERUSER_ID, {'name': name, 'email': email}, context=context)]
|
||||||
|
|
||||||
# add or remove follower
|
# add or remove follower
|
||||||
if _message_is_follower:
|
if _message_is_follower:
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ class sale_quote(http.Controller):
|
|||||||
res = request.registry.get('sale.order.line').product_id_change(request.cr, SUPERUSER_ID, order_id,
|
res = request.registry.get('sale.order.line').product_id_change(request.cr, SUPERUSER_ID, order_id,
|
||||||
False, option.product_id.id, option.quantity, option.uom_id.id, option.quantity, option.uom_id.id,
|
False, option.product_id.id, option.quantity, option.uom_id.id, option.quantity, option.uom_id.id,
|
||||||
option.name, order.partner_id.id, False, True, time.strftime('%Y-%m-%d'),
|
option.name, order.partner_id.id, False, True, time.strftime('%Y-%m-%d'),
|
||||||
False, order.fiscal_position.id, True, request.context)
|
False, order.fiscal_position.id, True, dict(request.context or {}, company_id=order.company_id.id))
|
||||||
vals = res.get('value', {})
|
vals = res.get('value', {})
|
||||||
if 'tax_id' in vals:
|
if 'tax_id' in vals:
|
||||||
vals['tax_id'] = [(6, 0, vals['tax_id'])]
|
vals['tax_id'] = [(6, 0, vals['tax_id'])]
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='project_id']" position="before">
|
<xpath expr="//field[@name='project_id']" position="before">
|
||||||
<field name="template_id" on_change="onchange_template_id(template_id, partner_id, fiscal_position, pricelist_id)"/>
|
<field name="template_id" context="{'company_id': company_id}" on_change="onchange_template_id(template_id, partner_id, fiscal_position, pricelist_id, context)"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='client_order_ref']" position="after">
|
<xpath expr="//field[@name='client_order_ref']" position="after">
|
||||||
<field name="require_payment"/>
|
<field name="require_payment"/>
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ class website_sale(http.Controller):
|
|||||||
|
|
||||||
if category:
|
if category:
|
||||||
category = category_obj.browse(cr, uid, int(category), context=context)
|
category = category_obj.browse(cr, uid, int(category), context=context)
|
||||||
|
category = category if category.exists() else False
|
||||||
|
|
||||||
attrib_list = request.httprequest.args.getlist('attrib')
|
attrib_list = request.httprequest.args.getlist('attrib')
|
||||||
attrib_values = [map(int,v.split("-")) for v in attrib_list if v]
|
attrib_values = [map(int,v.split("-")) for v in attrib_list if v]
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class sale_order(osv.Model):
|
|||||||
partner_id=so.partner_id.id,
|
partner_id=so.partner_id.id,
|
||||||
fiscal_position=so.fiscal_position.id,
|
fiscal_position=so.fiscal_position.id,
|
||||||
qty=qty,
|
qty=qty,
|
||||||
context=context
|
context=dict(context or {}, company_id=so.company_id.id)
|
||||||
)['value']
|
)['value']
|
||||||
|
|
||||||
if line_id:
|
if line_id:
|
||||||
|
|||||||
+18
-2
@@ -626,9 +626,9 @@ instead of a single view its ``arch`` field is composed of any number of
|
|||||||
<field name="model">idea.category</field>
|
<field name="model">idea.category</field>
|
||||||
<field name="inherit_id" ref="id_category_list"/>
|
<field name="inherit_id" ref="id_category_list"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<!-- find field description inside tree, and add the field
|
<!-- find field description and add the field
|
||||||
idea_ids after it -->
|
idea_ids after it -->
|
||||||
<xpath expr="/tree/field[@name='description']" position="after">
|
<xpath expr="//field[@name='description']" position="after">
|
||||||
<field name="idea_ids" string="Number of ideas"/>
|
<field name="idea_ids" string="Number of ideas"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
@@ -652,6 +652,22 @@ instead of a single view its ``arch`` field is composed of any number of
|
|||||||
alters the attributes of the matched element using special
|
alters the attributes of the matched element using special
|
||||||
``attribute`` elements in the ``xpath``'s body
|
``attribute`` elements in the ``xpath``'s body
|
||||||
|
|
||||||
|
.. tip::
|
||||||
|
|
||||||
|
When matching a single element, the ``position`` attribute can be set directly
|
||||||
|
on the element to be found. Both inheritances below will give the same result.
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<xpath expr="//field[@name='description']" position="after">
|
||||||
|
<field name="idea_ids" />
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<field name="description" position="after">
|
||||||
|
<field name="idea_ids" />
|
||||||
|
</field>
|
||||||
|
|
||||||
|
|
||||||
.. exercise:: Alter existing content
|
.. exercise:: Alter existing content
|
||||||
|
|
||||||
* Using model inheritance, modify the existing *Partner* model to add an
|
* Using model inheritance, modify the existing *Partner* model to add an
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
import logging
|
import logging
|
||||||
|
import pytz
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
@@ -212,22 +213,14 @@ class ir_sequence(models.Model):
|
|||||||
|
|
||||||
def _interpolation_dict():
|
def _interpolation_dict():
|
||||||
if self.env.context.get('ir_sequence_date'):
|
if self.env.context.get('ir_sequence_date'):
|
||||||
t = time.strptime(self.env.context.get('ir_sequence_date'), '%Y-%m-%d')
|
t = datetime.strptime(self.env.context.get('ir_sequence_date'), '%Y-%m-%d')
|
||||||
else:
|
else:
|
||||||
t = time.localtime() # Actually, the server is always in UTC.
|
t = datetime.now(pytz.timezone(self.env.context.get('tz') or 'UTC'))
|
||||||
return {
|
sequences = {
|
||||||
'year': time.strftime('%Y', t),
|
'year': '%Y', 'month': '%m', 'day': '%d', 'y': '%y', 'doy': '%j', 'woy': '%W',
|
||||||
'month': time.strftime('%m', t),
|
'weekday': '%w', 'h24': '%H', 'h12': '%I', 'min': '%M', 'sec': '%S'
|
||||||
'day': time.strftime('%d', t),
|
|
||||||
'y': time.strftime('%y', t),
|
|
||||||
'doy': time.strftime('%j', t),
|
|
||||||
'woy': time.strftime('%W', t),
|
|
||||||
'weekday': time.strftime('%w', t),
|
|
||||||
'h24': time.strftime('%H', t),
|
|
||||||
'h12': time.strftime('%I', t),
|
|
||||||
'min': time.strftime('%M', t),
|
|
||||||
'sec': time.strftime('%S', t),
|
|
||||||
}
|
}
|
||||||
|
return {key: t.strftime(sequence) for key, sequence in sequences.iteritems()}
|
||||||
|
|
||||||
d = _interpolation_dict()
|
d = _interpolation_dict()
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user