diff --git a/sale_discount_total/models/account_invoice.py b/sale_discount_total/models/account_invoice.py index 1fd4da9d2..fa6ab1452 100644 --- a/sale_discount_total/models/account_invoice.py +++ b/sale_discount_total/models/account_invoice.py @@ -26,15 +26,25 @@ from odoo import api, fields, models class AccountInvoice(models.Model): _inherit = "account.move" - discount_type = fields.Selection([('percent', 'Percentage'), ('amount', 'Amount')], string='Discount type', - readonly=True, - states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, - default='percent') + discount_type = fields.Selection( + [('percent', 'Percentage'), ('amount', 'Amount')], + string='Discount type', + readonly=True, + states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, + default='percent') discount_rate = fields.Float('Discount Rate', digits=(16, 2), - readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}) - amount_discount = fields.Monetary(string='Discount', store=True, readonly=True, compute='_compute_amount', + readonly=True, + states={'draft': [('readonly', False)], + 'sent': [('readonly', False)]}) + amount_discount = fields.Monetary(string='Discount', store=True, + compute='_compute_amount', readonly=True, track_visibility='always') + # def action_post(self): + # res = super(AccountInvoice, self).action_post() + # self.payment_state = "not_paid" + # return res + @api.depends( 'line_ids.matched_debit_ids.debit_move_id.move_id.payment_id.is_matched', 'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual', @@ -55,12 +65,15 @@ class AccountInvoice(models.Model): total_tax, total_tax_currency = 0.0, 0.0 total_residual, total_residual_currency = 0.0, 0.0 total, total_currency = 0.0, 0.0 - total_to_pay = 0.0 + total_to_pay = move.amount_total + currencies = set() for line in move.line_ids: if move.is_invoice(True): # === Invoices === - if line.display_type == 'tax' or (line.display_type == 'rounding' and line.tax_repartition_line_id): + + if line.display_type == 'tax' or ( + line.display_type == 'rounding' and line.tax_repartition_line_id): # Tax amount. total_tax += line.balance total_tax_currency += line.amount_currency @@ -83,44 +96,61 @@ class AccountInvoice(models.Model): total_currency += line.amount_currency sign = move.direction_sign - move.amount_untaxed = sign * (total_untaxed_currency if len(currencies) == 1 else total_untaxed) - move.amount_tax = sign * (total_tax_currency if len(currencies) == 1 else total_tax) + move.amount_untaxed = sign * (total_untaxed_currency if len( + currencies) == 1 else total_untaxed) + move.amount_tax = sign * ( + total_tax_currency if len(currencies) == 1 else total_tax) move.amount_total = sign * total_currency move.amount_residual = -sign * total_residual_currency move.amount_untaxed_signed = -total_untaxed move.amount_tax_signed = -total_tax - move.amount_total_signed = abs(total) if move.move_type == 'entry' else -total + move.amount_total_signed = abs( + total) if move.move_type == 'entry' else -total move.amount_residual_signed = total_residual - move.amount_total_in_currency_signed = abs(move.amount_total) if move.move_type == 'entry' else -( - sign * move.amount_total) - currency = len(currencies) == 1 and currencies.pop() or move.company_id.currency_id + move.amount_total_in_currency_signed = abs( + move.amount_total) if move.move_type == 'entry' else -( + sign * move.amount_total) + currency = len( + currencies) == 1 and currencies.pop() or move.company_id.currency_id new_pmt_state = 'not_paid' if move.move_type != 'entry' else False - if move.is_invoice(include_receipts=True) and move.state == 'posted': + if move.is_invoice( + include_receipts=True) and move.state == 'posted': if currency.is_zero(move.amount_residual): - if all(payment.is_matched for payment in move._get_reconciled_payments()): + if all(payment.is_matched for payment in + move._get_reconciled_payments()): new_pmt_state = 'paid' else: new_pmt_state = move._get_invoice_in_payment_state() - elif currency.compare_amounts(total_to_pay, total_residual) != 0: + elif currency.compare_amounts(total_to_pay, + abs(total_residual)) != 0: new_pmt_state = 'partial' - if new_pmt_state == 'paid' and move.move_type in ('in_invoice', 'out_invoice', 'entry'): + if new_pmt_state == 'paid' and move.move_type in ( + 'in_invoice', 'out_invoice', 'entry'): reverse_type = move.move_type == 'in_invoice' and 'in_refund' or move.move_type == 'out_invoice' and 'out_refund' or 'entry' reverse_moves = self.env['account.move'].search( - [('reversed_entry_id', '=', move.id), ('state', '=', 'posted'), ('move_type', '=', reverse_type)]) - - # We only set 'reversed' state in cas of 1 to 1 full reconciliation with a reverse entry; otherwise, we use the regular 'paid' state - reverse_moves_full_recs = reverse_moves.mapped('line_ids.full_reconcile_id') - if reverse_moves_full_recs.mapped('reconciled_line_ids.move_id').filtered(lambda x: x not in ( - reverse_moves + reverse_moves_full_recs.mapped('exchange_move_id'))) == move: + [('reversed_entry_id', '=', move.id), + ('state', '=', 'posted'), + ('move_type', '=', reverse_type)]) + + # We only set 'reversed' state in case of 1 to 1 full + # reconciliation with a reverse entry; otherwise, we use the + # regular 'paid' state + reverse_moves_full_recs = reverse_moves.mapped( + 'line_ids.full_reconcile_id') + if reverse_moves_full_recs.mapped( + 'reconciled_line_ids.move_id').filtered( + lambda x: x not in ( + reverse_moves + reverse_moves_full_recs.mapped( + 'exchange_move_id'))) == move: new_pmt_state = 'reversed' move.payment_state = new_pmt_state @api.onchange('discount_type', 'discount_rate', 'invoice_line_ids') - def supply_rate(self): + def _supply_rate(self): for inv in self: if inv.discount_type == 'percent': discount_totals = 0 @@ -155,4 +185,3 @@ class AccountInvoiceLine(models.Model): _inherit = "account.move.line" discount = fields.Float(string='Discount (%)', digits=(16, 20), default=0.0) - diff --git a/sale_discount_total/models/discount_approval.py b/sale_discount_total/models/discount_approval.py index d9d47a715..ba6a47714 100644 --- a/sale_discount_total/models/discount_approval.py +++ b/sale_discount_total/models/discount_approval.py @@ -33,8 +33,8 @@ class sale_discount(models.Model): ('sale', 'Sales Order'), ('done', 'Locked'), ('cancel', 'Cancelled'), - ], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', default='draft') - + ], string='Status', readonly=True, copy=False, index=True, + track_visibility='onchange', default='draft') def action_confirm(self): discnt = 0.0 @@ -49,7 +49,6 @@ class sale_discount(models.Model): return True super(sale_discount, self).action_confirm() - def action_approve(self): super(sale_discount, self).action_confirm() return True @@ -64,19 +63,25 @@ class Company(models.Model): ], string="Levels of Approvals", default='one_step', help="Provide a double validation mechanism for sales discount") - so_double_validation_limit = fields.Float(string="Percentage of Discount that requires double validation'", - help="Minimum discount percentage for which a double validation is required") + so_double_validation_limit = fields.Float( + string="Percentage of Discount that requires double validation'", + help="Minimum discount percentage for which a double validation is " + "required") class ResDiscountSettings(models.TransientModel): _inherit = 'res.config.settings' - so_order_approval = fields.Boolean("Sale Discount Approval", default=lambda self: self.env.user.company_id.so_double_validation == 'two_step') + so_order_approval = fields.Boolean("Sale Discount Approval", default=lambda + self: self.env.user.company_id.so_double_validation == 'two_step') - so_double_validation = fields.Selection(related='company_id.so_double_validation',string="Levels of Approvals *", readonly=False) - so_double_validation_limit = fields.Float(string="Discount limit requires approval in %", - related='company_id.so_double_validation_limit', readonly=False) + so_double_validation = fields.Selection( + related='company_id.so_double_validation', + string="Levels of Approvals *", readonly=False) + so_double_validation_limit = fields.Float( + string="Discount limit requires approval in %", + related='company_id.so_double_validation_limit', readonly=False) def set_values(self): super(ResDiscountSettings, self).set_values() - self.so_double_validation = 'two_step' if self.so_order_approval else 'one_step' \ No newline at end of file + self.so_double_validation = 'two_step' if self.so_order_approval else 'one_step' diff --git a/sale_discount_total/models/sale.py b/sale_discount_total/models/sale.py index 85e5937d1..a3e6da303 100644 --- a/sale_discount_total/models/sale.py +++ b/sale_discount_total/models/sale.py @@ -39,7 +39,8 @@ class SaleOrder(models.Model): for line in order.order_line: amount_untaxed += line.price_subtotal amount_tax += line.price_tax - amount_discount += (line.product_uom_qty * line.price_unit * line.discount) / 100 + amount_discount += ( + line.product_uom_qty * line.price_unit * line.discount) / 100 order.update({ 'amount_untaxed': amount_untaxed, 'amount_tax': amount_tax, @@ -47,20 +48,30 @@ class SaleOrder(models.Model): 'amount_total': amount_untaxed + amount_tax, }) - discount_type = fields.Selection([('percent', 'Percentage'), ('amount', 'Amount')], string='Discount type', - readonly=True, - states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, - default='percent') - discount_rate = fields.Float('Discount Rate', digits=dp.get_precision('Account'), - readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}) - amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', + discount_type = fields.Selection( + [('percent', 'Percentage'), ('amount', 'Amount')], + string='Discount type', + readonly=True, + states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, + default='percent') + discount_rate = fields.Float('Discount Rate', + digits=dp.get_precision('Account'), + readonly=True, + states={'draft': [('readonly', False)], + 'sent': [('readonly', False)]}) + amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, + readonly=True, compute='_amount_all', track_visibility='always') - amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, compute='_amount_all', + amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, + compute='_amount_all', track_visibility='always') - amount_total = fields.Monetary(string='Total', store=True, readonly=True, compute='_amount_all', + amount_total = fields.Monetary(string='Total', store=True, readonly=True, + compute='_amount_all', track_visibility='always') - amount_discount = fields.Monetary(string='Discount', store=True, readonly=True, compute='_amount_all', - digits=dp.get_precision('Account'), track_visibility='always') + amount_discount = fields.Monetary(string='Discount', store=True, + readonly=True, compute='_amount_all', + digits=dp.get_precision('Account'), + track_visibility='always') @api.onchange('discount_type', 'discount_rate', 'order_line') def supply_rate(self): @@ -79,7 +90,7 @@ class SaleOrder(models.Model): for line in order.order_line: line.discount = discount # print(line.discount) - new_sub_price = (line.price_unit * (discount/100)) + new_sub_price = (line.price_unit * (discount / 100)) line.total_discount = line.price_unit - new_sub_price def _prepare_invoice(self, ): @@ -87,6 +98,7 @@ class SaleOrder(models.Model): invoice_vals.update({ 'discount_type': self.discount_type, 'discount_rate': self.discount_rate, + 'amount_discount': self.amount_discount, }) return invoice_vals @@ -118,4 +130,5 @@ class SaleOrderLine(models.Model): _inherit = "sale.order.line" discount = fields.Float(string='Discount (%)', digits=(16, 20), default=0.0) - total_discount = fields.Float(string="Total Discount", default=0.0, store=True) \ No newline at end of file + total_discount = fields.Float(string="Total Discount", default=0.0, + store=True) diff --git a/sale_discount_total/views/account_invoice_view.xml b/sale_discount_total/views/account_invoice_view.xml index c3f5a05ff..b2767dfd1 100644 --- a/sale_discount_total/views/account_invoice_view.xml +++ b/sale_discount_total/views/account_invoice_view.xml @@ -11,17 +11,13 @@ [16, 2] - + -
-
-
-
+
diff --git a/sale_discount_total/views/sale_view.xml b/sale_discount_total/views/sale_view.xml index 2895ee553..57ed2ae4d 100644 --- a/sale_discount_total/views/sale_view.xml +++ b/sale_discount_total/views/sale_view.xml @@ -1,7 +1,6 @@ - discount.sale.order.form sale.order @@ -19,10 +18,11 @@ - - + + - - - - - - - - -
- + + + + + + +
- - sale.order.line.total.discount sale.order - - - + + +