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