Browse Source

Jul 19 : [FIX] Bug Fixed 'sale_discount_total'

pull/266/head
AjmalCybro 2 years ago
parent
commit
849566ca20
  1. 81
      sale_discount_total/models/account_invoice.py
  2. 25
      sale_discount_total/models/discount_approval.py
  3. 41
      sale_discount_total/models/sale.py
  4. 12
      sale_discount_total/views/account_invoice_view.xml
  5. 37
      sale_discount_total/views/sale_view.xml

81
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)

25
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'
self.so_double_validation = 'two_step' if self.so_order_approval else 'one_step'

41
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)
total_discount = fields.Float(string="Total Discount", default=0.0,
store=True)

12
sale_discount_total/views/account_invoice_view.xml

@ -11,17 +11,13 @@
<attribute name="digits">[16, 2]</attribute>
</xpath>
<xpath expr="//field[@name='tax_totals']" position="after">
<field name="amount_discount"/>
<field name="amount_discount" readonly="1" force_save="1"/>
</xpath>
<xpath expr="//field[@name='narration']" position="before">
<div>
<label for="discount_type" string="Discount Type :"/>
<field name="discount_type" class="oe_inline"/>
</div>
<div>
<label for="discount_rate" string="Discount Rate :"/>
<group>
<field name="discount_type" width="50px"/>
<field name="discount_rate" class="oe_inline"/>
</div>
</group>
</xpath>
</field>
</record>

37
sale_discount_total/views/sale_view.xml

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<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>
@ -19,10 +18,11 @@
<xpath expr="//group[@name='note_group']" position="replace">
<group name="note_group" col="6">
<group name="discount" colspan="2">
<field name="discount_type" groups="product.group_discount_per_so_line"/>
<field name="discount_rate" groups="product.group_discount_per_so_line"/>
<field name="discount_type"
groups="product.group_discount_per_so_line"/>
<field name="discount_rate"
groups="product.group_discount_per_so_line"/>
</group>
<group class="oe_subtotal_footer oe_right" colspan="2"
name="sale_total">
<field name="amount_untaxed" widget='monetary'
@ -43,17 +43,18 @@
widget='monetary'
options="{'currency_field': 'currency_id'}"/>
</group>
<group colspan="4">
<field colspan="2" name="note" nolabel="1" placeholder="Terms and conditions..."/>
</group>
<group class="oe_subtotal_footer oe_right" colspan="2" name="sale_total">
<field name="tax_totals" widget="account-tax-totals-field" nolabel="1" colspan="2" readonly="1"/>
</group>
<div class="clearfix"/>
<group colspan="4">
<field colspan="2" name="note" nolabel="1"
placeholder="Terms and conditions..."/>
</group>
<group class="oe_subtotal_footer oe_right" colspan="2"
name="sale_total">
<field name="tax_totals"
widget="account-tax-totals-field" nolabel="1"
colspan="2" readonly="1"/>
</group>
<div class="clearfix"/>
</group>
</xpath>
<!-- Roundoff the discount field -->
<xpath expr="//field[@name='order_line']/tree/field[@name='discount']"
@ -62,15 +63,15 @@
</xpath>
</field>
</record>
<record id="view_inherit_total_discount" model="ir.ui.view">
<field name="name">sale.order.line.total.discount</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//page/field[@name='order_line']/tree/field[@name='price_subtotal']" position="after">
<field name="total_discount" force_save="1" invisible="1"/>
</xpath>
<xpath expr="//page/field[@name='order_line']/tree/field[@name='price_subtotal']"
position="after">
<field name="total_discount" force_save="1" invisible="1"/>
</xpath>
</field>
</record>
</data>

Loading…
Cancel
Save