mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
Adding all from 11.0 https://github.com/hibou-io/odoo-hr-payroll
hr_payroll_holidays hr_payroll_input_name_report hr_payroll_input_report hr_payroll_payment hr_payroll_timesheet hr_payslip_line_date l10n_us_fl_hr_payroll l10n_us_hr_payroll l10n_us_mo_hr_payroll l10n_us_oh_hr_payroll l10n_us_va_hr_payroll
This commit is contained in:
3
hr_payroll_payment/__init__.py
Executable file
3
hr_payroll_payment/__init__.py
Executable file
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import hr_payroll_register_payment
|
||||
20
hr_payroll_payment/__manifest__.py
Executable file
20
hr_payroll_payment/__manifest__.py
Executable file
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
{
|
||||
'name': 'Payroll Payments',
|
||||
'author': 'Hibou Corp. <hello@hibou.io>',
|
||||
'version': '11.0.0.0.0',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 95,
|
||||
'summary': 'Register payments for Payroll Payslips',
|
||||
'description': """
|
||||
Adds the ability to register a payment on a payslip.
|
||||
""",
|
||||
'website': 'https://hibou.io/',
|
||||
'depends': ['hr_payroll_account'],
|
||||
'data': [
|
||||
'hr_payroll_register_payment.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': False,
|
||||
}
|
||||
124
hr_payroll_payment/hr_payroll_register_payment.py
Executable file
124
hr_payroll_payment/hr_payroll_register_payment.py
Executable file
@@ -0,0 +1,124 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class HrPayslip(models.Model):
|
||||
_inherit = 'hr.payslip'
|
||||
|
||||
@api.multi
|
||||
@api.depends('move_id', 'move_id.line_ids.full_reconcile_id')
|
||||
def _is_paid(self):
|
||||
for payslip in self:
|
||||
payslip.is_paid = (
|
||||
payslip.move_id and len(payslip.move_id.line_ids.filtered(lambda l: (
|
||||
l.partner_id.id == payslip.employee_id.address_home_id.id and
|
||||
l.account_id.internal_type == 'payable' and
|
||||
not l.reconciled
|
||||
))) == 0
|
||||
)
|
||||
|
||||
is_paid = fields.Boolean(string="Has been Paid", compute='_is_paid', store=True)
|
||||
|
||||
|
||||
class HrPayrollRegisterPaymentWizard(models.TransientModel):
|
||||
|
||||
_name = "hr.payroll.register.payment.wizard"
|
||||
_description = "Hr Payroll Register Payment wizard"
|
||||
|
||||
@api.model
|
||||
def _default_partner_id(self):
|
||||
context = dict(self._context or {})
|
||||
active_ids = context.get('active_ids', [])
|
||||
payslip = self.env['hr.payslip'].browse(active_ids)
|
||||
return payslip.employee_id.address_home_id.id
|
||||
|
||||
@api.model
|
||||
def _default_amount(self):
|
||||
context = dict(self._context or {})
|
||||
active_ids = context.get('active_ids', [])
|
||||
payslip = self.env['hr.payslip'].browse(active_ids)
|
||||
amount = 0.0
|
||||
for line in payslip.move_id.line_ids:
|
||||
if line.account_id.internal_type == 'payable' and line.partner_id.id == payslip.employee_id.address_home_id.id:
|
||||
amount += abs(line.balance)
|
||||
return amount
|
||||
|
||||
@api.model
|
||||
def _default_communication(self):
|
||||
context = dict(self._context or {})
|
||||
active_ids = context.get('active_ids', [])
|
||||
payslip = self.env['hr.payslip'].browse(active_ids)
|
||||
return payslip.number
|
||||
|
||||
partner_id = fields.Many2one('res.partner', string='Partner', required=True, default=_default_partner_id)
|
||||
journal_id = fields.Many2one('account.journal', string='Payment Method', required=True, domain=[('type', 'in', ('bank', 'cash'))])
|
||||
company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', readonly=True, required=True)
|
||||
payment_method_id = fields.Many2one('account.payment.method', string='Payment Type', required=True)
|
||||
amount = fields.Monetary(string='Payment Amount', required=True, default=_default_amount)
|
||||
currency_id = fields.Many2one('res.currency', string='Currency', required=True, default=lambda self: self.env.user.company_id.currency_id)
|
||||
payment_date = fields.Date(string='Payment Date', default=fields.Date.context_today, required=True)
|
||||
communication = fields.Char(string='Memo', default=_default_communication)
|
||||
hide_payment_method = fields.Boolean(compute='_compute_hide_payment_method',
|
||||
help="Technical field used to hide the payment method if the selected journal has only one available which is 'manual'")
|
||||
|
||||
@api.one
|
||||
@api.constrains('amount')
|
||||
def _check_amount(self):
|
||||
if not self.amount > 0.0:
|
||||
raise ValidationError('The payment amount must be strictly positive.')
|
||||
|
||||
@api.one
|
||||
@api.depends('journal_id')
|
||||
def _compute_hide_payment_method(self):
|
||||
if not self.journal_id:
|
||||
self.hide_payment_method = True
|
||||
return
|
||||
journal_payment_methods = self.journal_id.outbound_payment_method_ids
|
||||
self.hide_payment_method = len(journal_payment_methods) == 1 and journal_payment_methods[0].code == 'manual'
|
||||
|
||||
@api.onchange('journal_id')
|
||||
def _onchange_journal(self):
|
||||
if self.journal_id:
|
||||
# Set default payment method (we consider the first to be the default one)
|
||||
payment_methods = self.journal_id.outbound_payment_method_ids
|
||||
self.payment_method_id = payment_methods and payment_methods[0] or False
|
||||
# Set payment method domain (restrict to methods enabled for the journal and to selected payment type)
|
||||
return {'domain': {'payment_method_id': [('payment_type', '=', 'outbound'), ('id', 'in', payment_methods.ids)]}}
|
||||
return {}
|
||||
|
||||
@api.multi
|
||||
def payroll_post_payment(self):
|
||||
self.ensure_one()
|
||||
context = dict(self._context or {})
|
||||
active_ids = context.get('active_ids', [])
|
||||
payslip = self.env['hr.payslip'].browse(active_ids)
|
||||
|
||||
# Create payment and post it
|
||||
payment = self.env['account.payment'].create({
|
||||
'partner_type': 'supplier',
|
||||
'payment_type': 'outbound',
|
||||
'partner_id': self.partner_id.id,
|
||||
'journal_id': self.journal_id.id,
|
||||
'company_id': self.company_id.id,
|
||||
'payment_method_id': self.payment_method_id.id,
|
||||
'amount': self.amount,
|
||||
'currency_id': self.currency_id.id,
|
||||
'payment_date': self.payment_date,
|
||||
'communication': self.communication
|
||||
})
|
||||
payment.post()
|
||||
|
||||
# Reconcile the payment and the payroll, i.e. lookup on the payable account move lines
|
||||
account_move_lines_to_reconcile = self.env['account.move.line']
|
||||
for line in payment.move_line_ids:
|
||||
if line.account_id.internal_type == 'payable':
|
||||
account_move_lines_to_reconcile |= line
|
||||
for line in payslip.move_id.line_ids:
|
||||
if line.account_id.internal_type == 'payable' and line.partner_id.id == self.partner_id.id:
|
||||
account_move_lines_to_reconcile |= line
|
||||
|
||||
account_move_lines_to_reconcile.reconcile()
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
82
hr_payroll_payment/hr_payroll_register_payment.xml
Executable file
82
hr_payroll_payment/hr_payroll_register_payment.xml
Executable file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Add Filter for "Needs Payment" -->
|
||||
<record id="payslip_filter_needs_payment" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.select</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
<field name="priority">20</field>
|
||||
<field name="inherit_id" ref="hr_payroll.view_hr_payslip_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//filter[last()]" position="after">
|
||||
<filter string="Needs Payment" domain="[('is_paid', '=', False)]" help="Needs Payment Slip"/>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Wizard view to register payment -->
|
||||
<record id="hr_payroll_register_payment_view_form" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.register.payment.wizard.form</field>
|
||||
<field name="model">hr.payroll.register.payment.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Register Payment">
|
||||
<sheet>
|
||||
<field name="id" invisible="1"/>
|
||||
<div class="oe_title">
|
||||
<h1>Draft Payment</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="partner_id" required="1" context="{'default_is_company': True, 'default_supplier': True}"/>
|
||||
<field name="journal_id" widget="selection"/>
|
||||
<field name="hide_payment_method" invisible="1"/>
|
||||
<field name="payment_method_id" widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)]}"/>
|
||||
<label for="amount"/>
|
||||
<div name="amount_div" class="o_row">
|
||||
<field name="amount"/>
|
||||
<field name="currency_id" options="{'no_create': True, 'no_open': True}" groups="base.group_multi_currency"/>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<field name="payment_date"/>
|
||||
<field name="communication"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button string='Validate' name="payroll_post_payment" type="object" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-default" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Action to launch Wizard for register payment -->
|
||||
<record id="hr_payroll_register_payment_wizard_action" model="ir.actions.act_window">
|
||||
<field name="name">Register Payment</field>
|
||||
<field name="res_model">hr.payroll.register.payment.wizard</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="hr_payroll_register_payment_view_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'default_payment_type': 'inbound'}</field>
|
||||
<field name="domain">[('partner_type', '=', 'customer')]</field>
|
||||
</record>
|
||||
|
||||
<!-- Button on Payslip to launch Wizard for register payment -->
|
||||
<record id="hr_payslip_form" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.form</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
<field name="inherit_id" ref="hr_payroll.view_hr_payslip_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='refund_sheet']" position="before">
|
||||
<button name="%(hr_payroll_payment.hr_payroll_register_payment_wizard_action)d" type="action" string="Register Payment" class="oe_highlight" attrs="{'invisible': ['|', ('state', '!=', 'done'), ('is_paid', '=', True)]}" groups="account.group_account_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='credit_note']" position="after">
|
||||
<field name="is_paid" readonly="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user