[MERGE] hr_payroll_account: Migrate to new API

This commit is contained in:
Yannick Tivisse
2016-07-29 10:00:11 +02:00
12 changed files with 313 additions and 402 deletions
-15
View File
@@ -579,21 +579,6 @@ class HrPayslip(models.Model):
})
return res
# YTO TODO: employee_id and contract_id could be browse records
@api.multi
def onchange_contract_id(self, date_from, date_to, employee_id=False, contract_id=False):
# TODO it seems to be the mess in the onchanges
# we should have onchange_employee => onchange_contract => doing all the things
res = {
'value': {
'line_ids': [],
'name': '',
}
}
if not contract_id:
res['value'].update({'struct_id': False})
return self.with_context(contract=True).onchange_employee_id(date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id)
@api.onchange('employee_id', 'date_from')
def onchange_employee(self):
+1 -1
View File
@@ -1,5 +1,5 @@
#-*- coding:utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import hr_payroll_account
import models
import wizard
+4 -11
View File
@@ -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'
],
'data': ['hr_payroll_account_view.xml'],
'demo': ['hr_payroll_account_demo.xml'],
'test': ['../account/test/account_minimal_test.xml', 'test/hr_payroll_account.yml'],
'installable': True,
'auto_install': False,
'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'],
}
@@ -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,222 +0,0 @@
#-*- 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
class hr_payslip_line(osv.osv):
'''
Payslip Line
'''
_inherit = 'hr.payslip.line'
def _get_partner_id(self, cr, uid, payslip_line, credit_account, context=None):
"""
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
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'):
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'):
return partner_id
return False
class hr_payslip(osv.osv):
'''
Pay Slip
'''
_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),
}
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)
def onchange_contract_id(self, cr, uid, ids, date_from, date_to, employee_id=False, contract_id=False, context=None):
contract_obj = self.pool.get('hr.contract')
res = super(hr_payslip, self).onchange_contract_id(cr, uid, ids, date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id, context=context)
journal_id = contract_id and contract_obj.browse(cr, uid, contract_id, context=context).journal_id.id or (not contract_id and self._get_default_journal(cr, uid, context=None))
res['value'].update({'journal_id': journal_id})
return res
@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
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)
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')
for slip in self.browse(cr, uid, ids, context=context):
line_ids = []
debit_sum = 0.0
credit_sum = 0.0
date = timenow
name = _('Payslip of %s') % (slip.employee_id.name)
move = {
'narration': name,
'ref': slip.number,
'journal_id': slip.journal_id.id,
'date': date,
}
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):
continue
debit_account_id = line.salary_rule_id.account_debit.id
credit_account_id = line.salary_rule_id.account_credit.id
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),
'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,
})
line_ids.append(debit_line)
debit_sum += debit_line[2]['debit'] - debit_line[2]['credit']
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),
'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,
})
line_ids.append(credit_line)
credit_sum += credit_line[2]['credit'] - credit_line[2]['debit']
if float_compare(credit_sum, debit_sum, precision_digits=precision) == -1:
acc_id = slip.journal_id.default_credit_account_id.id
if not acc_id:
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,
'partner_id': False,
'account_id': acc_id,
'journal_id': slip.journal_id.id,
'date': date,
'debit': 0.0,
'credit': debit_sum - credit_sum,
})
line_ids.append(adjust_credit)
elif float_compare(debit_sum, credit_sum, precision_digits=precision) == -1:
acc_id = slip.journal_id.default_debit_account_id.id
if not acc_id:
raise UserError(_('The Expense Journal "%s" has not properly configured the Debit Account!') % (slip.journal_id.name))
adjust_debit = (0, 0, {
'name': _('Adjustment Entry'),
'partner_id': False,
'account_id': acc_id,
'journal_id': slip.journal_id.id,
'date': date,
'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)
class hr_salary_rule(osv.osv):
_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):
_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):
_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,
}
@@ -0,0 +1,4 @@
#-*- coding:utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import hr_payroll_account
@@ -0,0 +1,165 @@
#-*- coding:utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo.tools import float_compare, float_is_zero
class HrPayslipLine(models.Model):
_inherit = 'hr.payslip.line'
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
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 register_partner_id or self.salary_rule_id.account_credit.internal_type in ('receivable', 'payable'):
return partner_id
else:
if register_partner_id or self.salary_rule_id.account_debit.internal_type in ('receivable', 'payable'):
return partner_id
return False
class HrPayslip(models.Model):
_inherit = 'hr.payslip'
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)
@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(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'])
@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()
@api.multi
def process_sheet(self):
precision = self.env['decimal.precision'].precision_get('Payroll')
today = fields.Date.today()
for slip in self:
line_ids = []
debit_sum = 0.0
credit_sum = 0.0
name = _('Payslip of %s') % (slip.employee_id.name)
move_dict = {
'narration': name,
'ref': slip.number,
'journal_id': slip.journal_id.id,
'date': today,
}
for line in slip.details_by_salary_rule_category:
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
if debit_account_id:
debit_line = (0, 0, {
'name': line.name,
'partner_id': line._get_partner_id(credit_account=False),
'account_id': debit_account_id,
'journal_id': slip.journal_id.id,
'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']
if credit_account_id:
credit_line = (0, 0, {
'name': line.name,
'partner_id': line._get_partner_id(credit_account=True),
'account_id': credit_account_id,
'journal_id': slip.journal_id.id,
'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']
if float_compare(credit_sum, debit_sum, precision_digits=precision) == -1:
acc_id = slip.journal_id.default_credit_account_id.id
if not acc_id:
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': today,
'partner_id': False,
'account_id': acc_id,
'journal_id': slip.journal_id.id,
'date': today,
'debit': 0.0,
'credit': debit_sum - credit_sum,
})
line_ids.append(adjust_credit)
elif float_compare(debit_sum, credit_sum, precision_digits=precision) == -1:
acc_id = slip.journal_id.default_debit_account_id.id
if not acc_id:
raise UserError(_('The Expense Journal "%s" has not properly configured the Debit Account!') % (slip.journal_id.name))
adjust_debit = (0, 0, {
'name': _('Adjustment Entry'),
'partner_id': False,
'account_id': acc_id,
'journal_id': slip.journal_id.id,
'date': today,
'debit': credit_sum - debit_sum,
'credit': 0.0,
})
line_ids.append(adjust_debit)
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 HrSalaryRule(models.Model):
_inherit = 'hr.salary.rule'
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'
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'
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,124 +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']]
res_contract = self.onchange_contract_id(cr, uid, [ref('hr_payslip_0')], date_from, date_to, ref('hr_employee_john'), ref('hr_contract_john'), None)
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()