[MIG] hr_payroll_account: Migrate to new API (code + tests)
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
{
|
||||
'name': 'Payroll Accounting',
|
||||
'version': '1.0',
|
||||
'category': 'Human Resources',
|
||||
'description': """
|
||||
Generic Payroll system Integrated with Accounting.
|
||||
@@ -12,14 +11,8 @@ Generic Payroll system Integrated with Accounting.
|
||||
* Payment Encoding
|
||||
* Company Contribution Management
|
||||
""",
|
||||
'depends': [
|
||||
'hr_payroll',
|
||||
'account',
|
||||
'hr_expense'
|
||||
],
|
||||
'depends': ['hr_payroll', 'account', 'hr_expense'],
|
||||
'data': ['views/hr_payroll_account_views.xml'],
|
||||
'demo': ['data/hr_payroll_account_demo.xml'],
|
||||
'test': ['../account/test/account_minimal_test.xml', 'test/hr_payroll_account.yml'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'test': ['../account/test/account_minimal_test.xml'],
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<odoo>
|
||||
<record id="hr_payroll.hr_employee_payroll" model="hr.employee">
|
||||
<field name="address_home_id" ref="base.res_partner_main2"/>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,110 +1,76 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import time
|
||||
from datetime import date, datetime, timedelta
|
||||
|
||||
from openerp import api
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools import float_compare, float_is_zero
|
||||
from openerp.tools.translate import _
|
||||
from openerp.exceptions import UserError
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import float_compare, float_is_zero
|
||||
|
||||
class hr_payslip_line(osv.osv):
|
||||
'''
|
||||
Payslip Line
|
||||
'''
|
||||
|
||||
class HrPayslipLine(models.Model):
|
||||
_inherit = 'hr.payslip.line'
|
||||
|
||||
def _get_partner_id(self, cr, uid, payslip_line, credit_account, context=None):
|
||||
def _get_partner_id(self, credit_account):
|
||||
"""
|
||||
Get partner_id of slip line to use in account_move_line
|
||||
"""
|
||||
# use partner of salary rule or fallback on employee's address
|
||||
partner_id = payslip_line.salary_rule_id.register_id.partner_id.id or \
|
||||
payslip_line.slip_id.employee_id.address_home_id.id
|
||||
register_partner_id = self.salary_rule_id.register_id.partner_id
|
||||
partner_id = register_partner_id.id or self.slip_id.employee_id.address_home_id.id
|
||||
if credit_account:
|
||||
if payslip_line.salary_rule_id.register_id.partner_id or \
|
||||
payslip_line.salary_rule_id.account_credit.internal_type in ('receivable', 'payable'):
|
||||
if register_partner_id or self.salary_rule_id.account_credit.internal_type in ('receivable', 'payable'):
|
||||
return partner_id
|
||||
else:
|
||||
if payslip_line.salary_rule_id.register_id.partner_id or \
|
||||
payslip_line.salary_rule_id.account_debit.internal_type in ('receivable', 'payable'):
|
||||
if register_partner_id or self.salary_rule_id.account_debit.internal_type in ('receivable', 'payable'):
|
||||
return partner_id
|
||||
return False
|
||||
|
||||
|
||||
class hr_payslip(osv.osv):
|
||||
'''
|
||||
Pay Slip
|
||||
'''
|
||||
class HrPayslip(models.Model):
|
||||
_inherit = 'hr.payslip'
|
||||
_description = 'Pay Slip'
|
||||
|
||||
_columns = {
|
||||
'date': fields.date('Date Account', states={'draft': [('readonly', False)]}, readonly=True, help="Keep empty to use the period of the validation(Payslip) date."),
|
||||
'journal_id': fields.many2one('account.journal', 'Salary Journal',states={'draft': [('readonly', False)]}, readonly=True, required=True),
|
||||
'move_id': fields.many2one('account.move', 'Accounting Entry', readonly=True, copy=False),
|
||||
}
|
||||
date = fields.Date('Date Account', states={'draft': [('readonly', False)]}, readonly=True,
|
||||
help="Keep empty to use the period of the validation(Payslip) date.")
|
||||
journal_id = fields.Many2one('account.journal', 'Salary Journal', readonly=True, required=True,
|
||||
states={'draft': [('readonly', False)]}, default=lambda self: self.env['account.journal'].search([('type', '=', 'general')], limit=1))
|
||||
move_id = fields.Many2one('account.move', 'Accounting Entry', readonly=True, copy=False)
|
||||
|
||||
def _get_default_journal(self, cr, uid, context=None):
|
||||
journal_obj = self.pool.get('account.journal')
|
||||
res = journal_obj.search(cr, uid, [('type', '=', 'general')])
|
||||
if res:
|
||||
return res[0]
|
||||
return False
|
||||
|
||||
_defaults = {
|
||||
'journal_id': _get_default_journal,
|
||||
}
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if 'journal_id' in context:
|
||||
vals.update({'journal_id': context.get('journal_id')})
|
||||
return super(hr_payslip, self).create(cr, uid, vals, context=context)
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if 'journal_id' in self.env.context:
|
||||
vals['journal_id'] = self.env.context.get('journal_id')
|
||||
return super(HrPayslip, self).create(vals)
|
||||
|
||||
@api.onchange('contract_id')
|
||||
def onchange_contract(self):
|
||||
super(hr_payslip, self).onchange_contract()
|
||||
self.journal_id = self.contract_id and self.contract_id.journal_id.id or (not self.contract_id and self._get_default_journal())
|
||||
return
|
||||
super(HrPayslip, self).onchange_contract()
|
||||
self.journal_id = self.contract_id.journal_id.id or (not self.contract_id and self.default_get(['journal_id'])['journal_id'])
|
||||
|
||||
def cancel_sheet(self, cr, uid, ids, context=None):
|
||||
move_pool = self.pool.get('account.move')
|
||||
move_ids = []
|
||||
move_to_cancel = []
|
||||
for slip in self.browse(cr, uid, ids, context=context):
|
||||
if slip.move_id:
|
||||
move_ids.append(slip.move_id.id)
|
||||
if slip.move_id.state == 'posted':
|
||||
move_to_cancel.append(slip.move_id.id)
|
||||
move_pool.button_cancel(cr, uid, move_to_cancel, context=context)
|
||||
move_pool.unlink(cr, uid, move_ids, context=context)
|
||||
return super(hr_payslip, self).cancel_sheet(cr, uid, ids, context=context)
|
||||
@api.multi
|
||||
def cancel_sheet(self):
|
||||
moves = self.mapped('move_id')
|
||||
moves.filtered(lambda x: x.state == 'posted').button_cancel()
|
||||
moves.unlink()
|
||||
return super(HrPayslip, self).cancel_sheet()
|
||||
|
||||
def process_sheet(self, cr, uid, ids, context=None):
|
||||
move_pool = self.pool.get('account.move')
|
||||
hr_payslip_line_pool = self.pool['hr.payslip.line']
|
||||
precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Payroll')
|
||||
timenow = time.strftime('%Y-%m-%d')
|
||||
@api.multi
|
||||
def process_sheet(self):
|
||||
precision = self.env['decimal.precision'].precision_get('Payroll')
|
||||
today = fields.Date.today()
|
||||
|
||||
for slip in self.browse(cr, uid, ids, context=context):
|
||||
for slip in self:
|
||||
line_ids = []
|
||||
debit_sum = 0.0
|
||||
credit_sum = 0.0
|
||||
date = timenow
|
||||
|
||||
name = _('Payslip of %s') % (slip.employee_id.name)
|
||||
move = {
|
||||
move_dict = {
|
||||
'narration': name,
|
||||
'ref': slip.number,
|
||||
'journal_id': slip.journal_id.id,
|
||||
'date': date,
|
||||
'date': today,
|
||||
}
|
||||
for line in slip.details_by_salary_rule_category:
|
||||
amt = slip.credit_note and -line.total or line.total
|
||||
if float_is_zero(amt, precision_digits=precision):
|
||||
amount = slip.credit_note and -line.total or line.total
|
||||
if float_is_zero(amount, precision_digits=precision):
|
||||
continue
|
||||
debit_account_id = line.salary_rule_id.account_debit.id
|
||||
credit_account_id = line.salary_rule_id.account_credit.id
|
||||
@@ -112,14 +78,14 @@ class hr_payslip(osv.osv):
|
||||
if debit_account_id:
|
||||
debit_line = (0, 0, {
|
||||
'name': line.name,
|
||||
'partner_id': hr_payslip_line_pool._get_partner_id(cr, uid, line, credit_account=False, context=context),
|
||||
'partner_id': line._get_partner_id(credit_account=False),
|
||||
'account_id': debit_account_id,
|
||||
'journal_id': slip.journal_id.id,
|
||||
'date': date,
|
||||
'debit': amt > 0.0 and amt or 0.0,
|
||||
'credit': amt < 0.0 and -amt or 0.0,
|
||||
'analytic_account_id': line.salary_rule_id.analytic_account_id and line.salary_rule_id.analytic_account_id.id or False,
|
||||
'tax_line_id': line.salary_rule_id.account_tax_id and line.salary_rule_id.account_tax_id.id or False,
|
||||
'date': today,
|
||||
'debit': amount > 0.0 and amount or 0.0,
|
||||
'credit': amount < 0.0 and -amount or 0.0,
|
||||
'analytic_account_id': line.salary_rule_id.analytic_account_id.id,
|
||||
'tax_line_id': line.salary_rule_id.account_tax_id.id,
|
||||
})
|
||||
line_ids.append(debit_line)
|
||||
debit_sum += debit_line[2]['debit'] - debit_line[2]['credit']
|
||||
@@ -127,14 +93,14 @@ class hr_payslip(osv.osv):
|
||||
if credit_account_id:
|
||||
credit_line = (0, 0, {
|
||||
'name': line.name,
|
||||
'partner_id': hr_payslip_line_pool._get_partner_id(cr, uid, line, credit_account=True, context=context),
|
||||
'partner_id': line._get_partner_id(credit_account=True),
|
||||
'account_id': credit_account_id,
|
||||
'journal_id': slip.journal_id.id,
|
||||
'date': date,
|
||||
'debit': amt < 0.0 and -amt or 0.0,
|
||||
'credit': amt > 0.0 and amt or 0.0,
|
||||
'analytic_account_id': line.salary_rule_id.analytic_account_id and line.salary_rule_id.analytic_account_id.id or False,
|
||||
'tax_line_id': line.salary_rule_id.account_tax_id and line.salary_rule_id.account_tax_id.id or False,
|
||||
'date': today,
|
||||
'debit': amount < 0.0 and -amount or 0.0,
|
||||
'credit': amount > 0.0 and amount or 0.0,
|
||||
'analytic_account_id': line.salary_rule_id.analytic_account_id.id,
|
||||
'tax_line_id': line.salary_rule_id.account_tax_id.id,
|
||||
})
|
||||
line_ids.append(credit_line)
|
||||
credit_sum += credit_line[2]['credit'] - credit_line[2]['debit']
|
||||
@@ -145,11 +111,11 @@ class hr_payslip(osv.osv):
|
||||
raise UserError(_('The Expense Journal "%s" has not properly configured the Credit Account!') % (slip.journal_id.name))
|
||||
adjust_credit = (0, 0, {
|
||||
'name': _('Adjustment Entry'),
|
||||
'date': timenow,
|
||||
'date': today,
|
||||
'partner_id': False,
|
||||
'account_id': acc_id,
|
||||
'journal_id': slip.journal_id.id,
|
||||
'date': date,
|
||||
'date': today,
|
||||
'debit': 0.0,
|
||||
'credit': debit_sum - credit_sum,
|
||||
})
|
||||
@@ -164,52 +130,36 @@ class hr_payslip(osv.osv):
|
||||
'partner_id': False,
|
||||
'account_id': acc_id,
|
||||
'journal_id': slip.journal_id.id,
|
||||
'date': date,
|
||||
'date': today,
|
||||
'debit': credit_sum - debit_sum,
|
||||
'credit': 0.0,
|
||||
})
|
||||
line_ids.append(adjust_debit)
|
||||
|
||||
move.update({'line_ids': line_ids})
|
||||
move_id = move_pool.create(cr, uid, move, context=context)
|
||||
self.write(cr, uid, [slip.id], {'move_id': move_id, 'date' : date}, context=context)
|
||||
move_pool.post(cr, uid, [move_id], context=context)
|
||||
return super(hr_payslip, self).process_sheet(cr, uid, [slip.id], context=context)
|
||||
move_dict['line_ids'] = line_ids
|
||||
move = self.env['account.move'].create(move_dict)
|
||||
slip.write({'move_id': move.id, 'date': today})
|
||||
move.post()
|
||||
return super(HrPayslip, self).process_sheet()
|
||||
|
||||
|
||||
class hr_salary_rule(osv.osv):
|
||||
class HrSalaryRule(models.Model):
|
||||
_inherit = 'hr.salary.rule'
|
||||
_columns = {
|
||||
'analytic_account_id':fields.many2one('account.analytic.account', 'Analytic Account'),
|
||||
'account_tax_id':fields.many2one('account.tax', 'Tax'),
|
||||
'account_debit': fields.many2one('account.account', 'Debit Account', domain=[('deprecated', '=', False)]),
|
||||
'account_credit': fields.many2one('account.account', 'Credit Account', domain=[('deprecated', '=', False)]),
|
||||
}
|
||||
|
||||
class hr_contract(osv.osv):
|
||||
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account')
|
||||
account_tax_id = fields.Many2one('account.tax', 'Tax')
|
||||
account_debit = fields.Many2one('account.account', 'Debit Account', domain=[('deprecated', '=', False)])
|
||||
account_credit = fields.Many2one('account.account', 'Credit Account', domain=[('deprecated', '=', False)])
|
||||
|
||||
class HrContract(models.Model):
|
||||
_inherit = 'hr.contract'
|
||||
_description = 'Employee Contract'
|
||||
_columns = {
|
||||
'analytic_account_id':fields.many2one('account.analytic.account', 'Analytic Account'),
|
||||
'journal_id': fields.many2one('account.journal', 'Salary Journal'),
|
||||
}
|
||||
|
||||
class hr_payslip_run(osv.osv):
|
||||
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account')
|
||||
journal_id = fields.Many2one('account.journal', 'Salary Journal')
|
||||
|
||||
class HrPayslipRun(models.Model):
|
||||
_inherit = 'hr.payslip.run'
|
||||
_description = 'Payslip Run'
|
||||
_columns = {
|
||||
'journal_id': fields.many2one('account.journal', 'Salary Journal', states={'draft': [('readonly', False)]}, readonly=True, required=True),
|
||||
}
|
||||
|
||||
def _get_default_journal(self, cr, uid, context=None):
|
||||
journal_obj = self.pool.get('account.journal')
|
||||
res = journal_obj.search(cr, uid, [('type', '=', 'general')])
|
||||
if res:
|
||||
return res[0]
|
||||
return False
|
||||
|
||||
_defaults = {
|
||||
'journal_id': _get_default_journal,
|
||||
}
|
||||
journal_id = fields.Many2one('account.journal', 'Salary Journal', states={'draft': [('readonly', False)]}, readonly=True,
|
||||
required=True, default=lambda self: self.env['account.journal'].search([('type', '=', 'general')], limit=1))
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
-
|
||||
I test the "Payslip" in order to check the hr_payroll_account module in OpenERP.
|
||||
-
|
||||
I create a bank record.
|
||||
-
|
||||
!record {model: res.partner.bank, id: res_partner_bank_0}:
|
||||
acc_number: '001-9876543-21'
|
||||
partner_id: base.res_partner_12
|
||||
acc_type: bank
|
||||
bank_id: base.res_bank_1
|
||||
-
|
||||
I create a new employee "John".
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_john}:
|
||||
address_home_id: base.res_partner_address_2
|
||||
address_id: base.res_partner_address_12
|
||||
birthday: '1984-05-01'
|
||||
children: 0.0
|
||||
country_id: base.in
|
||||
department_id: hr.dep_rd
|
||||
gender: male
|
||||
marital: single
|
||||
name: John
|
||||
bank_account_id: res_partner_bank_0
|
||||
vehicle_distance: 0.0
|
||||
-
|
||||
I create a salary structure for 'Software Developer'.
|
||||
-
|
||||
!record {model: hr.payroll.structure, id: hr_payroll_structure_softwaredeveloper}:
|
||||
name: Salary Structure for Software Developer
|
||||
code: SD
|
||||
company_id: base.main_company
|
||||
parent_id: hr_payroll.structure_base
|
||||
rule_ids:
|
||||
- hr_payroll.hr_salary_rule_houserentallowance1
|
||||
- hr_payroll.hr_salary_rule_convanceallowance1
|
||||
- hr_payroll.hr_salary_rule_professionaltax1
|
||||
- hr_payroll.hr_salary_rule_providentfund1
|
||||
- hr_payroll.hr_salary_rule_meal_voucher
|
||||
- hr_payroll.hr_salary_rule_sales_commission
|
||||
-
|
||||
I create a contract for "John".
|
||||
-
|
||||
!record {model: hr.contract, id: hr_contract_john}:
|
||||
date_end: !eval "(datetime.now() + timedelta(days=365)).strftime('%Y-%m-%d')"
|
||||
date_start: !eval time.strftime('%Y-%m-%d')
|
||||
name: Contract for John
|
||||
wage: 5000.0
|
||||
type_id: hr_contract.hr_contract_type_emp
|
||||
employee_id: hr_employee_john
|
||||
struct_id: hr_payroll_structure_softwaredeveloper
|
||||
working_hours: resource.timesheet_group1
|
||||
journal_id: expenses_journal
|
||||
-
|
||||
I create a Payslip.
|
||||
-
|
||||
!record {model: hr.payslip, id: hr_payslip_0}:
|
||||
employee_id: hr_employee_john
|
||||
journal_id: expenses_journal
|
||||
|
||||
-
|
||||
The selection of an employee fills the contract, structure, worked days and input data fields.
|
||||
-
|
||||
!python {model: hr.payslip}: |
|
||||
import time
|
||||
from datetime import datetime
|
||||
from dateutil import relativedelta
|
||||
date_from = time.strftime('%Y-%m-01')
|
||||
worked_days_obj = self.pool.get('hr.payslip.worked_days')
|
||||
date_to = str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10]
|
||||
res = self.onchange_employee_id(cr, uid, [], date_from, date_to, ref("hr_employee_john"), False, None)
|
||||
vals = {
|
||||
'struct_id': res['value']['struct_id'],
|
||||
'contract_id': res['value']['contract_id'],
|
||||
'name': res['value']['name'],
|
||||
}
|
||||
vals['worked_days_line_ids'] = [(0,0,i) for i in res['value']['worked_days_line_ids']]
|
||||
vals['input_line_ids'] = [(0,0,i) for i in res['value']['input_line_ids']]
|
||||
vals.update({'contract_id': ref('hr_contract_john')})
|
||||
self.write(cr, uid, ref("hr_payslip_0"), vals)
|
||||
-
|
||||
I assign the amount to Input data.
|
||||
-
|
||||
!python {model: hr.payslip.input}: |
|
||||
ids = self.search(cr, uid, [('payslip_id', '=', ref("hr_payslip_0"))])
|
||||
self.write(cr, uid, ids, {'amount': 5.0})
|
||||
-
|
||||
I verify the payslip is in draft state.
|
||||
-
|
||||
!python {model: hr.payslip}: |
|
||||
payslip_brw=self.browse(cr, uid, ref("hr_payslip_0"))
|
||||
assert(payslip_brw.state == 'draft'), 'State not changed!'
|
||||
-
|
||||
I click on "Compute Sheet" button.
|
||||
-
|
||||
!python {model: hr.payslip}: |
|
||||
self.compute_sheet(cr, uid, [ref("hr_payslip_0")], {"lang": "en_US", "tz": False,
|
||||
"active_model": "ir.ui.menu", "department_id": False, "active_ids": [ref("hr_payroll.menu_department_tree")],
|
||||
"section_id": False, "active_id": ref("hr_payroll.menu_department_tree"),
|
||||
})
|
||||
-
|
||||
I want to check cancel button. So I first cancel the sheet then make it set to draft.
|
||||
-
|
||||
!python {model: hr.payslip}: |
|
||||
self.cancel_sheet(cr, uid, [ref("hr_payslip_0")], None)
|
||||
self.signal_workflow(cr, uid, [ref("hr_payslip_0")], 'draft')
|
||||
-
|
||||
Then I click on the "Confirm" button.
|
||||
-
|
||||
!workflow {model: hr.payslip, action: hr_verify_sheet, ref: hr_payslip_0}
|
||||
-
|
||||
I verify that the Accounting Entries are created.
|
||||
-
|
||||
!python {model: hr.payslip}: |
|
||||
payslip = self.browse(cr, uid, ref("hr_payslip_0"))
|
||||
assert payslip.move_id, "Accounting Entries has not been created"
|
||||
-
|
||||
I verify that the payslip is in done state.
|
||||
-
|
||||
!python {model: hr.payslip}: |
|
||||
payslip_brw=self.browse(cr, uid, ref("hr_payslip_0"))
|
||||
assert(payslip_brw.state == 'done'), 'State not changed!'
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import test_hr_payroll_account
|
||||
@@ -0,0 +1,121 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import time
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from dateutil import relativedelta
|
||||
from odoo import fields, tools
|
||||
|
||||
from openerp.addons.account.tests.account_test_classes import AccountingTestCase
|
||||
from odoo.modules.module import get_module_resource
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
class TestHrPayrollAccount(common.TransactionCase):
|
||||
|
||||
def _load(self, module, *args):
|
||||
tools.convert_file(self.cr, 'hr_payroll_account',
|
||||
get_module_resource(module, *args), {}, 'init', False, 'test', self.registry._assertion_report)
|
||||
|
||||
def setUp(self):
|
||||
super(TestHrPayrollAccount, self).setUp()
|
||||
|
||||
self._load('account', 'test', 'account_minimal_test.xml')
|
||||
|
||||
self.payslip_action_id = self.ref('hr_payroll.menu_department_tree')
|
||||
|
||||
self.res_partner_bank = self.env['res.partner.bank'].create({
|
||||
'acc_number': '001-9876543-21',
|
||||
'partner_id': self.ref('base.res_partner_12'),
|
||||
'acc_type': 'bank',
|
||||
'bank_id': self.ref('base.res_bank_1'),
|
||||
})
|
||||
|
||||
self.hr_employee_john = self.env['hr.employee'].create({
|
||||
'address_home_id': self.ref('base.res_partner_address_2'),
|
||||
'address_id': self.ref('base.res_partner_address_12'),
|
||||
'birthday': '1984-05-01',
|
||||
'children': 0.0,
|
||||
'country_id': self.ref('base.in'),
|
||||
'department_id': self.ref('hr.dep_rd'),
|
||||
'gender': 'male',
|
||||
'marital': 'single',
|
||||
'name': 'John',
|
||||
'bank_account_id': self.res_partner_bank.bank_id.id,
|
||||
'vehicle_distance': 0.0,
|
||||
})
|
||||
|
||||
self.hr_structure_softwaredeveloper = self.env['hr.payroll.structure'].create({
|
||||
'name': 'Salary Structure for Software Developer',
|
||||
'code': 'SD',
|
||||
'company_id': self.ref('base.main_company'),
|
||||
'parent_id': self.ref('hr_payroll.structure_base'),
|
||||
'rule_ids': [(6, 0, [
|
||||
self.ref('hr_payroll.hr_salary_rule_houserentallowance1'),
|
||||
self.ref('hr_payroll.hr_salary_rule_convanceallowance1'),
|
||||
self.ref('hr_payroll.hr_salary_rule_professionaltax1'),
|
||||
self.ref('hr_payroll.hr_salary_rule_providentfund1'),
|
||||
self.ref('hr_payroll.hr_salary_rule_meal_voucher'),
|
||||
self.ref('hr_payroll.hr_salary_rule_sales_commission')
|
||||
])],
|
||||
})
|
||||
|
||||
# Create account journal.
|
||||
self.hr_contract_john = self.env['hr.contract'].create({
|
||||
'date_end': fields.Date.to_string(datetime.now() + timedelta(days=365)),
|
||||
'date_start': fields.Date.today(),
|
||||
'name': 'Contract for John',
|
||||
'wage': 5000.0,
|
||||
'type_id': self.ref('hr_contract.hr_contract_type_emp'),
|
||||
'employee_id': self.hr_employee_john.id,
|
||||
'struct_id': self.hr_structure_softwaredeveloper.id,
|
||||
'working_hours': self.ref('resource.timesheet_group1'),
|
||||
'journal_id': self.ref('hr_payroll_account.expenses_journal'),
|
||||
})
|
||||
|
||||
self.hr_payslip = self.env['hr.payslip'].create({
|
||||
'employee_id': self.hr_employee_john.id,
|
||||
'journal_id': self.ref('hr_payroll_account.expenses_journal'),
|
||||
})
|
||||
|
||||
def test_00_hr_payslip(self):
|
||||
""" checking the process of payslip. """
|
||||
|
||||
date_from = time.strftime('%Y-%m-01')
|
||||
date_to = str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10]
|
||||
res = self.hr_payslip.onchange_employee_id(date_from, date_to, self.hr_employee_john.id)
|
||||
vals = {
|
||||
'struct_id': res['value']['struct_id'],
|
||||
'contract_id': res['value']['contract_id'],
|
||||
'name': res['value']['name'],
|
||||
}
|
||||
vals['worked_days_line_ids'] = [(0, 0, i) for i in res['value']['worked_days_line_ids']]
|
||||
vals['input_line_ids'] = [(0, 0, i) for i in res['value']['input_line_ids']]
|
||||
vals.update({'contract_id': self.hr_contract_john.id})
|
||||
self.hr_payslip.write(vals)
|
||||
|
||||
# I assign the amount to Input data.
|
||||
payslip_input = self.env['hr.payslip.input'].search([('payslip_id', '=', self.hr_payslip.id)])
|
||||
payslip_input.write({'amount': 5.0})
|
||||
|
||||
# I verify the payslip is in draft state.
|
||||
self.assertEqual(self.hr_payslip.state, 'draft', 'State not changed!')
|
||||
|
||||
# I click on "Compute Sheet" button.
|
||||
context = {"lang": "en_US", "tz": False, "active_model": 'hr.payslip', "department_id": False, "active_ids": [self.payslip_action_id], "section_id": False, "active_id": self.payslip_action_id}
|
||||
self.hr_payslip.with_context(context).compute_sheet()
|
||||
|
||||
# I want to check cancel button. So I first cancel the sheet then make it set to draft.
|
||||
self.hr_payslip.cancel_sheet()
|
||||
self.assertEqual(self.hr_payslip.state, 'cancel', "Payslip is rejected.")
|
||||
self.hr_payslip.signal_workflow('draft')
|
||||
|
||||
# Confirm Payslip
|
||||
self.hr_payslip.signal_workflow('hr_verify_sheet')
|
||||
|
||||
# I verify that the Accounting Entries are created.
|
||||
self.assertTrue(self.hr_payslip.move_id, 'Accounting Entries has not been created')
|
||||
|
||||
# I verify that the payslip is in done state.
|
||||
self.assertEqual(self.hr_payslip.state, 'done', 'State not changed!')
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="view_hr_payslip_inherit_form">
|
||||
<field name="name">hr.payslip.inherit.form</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
@@ -85,6 +83,4 @@
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import osv
|
||||
from odoo import api, models
|
||||
|
||||
class hr_payslip_employees(osv.osv_memory):
|
||||
class HrPayslipEmployees(models.TransientModel):
|
||||
_inherit = 'hr.payslip.employees'
|
||||
|
||||
_inherit ='hr.payslip.employees'
|
||||
|
||||
def compute_sheet(self, cr, uid, ids, context=None):
|
||||
run_pool = self.pool.get('hr.payslip.run')
|
||||
if context is None:
|
||||
context = {}
|
||||
if context.get('active_id'):
|
||||
run_data = run_pool.read(cr, uid, context['active_id'], ['journal_id'])
|
||||
journal_id = run_data.get('journal_id')
|
||||
journal_id = journal_id and journal_id[0] or False
|
||||
if journal_id:
|
||||
context = dict(context, journal_id=journal_id)
|
||||
return super(hr_payslip_employees, self).compute_sheet(cr, uid, ids, context=context)
|
||||
@api.multi
|
||||
def compute_sheet(self):
|
||||
journal_id = False
|
||||
if self.env.context.get('active_id'):
|
||||
journal_id = self.env['hr.payslip.run'].browse(self.env.context.get['active_id']).journal_id.id
|
||||
return super(HrPayslipEmployees, self).with_context(journal_id=journal_id).compute_sheet()
|
||||
|
||||
Reference in New Issue
Block a user