Initial commit on branch odoo_DuyDat
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 . import account_move
|
||||
from . import account_payment_register
|
||||
from . import loan_documents
|
||||
from . import loan_request
|
||||
from . import loan_type
|
||||
from . import repayment_lines
|
||||
from . import res_config_settings
|
||||
from . import res_partner
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,54 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 models
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
"""Alter loan repayment line state on draft and cancel button click"""
|
||||
_inherit = 'account.move'
|
||||
|
||||
def button_draft(self):
|
||||
"""Change repayment record state to 'invoiced'
|
||||
while reset to draft the invoice"""
|
||||
res = super().button_draft()
|
||||
loan_line_ids = self.env['repayment.line'].search([
|
||||
('name', 'ilike', self.payment_reference)])
|
||||
if loan_line_ids:
|
||||
loan_line_ids.update({
|
||||
'state': 'invoiced',
|
||||
'invoice': True
|
||||
})
|
||||
return res
|
||||
|
||||
def button_cancel(self):
|
||||
"""Change repayment record state to 'unpaid'
|
||||
while cancelling the invoice"""
|
||||
res = super().button_cancel()
|
||||
for record in self:
|
||||
loan_line_ids = self.env['repayment.line'].search([
|
||||
('name', 'ilike', record.payment_reference)])
|
||||
if loan_line_ids:
|
||||
loan_line_ids.update({
|
||||
'state': 'unpaid',
|
||||
'invoice': False
|
||||
})
|
||||
return res
|
||||
@@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 models
|
||||
|
||||
|
||||
class AccountPaymentRegister(models.TransientModel):
|
||||
"""Alter loan repayment line state based on invoice status"""
|
||||
_inherit = 'account.payment.register'
|
||||
|
||||
def _post_payments(self, to_process, edit_mode=False):
|
||||
"""Change repayment record state to 'paid' while registering the
|
||||
payment"""
|
||||
res = super()._post_payments(to_process, edit_mode=False)
|
||||
for record in self:
|
||||
loan_line_id = self.env['repayment.line'].search([
|
||||
('name', 'ilike', record.communication)])
|
||||
loan_line_id.write({'state': 'paid'})
|
||||
return res
|
||||
@@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 fields, models
|
||||
|
||||
|
||||
class LoanDocuments(models.Model):
|
||||
"""Documents required to approve loan, eg:-Aadhar, Pan"""
|
||||
_name = 'loan.documents'
|
||||
_description = 'Loan Documents'
|
||||
_rec_name = 'loan_proofs'
|
||||
|
||||
loan_proofs = fields.Char(string="Proofs", help="Document name "
|
||||
"for identification", required=True)
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
readonly=True,
|
||||
help="Company Name",
|
||||
default=lambda self:
|
||||
self.env.company)
|
||||
@@ -0,0 +1,265 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class LoanRequest(models.Model):
|
||||
"""Can create new loan requests and manage records"""
|
||||
_name = 'loan.request'
|
||||
_inherit = ['mail.thread']
|
||||
_description = 'Loan Request'
|
||||
|
||||
name = fields.Char(string='Loan Reference', readonly=True,
|
||||
copy=False, help="Sequence number for loan requests",
|
||||
default=lambda self: 'New')
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
readonly=True,
|
||||
help="Company Name",
|
||||
default=lambda self: self.env.company)
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
required=True, help="Currency",
|
||||
default=lambda self: self.env.user.company_id.
|
||||
currency_id)
|
||||
loan_type_id = fields.Many2one('loan.type', string='Loan Type',
|
||||
required=True, help="Can choose different "
|
||||
"loan types suitable")
|
||||
loan_amount = fields.Float(string="Loan Amount",
|
||||
help="Total loan amount", )
|
||||
disbursal_amount = fields.Float(string="Disbursal Amount",
|
||||
help="Total loan amount "
|
||||
"available to disburse")
|
||||
tenure = fields.Integer(string="Tenure", default=1,
|
||||
help="Installment period")
|
||||
interest_rate = fields.Float(string="Interest Rate", help="Interest "
|
||||
"percentage")
|
||||
date = fields.Date(string="Date", default=fields.Date.today(),
|
||||
readonly=True, help="Date")
|
||||
partner_id = fields.Many2one('res.partner', string="Partner",
|
||||
required=True,
|
||||
help="Partner")
|
||||
repayment_lines_ids = fields.One2many('repayment.line',
|
||||
'loan_id',
|
||||
string="Loan Line", index=True,
|
||||
help="Repayment lines")
|
||||
documents_ids = fields.Many2many('loan.documents',
|
||||
string="Proofs",
|
||||
help="Documents as proof")
|
||||
img_attachment_ids = fields.Many2many('ir.attachment',
|
||||
relation="m2m_ir_identity_card_rel",
|
||||
column1="documents_ids",
|
||||
string="Images",
|
||||
help="Image proofs")
|
||||
journal_id = fields.Many2one('account.journal',
|
||||
string="Journal",
|
||||
help="Journal types",
|
||||
domain="[('type', '=', 'purchase'),"
|
||||
"('company_id', '=', company_id)]",
|
||||
)
|
||||
debit_account_id = fields.Many2one('account.account',
|
||||
string="Debit account",
|
||||
help="Choose account for "
|
||||
"disbursement debit")
|
||||
credit_account_id = fields.Many2one('account.account',
|
||||
string="Credit account",
|
||||
help="Choose account for "
|
||||
"disbursement credit")
|
||||
reject_reason = fields.Text(string="Reason", help="Displays "
|
||||
"rejected reason")
|
||||
request = fields.Boolean(string="Request",
|
||||
help="For monitoring the record")
|
||||
state = fields.Selection(string='State',
|
||||
selection=[('draft', 'Draft'), ('confirmed', 'Confirmed'),
|
||||
('waiting', 'Waiting For Approval'),
|
||||
('approved', 'Approved'), ('disbursed', 'Disbursed'),
|
||||
('rejected', 'Rejected'), ('closed', 'Closed')],
|
||||
copy=False, tracking=True, default='draft', help="Loan request states")
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
"""create auto sequence for the loan request records"""
|
||||
loan_count = self.env['loan.request'].search(
|
||||
[('partner_id', '=', vals['partner_id']),
|
||||
('state', 'not in', ('draft', 'rejected', 'closed'))])
|
||||
if loan_count:
|
||||
for rec in loan_count:
|
||||
if rec.state != 'closed':
|
||||
raise UserError(
|
||||
_('The partner has already an ongoing loan.'))
|
||||
else:
|
||||
if vals.get('name', 'New') == 'New':
|
||||
vals['name'] = self.env['ir.sequence'].next_by_code(
|
||||
'increment_loan_ref')
|
||||
res = super().create(vals)
|
||||
return res
|
||||
|
||||
@api.onchange('loan_type_id')
|
||||
def _onchange_loan_type_id(self):
|
||||
"""Changing field values based on the chosen loan type"""
|
||||
type_id = self.loan_type_id
|
||||
self.loan_amount = type_id.loan_amount
|
||||
self.disbursal_amount = type_id.disbursal_amount
|
||||
self.tenure = type_id.tenure
|
||||
self.interest_rate = type_id.interest_rate
|
||||
self.documents_ids = type_id.documents_ids
|
||||
|
||||
def action_loan_request(self):
|
||||
"""Changes the state to confirmed and send confirmation mail"""
|
||||
self.write({'state': "confirmed"})
|
||||
partner = self.partner_id
|
||||
loan_no = self.name
|
||||
subject = 'Loan Confirmation'
|
||||
message = (f"Dear {partner.name},<br/> This is a confirmation mail "
|
||||
f"for your loan{loan_no}. We have submitted your loan "
|
||||
f"for approval.")
|
||||
outgoing_mail = self.company_id.email
|
||||
mail_values = {
|
||||
'subject': subject,
|
||||
'email_from': outgoing_mail,
|
||||
'author_id': self.env.user.partner_id.id,
|
||||
'email_to': partner.email,
|
||||
'body_html': message,
|
||||
}
|
||||
mail = self.env['mail.mail'].sudo().create(mail_values)
|
||||
mail.send()
|
||||
|
||||
def action_request_for_loan(self):
|
||||
"""Change the state to waiting for approval"""
|
||||
if self.request:
|
||||
self.write({'state': "waiting"})
|
||||
else:
|
||||
message_id = self.env['message.popup'].create(
|
||||
{'message': _("Compute the repayments before requesting")})
|
||||
return {
|
||||
'name': _('Repayment'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'message.popup',
|
||||
'res_id': message_id.id,
|
||||
'target': 'new'
|
||||
}
|
||||
|
||||
def action_loan_approved(self):
|
||||
"""Change to Approved state"""
|
||||
self.write({'state': "approved"})
|
||||
|
||||
def action_disburse_loan(self):
|
||||
"""Disbursing the loan to customer and creating journal
|
||||
entry for the disbursement"""
|
||||
self.write({'state': "disbursed"})
|
||||
for loan in self:
|
||||
amount = loan.disbursal_amount
|
||||
loan_name = loan.partner_id.name
|
||||
reference = loan.name
|
||||
journal_id = loan.journal_id.id
|
||||
debit_account_id = loan.debit_account_id.id
|
||||
credit_account_id = loan.credit_account_id.id
|
||||
date_now = loan.date
|
||||
debit_vals = {
|
||||
'name': loan_name,
|
||||
'account_id': debit_account_id,
|
||||
'journal_id': journal_id,
|
||||
'date': date_now,
|
||||
'debit': amount > 0.0 and amount or 0.0,
|
||||
'credit': amount < 0.0 and -amount or 0.0,
|
||||
}
|
||||
credit_vals = {
|
||||
'name': loan_name,
|
||||
'account_id': credit_account_id,
|
||||
'journal_id': journal_id,
|
||||
'date': date_now,
|
||||
'debit': amount < 0.0 and -amount or 0.0,
|
||||
'credit': amount > 0.0 and amount or 0.0,
|
||||
}
|
||||
vals = {
|
||||
'name': f'DIS / {reference}',
|
||||
'narration': reference,
|
||||
'ref': reference,
|
||||
'journal_id': journal_id,
|
||||
'date': date_now,
|
||||
'line_ids': [(0, 0, debit_vals), (0, 0, credit_vals)]
|
||||
}
|
||||
move = self.env['account.move'].create(vals)
|
||||
move.action_post()
|
||||
return True
|
||||
|
||||
def action_close_loan(self):
|
||||
"""Closing the loan"""
|
||||
demo = []
|
||||
for check in self.repayment_lines_ids:
|
||||
if check.state == 'unpaid':
|
||||
demo.append(check)
|
||||
if len(demo) >= 1:
|
||||
message_id = self.env['message.popup'].create(
|
||||
{'message': _("Pending Repayments")})
|
||||
return {
|
||||
'name': _('Repayment'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'message.popup',
|
||||
'res_id': message_id.id,
|
||||
'target': 'new'
|
||||
}
|
||||
self.write({'state': "closed"})
|
||||
|
||||
def action_loan_rejected(self):
|
||||
"""You can add reject reasons here"""
|
||||
return {'type': 'ir.actions.act_window',
|
||||
'name': 'Loan Rejection',
|
||||
'res_model': 'reject.reason',
|
||||
'target': 'new',
|
||||
'view_mode': 'form',
|
||||
'context': {'default_loan': self.name}
|
||||
}
|
||||
|
||||
def action_compute_repayment(self):
|
||||
"""This automatically create the installment the employee need to pay to
|
||||
company based on payment start date and the no of installments.
|
||||
"""
|
||||
self.request = True
|
||||
for loan in self:
|
||||
loan.repayment_lines_ids.unlink()
|
||||
date_start = datetime.strptime(str(loan.date),'%Y-%m-%d') + relativedelta(months=1)
|
||||
amount = loan.loan_amount / loan.tenure
|
||||
interest = loan.loan_amount * loan.interest_rate
|
||||
interest_amount = interest / loan.tenure
|
||||
total_amount = amount + interest_amount
|
||||
partner = self.partner_id
|
||||
for rand_num in range(1, loan.tenure + 1):
|
||||
self.env['repayment.line'].create({
|
||||
'name': f"{loan.name}/{rand_num}",
|
||||
'partner_id': partner.id,
|
||||
'date': date_start,
|
||||
'amount': amount,
|
||||
'interest_amount': interest_amount,
|
||||
'total_amount': total_amount,
|
||||
'interest_account_id': self.env.ref('advanced_loan_management.'
|
||||
'loan_management_'
|
||||
'inrst_accounts').id,
|
||||
'repayment_account_id': self.env.ref('advanced_loan_management.'
|
||||
'demo_'
|
||||
'loan_accounts').id,
|
||||
'loan_id': loan.id})
|
||||
date_start += relativedelta(months=1)
|
||||
return True
|
||||
@@ -0,0 +1,57 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 LoanTypes(models.Model):
|
||||
"""Create different types of Loans, And can wisely choose while requesting
|
||||
for loan"""
|
||||
_name = 'loan.type'
|
||||
_inherit = ['mail.thread']
|
||||
_description = 'Loan Type'
|
||||
|
||||
name = fields.Char(string='Name', help="LoanType Name", required=True)
|
||||
loan_amount = fields.Integer(string='Loan Amount', help="Loan Amount", required=True)
|
||||
tenure = fields.Integer(string='Tenure', default='1',
|
||||
help="Amortization period")
|
||||
tenure_plan = fields.Char(string="Tenure Plan", default='Monthly',
|
||||
readonly='True', help="EMI payment plan")
|
||||
interest_rate = fields.Float(string='Interest Rate',
|
||||
help="Loan Interest Rate")
|
||||
disbursal_amount = fields.Float(string='Disbursal Amount',
|
||||
compute='_compute_disbursal_amount',
|
||||
help="Total Amount To Be Disbursed")
|
||||
documents_ids = fields.Many2many('loan.documents',
|
||||
string="Documents",
|
||||
help="Personal Proofs")
|
||||
processing_fee = fields.Integer(string="Processing Fee",
|
||||
help="Amount For Initializing The Loan")
|
||||
note = fields.Text(string="Criteria", help="Criteria for approving "
|
||||
"loan requests")
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
readonly=True, help="Company Name",
|
||||
default=lambda self: self.env.company, )
|
||||
|
||||
@api.depends('processing_fee', 'loan_amount')
|
||||
def _compute_disbursal_amount(self):
|
||||
"""Calculating amount for disbursing"""
|
||||
self.disbursal_amount = self.loan_amount - self.processing_fee
|
||||
@@ -0,0 +1,149 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 fields, models
|
||||
|
||||
|
||||
class RepaymentLine(models.Model):
|
||||
"""Loan repayments """
|
||||
_name = "repayment.line"
|
||||
_description = "Repayment Line"
|
||||
|
||||
name = fields.Char(string="Loan ", default="/", readonly=True,
|
||||
help="Repayment no: of loan")
|
||||
partner_id = fields.Many2one('res.partner', string="Partner",
|
||||
required=True,
|
||||
help="Partner")
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
readonly=True,
|
||||
help="Company",
|
||||
default=lambda self: self.env.company)
|
||||
date = fields.Date(string="Payment Date", required=True,
|
||||
default=fields.Date.today(),
|
||||
readonly=True,
|
||||
help="Date of the payment")
|
||||
amount = fields.Float(string="Amount", required=True, help="Amount",
|
||||
digits=(16, 2))
|
||||
interest_amount = fields.Float(string="Interest Amount", required=True,
|
||||
help="Interest Amount", digits=(16, 2))
|
||||
total_amount = fields.Float(string="Total Amount", required=True,
|
||||
help="Total Amount", digits=(16, 2))
|
||||
loan_id = fields.Many2one('loan.request', string="Loan Ref.",
|
||||
help="Loan",
|
||||
readonly=True)
|
||||
state = fields.Selection(string="State",
|
||||
selection=[('unpaid', 'Unpaid'),
|
||||
('invoiced', 'Invoiced'),
|
||||
('paid', 'Paid')], copy=False,
|
||||
default='unpaid',
|
||||
help="Includes paid and unpaid states for each "
|
||||
"repayments", )
|
||||
journal_loan_id = fields.Many2one('account.journal',
|
||||
string="Journal",
|
||||
store=True, default=lambda self: self.
|
||||
env['account.journal'].
|
||||
search([('code', 'like', 'CSH1')]),
|
||||
help="Journal Record")
|
||||
interest_account_id = fields.Many2one('account.account',
|
||||
string="Interest",
|
||||
store=True,
|
||||
help="Account For Interest")
|
||||
repayment_account_id = fields.Many2one('account.account',
|
||||
string="Repayment",
|
||||
store=True,
|
||||
help="Account For Repayment")
|
||||
invoice = fields.Boolean(string="invoice", default=False,
|
||||
help="For monitoring the record")
|
||||
|
||||
def action_pay_emi(self):
|
||||
"""Creates invoice for each EMI"""
|
||||
time_now = self.date
|
||||
interest_product_id = self.env['ir.config_parameter'].sudo().get_param(
|
||||
'advanced_loan_management.interest_product_id')
|
||||
repayment_product_id = self.env['ir.config_parameter'].sudo().get_param(
|
||||
'advanced_loan_management.repayment_product_id')
|
||||
for rec in self:
|
||||
loan_lines_ids = self.env['repayment.line'].search(
|
||||
[('loan_id', '=', rec.loan_id.id)], order='date asc')
|
||||
for line in loan_lines_ids:
|
||||
if line.date < rec.date and line.state in \
|
||||
('unpaid', 'invoiced'):
|
||||
message_id = self.env['message.popup'].create(
|
||||
{'message': (
|
||||
"You have pending amounts")})
|
||||
return {
|
||||
'name': 'Repayment',
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'message.popup',
|
||||
'res_id': message_id.id,
|
||||
'target': 'new'
|
||||
}
|
||||
|
||||
invoice = self.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'invoice_date': time_now,
|
||||
'partner_id': self.partner_id.id,
|
||||
'currency_id': self.company_id.currency_id.id,
|
||||
'payment_reference': self.name,
|
||||
'invoice_line_ids': [
|
||||
(0, 0, {
|
||||
'price_unit': self.amount,
|
||||
'product_id': repayment_product_id,
|
||||
'name': 'Repayment',
|
||||
'account_id': self.repayment_account_id.id,
|
||||
'quantity': 1,
|
||||
}),
|
||||
(0, 0, {
|
||||
'price_unit': self.interest_amount,
|
||||
'product_id': interest_product_id,
|
||||
'name': 'Interest amount',
|
||||
'account_id': self.interest_account_id.id,
|
||||
'quantity': 1,
|
||||
}),
|
||||
],
|
||||
})
|
||||
if invoice:
|
||||
invoice.action_post()
|
||||
self.invoice=True
|
||||
self.write({'state':'invoiced'})
|
||||
return {
|
||||
'name': 'Invoice',
|
||||
'res_model': 'account.move',
|
||||
'res_id': invoice.id,
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
}
|
||||
|
||||
def action_view_invoice(self):
|
||||
"""To view the invoices"""
|
||||
invoice = self.env['account.move'].search([
|
||||
('payment_reference', '=', self.name)
|
||||
])
|
||||
self.invoice = True
|
||||
|
||||
return {
|
||||
'name': 'Invoice',
|
||||
'res_model': 'account.move',
|
||||
'res_id': invoice.id,
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
"""Add new fields to display service products"""
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
interest_product_id = fields.Many2one('product.product',
|
||||
string="Interest Product",
|
||||
config_parameter="advanced_loan_management.interest_product_id",
|
||||
help="Product For Interest "
|
||||
"To Create Invoice Lines")
|
||||
repayment_product_id = fields.Many2one('product.product',
|
||||
string="Repayment Product",
|
||||
config_parameter="advanced_loan_management.repayment_product_id",
|
||||
help="Product For Repayment "
|
||||
"To Create Invoice Lines")
|
||||
@@ -0,0 +1,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Gayathri V (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 fields, models
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
"""Add new tab to display partner's loan count"""
|
||||
_inherit = "res.partner"
|
||||
|
||||
def _compute_partner_loans(self):
|
||||
"""This compute the loan amount and total loans count of a partner."""
|
||||
self.loan_count = self.env['loan.request'].search_count(
|
||||
[('partner_id', '=', self.id),
|
||||
('state', 'in', ('disbursed', 'closed'))])
|
||||
|
||||
loan_count = fields.Integer(string="Loan Count",
|
||||
compute='_compute_partner_loans',
|
||||
help="Displays numbers of loans "
|
||||
"ongoing and closed by the employee")
|
||||
|
||||
def action_view_loans(self):
|
||||
"""Returns loan records of current employee"""
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Loans',
|
||||
'view_mode': 'tree',
|
||||
'res_model': 'loan.request',
|
||||
'domain': [('partner_id', '=', self.id)],
|
||||
'context': "{'create': False}"
|
||||
}
|
||||
Reference in New Issue
Block a user