[IMP] sale: allow to show total of order line tax inc or based on unit price.
Allow to set in configuration mode b2b or b2c. Change the column of order line in sale view and in reports depending of sale. Fix price_reduce field (wrong if tax was included in price) and merge with code discounted_price from website_sale. Change header from reports "Price Tax Excluded' by 'Price' in report. That is wrong, sometime the amount can haxe tax included in the price.
This commit is contained in:
@@ -55,7 +55,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"></td>
|
||||
<td><strong>Sub-Total :</strong></td>
|
||||
<td><strong>Subtotal :</strong></td>
|
||||
<td class="text-right"><span t-esc="format(Totals[o.id][currency]['due'], 'monetary', currency)"/></td>
|
||||
<td class="text-right"><span t-esc="format(Totals[o.id][currency]['paid'], 'monetary', currency)"/></td>
|
||||
<td class="text-right"><span t-esc="format(Totals[o.id][currency]['mat'], 'monetary', currency)"/></td>
|
||||
|
||||
@@ -66,9 +66,15 @@ class sale_configuration(osv.TransientModel):
|
||||
(1, 'Display 3 fields on sales orders: customer, invoice address, delivery address')
|
||||
], "Addresses", implied_group='sale.group_delivery_invoice_address'),
|
||||
'sale_pricelist_setting': fields.selection([('fixed', 'A single sale price per product'), ('percentage', 'Different prices per customer segment'), ('formula', 'Advanced pricing based on formula')], required=True,
|
||||
help='Fix Price: all price manage from products sale price.\n'
|
||||
'Different prices per Customer: you can assign price on buying of minimum quantity in products sale tab.\n'
|
||||
'Advanced pricing based on formula: You can have all the rights on pricelist'),
|
||||
help='Fix Price: all price manage from products sale price.\n'
|
||||
'Different prices per Customer: you can assign price on buying of minimum quantity in products sale tab.\n'
|
||||
'Advanced pricing based on formula: You can have all the rights on pricelist'),
|
||||
'group_show_price_subtotal': fields.boolean("Show subtotal", implied_group='sale.group_show_price_subtotal', group='base.group_portal,base.group_user,base.group_public'),
|
||||
'group_show_price_total': fields.boolean("Show total", implied_group='sale.group_show_price_total', group='base.group_portal,base.group_user,base.group_public'),
|
||||
'sale_show_tax': fields.selection([
|
||||
('total', 'Show line subtotals with taxes included (B2C)'),
|
||||
('subtotal', 'Show line subtotals without taxes (except if unit price includes taxes) (B2B)')], "Tax Display",
|
||||
required=True),
|
||||
'default_invoice_policy': fields.selection([
|
||||
('order', 'Invoice ordered quantities'),
|
||||
('delivery', 'Invoice delivered quantities')
|
||||
@@ -87,6 +93,7 @@ class sale_configuration(osv.TransientModel):
|
||||
|
||||
_defaults = {
|
||||
'sale_pricelist_setting': 'fixed',
|
||||
'sale_show_tax': 'subtotal',
|
||||
'default_invoice_policy': 'order',
|
||||
}
|
||||
|
||||
@@ -111,3 +118,13 @@ class sale_configuration(osv.TransientModel):
|
||||
if sale_pricelist_setting == 'formula':
|
||||
return {'value': {'group_pricelist_item': True, 'group_sale_pricelist': True, 'group_product_pricelist': False}}
|
||||
return {'value': {'group_pricelist_item': False, 'group_sale_pricelist': False, 'group_product_pricelist': False}}
|
||||
|
||||
def set_sale_tax_defaults(self, cr, uid, ids, context=None):
|
||||
sale_tax = self.browse(cr, uid, ids, context=context).sale_show_tax
|
||||
res = self.pool.get('ir.values').set_default(cr, SUPERUSER_ID, 'sale.config.settings', 'sale_show_tax', sale_tax)
|
||||
return res
|
||||
|
||||
def onchange_sale_tax(self, cr, uid, ids, sale_show_tax, context=None):
|
||||
res = {'value': dict(group_show_price_subtotal=False, group_show_price_total=False)}
|
||||
res['value']['group_show_price_%s' % sale_show_tax] = True
|
||||
return res
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
<field name="group_sale_layout" widget="radio"/>
|
||||
<field name="auto_done_setting" widget="radio"/>
|
||||
<field name="group_warning_sale" widget="radio"/>
|
||||
<label for="sale_show_tax"/>
|
||||
<div>
|
||||
<field name="sale_show_tax" class="oe_inline" widget="radio" on_change="onchange_sale_tax(sale_show_tax)"/>
|
||||
<field name="group_show_price_subtotal" class="oe_inline" invisible="1"/>
|
||||
<field name="group_show_price_total" class="oe_inline" invisible="1"/>
|
||||
</div>
|
||||
<label for="sale_pricelist_setting" string="Sale Price"/>
|
||||
<div>
|
||||
<field name="sale_pricelist_setting" class="oe_inline" widget="radio" on_change="onchange_sale_price(sale_pricelist_setting)"/>
|
||||
|
||||
+14
-2
@@ -618,10 +618,20 @@ class SaleOrderLine(models.Model):
|
||||
qty_invoiced -= self.env['product.uom']._compute_qty_obj(invoice_line.uom_id, invoice_line.quantity, line.product_uom)
|
||||
line.qty_invoiced = qty_invoiced
|
||||
|
||||
@api.depends('price_subtotal', 'product_uom_qty')
|
||||
@api.depends('price_unit', 'discount')
|
||||
def _get_price_reduce(self):
|
||||
for line in self:
|
||||
line.price_reduce = line.price_subtotal / line.product_uom_qty if line.product_uom_qty else 0.0
|
||||
line.price_reduce = line.price_unit * (1.0 - line.discount / 100.0)
|
||||
|
||||
@api.depends('price_total', 'product_uom_qty')
|
||||
def _get_price_reduce_tax(self):
|
||||
for line in self:
|
||||
line.price_reduce_taxinc = line.price_total / line.product_uom_qty if line.product_uom_qty else 0.0
|
||||
|
||||
@api.depends('price_subtotal', 'product_uom_qty')
|
||||
def _get_price_reduce_notax(self):
|
||||
for line in self:
|
||||
line.price_reduce_taxexcl = line.price_subtotal / line.product_uom_qty if line.product_uom_qty else 0.0
|
||||
|
||||
@api.multi
|
||||
def _compute_tax_id(self):
|
||||
@@ -723,6 +733,8 @@ class SaleOrderLine(models.Model):
|
||||
|
||||
price_reduce = fields.Monetary(compute='_get_price_reduce', string='Price Reduce', readonly=True, store=True)
|
||||
tax_id = fields.Many2many('account.tax', string='Taxes', domain=['|', ('active', '=', False), ('active', '=', True)])
|
||||
price_reduce_taxinc = fields.Monetary(compute='_get_price_reduce_tax', string='Price Reduce Tax inc', readonly=True, store=True)
|
||||
price_reduce_taxexcl = fields.Monetary(compute='_get_price_reduce_notax', string='Price Reduce Tax excl', readonly=True, store=True)
|
||||
|
||||
discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'), default=0.0)
|
||||
|
||||
|
||||
@@ -282,7 +282,8 @@
|
||||
<field name="tax_id" widget="many2many_tags" domain="[('type_tax_use','=','sale'),('company_id','=',parent.company_id)]"
|
||||
attrs="{'readonly': [('qty_invoiced', '>', 0)]}"/>
|
||||
<field name="discount" groups="sale.group_discount_per_so_line"/>
|
||||
<field name="price_subtotal" widget="monetary"/>
|
||||
<field name="price_subtotal" widget="monetary" groups="sale.group_show_price_subtotal"/>
|
||||
<field name="price_total" widget="monetary" groups="sale.group_show_price_total"/>
|
||||
<field name="qty_delivered_updateable" invisible="1"/>
|
||||
<field name="procurement_ids" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
|
||||
@@ -13,6 +13,20 @@
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
</record>
|
||||
|
||||
<record id="group_show_price_subtotal" model="res.groups">
|
||||
<field name="name">Show subtotal</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
<field name="comment">
|
||||
Only included taxes in the subtotal that are already included in the unit price.
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="group_show_price_total" model="res.groups">
|
||||
<field name="name">Show total (tax inc)</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
<field name="comment">Display the total of the line with all taxes included</field>
|
||||
</record>
|
||||
|
||||
<record id="group_mrp_properties" model="res.groups">
|
||||
<field name="name">Properties on lines</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
<th class="text-right">Unit Price</th>
|
||||
<th t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">Disc.(%)</th>
|
||||
<th class="text-right">Taxes</th>
|
||||
<th class="text-right">Tax Excluded Price</th>
|
||||
<th class="text-right" groups="sale.group_show_price_subtotal">Price</th>
|
||||
<th class="text-right price_tax_included" groups="sale.group_show_price_total">Total Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="invoice_tbody">
|
||||
@@ -46,10 +47,14 @@
|
||||
<td class="text-right">
|
||||
<span t-esc="', '.join(map(lambda x: x.name, l.invoice_line_tax_ids))"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<td class="text-right" groups="sale.group_show_price_subtotal">
|
||||
<span t-field="l.price_subtotal"
|
||||
t-field-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_total">
|
||||
<span t-field="l.price_total"
|
||||
t-field-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -64,7 +64,8 @@
|
||||
<th class="text-right">Unit Price</th>
|
||||
<th t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">Disc.(%)</th>
|
||||
<th class="text-right">Taxes</th>
|
||||
<th class="text-right">Tax Excluded Price</th>
|
||||
<th class="text-right" groups="sale.group_show_price_subtotal">Price</th>
|
||||
<th class="text-right price_tax_included" groups="sale.group_show_price_total">Total Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="sale_tbody">
|
||||
@@ -95,10 +96,14 @@
|
||||
<td class="text-right">
|
||||
<span t-esc="', '.join(map(lambda x: (x.description or x.name), l.tax_id))"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<td class="text-right" groups="sale.group_show_price_subtotal">
|
||||
<span t-field="l.price_subtotal"
|
||||
t-field-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_total">
|
||||
<span t-field="l.price_total"
|
||||
t-field-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
<th>Taxes</th>
|
||||
<th><span t-if="True in [line.discount > 0 for line in quotation.order_line]">Discount</span></th>
|
||||
<th class="text-right">Unit Price</th>
|
||||
<th class="text-right">Tax Excluded Price</th>
|
||||
<th class="text-right" groups="sale.group_show_price_subtotal">Price</th>
|
||||
<th class="text-right price_tax_included" groups="sale.group_show_price_total">Total Price</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -69,10 +70,13 @@
|
||||
<t t-esc="'%.2f' % ((1-line.discount / 100.0) * line.price_unit)"/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-right"
|
||||
t-field="line.price_subtotal"
|
||||
t-field-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
||||
<td class="text-right" groups="sale.group_show_price_subtotal">
|
||||
<span t-field="l.price_subtotal"
|
||||
t-field-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_total">
|
||||
<span t-field="l.price_total"
|
||||
t-field-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a t-attf-href="./update_line/#{ line.id }/?order_id=#{ quotation.id }&unlink=True&token=#{ quotation.access_token }" class="mb8 js_update_line_json hidden-print" t-if="line.option_line_id">
|
||||
|
||||
@@ -120,17 +120,6 @@ class SaleOrder(models.Model):
|
||||
return random.sample(accessory_products, min(len(accessory_products), 3))
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
discounted_price = fields.Float(compute='_compute_discounted_price', digits_compute=dp.get_precision('Product Price'))
|
||||
|
||||
@api.depends('price_unit', 'discount')
|
||||
def _compute_discounted_price(self):
|
||||
for line in self:
|
||||
line.discounted_price = line.price_unit * (1.0 - line.discount / 100.0)
|
||||
|
||||
|
||||
class Website(models.Model):
|
||||
_inherit = 'website'
|
||||
|
||||
|
||||
@@ -746,7 +746,7 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="cart_lines" name="Shopping Cart">
|
||||
<template id="cart_lines" name="Shopping Cart Lines">
|
||||
<div t-if="not website_sale_order or not website_sale_order.website_order_line" class="js_cart_lines well well-lg">
|
||||
Your cart is empty!
|
||||
</div>
|
||||
@@ -790,13 +790,13 @@
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center" id="td-price" name="price">
|
||||
<del t-attf-class="text-danger #{'' if line.product_id.lst_price > line.discounted_price else 'hidden'}" style="text-decoration: line-through; white-space: nowrap;"
|
||||
<del t-attf-class="text-danger #{'' if line.product_id.lst_price > line.price_reduce else 'hidden'}" style="text-decoration: line-through; white-space: nowrap;"
|
||||
t-field="line.product_id.lst_price" t-field-options='{
|
||||
"widget": "monetary",
|
||||
"from_currency": line.company_id.currency_id,
|
||||
"display_currency": website.currency_id
|
||||
}'/>
|
||||
<span t-field="line.discounted_price" style="white-space: nowrap;" t-field-options='{
|
||||
<span t-field="line.price_reduce" style="white-space: nowrap;" t-field-options='{
|
||||
"widget": "monetary",
|
||||
"display_currency": website.currency_id
|
||||
}'/>
|
||||
|
||||
Reference in New Issue
Block a user