8 changed files with 281 additions and 0 deletions
@ -0,0 +1 @@ |
|||||
|
import models |
@ -0,0 +1,30 @@ |
|||||
|
{ |
||||
|
'name': 'Sale Discount for Total Amount', |
||||
|
'version': '1.0', |
||||
|
'category': 'sale', |
||||
|
'sequence': 6, |
||||
|
'summary': "extension of default Sale Management module meant to provide discount for total amount", |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'website': 'http://www.cybrosys.com', |
||||
|
|
||||
|
'description': """ |
||||
|
|
||||
|
Sale Discount for Total Amount |
||||
|
======================= |
||||
|
Module to manage discount for total amount in Sale. |
||||
|
Two Type of Discount, |
||||
|
Discount by a fixed value, |
||||
|
Discount by a percentage... |
||||
|
""", |
||||
|
'depends': ['sale', 'base', 'stock'], |
||||
|
'data': [ |
||||
|
'views/sale_view.xml', |
||||
|
'views/account_invoice_view.xml' |
||||
|
|
||||
|
], |
||||
|
'demo': [ |
||||
|
], |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
import account_invoice |
||||
|
import sale |
@ -0,0 +1,88 @@ |
|||||
|
from openerp import api, models, fields |
||||
|
from openerp.osv import osv |
||||
|
import openerp.addons.decimal_precision as dp |
||||
|
|
||||
|
|
||||
|
class AccountInvoice(models.Model): |
||||
|
_inherit = "account.invoice" |
||||
|
|
||||
|
@api.one |
||||
|
@api.depends('invoice_line.price_subtotal', 'tax_line.amount') |
||||
|
def _compute_amount(self): |
||||
|
self.amount_untaxed = sum(line.price_subtotal for line in self.invoice_line) |
||||
|
self.amount_tax = sum(line.amount for line in self.tax_line) |
||||
|
if self.discount_type == 'percent': |
||||
|
self.amount_discount = ((self.amount_untaxed + self.amount_tax) * self.discount_rate) / 100 |
||||
|
elif self.discount_type == 'amount': |
||||
|
self.amount_discount = self.discount_rate |
||||
|
self.amount_total = self.amount_untaxed + self.amount_tax - self.amount_discount |
||||
|
|
||||
|
discount_type = fields.Selection([('percent', 'Percentage'), ('amount', 'Amount')], 'Discount Type', readonly=True, |
||||
|
states={'draft': [('readonly', False)]}) |
||||
|
discount_rate = fields.Float('Discount rate', digits_compute=dp.get_precision('Account'), readonly=True, |
||||
|
states={'draft': [('readonly', False)]}) |
||||
|
amount_discount = fields.Float(string='Discount', digits=dp.get_precision('Account'), |
||||
|
readonly=True, compute='_compute_amount') |
||||
|
amount_untaxed = fields.Float(string='Subtotal', digits=dp.get_precision('Account'), |
||||
|
readonly=True, compute='_compute_amount', track_visibility='always') |
||||
|
amount_tax = fields.Float(string='Tax', digits=dp.get_precision('Account'), |
||||
|
readonly=True, compute='_compute_amount') |
||||
|
amount_total = fields.Float(string='Total', digits=dp.get_precision('Account'), |
||||
|
readonly=True, compute='_compute_amount') |
||||
|
|
||||
|
@api.onchange('discount_type', 'discount_rate') |
||||
|
def compute_discount(self): |
||||
|
for inv in self: |
||||
|
amount = sum(line.price_subtotal for line in self.invoice_line) |
||||
|
tax = sum(line.amount for line in self.tax_line) |
||||
|
if inv.discount_type == 'percent': |
||||
|
if inv.discount_rate == 100: |
||||
|
disc_amnt = amount + tax |
||||
|
else: |
||||
|
disc_amnt = (amount + tax) * inv.discount_rate / 100 |
||||
|
total = amount + tax - disc_amnt |
||||
|
self.amount_discount = disc_amnt |
||||
|
self.amount_total = total |
||||
|
else: |
||||
|
total = (amount + tax) - inv.discount_rate |
||||
|
self.amount_discount = inv.discount_rate |
||||
|
self.amount_total = total |
||||
|
|
||||
|
@api.model |
||||
|
def _prepare_refund(self, invoice, date=None, period_id=None, description=None, journal_id=None): |
||||
|
res = super(AccountInvoice, self)._prepare_refund(invoice, date, period_id, |
||||
|
description, journal_id) |
||||
|
res.update({ |
||||
|
'discount_type': self.discount_type, |
||||
|
'discount_rate': self.discount_rate, |
||||
|
}) |
||||
|
return res |
||||
|
|
||||
|
|
||||
|
class invoice_line(osv.Model): |
||||
|
_inherit = 'account.invoice.line' |
||||
|
|
||||
|
def move_line_get(self, cr, uid, invoice_id, context=None): |
||||
|
res = super(invoice_line, self).move_line_get(cr, uid, invoice_id, context=context) |
||||
|
inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id, context=context) |
||||
|
|
||||
|
if inv.type in ('out_invoice', 'out_refund') and inv.discount_type: |
||||
|
prop = self.pool.get('ir.property').get(cr, uid, 'property_account_income_categ', 'product.category', |
||||
|
context=context) |
||||
|
prop_id = prop and prop.id or False |
||||
|
account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, inv.fiscal_position or False, |
||||
|
prop_id) |
||||
|
sign = -1 |
||||
|
|
||||
|
res.append({ |
||||
|
'name': 'Discount', |
||||
|
'price_unit': sign * inv.amount_discount, |
||||
|
'quantity': 1, |
||||
|
'price': sign * inv.amount_discount, |
||||
|
'account_id': account_id, |
||||
|
'product_id': False, |
||||
|
'uos_id': False, |
||||
|
'account_analytic_id': False, |
||||
|
'taxes': False, |
||||
|
}) |
||||
|
return res |
@ -0,0 +1,91 @@ |
|||||
|
from openerp.osv import fields, osv |
||||
|
from openerp import api |
||||
|
import openerp.addons.decimal_precision as dp |
||||
|
|
||||
|
|
||||
|
class SaleOrder(osv.Model): |
||||
|
_inherit = 'sale.order' |
||||
|
|
||||
|
def _amount_all(self, cr, uid, ids, field_name, arg, context=None): |
||||
|
cur_obj = self.pool.get('res.currency') |
||||
|
res = {} |
||||
|
for order in self.browse(cr, uid, ids, context=context): |
||||
|
res[order.id] = { |
||||
|
'amount_untaxed': 0.0, |
||||
|
'amount_discount': 0.0, |
||||
|
'amount_tax': 0.0, |
||||
|
'amount_total': 0.0, |
||||
|
} |
||||
|
val = val1 = val2 = 0.0 |
||||
|
cur = order.pricelist_id.currency_id |
||||
|
for line in order.order_line: |
||||
|
val1 += line.price_subtotal |
||||
|
val += self._amount_line_tax(cr, uid, line, context=context) |
||||
|
if order.discount_type == 'amount': |
||||
|
val2 = order.discount_rate |
||||
|
elif order.discount_type == 'percent': |
||||
|
val2 = ((val1 + val) * order.discount_rate) / 100 |
||||
|
res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val) |
||||
|
res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur, val1) |
||||
|
res[order.id]['amount_discount'] = cur_obj.round(cr, uid, cur, val2) |
||||
|
res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax'] - \ |
||||
|
res[order.id]['amount_discount'] |
||||
|
return res |
||||
|
|
||||
|
def _get_order(self, cr, uid, ids, context=None): |
||||
|
result = {} |
||||
|
for line in self.pool.get('sale.order.line').browse(cr, uid, ids, context=context): |
||||
|
result[line.order_id.id] = True |
||||
|
return result.keys() |
||||
|
|
||||
|
_columns = { |
||||
|
'discount_type': fields.selection([ |
||||
|
('percent', 'Percentage'), |
||||
|
('amount', 'Amount')], 'Discount type'), |
||||
|
'discount_rate': fields.float('Discount Amount', digits_compute=dp.get_precision('Account'), |
||||
|
readonly=True, |
||||
|
states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, ), |
||||
|
'amount_discount': fields.function(_amount_all, digits_compute=dp.get_precision('Account'), string='Discount', |
||||
|
multi='sums', help="The total discount."), |
||||
|
'amount_untaxed': fields.function(_amount_all, digits_compute=dp.get_precision('Account'), |
||||
|
string='Untaxed Amount', |
||||
|
multi='sums', help="The amount without tax.", track_visibility='always'), |
||||
|
'amount_tax': fields.function(_amount_all, digits_compute=dp.get_precision('Account'), string='Taxes', |
||||
|
multi='sums', help="The tax amount."), |
||||
|
'amount_total': fields.function(_amount_all, digits_compute=dp.get_precision('Account'), string='Total', |
||||
|
multi='sums', help="The total amount."), |
||||
|
} |
||||
|
|
||||
|
_defaults = { |
||||
|
'discount_type': 'percent', |
||||
|
} |
||||
|
|
||||
|
@api.onchange('discount_type', 'discount_rate') |
||||
|
def compute_discount(self): |
||||
|
for order in self: |
||||
|
val1 = val2 = 0.0 |
||||
|
for line in order.order_line: |
||||
|
val1 += line.price_subtotal |
||||
|
val2 += self._amount_line_tax(line) |
||||
|
if order.discount_type == 'percent': |
||||
|
if order.discount_rate == 100: |
||||
|
disc_amnt = val1 + val2 |
||||
|
else: |
||||
|
disc_amnt = (val1 + val2) * order.discount_rate / 100 |
||||
|
total = val1 + val2 - disc_amnt |
||||
|
self.currency_id = order.pricelist_id.currency_id |
||||
|
self.amount_discount = disc_amnt |
||||
|
self.amount_total = total |
||||
|
else: |
||||
|
total = (val1 + val2) - order.discount_rate |
||||
|
self.currency_id = order.pricelist_id.currency_id |
||||
|
self.amount_discount = order.discount_rate |
||||
|
self.amount_total = total |
||||
|
|
||||
|
def _prepare_invoice(self, cr, uid, order, lines, context=None): |
||||
|
invoice_vals = super(SaleOrder, self)._prepare_invoice(cr, uid, order, lines, context=context) |
||||
|
invoice_vals.update({ |
||||
|
'discount_type': order.discount_type, |
||||
|
'discount_rate': order.discount_rate |
||||
|
}) |
||||
|
return invoice_vals |
After Width: | Height: | Size: 3.1 KiB |
@ -0,0 +1,35 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<record id="discount_account_invoice_view_form1" model="ir.ui.view"> |
||||
|
<field name="name">discount.account.invoice</field> |
||||
|
<field name="model">account.invoice</field> |
||||
|
<field name="inherit_id" ref="account.invoice_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//group[@class='oe_subtotal_footer oe_right']" position="replace"> |
||||
|
<group col="4"> |
||||
|
<group name="discount"> |
||||
|
<field name="discount_type"/> |
||||
|
<field name="discount_rate"/> |
||||
|
</group> |
||||
|
<group class="oe_subtotal_footer oe_right"> |
||||
|
<field name="amount_untaxed" widget="monetary" options="{'currency_field': 'currency_id'}"/> |
||||
|
<div> |
||||
|
<label for="amount_tax"/> |
||||
|
<button name="button_reset_taxes" states="draft,proforma2" |
||||
|
string="(update)" class="oe_link oe_edit_only" |
||||
|
type="object" help="Recompute taxes and total"/> |
||||
|
</div> |
||||
|
<field name="amount_tax" nolabel="1" widget="monetary" options="{'currency_field': 'currency_id'}"/> |
||||
|
<field name="amount_discount" widget='monetary' options="{'currency_field': 'currency_id'}"/> |
||||
|
<field name="amount_total" class="oe_subtotal_footer_separator" widget="monetary" options="{'currency_field': 'currency_id'}"/> |
||||
|
<field name="residual" groups="account.group_account_user" widget="monetary" options="{'currency_field': 'currency_id'}"/> |
||||
|
<field name="reconciled" invisible="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</xpath> |
||||
|
|
||||
|
</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,34 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<record id="discount_sale_view_form" model="ir.ui.view"> |
||||
|
<field name="name">discount.sale.order.form</field> |
||||
|
<field name="model">sale.order</field> |
||||
|
<field name="inherit_id" ref="sale.view_order_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//group[@name='sale_total']" position="replace"> |
||||
|
<group col="4"> |
||||
|
<group name="discount"> |
||||
|
<field name="discount_type"/> |
||||
|
<field name="discount_rate"/> |
||||
|
</group> |
||||
|
<group class="oe_subtotal_footer oe_right" colspan="2" name="sale_total"> |
||||
|
<field name="amount_untaxed" widget='monetary' options="{'currency_field': 'currency_id'}"/> |
||||
|
<field name="amount_tax" widget='monetary' options="{'currency_field': 'currency_id'}"/> |
||||
|
<field name="amount_discount" widget='monetary' options="{'currency_field': 'currency_id'}"/> |
||||
|
<div class="oe_subtotal_footer_separator oe_inline"> |
||||
|
<label for="amount_total" /> |
||||
|
<button name="button_dummy" |
||||
|
states="draft,sent" string="(update)" type="object" class="oe_edit_only oe_link"/> |
||||
|
</div> |
||||
|
<field name="amount_total" nolabel="1" class="oe_subtotal_footer_separator" widget='monetary' options="{'currency_field': 'currency_id'}"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</xpath> |
||||
|
<xpath expr="//button[@string='Create Invoice']" position="attributes"> |
||||
|
<attribute name="context">{'discount_type':discount_type,'discount_rate':discount_rate,'amount_discount':amount_discount}</attribute> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</openerp> |
Loading…
Reference in new issue