1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from datetime import datetime
from dateutil.relativedelta import relativedelta
from odoo.exceptions import ValidationError, UserError
class HrLoan(models.Model):
_name = 'hr.loan'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Loan Request"
@api.model
def default_get(self, field_list):
result = super(HrLoan, self).default_get(field_list)
if result.get('user_id'):
ts_user_id = result['user_id']
else:
ts_user_id = self.env.context.get('user_id', self.env.user.id)
result['employee_id'] = self.env['hr.employee'].search([('user_id', '=', ts_user_id)], limit=1).id
return result
def _compute_loan_amount(self):
total_paid = 0.0
for loan in self:
for line in loan.loan_lines:
if line.paid:
total_paid += line.amount
balance_amount = loan.loan_amount - total_paid
loan.total_amount = loan.loan_amount
loan.balance_amount = balance_amount
loan.total_paid_amount = total_paid
name = fields.Char(string="Loan Name", default="/", readonly=True, help="Name of the loan")
date = fields.Date(string="Date", default=fields.Date.today(), readonly=True, help="Date")
employee_id = fields.Many2one('hr.employee', string="Employee", required=True, help="Employee")
department_id = fields.Many2one('hr.department', related="employee_id.department_id", readonly=True,
string="Department", help="Employee")
installment = fields.Integer(string="No Of Installments", default=1, help="Number of installments")
payment_date = fields.Date(string="Payment Start Date", required=True, default=fields.Date.today(), help="Date of "
"the "
"paymemt")
loan_lines = fields.One2many('hr.loan.line', 'loan_id', string="Loan Line", index=True)
company_id = fields.Many2one('res.company', 'Company', readonly=True, help="Company",
default=lambda self: self.env.user.company_id,
states={'draft': [('readonly', False)]})
currency_id = fields.Many2one('res.currency', string='Currency', required=True, help="Currency",
default=lambda self: self.env.user.company_id.currency_id)
job_position = fields.Many2one('hr.job', related="employee_id.job_id", readonly=True, string="Job Position",
help="Job position")
loan_amount = fields.Float(string="Loan Amount", required=True, help="Loan amount")
total_amount = fields.Float(string="Total Amount", store=True, readonly=True, compute='_compute_loan_amount',
help="Total loan amount")
balance_amount = fields.Float(string="Balance Amount", store=True, compute='_compute_loan_amount', help="Balance amount")
total_paid_amount = fields.Float(string="Total Paid Amount", store=True, compute='_compute_loan_amount',
help="Total paid amount")
state = fields.Selection([
('draft', 'Draft'),
('waiting_approval_1', 'Submitted'),
('approve', 'Approved'),
('refuse', 'Refused'),
('cancel', 'Canceled'),
], string="State", default='draft', track_visibility='onchange', copy=False, )
@api.model
def create(self, values):
loan_count = self.env['hr.loan'].search_count(
[('employee_id', '=', values['employee_id']), ('state', '=', 'approve'),
('balance_amount', '!=', 0)])
if loan_count:
raise ValidationError(_("The employee has already a pending installment"))
else:
values['name'] = self.env['ir.sequence'].get('hr.loan.seq') or ' '
res = super(HrLoan, self).create(values)
return res
def compute_installment(self):
"""This automatically create the installment the employee need to pay to
company based on payment start date and the no of installments.
"""
for loan in self:
loan.loan_lines.unlink()
date_start = datetime.strptime(str(loan.payment_date), '%Y-%m-%d')
amount = loan.loan_amount / loan.installment
for i in range(1, loan.installment + 1):
self.env['hr.loan.line'].create({
'date': date_start,
'amount': amount,
'employee_id': loan.employee_id.id,
'loan_id': loan.id})
date_start = date_start + relativedelta(months=1)
loan._compute_loan_amount()
return True
def action_refuse(self):
return self.write({'state': 'refuse'})
def action_submit(self):
self.write({'state': 'waiting_approval_1'})
def action_cancel(self):
self.write({'state': 'cancel'})
def action_approve(self):
for data in self:
if not data.loan_lines:
raise ValidationError(_("Please Compute installment"))
else:
self.write({'state': 'approve'})
def unlink(self):
for loan in self:
if loan.state not in ('draft', 'cancel'):
raise UserError(
'You cannot delete a loan which is not in draft or cancelled state')
return super(HrLoan, self).unlink()
class InstallmentLine(models.Model):
_name = "hr.loan.line"
_description = "Installment Line"
date = fields.Date(string="Payment Date", required=True, help="Date of the payment")
employee_id = fields.Many2one('hr.employee', string="Employee", help="Employee")
amount = fields.Float(string="Amount", required=True, help="Amount")
paid = fields.Boolean(string="Paid", help="Paid")
loan_id = fields.Many2one('hr.loan', string="Loan Ref.", help="Loan")
payslip_id = fields.Many2one('hr.payslip', string="Payslip Ref.", help="Payslip")
class HrEmployee(models.Model):
_inherit = "hr.employee"
def _compute_employee_loans(self):
"""This compute the loan amount and total loans count of an employee.
"""
self.loan_count = self.env['hr.loan'].search_count([('employee_id', '=', self.id)])
loan_count = fields.Integer(string="Loan Count", compute='_compute_employee_loans')
|