You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
7.5 KiB
174 lines
7.5 KiB
# -*- coding: utf-8 -*-
|
|
###############################################################################
|
|
#
|
|
# Cybrosys Technologies Pvt. Ltd.
|
|
#
|
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
|
|
# Author: Aysha Shalin (odoo@cybrosys.com)
|
|
#
|
|
# You can modify it under the terms of the GNU AFFERO
|
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
|
|
#
|
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
# (AGPL v3) along with this program.
|
|
# If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
###############################################################################
|
|
from odoo import api, fields, models, _
|
|
|
|
|
|
class SaleOrder(models.Model):
|
|
""" Extend the base Sale Order model to add custom fields and behaviors
|
|
for Sale Order Payment Status. """
|
|
_inherit = "sale.order"
|
|
_description = 'Sale order'
|
|
|
|
payment_status = fields.Char(string="Payment Status",
|
|
compute="_compute_payment_status",
|
|
help="Field to check the payment status of the"
|
|
" sale order")
|
|
payment_details = fields.Binary(string="Payment Details",
|
|
compute="_compute_payment_details",
|
|
help="Shows the payment done details "
|
|
"including date and amount")
|
|
amount_due = fields.Float(string="Amount Due",
|
|
compute='_compute_amount_due',
|
|
help="Shows the amount that in due for the "
|
|
"corresponding sale order")
|
|
invoice_state = fields.Char(string="Invoice State",
|
|
compute="_compute_invoice_state",
|
|
help="Field to check the invoice state of "
|
|
"sale order")
|
|
|
|
@api.depends('invoice_ids')
|
|
def _compute_payment_status(self):
|
|
""" The function will compute the payment status of the sale order, if
|
|
an invoice is created for the corresponding sale order.Payment status
|
|
will be either in paid,not paid,partially paid, reversed etc. """
|
|
for order in self:
|
|
order.payment_status = 'No invoice'
|
|
payment_states = order.invoice_ids.mapped('payment_state')
|
|
status_length = len(payment_states)
|
|
if 'partial' in payment_states:
|
|
order.payment_status = 'Partially Paid'
|
|
elif 'not_paid' in payment_states and any(
|
|
(True for x in ['paid', 'in_payment', 'partial'] if
|
|
x in payment_states)):
|
|
order.payment_status = 'Partially Paid'
|
|
elif 'not_paid' in payment_states and status_length == \
|
|
payment_states.count('not_paid'):
|
|
order.payment_status = 'Not Paid'
|
|
elif 'paid' in payment_states and status_length == \
|
|
payment_states.count('paid') and order.amount_due == 0:
|
|
order.payment_status = 'Paid'
|
|
elif 'paid' in payment_states and status_length == \
|
|
payment_states.count('paid') and order.amount_due != 0:
|
|
order.payment_status = 'Partially Paid'
|
|
elif 'in_payment' in payment_states and status_length == \
|
|
payment_states.count('in_payment'):
|
|
order.payment_status = 'In Payment'
|
|
elif 'reversed' in payment_states and status_length == \
|
|
payment_states.count('reversed'):
|
|
order.payment_status = 'Reversed'
|
|
else:
|
|
order.payment_status = 'No invoice'
|
|
|
|
@api.depends('invoice_ids')
|
|
def _compute_invoice_state(self):
|
|
""" The function will compute the state of the invoice , Once an invoice
|
|
is existing in a sale order. """
|
|
for rec in self:
|
|
rec.invoice_state = 'No invoice'
|
|
for order in rec.invoice_ids:
|
|
if order.state == 'posted':
|
|
rec.invoice_state = 'posted'
|
|
elif order.state != 'posted':
|
|
rec.invoice_state = 'draft'
|
|
else:
|
|
rec.invoice_state = 'No invoice'
|
|
|
|
@api.depends('invoice_ids')
|
|
def _compute_amount_due(self):
|
|
"""The function is used to compute the amount due from the invoice and
|
|
if payment is registered."""
|
|
for rec in self:
|
|
amount_due = 0
|
|
for order in rec.invoice_ids:
|
|
amount_due = amount_due + (order.amount_total -
|
|
order.amount_residual)
|
|
rec.amount_due = rec.amount_total - amount_due
|
|
|
|
def action_open_business_doc(self):
|
|
""" This method is intended to be used in the context of an
|
|
account.move record.
|
|
It retrieves the associated payment record and opens it in a new window.
|
|
|
|
:return: A dictionary describing the action to be performed.
|
|
:rtype: dict """
|
|
name = _("Journal Entry")
|
|
move = self.env['account.move'].browse(self.id)
|
|
res_model = 'account.payment'
|
|
res_id = move.payment_id.id
|
|
return {
|
|
'name': name,
|
|
'type': 'ir.actions.act_window',
|
|
'view_mode': 'form',
|
|
'views': [(False, 'form')],
|
|
'res_model': res_model,
|
|
'res_id': res_id,
|
|
'target': 'current',
|
|
}
|
|
|
|
def js_remove_outstanding_partial(self, partial_id):
|
|
""" Called by the 'payment' widget to remove a reconciled entry to the
|
|
present invoice.
|
|
|
|
:param partial_id: The id of an existing partial reconciled with the
|
|
current invoice.
|
|
"""
|
|
self.ensure_one()
|
|
partial = self.env['account.partial.reconcile'].browse(partial_id)
|
|
return partial.unlink()
|
|
|
|
@api.depends('invoice_ids')
|
|
def _compute_payment_details(self):
|
|
""" Compute the payment details from invoices and added into the sale
|
|
order form view. """
|
|
for rec in self:
|
|
payment = []
|
|
rec.payment_details = False
|
|
if rec.invoice_ids:
|
|
for line in rec.invoice_ids:
|
|
if line.invoice_payments_widget:
|
|
for pay in line.invoice_payments_widget['content']:
|
|
payment.append(pay)
|
|
for line in rec.invoice_ids:
|
|
if line.invoice_payments_widget:
|
|
payment_line = line.invoice_payments_widget
|
|
payment_line['content'] = payment
|
|
rec.payment_details = payment_line
|
|
break
|
|
rec.payment_details = False
|
|
|
|
def action_register_payment(self):
|
|
""" Open the account.payment.register wizard to pay the selected journal
|
|
entries.
|
|
:return: An action opening the account.payment.register wizard.
|
|
"""
|
|
self.ensure_one()
|
|
return {
|
|
'name': _('Register Payment'),
|
|
'res_model': 'account.payment.register',
|
|
'view_mode': 'form',
|
|
'context': {
|
|
'active_model': 'account.move',
|
|
'active_ids': self.invoice_ids.ids,
|
|
},
|
|
'target': 'new',
|
|
'type': 'ir.actions.act_window',
|
|
}
|
|
|