diff --git a/employee_bonus_manager/__manifest__.py b/employee_bonus_manager/__manifest__.py index 6f6283eae..dd641fdb6 100644 --- a/employee_bonus_manager/__manifest__.py +++ b/employee_bonus_manager/__manifest__.py @@ -21,7 +21,7 @@ ############################################################################### { 'name': 'Employee Bonus', - 'version': '16.0.1.0.0', + 'version': '16.0.2.1.0', 'category': 'Human Resources', 'summary': 'This module will help you in managing the employee bonus.', 'description': """This module helps to manage the bonus for employees , the @@ -30,12 +30,14 @@ 'company': 'Cybrosys Techno Solutions', 'maintainer': 'Cybrosys Techno Solutions', 'website': "https://www.cybrosys.com", - 'depends': ['base', 'hr'], + 'depends': ['base', 'hr','account','hr_payroll_community'], 'data': [ 'security/employee_bonus_manager_groups.xml', 'security/bonus_request_security.xml', 'security/ir.model.access.csv', 'data/ir_sequence_data.xml', + 'data/hr_salary_rule_data.xml', + 'data/hr_payroll_structure_data.xml', 'views/bonus_request_views.xml', 'views/bonus_reason_views.xml', 'views/employee_bonus_manager_menus.xml' diff --git a/employee_bonus_manager/data/hr_payroll_structure_data.xml b/employee_bonus_manager/data/hr_payroll_structure_data.xml new file mode 100644 index 000000000..e22e17deb --- /dev/null +++ b/employee_bonus_manager/data/hr_payroll_structure_data.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/employee_bonus_manager/data/hr_salary_rule_data.xml b/employee_bonus_manager/data/hr_salary_rule_data.xml new file mode 100644 index 000000000..09af951b8 --- /dev/null +++ b/employee_bonus_manager/data/hr_salary_rule_data.xml @@ -0,0 +1,11 @@ + + + + Employee Bonus + BONUS + + + code + result = inputs.BONUS.amount + + \ No newline at end of file diff --git a/employee_bonus_manager/data/ir_sequence_data.xml b/employee_bonus_manager/data/ir_sequence_data.xml index 5882e9471..e0650aae8 100644 --- a/employee_bonus_manager/data/ir_sequence_data.xml +++ b/employee_bonus_manager/data/ir_sequence_data.xml @@ -1,6 +1,5 @@ - - - + + Bonus Request Sequence bonus.request @@ -8,4 +7,4 @@ 4 - + \ No newline at end of file diff --git a/employee_bonus_manager/doc/RELEASE_NOTES.md b/employee_bonus_manager/doc/RELEASE_NOTES.md index 17ade27bd..9f4b31b8b 100644 --- a/employee_bonus_manager/doc/RELEASE_NOTES.md +++ b/employee_bonus_manager/doc/RELEASE_NOTES.md @@ -5,3 +5,9 @@ #### ADD Initial Commit for Employee Bonus + +#### 27.0.2024 +#### Version 16.0.2.1.0 +#### UPDT + +Add functionality of calculate payslip based on the employee bonus \ No newline at end of file diff --git a/employee_bonus_manager/models/__init__.py b/employee_bonus_manager/models/__init__.py index 3b55cac74..b638b5aa3 100644 --- a/employee_bonus_manager/models/__init__.py +++ b/employee_bonus_manager/models/__init__.py @@ -21,3 +21,4 @@ ############################################################################### from . import bonus_reason from . import bonus_request +from . import hr_payslip diff --git a/employee_bonus_manager/models/bonus_reason.py b/employee_bonus_manager/models/bonus_reason.py index 059ac5efe..ef3360970 100644 --- a/employee_bonus_manager/models/bonus_reason.py +++ b/employee_bonus_manager/models/bonus_reason.py @@ -22,10 +22,11 @@ from odoo import fields, models + class BonusReason(models.Model): """ This class is used to create the bonus reasons. """ _name = "bonus.reason" _description = 'Bonus Reasons' name = fields.Char(string='Reason', required=True, - help='Reason to be added for the bonus requests.') + help='Reason to be added for the bonus requests.') \ No newline at end of file diff --git a/employee_bonus_manager/models/bonus_request.py b/employee_bonus_manager/models/bonus_request.py index 01fc757d7..95c3260cd 100644 --- a/employee_bonus_manager/models/bonus_request.py +++ b/employee_bonus_manager/models/bonus_request.py @@ -31,7 +31,7 @@ class BonusRequest(models.Model): override create function for generating sequence number for the new records of the model. action_confirm(self): - actions to perform when clicking on the 'Confirm' button. + actions to perform when clicking on the 'Submit' button. action_department_approve(self): actions to perform when clicking on the 'Approve by Department' button. @@ -42,18 +42,23 @@ class BonusRequest(models.Model): actions to perform when clicking on the 'Reject' button. action_reset_to_draft(self): actions to perform when clicking on the 'Reset to Draft' button. + action_post_journal_entry(self): + actions to create and post a journal entry for the bonus. + action_view_journal_items(self): + action to view the journal items for the bonus request. """ _name = 'bonus.request' _description = 'Bonus Request' _inherit = 'mail.thread' - _rec_name = 'reference_no' + _rec_name = 'reference' - reference_no = fields.Char(string='Reference Number', copy=False, - help='Sequence number for the bonus request.') + reference = fields.Char(string='Reference Number', copy=False, + help='Sequence number for the bonus request.') state = fields.Selection( - [('draft', 'Draft'), ('confirmed', 'Confirmed'), + [('draft', 'Draft'), ('submitted', 'Submitted'), ('department_approved', 'Department Approved'), - ('manager_approved', 'Manager Approved'), ('rejected', 'Rejected')], + ('manager_approved', 'Manager Approved'), ('accounting', 'Accounting Head Approved'), + ('posted', 'Posted'), ('rejected', 'Rejected')], string='State', default='draft', copy=False, tracking=True, help='State of the bonus request.') employee_id = fields.Many2one( @@ -63,8 +68,8 @@ class BonusRequest(models.Model): 'res.users', string='User', related='employee_id.user_id', help='The user of the employee(If any)') department_id = fields.Many2one('hr.department', string='Department', - related='employee_id.department_id', - help='The department of the employee.') + related='employee_id.department_id', + help='The department of the employee.') job_id = fields.Many2one( 'hr.job', string='Job', related='employee_id.job_id', help='Job of the employee') @@ -81,7 +86,7 @@ class BonusRequest(models.Model): bonus_amount = fields.Float(string='Bonus Amount', tracking=True, help='This amount will be given as the bonus.') currency_id = fields.Many2one( - 'res.currency', string='Company Currency', required=True, + 'res.currency', string='Company Currency', required=True, readonly=True, default=lambda self: self.env.user.company_id.currency_id, help='Company Currency') @@ -100,6 +105,21 @@ class BonusRequest(models.Model): hr_manager_id = fields.Many2one( 'res.users', string='Manager', readonly=True, copy=False, help='Name of the Manager, who approved the bonus request.') + journal_id = fields.Many2one('account.journal', string='Bonus Journal', + help='The Journal for bonus request', + company_dependent=True, required=False, + domain="[('type', '=', 'general')]") + move_id = fields.Many2one('account.move', string='Accounting Entry', + help='Accounting entry of bonus request', + readonly=True) + credit_account_id = fields.Many2one('account.account', + string='Credit Account', + help='The credit account for creating ' + 'journal entry') + debit_account_id = fields.Many2one('account.account', + string='Debit Account', + help='The debit account for creating ' + 'journal entry') @api.model def create(self, vals): @@ -109,21 +129,21 @@ class BonusRequest(models.Model): Returns: models.Model: the created records of 'bonus.request'. """ - if vals.get('reference_no', 'New') == 'New': - vals['reference_no'] = self.env['ir.sequence'].next_by_code( + if vals.get('reference', 'New') == 'New': + vals['reference'] = self.env['ir.sequence'].next_by_code( 'bonus.request') or 'New' res = super(BonusRequest, self).create(vals) return res def action_confirm(self): """ - Function for the 'Confirm' button to change the state to 'confirmed', + Function for the 'Submit' button to change the state to 'submitted', and update the confirmed user and date. """ self.write({ - 'state': 'confirmed', + 'state': 'submitted', 'confirmed_user_id': self._uid, - 'confirmed_date': fields.Datetime.today() + 'confirmed_date': fields.Date.today() }) def action_department_approve(self): @@ -135,18 +155,18 @@ class BonusRequest(models.Model): self.write({ 'state': 'department_approved', 'department_manager_id': self._uid, - 'department_approved_date': fields.Datetime.today() + 'department_approved_date': fields.Date.today() }) def action_manager_approve(self): """ Function for the 'Approve by Manager' button to change the state to - 'manager_approved', and update the HR manager and approved date & time. + 'manager_approved', and update the HR manager and approved date. """ self.write({ 'state': 'manager_approved', 'hr_manager_id': self._uid, - 'manager_approved_date': fields.Datetime.today() + 'manager_approved_date': fields.Date.today() }) def action_reject(self): @@ -169,3 +189,42 @@ class BonusRequest(models.Model): 'hr_manager_id': False, 'manager_approved_date': False }) + + def action_post_journal_entry(self): + """ Function for the 'Post Journal Entry' button to create and post a journal entry + for approved bonus request and change state to 'posted' """ + account_move = self.env['account.move'].create({ + 'ref': self.reference, + 'state': 'draft', + 'date': self.manager_approved_date, + 'journal_id': self.journal_id.id, + 'line_ids': [ + (0, 0, { + 'account_id': self.credit_account_id.id, + 'credit': self.bonus_amount, + 'name': self.employee_id.name + '-' + self.reference, + 'debit': 0.0, + }), + (0, 0, { + 'account_id': self.debit_account_id.id, + 'debit': self.bonus_amount, + 'name': self.employee_id.name + '-' + self.reference, + 'credit': 0.0, + }) + ] + }) + account_move.action_post() + self.write({ + 'move_id': account_move.id, + 'state': 'posted' + }) + + def action_view_journal_items(self): + """To view the journal items for the bonus request""" + return { + 'name': 'Journal Items', + 'type': 'ir.actions.act_window', + 'res_model': 'account.move', + 'view_mode': 'form', + 'res_id': self.move_id.id + } \ No newline at end of file diff --git a/employee_bonus_manager/models/hr_payslip.py b/employee_bonus_manager/models/hr_payslip.py new file mode 100644 index 000000000..d2d4564be --- /dev/null +++ b/employee_bonus_manager/models/hr_payslip.py @@ -0,0 +1,28 @@ +from odoo import api, fields, models + + +class HrPayslip(models.Model): + """ This class extends hr.payslip to include bonus amounts in payslip calculation. """ + _inherit = "hr.payslip" + + @api.onchange('employee_id', 'date_from', 'date_to', 'struct_id') + def _onchange_employee(self): + """ When changing employee, load bonus amount as other input """ + self.ensure_one() # Ensure single record for onchange + bonus_rule = self.env.ref('employee_bonus_manager.hr_salary_rule_bonus') + rules = self.struct_id.rule_ids.mapped('name') + if bonus_rule.name in rules: + bonus = self.env['bonus.request'].search([ + ('employee_id', '=', self.employee_id.id), + ('state', '=', 'posted'), + ('move_id.state', '=', 'posted'), + ('move_id.date', '>=', self.date_from), + ('move_id.date', '<=', self.date_to) + ]) + amount = sum(bonus.mapped('bonus_amount')) + self.input_line_ids = [(0, 0, { + 'name': 'Bonus', + 'code': 'BONUS', + 'contract_id': self.contract_id.id, + 'amount': amount, + })] diff --git a/employee_bonus_manager/views/bonus_reason_views.xml b/employee_bonus_manager/views/bonus_reason_views.xml index 1190a7f54..e0acf013b 100644 --- a/employee_bonus_manager/views/bonus_reason_views.xml +++ b/employee_bonus_manager/views/bonus_reason_views.xml @@ -10,8 +10,9 @@ + - + bonus.reason.view.form bonus.reason @@ -27,6 +28,7 @@ + Bonus Reasons diff --git a/employee_bonus_manager/views/bonus_request_views.xml b/employee_bonus_manager/views/bonus_request_views.xml index f61ba36d4..d1a0f153c 100644 --- a/employee_bonus_manager/views/bonus_request_views.xml +++ b/employee_bonus_manager/views/bonus_request_views.xml @@ -7,41 +7,59 @@
- -
+
+ +

