summaryrefslogtreecommitdiff
path: root/ohrms_loan/models
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 17:14:58 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 17:14:58 +0700
commit1ca3b3df3421961caec3b747a364071c80f5c7da (patch)
tree6778a1f0f3f9b4c6e26d6d87ccde16e24da6c9d6 /ohrms_loan/models
parentb57188be371d36d96caac4b8d65a40745c0e972c (diff)
initial commit
Diffstat (limited to 'ohrms_loan/models')
-rw-r--r--ohrms_loan/models/__init__.py4
-rw-r--r--ohrms_loan/models/hr_loan.py141
-rw-r--r--ohrms_loan/models/hr_payroll.py79
3 files changed, 224 insertions, 0 deletions
diff --git a/ohrms_loan/models/__init__.py b/ohrms_loan/models/__init__.py
new file mode 100644
index 0000000..c4e2501
--- /dev/null
+++ b/ohrms_loan/models/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+from . import hr_loan
+from . import hr_payroll
+
diff --git a/ohrms_loan/models/hr_loan.py b/ohrms_loan/models/hr_loan.py
new file mode 100644
index 0000000..595c87d
--- /dev/null
+++ b/ohrms_loan/models/hr_loan.py
@@ -0,0 +1,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')
diff --git a/ohrms_loan/models/hr_payroll.py b/ohrms_loan/models/hr_payroll.py
new file mode 100644
index 0000000..7e2b645
--- /dev/null
+++ b/ohrms_loan/models/hr_payroll.py
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+import time
+import babel
+from odoo import models, fields, api, tools, _
+from datetime import datetime
+
+
+class HrPayslipInput(models.Model):
+ _inherit = 'hr.payslip.input'
+
+ loan_line_id = fields.Many2one('hr.loan.line', string="Loan Installment", help="Loan installment")
+
+
+class HrPayslip(models.Model):
+ _inherit = 'hr.payslip'
+
+ @api.onchange('employee_id', 'date_from', 'date_to')
+ def onchange_employee(self):
+ if (not self.employee_id) or (not self.date_from) or (not self.date_to):
+ return
+
+ employee = self.employee_id
+ date_from = self.date_from
+ date_to = self.date_to
+ contract_ids = []
+
+ ttyme = datetime.fromtimestamp(time.mktime(time.strptime(str(date_from), "%Y-%m-%d")))
+ locale = self.env.context.get('lang') or 'en_US'
+ self.name = _('Salary Slip of %s for %s') % (
+ employee.name, tools.ustr(babel.dates.format_date(date=ttyme, format='MMMM-y', locale=locale)))
+ self.company_id = employee.company_id
+
+ if not self.env.context.get('contract') or not self.contract_id:
+ contract_ids = self.get_contract(employee, date_from, date_to)
+ if not contract_ids:
+ return
+ self.contract_id = self.env['hr.contract'].browse(contract_ids[0])
+
+ if not self.contract_id.struct_id:
+ return
+ self.struct_id = self.contract_id.struct_id
+
+ # computation of the salary input
+ contracts = self.env['hr.contract'].browse(contract_ids)
+ worked_days_line_ids = self.get_worked_day_lines(contracts, date_from, date_to)
+ worked_days_lines = self.worked_days_line_ids.browse([])
+ for r in worked_days_line_ids:
+ worked_days_lines += worked_days_lines.new(r)
+ self.worked_days_line_ids = worked_days_lines
+ if contracts:
+ input_line_ids = self.get_inputs(contracts, date_from, date_to)
+ input_lines = self.input_line_ids.browse([])
+ for r in input_line_ids:
+ input_lines += input_lines.new(r)
+ self.input_line_ids = input_lines
+ return
+
+ def get_inputs(self, contract_ids, date_from, date_to):
+ """This Compute the other inputs to employee payslip.
+ """
+ res = super(HrPayslip, self).get_inputs(contract_ids, date_from, date_to)
+ contract_obj = self.env['hr.contract']
+ emp_id = contract_obj.browse(contract_ids[0].id).employee_id
+ lon_obj = self.env['hr.loan'].search([('employee_id', '=', emp_id.id), ('state', '=', 'approve')])
+ for loan in lon_obj:
+ for loan_line in loan.loan_lines:
+ if date_from <= loan_line.date <= date_to and not loan_line.paid:
+ for result in res:
+ if result.get('code') == 'LO':
+ result['amount'] = loan_line.amount
+ result['loan_line_id'] = loan_line.id
+ return res
+
+ def action_payslip_done(self):
+ for line in self.input_line_ids:
+ if line.loan_line_id:
+ line.loan_line_id.paid = True
+ line.loan_line_id.loan_id._compute_loan_amount()
+ return super(HrPayslip, self).action_payslip_done()