Add multi-company support hr_holidays_usability
Add modules hr_holidays_lunch_voucher and hr_holidays_lunch_voucher_natixis
This commit is contained in:
7
hr_holidays_lunch_voucher/__init__.py
Normal file
7
hr_holidays_lunch_voucher/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import company
|
||||
from . import hr_holidays
|
||||
from . import hr_employee
|
||||
from . import lunch_voucher_attribution
|
||||
from . import wizard
|
||||
28
hr_holidays_lunch_voucher/__openerp__.py
Normal file
28
hr_holidays_lunch_voucher/__openerp__.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
'name': 'HR Holidays Lunch Voucher',
|
||||
'version': '10.0.1.0.0',
|
||||
'category': 'Human Resources',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Manage lunch vouchers in holidays requests',
|
||||
'description': '',
|
||||
'author': 'Akretion',
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': ['hr_holidays_usability', 'purchase'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'security/lunch_voucher_security.xml',
|
||||
'product_data.xml',
|
||||
'company_view.xml',
|
||||
'wizard/lunch_voucher_purchase_view.xml',
|
||||
'lunch_voucher_attribution_view.xml',
|
||||
'hr_employee_view.xml',
|
||||
'hr_holidays_view.xml',
|
||||
'wizard/hr_holidays_post_view.xml',
|
||||
],
|
||||
'installable': True,
|
||||
}
|
||||
20
hr_holidays_lunch_voucher/company.py
Normal file
20
hr_holidays_lunch_voucher/company.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields
|
||||
import openerp.addons.decimal_precision as dp
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
lunch_voucher_product_id = fields.Many2one(
|
||||
'product.product', string='Lunch Voucher Product',
|
||||
ondelete='restrict')
|
||||
lunch_voucher_employer_price = fields.Float(
|
||||
'Lunch Voucher Employer Price', digits=dp.get_precision('Account'))
|
||||
|
||||
# Add constrain to check that lunch_voucher_employer_price is between
|
||||
# 50% and 60% of the price of lunch_voucher_product_id for France
|
||||
29
hr_holidays_lunch_voucher/company_view.xml
Normal file
29
hr_holidays_lunch_voucher/company_view.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
© 2017 Akretion France (www.akretion.com)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<record id="view_company_form" model="ir.ui.view">
|
||||
<field name="name">lunch_voucher.company.form</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="account_grp" position="after">
|
||||
<group name="lunch_voucher" string="Lunch Vouchers">
|
||||
<field name="lunch_voucher_product_id"/>
|
||||
<!-- <field name="lunch_voucher_po_type"/> -->
|
||||
<field name="lunch_voucher_employer_price"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
12
hr_holidays_lunch_voucher/hr_employee.py
Normal file
12
hr_holidays_lunch_voucher/hr_employee.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields
|
||||
|
||||
|
||||
class HrEmployee(models.Model):
|
||||
_inherit = 'hr.employee'
|
||||
|
||||
lunch_voucher = fields.Boolean(string="Has Lunch Vouchers", default=True)
|
||||
25
hr_holidays_lunch_voucher/hr_employee_view.xml
Normal file
25
hr_holidays_lunch_voucher/hr_employee_view.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
© 2017 Akretion France (www.akretion.com)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<record id="view_employee_form_leave_inherit" model="ir.ui.view">
|
||||
<field name="name">lunch_voucher.hr.employee.form</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr_holidays_usability.view_employee_form_leave_inherit"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="holidays" position="inside">
|
||||
<field name="lunch_voucher"/>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
45
hr_holidays_lunch_voucher/hr_holidays.py
Normal file
45
hr_holidays_lunch_voucher/hr_holidays.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
|
||||
class HrHolidays(models.Model):
|
||||
_inherit = 'hr.holidays'
|
||||
|
||||
lunch_voucher_id = fields.Many2one(
|
||||
'lunch.voucher.attribution',
|
||||
string="Related Lunch Voucher Attribution")
|
||||
lunch_voucher_remove_qty = fields.Integer(
|
||||
compute='_compute_lunch_voucher_remove_qty', readonly=True,
|
||||
store=True, string='Lunch Vouchers to Deduct')
|
||||
|
||||
@api.depends('employee_id', 'vacation_date_from', 'vacation_date_to')
|
||||
@api.multi
|
||||
def _compute_lunch_voucher_remove_qty(self):
|
||||
hhpo = self.env['hr.holidays.public']
|
||||
for hol in self:
|
||||
qty = 0
|
||||
if (
|
||||
hol.type == 'remove' and
|
||||
hol.vacation_date_from and
|
||||
hol.vacation_date_to):
|
||||
start_date_dt = fields.Date.from_string(hol.vacation_date_from)
|
||||
end_date_str = hol.vacation_date_to
|
||||
date_dt = start_date_dt
|
||||
# Remove 1 full LV when vacation_time_from == noon
|
||||
# and also when vacation_time_to == noon
|
||||
while True:
|
||||
if (
|
||||
date_dt.weekday() not in (5, 6) and
|
||||
not hhpo.is_public_holiday(
|
||||
date_dt, hol.employee_id.id)):
|
||||
qty += 1
|
||||
date_dt += relativedelta(days=1)
|
||||
date_str = fields.Date.to_string(date_dt)
|
||||
if date_str > end_date_str:
|
||||
break
|
||||
hol.lunch_voucher_remove_qty = qty
|
||||
39
hr_holidays_lunch_voucher/hr_holidays_view.xml
Normal file
39
hr_holidays_lunch_voucher/hr_holidays_view.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
© 2017 Akretion (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<record id="edit_holiday_new" model="ir.ui.view">
|
||||
<field name="name">hr_holidays_lunch_voucher.leave_request_form</field>
|
||||
<field name="model">hr.holidays</field>
|
||||
<field name="inherit_id" ref="hr_holidays_usability.edit_holiday_new"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="counters" position="after">
|
||||
<group name="lunch_vouchers" string="Lunch Vouchers" attrs="{'invisible': [('type', '!=', 'remove')]}">
|
||||
<field name="lunch_voucher_remove_qty"/>
|
||||
<field name="lunch_voucher_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_holiday" model="ir.ui.view">
|
||||
<field name="name">hr_holidays_lunch_voucher.leave_request_tree</field>
|
||||
<field name="model">hr.holidays</field>
|
||||
<field name="inherit_id" ref="hr_holidays_usability.view_holiday"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="number_of_days" position="after">
|
||||
<field name="lunch_voucher_remove_qty" string="Lunch Vouchers -=" sum="Total"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
45
hr_holidays_lunch_voucher/lunch_voucher_attribution.py
Normal file
45
hr_holidays_lunch_voucher/lunch_voucher_attribution.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
class LunchVoucherAttribution(models.Model):
|
||||
_name = 'lunch.voucher.attribution'
|
||||
_description = 'Lunch Voucher Attribution'
|
||||
_order = 'date desc'
|
||||
|
||||
employee_id = fields.Many2one(
|
||||
'hr.employee', string='Employee', ondelete='restrict',
|
||||
required=True, readonly=True)
|
||||
company_id = fields.Many2one(
|
||||
related='employee_id.resource_id.company_id', readonly=True,
|
||||
store=True)
|
||||
date = fields.Date('Attribution Date', readonly=True)
|
||||
purchase_id = fields.Many2one(
|
||||
'purchase.order', 'Purchase Order',
|
||||
readonly=True)
|
||||
month_work_days = fields.Integer(
|
||||
'Month Work Days',
|
||||
help="Number of work days of the month (without taking into "
|
||||
"account the holidays)")
|
||||
no_lunch_days = fields.Integer(
|
||||
compute='_compute_qty', string='No Lunch Days',
|
||||
readonly=True, store=True)
|
||||
qty = fields.Integer(
|
||||
compute='_compute_qty', readonly=True, store=True,
|
||||
string='Lunch Voucher Quantity')
|
||||
holiday_ids = fields.One2many(
|
||||
'hr.holidays', 'lunch_voucher_id', readonly=True)
|
||||
|
||||
@api.depends('month_work_days', 'holiday_ids.lunch_voucher_remove_qty')
|
||||
@api.multi
|
||||
def _compute_qty(self):
|
||||
for rec in self:
|
||||
no_lunch_days = 0
|
||||
for hol in rec.holiday_ids:
|
||||
no_lunch_days += hol.lunch_voucher_remove_qty
|
||||
rec.no_lunch_days = no_lunch_days
|
||||
rec.qty = rec.month_work_days - no_lunch_days
|
||||
97
hr_holidays_lunch_voucher/lunch_voucher_attribution_view.xml
Normal file
97
hr_holidays_lunch_voucher/lunch_voucher_attribution_view.xml
Normal file
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
© 2017 Akretion France (www.akretion.com)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<record id="lunch_voucher_attribution_form" model="ir.ui.view">
|
||||
<field name="name">lunch.voucher.attribution.form</field>
|
||||
<field name="model">lunch.voucher.attribution</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Lunch Vouchers Attribution">
|
||||
<group name="main">
|
||||
<field name="employee_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="date"/>
|
||||
<field name="month_work_days"/>
|
||||
<field name="no_lunch_days"/>
|
||||
<field name="qty"/>
|
||||
<field name="purchase_id"/>
|
||||
</group>
|
||||
<group name="holidays" string="Related Holidays">
|
||||
<field name="holiday_ids" nolabel="1" context="{'tree_view_ref': 'hr_holidays_lunch_voucher.view_holiday', 'form_view_ref': 'hr_holidays_lunch_voucher.edit_holiday_new'}"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="lunch_voucher_attribution_tree" model="ir.ui.view">
|
||||
<field name="name">lunch.voucher.attribution.tree</field>
|
||||
<field name="model">lunch.voucher.attribution</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Lunch Vouchers Attribution">
|
||||
<field name="date"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="month_work_days"/>
|
||||
<field name="no_lunch_days" sum="Total"/>
|
||||
<field name="qty" sum="Total"/>
|
||||
<field name="purchase_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="lunch_voucher_attribution_search" model="ir.ui.view">
|
||||
<field name="name">lunch.voucher.attribution.search</field>
|
||||
<field name="model">lunch.voucher.attribution</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Lunch Vouchers Attribution">
|
||||
<field name="date"/>
|
||||
<field name="employee_id"/>
|
||||
<filter name="purchased" string="Purchased" domain="[('purchase_id', '!=', False)]"/>
|
||||
<filter name="to_purchase" string="To Purchase" domain="[('purchase_id', '=', False)]"/>
|
||||
<group string="Group By" name="groupby">
|
||||
<filter name="employee_groupby" string="Employee" context="{'group_by': 'employee_id'}"/>
|
||||
<filter name="purchase_order_groupby" string="Purchase Order" context="{'group_by': 'purchase_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="lunch_voucher_attribution_graph" model="ir.ui.view">
|
||||
<field name="name">lunch.voucher.attribution.graph</field>
|
||||
<field name="model">lunch.voucher.attribution</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Lunch Vouchers Attribution" type="pivot">
|
||||
<field name="date" type="row" interval="month"/>
|
||||
<field name="qty" type="measure"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="lunch_voucher_attribution_action" model="ir.actions.act_window">
|
||||
<field name="name">Lunch Voucher Attribution</field>
|
||||
<field name="res_model">lunch.voucher.attribution</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="lunch_voucher_attribution_menu"
|
||||
action="lunch_voucher_attribution_action"
|
||||
parent="hr_holidays.menu_open_ask_holidays" sequence="200"/>
|
||||
|
||||
<act_window id="lunch_voucher_attribution_action_create_po"
|
||||
multi="True"
|
||||
key2="client_action_multi"
|
||||
name="Create Purchase Order"
|
||||
res_model="lunch.voucher.purchase"
|
||||
src_model="lunch.voucher.attribution"
|
||||
view_mode="form"
|
||||
target="new" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
27
hr_holidays_lunch_voucher/product_data.xml
Normal file
27
hr_holidays_lunch_voucher/product_data.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
|
||||
<record id="lunch_voucher_product" model="product.product">
|
||||
<field name="name">Lunch Vouchers</field>
|
||||
<field name="categ_id" ref="product.product_category_all"/>
|
||||
<field name="sale_ok" eval="False"/>
|
||||
<field name="purchase_ok" eval="True"/>
|
||||
<field name="list_price">0</field>
|
||||
<field name="standard_price">8</field>
|
||||
<field name="type">service</field> <!-- For those who want to manage stock of lunch vouchers, they can switch type to product manually -->
|
||||
<field name="uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="uom_po_id" ref="product.product_uom_unit"/>
|
||||
<field name="supplier_taxes_id" eval="False"/>
|
||||
<field name="taxes_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="base.main_company" model="res.company">
|
||||
<field name="lunch_voucher_product_id" ref="lunch_voucher_product"/>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
3
hr_holidays_lunch_voucher/security/ir.model.access.csv
Normal file
3
hr_holidays_lunch_voucher/security/ir.model.access.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_lunch_voucher_attribution_full,Full access on lunch_voucher_attribution,model_lunch_voucher_attribution,base.group_hr_manager,1,1,1,1
|
||||
access_lunch_voucher_attribution_read,Read access on lunch_voucher_attribution,model_lunch_voucher_attribution,base.group_user,1,0,0,0
|
||||
|
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
|
||||
<record id="lunch_voucher_attribution_employee" model="ir.rule">
|
||||
<field name="name">Personal Lunch Voucher Attributions</field>
|
||||
<field name="model_id" ref="hr_holidays_lunch_voucher.model_lunch_voucher_attribution"/>
|
||||
<field name="domain_force">[('employee_id.user_id', '=', user.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="lunch_voucher_attribution_officer" model="ir.rule">
|
||||
<field name="name">HR Officer sees all Lunch Voucher Attributions</field>
|
||||
<field name="model_id" ref="hr_holidays_lunch_voucher.model_lunch_voucher_attribution"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_hr_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="lunch_voucher_attribution_multicompany_rule" model="ir.rule">
|
||||
<field name="name">Lunch Voucher Attribution multi-company</field>
|
||||
<field name="model_id" ref="hr_holidays_lunch_voucher.model_lunch_voucher_attribution"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
4
hr_holidays_lunch_voucher/wizard/__init__.py
Normal file
4
hr_holidays_lunch_voucher/wizard/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from . import hr_holidays_post
|
||||
from . import lunch_voucher_purchase
|
||||
74
hr_holidays_lunch_voucher/wizard/hr_holidays_post.py
Normal file
74
hr_holidays_lunch_voucher/wizard/hr_holidays_post.py
Normal file
@@ -0,0 +1,74 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
from dateutil.relativedelta import relativedelta
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HrHolidaysPost(models.TransientModel):
|
||||
_inherit = 'hr.holidays.post'
|
||||
|
||||
lunch_voucher_po = fields.Boolean(
|
||||
string='Generate Lunch Voucher Purchase Order')
|
||||
work_days = fields.Integer(string='Work Days')
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
res = super(HrHolidaysPost, self).default_get(fields_list)
|
||||
hhpo = self.env['hr.holidays.public']
|
||||
company = self.env.user.company_id
|
||||
if company.lunch_voucher_product_id:
|
||||
res['lunch_voucher_po'] = True
|
||||
today = fields.Date.context_today(self)
|
||||
today_dt = fields.Date.from_string(today)
|
||||
cur_month = today_dt.month
|
||||
# last day of month
|
||||
date_dt = today_dt + relativedelta(day=31)
|
||||
work_days = date_dt.day
|
||||
logger.info('Number of days in the month: %d', work_days)
|
||||
# from last day of month to the first
|
||||
while date_dt.month == cur_month:
|
||||
if hhpo.is_public_holiday(date_dt):
|
||||
work_days -= 1
|
||||
logger.info(
|
||||
"%s is a bank holiday, don't count", date_dt)
|
||||
# if it's a saturday/sunday
|
||||
elif date_dt.weekday() in (5, 6):
|
||||
work_days -= 1
|
||||
logger.info(
|
||||
"%s is a saturday/sunday, don't count", date_dt)
|
||||
date_dt += relativedelta(days=-1)
|
||||
logger.info('Number of work days in the month: %d', work_days)
|
||||
res['work_days'] = work_days
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def run(self):
|
||||
self.ensure_one()
|
||||
lvao = self.env['lunch.voucher.attribution']
|
||||
today = fields.Date.context_today(self)
|
||||
employees = self.env['hr.employee'].search([
|
||||
('lunch_voucher', '=', True),
|
||||
('company_id', '=', self.env.user.company_id.id),
|
||||
])
|
||||
lv_dict = {}
|
||||
for employee in employees:
|
||||
lv_dict[employee.id] = []
|
||||
for hol in self.holidays_to_post_ids:
|
||||
if not hol.lunch_voucher_id and hol.employee_id.id in lv_dict:
|
||||
lv_dict[hol.employee_id.id].append(hol.id)
|
||||
for employee_id, hol_ids in lv_dict.iteritems():
|
||||
vals = {
|
||||
'employee_id': employee_id,
|
||||
'date': today,
|
||||
'month_work_days': self.work_days,
|
||||
}
|
||||
if hol_ids:
|
||||
vals['holiday_ids'] = [(6, 0, hol_ids)]
|
||||
lvao.create(vals)
|
||||
return super(HrHolidaysPost, self).run()
|
||||
27
hr_holidays_lunch_voucher/wizard/hr_holidays_post_view.xml
Normal file
27
hr_holidays_lunch_voucher/wizard/hr_holidays_post_view.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
© 2017 Akretion (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<record id="hr_holidays_post_form" model="ir.ui.view">
|
||||
<field name="name">hr_holidays_post_form</field>
|
||||
<field name="model">hr.holidays.post</field>
|
||||
<field name="inherit_id" ref="hr_holidays_usability.hr_holidays_post_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="holidays_to_post_ids" position="before">
|
||||
<field name="lunch_voucher_po" states="done"/>
|
||||
<field name="work_days"
|
||||
attrs="{'invisible': ['|', ('state', '!=', 'done'), ('lunch_voucher_po', '=', False)]}"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
77
hr_holidays_lunch_voucher/wizard/lunch_voucher_purchase.py
Normal file
77
hr_holidays_lunch_voucher/wizard/lunch_voucher_purchase.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, api, _
|
||||
from openerp.exceptions import Warning as UserError
|
||||
|
||||
|
||||
class LunchVoucherPurchase(models.TransientModel):
|
||||
_name = 'lunch.voucher.purchase'
|
||||
_description = 'Purchase Lunch Vouchers Wizard'
|
||||
|
||||
@api.multi
|
||||
def run(self):
|
||||
self.ensure_one()
|
||||
company = self.env.user.company_id
|
||||
if not company.lunch_voucher_product_id:
|
||||
raise UserError(_(
|
||||
"Lunch Voucher Product not configured on company %s")
|
||||
% company.name)
|
||||
if not company.lunch_voucher_product_id.seller_id:
|
||||
raise UserError(_(
|
||||
"Missing supplier on Product '%s'.")
|
||||
% company.lunch_voucher_product_id.name)
|
||||
|
||||
poo = self.env['purchase.order']
|
||||
polo = self.env['purchase.order.line']
|
||||
lvao = self.env['lunch.voucher.attribution']
|
||||
assert self._context.get('active_model') ==\
|
||||
'lunch.voucher.attribution', 'wrong source model'
|
||||
assert self._context.get('active_ids'), 'missing active_ids in ctx'
|
||||
lvouchers = lvao.browse(self._context['active_ids'])
|
||||
total_qty = 0
|
||||
for lvoucher in lvouchers:
|
||||
if lvoucher.purchase_id:
|
||||
raise UserError(_(
|
||||
"One of the Lunch Voucher Attributions you selected "
|
||||
"related to employee '%s' is already linked to a "
|
||||
"purchase order.") % lvoucher.employee_id.name)
|
||||
if lvoucher.qty < 0:
|
||||
raise UserError(_(
|
||||
"One of the Lunch Voucher Attributions you selected "
|
||||
"related to employee '%s' has a negative quantity.")
|
||||
% lvoucher.employee_id.name)
|
||||
total_qty += lvoucher.qty
|
||||
|
||||
supplier = company.lunch_voucher_product_id.seller_id
|
||||
pick_type_id = poo.default_get(['picking_type_id'])['picking_type_id']
|
||||
onchange_ptype_vals = poo.browse(False).onchange_picking_type_id(
|
||||
pick_type_id)
|
||||
vals = onchange_ptype_vals['value']
|
||||
onchange_vals = poo.browse(False).onchange_partner_id(supplier.id)
|
||||
vals.update(onchange_vals['value'])
|
||||
vals['partner_id'] = supplier.id
|
||||
|
||||
product = company.lunch_voucher_product_id
|
||||
onchange_product_vals = polo.browse(False).onchange_product_id(
|
||||
vals.get('pricelist_id'), product.id, total_qty, False,
|
||||
supplier.id, fiscal_position_id=vals.get('fiscal_position_id'))
|
||||
lvals = onchange_product_vals['value']
|
||||
lvals['product_id'] = product.id
|
||||
lvals['product_qty'] = total_qty
|
||||
if lvals['taxes_id']:
|
||||
lvals['taxes_id'] = [(6, 0, lvals['taxes_id'])]
|
||||
vals['order_line'] = [(0, 0, lvals)]
|
||||
po = poo.create(vals)
|
||||
lvouchers.write({'purchase_id': po.id})
|
||||
|
||||
action = self.env['ir.actions.act_window'].for_xml_id(
|
||||
'purchase', 'purchase_rfq')
|
||||
action.update({
|
||||
'res_id': po.id,
|
||||
'view_mode': 'form,tree',
|
||||
'views': False,
|
||||
})
|
||||
return action
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
© 2017 Akretion (http://www.akretion.com/)
|
||||
@author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="lunch_voucher_purchase_form" model="ir.ui.view">
|
||||
<field name="name">lunch_voucher_purchase_form</field>
|
||||
<field name="model">lunch.voucher.purchase</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create Purchase Order of Lunch Vouchers">
|
||||
<group name="main">
|
||||
<label string="Click on the button below to create the purchase order for the selected lunch vouchers attributions." colspan="2"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="run" type="object" string="Create"
|
||||
class="oe_highlight"/>
|
||||
<button special="cancel" string="Cancel" class="oe_link"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="lunch_voucher_purchase_action" model="ir.actions.act_window">
|
||||
<field name="name">Create PO for Lunch Vouchers</field>
|
||||
<field name="res_model">lunch.voucher.purchase</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
4
hr_holidays_lunch_voucher_natixis/__init__.py
Normal file
4
hr_holidays_lunch_voucher_natixis/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import company
|
||||
from . import wizard
|
||||
20
hr_holidays_lunch_voucher_natixis/__openerp__.py
Normal file
20
hr_holidays_lunch_voucher_natixis/__openerp__.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
'name': 'HR Holidays Lunch Voucher Natixis',
|
||||
'version': '10.0.1.0.0',
|
||||
'category': 'Human Resources',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Generate order file for Natixis lunch vouchers',
|
||||
'description': '',
|
||||
'author': 'Akretion',
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': ['hr_holidays_lunch_voucher'],
|
||||
'data': [
|
||||
'company_view.xml',
|
||||
],
|
||||
'installable': True,
|
||||
}
|
||||
15
hr_holidays_lunch_voucher_natixis/company.py
Normal file
15
hr_holidays_lunch_voucher_natixis/company.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
lunch_voucher_natixis_customer_code = fields.Char(
|
||||
string='Natixis Customer Ref', size=7)
|
||||
lunch_voucher_natixis_delivery_code = fields.Char(
|
||||
string='Natixis Delivery Code', size=7)
|
||||
26
hr_holidays_lunch_voucher_natixis/company_view.xml
Normal file
26
hr_holidays_lunch_voucher_natixis/company_view.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
© 2017 Akretion France (www.akretion.com)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<record id="view_company_form" model="ir.ui.view">
|
||||
<field name="name">natixis.lunch_voucher.company.form</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="hr_holidays_lunch_voucher.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="lunch_voucher" position="inside">
|
||||
<field name="lunch_voucher_natixis_customer_code"/>
|
||||
<field name="lunch_voucher_natixis_delivery_code"/>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
3
hr_holidays_lunch_voucher_natixis/wizard/__init__.py
Normal file
3
hr_holidays_lunch_voucher_natixis/wizard/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from . import lunch_voucher_purchase
|
||||
@@ -0,0 +1,81 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.exceptions import Warning as UserError
|
||||
|
||||
|
||||
class LunchVoucherPurchase(models.TransientModel):
|
||||
_inherit = 'lunch.voucher.purchase'
|
||||
|
||||
@api.multi
|
||||
def run(self):
|
||||
self.ensure_one()
|
||||
action = super(LunchVoucherPurchase, self).run()
|
||||
company = self.env.user.company_id
|
||||
lvao = self.env['lunch.voucher.attribution']
|
||||
assert self._context.get('active_model')\
|
||||
== 'lunch.voucher.attribution', 'wrong source model'
|
||||
assert self._context.get('active_ids'), 'missing active_ids in ctx'
|
||||
if not company.lunch_voucher_natixis_customer_code:
|
||||
raise UserError(_(
|
||||
"Missing Natixis Customer Ref on company '%s'.")
|
||||
% company.name)
|
||||
if not company.lunch_voucher_natixis_delivery_code:
|
||||
raise UserError(_(
|
||||
"Missing Natixis Delivery Code on company '%s'.")
|
||||
% company.name)
|
||||
if len(company.lunch_voucher_natixis_customer_code) != 7:
|
||||
raise UserError(_(
|
||||
"Natixis Customer Ref '%s' on company '%s' should "
|
||||
"have 7 characters/digits.")
|
||||
% (company.lunch_voucher_natixis_customer_code, company.name))
|
||||
if len(company.lunch_voucher_natixis_delivery_code) != 7:
|
||||
raise UserError(_(
|
||||
"Natixis Delivery Code on company '%s' should "
|
||||
"have 7 characters/digits.")
|
||||
% (company.lunch_voucher_natixis_delivery_code, company.name))
|
||||
if not company.lunch_voucher_employer_price:
|
||||
raise UserError(_(
|
||||
"Lunch Voucher Employer Price not set on company '%s'.")
|
||||
% company.name)
|
||||
lvouchers = lvao.browse(self._context['active_ids'])
|
||||
of = u''
|
||||
tmp = {}
|
||||
for lvoucher in lvouchers:
|
||||
if lvoucher.qty > 0:
|
||||
if lvoucher.qty not in tmp:
|
||||
tmp[lvoucher.qty] = 1
|
||||
else:
|
||||
tmp[lvoucher.qty] += 1
|
||||
for vouchers_per_pack, pack_qty in tmp.iteritems():
|
||||
if vouchers_per_pack > 99:
|
||||
raise UserError(_(
|
||||
"Cannot order more than 99 vouchers per pack"))
|
||||
line = u'%s%s%s%s%s%s%s%s\n' % (
|
||||
company.lunch_voucher_natixis_delivery_code,
|
||||
company.lunch_voucher_natixis_customer_code,
|
||||
unicode(pack_qty).zfill(3),
|
||||
unicode(vouchers_per_pack).zfill(2),
|
||||
unicode(pack_qty * vouchers_per_pack).zfill(5),
|
||||
'{:05.2f}'.format(
|
||||
company.lunch_voucher_product_id.standard_price),
|
||||
'{:05.2f}'.format(company.lunch_voucher_employer_price),
|
||||
' ' * 64)
|
||||
of += line
|
||||
today_dt = fields.Date.from_string(
|
||||
fields.Date.context_today(self))
|
||||
filename = 'E%s_%s.txt' % (
|
||||
company.lunch_voucher_natixis_customer_code,
|
||||
today_dt.strftime('%d%m%Y'))
|
||||
self.env['ir.attachment'].create({
|
||||
'name': filename,
|
||||
'res_id': action['res_id'],
|
||||
'res_model': 'purchase.order',
|
||||
'datas': of.encode('base64'),
|
||||
'datas_fname': filename,
|
||||
'type': 'binary',
|
||||
})
|
||||
return action
|
||||
@@ -241,6 +241,10 @@ class HrHolidays(models.Model):
|
||||
string='Public Title',
|
||||
help="Warning: this title is shown publicly in the "
|
||||
"calendar. Don't write private/personnal information in this field.")
|
||||
# by default, there is no company_id field on hr.holidays !
|
||||
company_id = fields.Many2one(
|
||||
related='employee_id.resource_id.company_id', store=True,
|
||||
readonly=True)
|
||||
|
||||
@api.one
|
||||
@api.constrains(
|
||||
|
||||
@@ -61,6 +61,7 @@ hr_holidays.edit_holiday_new is used for both leaves and allocation -->
|
||||
</group>
|
||||
</field>
|
||||
<field name="department_id" position="after">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="posted_date" groups="base.group_hr_manager"/>
|
||||
</field>
|
||||
</field>
|
||||
@@ -90,6 +91,7 @@ hr_holidays.edit_holiday_new is used for both leaves and allocation -->
|
||||
</field>
|
||||
<field name="holiday_status_id" position="after">
|
||||
<field name="posted_date" groups="base.group_hr_manager"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="0">
|
||||
<data noupdate="1">
|
||||
|
||||
<!--
|
||||
Employee : only see his holidays
|
||||
@@ -41,5 +41,12 @@ Manager = person that administrates the holidays process : can see everything, d
|
||||
<field name="groups" eval="[(4, ref('base.group_hr_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="hr_holidays_multicompany_rule" model="ir.rule">
|
||||
<field name="name">Holidays multi-company</field>
|
||||
<field name="model_id" ref="hr_holidays.model_hr_holidays"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -31,7 +31,9 @@ class HrHolidaysMassAllocation(models.TransientModel):
|
||||
@api.model
|
||||
def _default_employees(self):
|
||||
return self.env['hr.employee'].search([
|
||||
('holiday_exclude_mass_allocation', '=', False)])
|
||||
('holiday_exclude_mass_allocation', '=', False),
|
||||
('company_id', '=', self.env.user.company_id.id),
|
||||
])
|
||||
|
||||
@api.model
|
||||
def _get_default_holiday_status(self):
|
||||
|
||||
@@ -56,6 +56,7 @@ class HrHolidaysPost(models.TransientModel):
|
||||
('state', '=', 'validate'),
|
||||
('posted_date', '=', False),
|
||||
('vacation_date_to', '<=', self.before_date),
|
||||
('company_id', '=', self.env.user.company_id.id),
|
||||
])
|
||||
self.write({
|
||||
'state': 'done',
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
<field name="name">hr_holidays_post_form</field>
|
||||
<field name="model">hr.holidays.post</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Post Leaves" version="7.0">
|
||||
<form string="Post Leaves">
|
||||
<group name="main" string="Leave Requests to Post">
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="before_date" states="draft"/>
|
||||
<field name="holidays_to_post_ids" nolabel="1"
|
||||
context="{'tree_view_ref': 'hr_holidays.view_holiday'}"
|
||||
states="done"/>
|
||||
states="done" colspan="2"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="select_date" type="object" string="Get Holiday Requests"
|
||||
|
||||
Reference in New Issue
Block a user