- +

- +

- + - + @@ -52,6 +70,7 @@ + @@ -60,6 +79,21 @@ + + + + + + + + + + + +
@@ -69,17 +103,18 @@ - - - bonus.request.view.tree + + + + bonus.request.view.list bonus.request - - + @@ -101,13 +136,14 @@ + bonus.request.view.kanban bonus.request - - + + @@ -139,7 +175,7 @@
- +
@@ -152,6 +188,7 @@ + bonus.request.view.graph @@ -163,6 +200,7 @@ + bonus.request.view.pivot @@ -174,6 +212,7 @@ + bonus.request.view.calendar @@ -196,13 +235,14 @@ + bonus.request.view.search bonus.request - + @@ -225,18 +265,17 @@ - - - - - - - + + + + + + + + Bonus Requests @@ -249,6 +288,7 @@

+ Department Approval @@ -256,7 +296,7 @@ bonus.request tree,kanban,graph,pivot,calendar,form {'create': False} - [('state','=','confirmed')] + [('state', '=', 'submitted')]

@@ -264,6 +304,7 @@

+ Manager Approval @@ -271,7 +312,7 @@ bonus.request tree,kanban,graph,pivot,calendar,form {'create': False} - [('state','=','department_approved')] + [('state', '=', 'department_approved')]

@@ -279,4 +320,20 @@

+ + + + Accounting Head Approval + ir.actions.act_window + bonus.request + tree,kanban,graph,pivot,calendar,form + {'create': False} + [('state', '=', 'manager_approved')] + + +

+ No requests found for Accounting Head +

+
+
diff --git a/employee_bonus_manager/views/employee_bonus_manager_menus.xml b/employee_bonus_manager/views/employee_bonus_manager_menus.xml index c5ebcc432..ca3c23151 100644 --- a/employee_bonus_manager/views/employee_bonus_manager_menus.xml +++ b/employee_bonus_manager/views/employee_bonus_manager_menus.xml @@ -1,27 +1,29 @@ - - + - + + groups="employee_bonus_manager.employee_bonus_manager_department" sequence="2"/> + + + parent="employee_bonus_manager.employee_bonus_manager_config_menu_root" action="bonus_reason_action" + sequence="1"/>>