get endpoin request employee and mission
This commit is contained in:
parent
99ca6a0d48
commit
0f02f5147e
|
|
@ -10,3 +10,4 @@ from . import pettie
|
|||
from . import project_timesheet
|
||||
from . import employee_other_request
|
||||
from . import content_common
|
||||
from . import official_mission
|
||||
|
|
|
|||
|
|
@ -1,24 +1,36 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import werkzeug
|
||||
from odoo import http, tools
|
||||
from odoo.http import request, Response
|
||||
from odoo.exceptions import UserError
|
||||
import base64
|
||||
from ...validator import validator
|
||||
from ...http_helper import http_helper
|
||||
from odoo.tools.translate import _
|
||||
import json
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from odoo import http, _
|
||||
from odoo.exceptions import UserError, AccessError, ValidationError
|
||||
from odoo.http import request
|
||||
from ...http_helper import http_helper
|
||||
from ...validator import validator
|
||||
from datetime import date, datetime
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def convert_dates_in_data(data):
|
||||
if isinstance(data, dict):
|
||||
for key, value in data.items():
|
||||
data[key] = convert_dates_in_data(value)
|
||||
return data
|
||||
elif isinstance(data, list):
|
||||
return [convert_dates_in_data(item) for item in data]
|
||||
elif isinstance(data, (date, datetime)):
|
||||
return data.isoformat()
|
||||
else:
|
||||
return data
|
||||
|
||||
class EmployeeOtherRequest(http.Controller):
|
||||
|
||||
def get_lable_selection(self, rec, field_name, state):
|
||||
return dict(rec._fields[field_name]._description_selection(http.request.env)).get(state)
|
||||
|
||||
@http.route(['/rest_api/v2/employeeRequest/types', '/rest_api/v2/employeeRequest/types/<string:key>'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
@http.route(['/rest_api/v2/employeeRequest/types', '/rest_api/v2/employeeRequest/types/<string:key>'], type='http',
|
||||
auth='none', csrf=False, methods=['GET'])
|
||||
def get_employee_other_request_type(self, key=None):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
result = validator.verify_token(token)
|
||||
|
|
@ -26,26 +38,45 @@ class EmployeeOtherRequest(http.Controller):
|
|||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400, message=_("You are not allowed to perform this operation. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"You are not allowed to perform this operation. please check with one of your team admins"),
|
||||
success=False)
|
||||
employee = http.request.env['hr.employee'].search(
|
||||
[('user_id', '=', user.id)], limit=1)
|
||||
if not employee:
|
||||
return http_helper.response(code=400, message=_("You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
|
||||
try:
|
||||
data = {"other_request_types": dict(http.request.env['employee.other.request']._fields['request_type']._description_selection(http.request.env)),
|
||||
"salary_request_print_type": dict(http.request.env['employee.other.request']._fields['print_type']._description_selection(http.request.env)),
|
||||
"salary_request_state": dict(http.request.env['employee.other.request']._fields['state']._description_selection(http.request.env)),
|
||||
"certification_degree": dict(http.request.env['hr.certification']._fields['certification_degree']._description_selection(http.request.env)),
|
||||
"qualification_degree": dict(http.request.env['hr.qualification']._fields['qualification_degree']._description_selection(http.request.env)),
|
||||
"gender": dict(http.request.env['hr.employee.dependent']._fields['gender']._description_selection(http.request.env)),
|
||||
"relation": dict(http.request.env['hr.employee.dependent']._fields['relation']._description_selection(http.request.env)),
|
||||
data = {"other_request_types": dict(
|
||||
http.request.env['employee.other.request']._fields['request_type']._description_selection(
|
||||
http.request.env)),
|
||||
"salary_request_print_type": dict(
|
||||
http.request.env['employee.other.request']._fields['print_type']._description_selection(
|
||||
http.request.env)),
|
||||
"salary_request_state": dict(
|
||||
http.request.env['employee.other.request']._fields['state']._description_selection(
|
||||
http.request.env)),
|
||||
"certification_degree": dict(
|
||||
http.request.env['hr.certification']._fields['certification_degree']._description_selection(
|
||||
http.request.env)),
|
||||
"qualification_degree": dict(
|
||||
http.request.env['hr.qualification']._fields['qualification_degree']._description_selection(
|
||||
http.request.env)),
|
||||
"gender": dict(http.request.env['hr.employee.dependent']._fields['gender']._description_selection(
|
||||
http.request.env)),
|
||||
"relation": dict(
|
||||
http.request.env['hr.employee.dependent']._fields['relation']._description_selection(
|
||||
http.request.env)),
|
||||
"nationality": request.env['res.country'].sudo().search([]).read(['id', 'name']),
|
||||
"uni_name_UniversityName": request.env['office.office'].sudo().search([]).read(['id', 'name']),
|
||||
"col_name_College": request.env['hr.college'].sudo().search([]).read(['id', 'name']),
|
||||
"hr_qualification_name": request.env['hr.qualification.name'].sudo().search([]).read(['id', 'name']),
|
||||
"qualification_specification": request.env['qualification.specification'].sudo().search([('type', '=', 'qualification')]).read(['id', 'name']),
|
||||
"certificate_specification": request.env['qualification.specification'].sudo().search([("type", "=", "certificate")]).read(['id', 'name']),
|
||||
"hr_qualification_name": request.env['hr.qualification.name'].sudo().search([]).read(
|
||||
['id', 'name']),
|
||||
"qualification_specification": request.env['qualification.specification'].sudo().search(
|
||||
[('type', '=', 'qualification')]).read(['id', 'name']),
|
||||
"certificate_specification": request.env['qualification.specification'].sudo().search(
|
||||
[("type", "=", "certificate")]).read(['id', 'name']),
|
||||
"membership_type": request.env['membership.types'].sudo().search([]).read(['id', 'name']),
|
||||
"membership_categorys": request.env['membership.categorys'].sudo().search([]).read(['id', 'name']),
|
||||
}
|
||||
|
|
@ -58,7 +89,8 @@ class EmployeeOtherRequest(http.Controller):
|
|||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=403, message=message)
|
||||
|
||||
@http.route(['/rest_api/v2/employeeRequests/', '/rest_api/v2/employeeRequests/<int:id>'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
@http.route(['/rest_api/v2/employeeRequests/', '/rest_api/v2/employeeRequests/<int:id>'], type='http', auth='none',
|
||||
csrf=False, methods=['GET'])
|
||||
def get_employee_other_requests(self, id=None, approvel=None, page=None, **kw):
|
||||
page = page if page else 1
|
||||
page, offset, limit, prev = validator.get_page_pagination(page)
|
||||
|
|
@ -68,21 +100,28 @@ class EmployeeOtherRequest(http.Controller):
|
|||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400, message=_("You are not allowed to perform this operation. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"You are not allowed to perform this operation. please check with one of your team admins"),
|
||||
success=False)
|
||||
employee = http.request.env['hr.employee'].search([('user_id', '=', user.id)], limit=1)
|
||||
if not employee:
|
||||
return http_helper.response(code=400, message=_("You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
|
||||
try:
|
||||
if approvel:
|
||||
domain = [('state', '!=', 'draft'),('employee_id', '!=', employee.id)]
|
||||
emp_requests = http.request.env['employee.other.request'].search(domain, order='date desc', offset=offset, limit=limit)
|
||||
domain = [('state', '!=', 'draft'), ('employee_id', '!=', employee.id)]
|
||||
emp_requests = http.request.env['employee.other.request'].search(domain, order='date desc',
|
||||
offset=offset, limit=limit)
|
||||
count = http.request.env['employee.other.request'].search_count(domain)
|
||||
else:
|
||||
emp_requests = http.request.env['employee.other.request'].search([('employee_id', '=', employee.id)], order='date desc', offset=offset, limit = limit)
|
||||
emp_requests = http.request.env['employee.other.request'].search([('employee_id', '=', employee.id)],
|
||||
order='date desc', offset=offset,
|
||||
limit=limit)
|
||||
count = http.request.env['employee.other.request'].search_count([('employee_id', '=', employee.id)])
|
||||
if id:
|
||||
emp_requests = http.request.env['employee.other.request'].search([('id', '=', int(id))], order='date desc')
|
||||
emp_requests = http.request.env['employee.other.request'].search([('id', '=', int(id))],
|
||||
order='date desc')
|
||||
count = http.request.env['employee.other.request'].search_count([('id', '=', int(id))])
|
||||
employeeRequests = []
|
||||
if emp_requests:
|
||||
|
|
@ -96,7 +135,7 @@ class EmployeeOtherRequest(http.Controller):
|
|||
'request_type': s.request_type,
|
||||
'request_type_lable': self.get_lable_selection(s, 'request_type', s.request_type),
|
||||
'state': s.state,
|
||||
'state_lable': self.get_lable_selection(s, 'state', s.state),
|
||||
'state_name': self.get_lable_selection(s, 'state', s.state),
|
||||
}
|
||||
employee_dependant = []
|
||||
for dep in s.employee_dependant:
|
||||
|
|
@ -104,7 +143,7 @@ class EmployeeOtherRequest(http.Controller):
|
|||
'name': dep.name or '',
|
||||
'age': dep.age or '',
|
||||
'birthday': str(dep.birthday or ''),
|
||||
'gender': dep.gender or '',
|
||||
'gender': dep.gender or '',
|
||||
'gender_lable': self.get_lable_selection(dep, 'gender', dep.gender),
|
||||
'relation': dep.relation or '',
|
||||
'relation_lable': self.get_lable_selection(dep, 'relation', dep.relation),
|
||||
|
|
@ -137,8 +176,10 @@ class EmployeeOtherRequest(http.Controller):
|
|||
'contact_email': qua.contact_email or '',
|
||||
'country_name': qua.country_name.read(['id', 'name'])[0] or {},
|
||||
'qualification_degree': qua.qualification_degree or '',
|
||||
'qualification_degree_lable': self.get_lable_selection(qua, 'qualification_degree', qua.qualification_degree),
|
||||
'qualification_specification_id': qua.qualification_specification_id.read(['id', 'name'])[0] or {},
|
||||
'qualification_degree_lable': self.get_lable_selection(qua, 'qualification_degree',
|
||||
qua.qualification_degree),
|
||||
'qualification_specification_id': qua.qualification_specification_id.read(['id', 'name'])[
|
||||
0] or {},
|
||||
'qualification_id': qua.qualification_id.read(['id', 'name'])[0] or {},
|
||||
# 'attachment': qua.attachment,
|
||||
|
||||
|
|
@ -153,8 +194,9 @@ class EmployeeOtherRequest(http.Controller):
|
|||
'cer_name': cer.car_name or '',
|
||||
'certification_specification': cer.certification_specification_id.name or '',
|
||||
'issue_org': cer.issue_org or '',
|
||||
'certification_degree': cer.certification_degree or '',
|
||||
'certification_degree_lable': self.get_lable_selection(cer, 'certification_degree', cer.certification_degree),
|
||||
'certification_degree': cer.certification_degree or '',
|
||||
'certification_degree_lable': self.get_lable_selection(cer, 'certification_degree',
|
||||
cer.certification_degree),
|
||||
'issue_date': str(cer.issue_date or ''),
|
||||
'exp_date': str(cer.exp_date or ''),
|
||||
'country_id': cer.country_name.read(['id', 'name'])[0] or {},
|
||||
|
|
@ -165,8 +207,8 @@ class EmployeeOtherRequest(http.Controller):
|
|||
|
||||
employeeRequests.append(value)
|
||||
next = validator.get_page_pagination_next(page, count)
|
||||
url = "/rest_api/v2/employeeRequests?approvel=%s&page=%s" % ( approvel, next) if next else False
|
||||
prev_url = "/rest_api/v2/employeeRequests?approvel=%s&page=%s" % ( approvel, prev) if prev else False
|
||||
url = "/rest_api/v2/employeeRequests?approvel=%s&page=%s" % (approvel, next) if next else False
|
||||
prev_url = "/rest_api/v2/employeeRequests?approvel=%s&page=%s" % (approvel, prev) if prev else False
|
||||
data = {'links': {'prev': prev_url, 'next': url, },
|
||||
'count': count,
|
||||
'results': {'employeeRequests': employeeRequests, }}
|
||||
|
|
@ -189,29 +231,709 @@ class EmployeeOtherRequest(http.Controller):
|
|||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400, message=_("You are not allowed to perform this operation. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"You are not allowed to perform this operation. please check with one of your team admins"),
|
||||
success=False)
|
||||
employee = http.request.env['hr.employee'].search([('user_id', '=', user.id)], limit=1)
|
||||
if not employee:
|
||||
return http_helper.response(code=400, message=_("You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
if not reportname:
|
||||
return http_helper.response(code=400, message=_("please sent report name . please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"please sent report name . please check with one of your team admins"), success=False)
|
||||
report = request.env['ir.actions.report']._get_report_from_name(reportname)
|
||||
if docids:
|
||||
docids = [int(i) for i in docids.split(',')]
|
||||
else:
|
||||
return http_helper.response(code=400, message=_("please sent id recrod print report. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"please sent id recrod print report. please check with one of your team admins"), success=False)
|
||||
if report:
|
||||
model = report.model_id.model or report.model
|
||||
if len(request.env[model].search([('id', 'in', docids)])) < len(docids):
|
||||
return http_helper.response(code=400, message=_("You Have issue in your data not found. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"You Have issue in your data not found. please check with one of your team admins"), success=False)
|
||||
else:
|
||||
return http_helper.response(code=400, message=_("You Have issue in your report not found. please check with one of your team admins"), success=False)
|
||||
return http_helper.response(code=400, message=_(
|
||||
"You Have issue in your report not found. please check with one of your team admins"), success=False)
|
||||
try:
|
||||
context = dict(request.env.context)
|
||||
pdf = report.with_context(context)._render_qweb_pdf(docids, data=data)[0]
|
||||
pdfhttpheaders = [('Content-Type', 'application/pdf'),('Content-Length', len(pdf))]
|
||||
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
|
||||
return request.make_response(pdf, headers=pdfhttpheaders)
|
||||
except Exception as e:
|
||||
_logger.error(str(e))
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=403, message=message)
|
||||
return http_helper.errcode(code=403, message=message)
|
||||
|
||||
|
||||
class EmployeeOtherRequestController(http.Controller):
|
||||
"""
|
||||
Controller for Employee Other Requests (employee.other.request)
|
||||
|
||||
Endpoints:
|
||||
3.1 Create Request (POST /rest_api/v2/employee_other_request)
|
||||
3.2 Get All Requests (Paginate) (GET /rest_api/v2/employee_other_request)
|
||||
3.3 Get Request by ID (GET /rest_api/v2/employee_request/<id>)
|
||||
3.4 Update Request (PATCH /rest_api/v2/employee_other_request/<id>)
|
||||
3.5 Delete Request (DELETE /rest_api/v2/employee_other_request/<id>)
|
||||
"""
|
||||
def get_lable_selection(self, rec, field_name, state):
|
||||
return dict(rec._fields[field_name]._description_selection(http.request.env)).get(state)
|
||||
# --------------------------------------------
|
||||
# Utilities
|
||||
# --------------------------------------------
|
||||
def _prepare_employee_dependant_lines(self, dependant_list):
|
||||
"""
|
||||
Convert the list of employee_dependant dicts from the request
|
||||
into Odoo One2many commands: (0, 0, {vals})
|
||||
"""
|
||||
commands = []
|
||||
for dep in dependant_list or []:
|
||||
commands.append((0, 0, {
|
||||
"name": dep.get("name"),
|
||||
"relation": dep.get("relation"),
|
||||
"date_of_birth": dep.get("date_of_birth"),
|
||||
}))
|
||||
return commands
|
||||
|
||||
def _prepare_qualification_employee_lines(self, quals_list):
|
||||
"""
|
||||
Convert the list of qualification_employee dicts from the request
|
||||
into One2many commands for hr.qualification model
|
||||
"""
|
||||
commands = []
|
||||
for q in quals_list or []:
|
||||
commands.append((0, 0, {
|
||||
"qualification_name": q.get("qualification_name"),
|
||||
"date_obtained": str(q.get("date_obtained","")),
|
||||
"institute": q.get("institute"),
|
||||
}))
|
||||
return commands
|
||||
|
||||
def _prepare_certification_employee_lines(self, certs_list):
|
||||
"""
|
||||
Convert the list of certification_employee dicts from the request
|
||||
into One2many commands for hr.certification model
|
||||
"""
|
||||
commands = []
|
||||
for c in certs_list or []:
|
||||
commands.append((0, 0, {
|
||||
"certification_name": c.get("certification_name"),
|
||||
"date_obtained":str( c.get("date_obtained","")),
|
||||
"organization": c.get("organization"),
|
||||
}))
|
||||
return commands
|
||||
|
||||
def _get_request_return_data(self, req):
|
||||
"""
|
||||
Build a dictionary of fields to return for a single record
|
||||
(similar to the detailed response in 3.3 Get Request by ID)
|
||||
"""
|
||||
res = {
|
||||
"id": req.id,
|
||||
"from_hr": req.from_hr,
|
||||
"date": req.date,
|
||||
"comment": req.comment or "",
|
||||
"state": req.state,
|
||||
'state_name': self.get_lable_selection(req, 'state', req.state),
|
||||
"request_type": req.request_type,
|
||||
"employee_id": req.employee_id.id if req.employee_id else None,
|
||||
"employee_dependant": [],
|
||||
"qualification_employee": [],
|
||||
"certification_employee": [],
|
||||
"create_insurance_request": req.create_insurance_request,
|
||||
"print_type": req.print_type,
|
||||
"destination": req.destination.id if req.destination else None,
|
||||
"parent_request_id": req.parent_request_id.id if req.parent_request_id else None,
|
||||
"company_id": req.company_id.id if req.company_id else None,
|
||||
}
|
||||
res = convert_dates_in_data(res)
|
||||
|
||||
# Build One2many lines for employee_dependant
|
||||
for dep in req.employee_dependant:
|
||||
res["employee_dependant"].append({
|
||||
"name": dep.name,
|
||||
"relation": dep.relation,
|
||||
"date_of_birth": dep.date_of_birth,
|
||||
})
|
||||
|
||||
# Build One2many lines for qualification_employee
|
||||
for q in req.qualification_employee:
|
||||
res["qualification_employee"].append({
|
||||
"qualification_name": q.qualification_name,
|
||||
"date_obtained": q.date_obtained,
|
||||
"institute": q.institute,
|
||||
})
|
||||
res["qualification_employee"] = convert_dates_in_data(res["qualification_employee"])
|
||||
# Build One2many lines for certification_employee
|
||||
for c in req.certification_employee:
|
||||
res["certification_employee"].append({
|
||||
"certification_name": c.certification_name,
|
||||
"date_obtained": c.date_obtained,
|
||||
"organization": c.organization,
|
||||
})
|
||||
res["certification_employee"] = convert_dates_in_data(res["certification_employee"])
|
||||
|
||||
return res
|
||||
|
||||
# --------------------------------------------
|
||||
# 3.1 Create Request (POST)
|
||||
# --------------------------------------------
|
||||
@http.route(['/rest_api/v2/employee_other_request'],
|
||||
type='http', auth='none', csrf=False, methods=['POST'])
|
||||
def create_request(self, **kw):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(
|
||||
code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False
|
||||
)
|
||||
|
||||
# 2) Validate/Parse Body
|
||||
required_fields = ["date", "request_type", "employee_id", "company_id"]
|
||||
missing = [f for f in required_fields if f not in body]
|
||||
if missing:
|
||||
return http_helper.response(
|
||||
code=400,
|
||||
message=_("Missing required fields: %s") % ", ".join(missing),
|
||||
success=False
|
||||
)
|
||||
|
||||
try:
|
||||
with request.env.cr.savepoint():
|
||||
# Prepare Odoo create vals
|
||||
vals = {
|
||||
"from_hr": body.get("from_hr", False),
|
||||
"date": body["date"],
|
||||
"comment": body.get("comment") or "",
|
||||
"request_type": body["request_type"],
|
||||
"employee_id": body["employee_id"],
|
||||
"employee_dependant": self._prepare_employee_dependant_lines(body.get("employee_dependant", [])),
|
||||
"qualification_employee": self._prepare_qualification_employee_lines(
|
||||
body.get("qualification_employee", [])),
|
||||
"certification_employee": self._prepare_certification_employee_lines(
|
||||
body.get("certification_employee", [])),
|
||||
"create_insurance_request": body.get("create_insurance_request", False),
|
||||
"print_type": body.get("print_type", ""),
|
||||
"destination": body.get("destination") or False,
|
||||
"parent_request_id": body.get("parent_request_id") or False,
|
||||
"company_id": body["company_id"],
|
||||
}
|
||||
|
||||
# Create record
|
||||
new_req = request.env["employee.other.request"].sudo().create(vals)
|
||||
|
||||
# Build success response
|
||||
data = self._get_request_return_data(new_req)
|
||||
return http_helper.response(
|
||||
message=_("Request created successfully"),
|
||||
data=data
|
||||
)
|
||||
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.error("Error creating request: %s", str(e))
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Unexpected error while creating request")
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
# --------------------------------------------
|
||||
# 3.2 Get All Requests (GET) with Pagination
|
||||
# --------------------------------------------
|
||||
@http.route(['/rest_api/v2/employee_other_request'],
|
||||
type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_all_requests(self, **kw):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(
|
||||
code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False
|
||||
)
|
||||
|
||||
try:
|
||||
# 2) Parse Query params
|
||||
page = int(kw.get("page", 1))
|
||||
limit = int(kw.get("limit", 10))
|
||||
sort = kw.get("sort", "") # e.g. 'date' or '-state'
|
||||
filters_str = kw.get("filters", "") # e.g. 'state=approved'
|
||||
|
||||
domain = []
|
||||
if filters_str:
|
||||
# Very naive filter parser: "state=approved;request_type=insurance"
|
||||
for part in filters_str.split(";"):
|
||||
if "=" in part:
|
||||
k, v = part.split("=", 1)
|
||||
if ',' in v:
|
||||
domain.append((k.strip(), "in", v.split(',')))
|
||||
else:
|
||||
domain.append((k.strip(), "=", v.strip()))
|
||||
domain.append(('request_type', 'in', ['salary_define', 'salary_fixing']))
|
||||
|
||||
offset = (page - 1) * limit if page > 0 else 0
|
||||
order = False
|
||||
if sort:
|
||||
if sort.startswith("-"):
|
||||
order = sort[1:] + " desc"
|
||||
else:
|
||||
order = sort + " asc"
|
||||
|
||||
RequestObj = request.env["employee.other.request"].with_user(user.id)
|
||||
total_count = RequestObj.search_count(domain)
|
||||
records = RequestObj.search(domain, offset=offset, limit=limit, order=order)
|
||||
|
||||
# Build minimal list
|
||||
request_list = []
|
||||
for r in records:
|
||||
request_list.append(self._get_request_return_data(r))
|
||||
request_list = convert_dates_in_data(request_list)
|
||||
result_data = {
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
"total_records": total_count,
|
||||
"requests": request_list,
|
||||
}
|
||||
return http_helper.response(
|
||||
message=_("Requests retrieved successfully"),
|
||||
data=result_data
|
||||
)
|
||||
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.error("Error getting requests: %s", str(e))
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Unexpected error while listing requests")
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
# --------------------------------------------
|
||||
# 3.3 Get Request by ID (GET)
|
||||
# /rest_api/v2/employee_request/<id>
|
||||
# --------------------------------------------
|
||||
@http.route(['/rest_api/v2/employee_request/<int:req_id>'],
|
||||
type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_request_by_id(self, req_id, **kw):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(
|
||||
code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False
|
||||
)
|
||||
|
||||
try:
|
||||
req = request.env["employee.other.request"].sudo().search([("id", "=", req_id)], limit=1)
|
||||
if not req:
|
||||
return http_helper.response(code=404, message="Request not found", success=False)
|
||||
|
||||
data = self._get_request_return_data(req)
|
||||
return http_helper.response(
|
||||
message=_("Request retrieved successfully"),
|
||||
data=data
|
||||
)
|
||||
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.error("Error getting request by ID: %s", str(e))
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Unexpected error while getting request by ID")
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
# --------------------------------------------
|
||||
# 3.4 Update Request (PATCH)
|
||||
# /rest_api/v2/employee_other_request/<id>
|
||||
# --------------------------------------------
|
||||
@http.route(['/rest_api/v2/employee_other_request/<int:req_id>'],
|
||||
type='http', auth='none', csrf=False, methods=['PATCH'])
|
||||
def update_request(self, req_id, **kw):
|
||||
"""
|
||||
Allows partial update of fields present in the request body.
|
||||
Example Body:
|
||||
{
|
||||
"state": "approved",
|
||||
"comment": "Request approved by HR.",
|
||||
"print_type": "no_salary"
|
||||
}
|
||||
"""
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(
|
||||
code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False
|
||||
)
|
||||
|
||||
try:
|
||||
with request.env.cr.savepoint():
|
||||
req = request.env["employee.other.request"].sudo().search([("id", "=", req_id)], limit=1)
|
||||
if not req:
|
||||
return http_helper.response(code=404, message="Request not found", success=False)
|
||||
|
||||
# Build a vals dict for fields that appear in the body
|
||||
updatable_fields = [
|
||||
"from_hr", "date", "comment", "state", "request_type",
|
||||
"employee_id", "create_insurance_request", "print_type",
|
||||
"destination", "parent_request_id", "company_id"
|
||||
]
|
||||
vals = {}
|
||||
for field_name in updatable_fields:
|
||||
if field_name in body:
|
||||
vals[field_name] = body[field_name]
|
||||
|
||||
# Handle One2many lines if needed
|
||||
if "employee_dependant" in body:
|
||||
# Clear existing lines, then add the new ones
|
||||
vals["employee_dependant"] = [(5, 0, 0)]
|
||||
vals["employee_dependant"] += self._prepare_employee_dependant_lines(body["employee_dependant"])
|
||||
if "qualification_employee" in body:
|
||||
vals["qualification_employee"] = [(5, 0, 0)]
|
||||
vals["qualification_employee"] += self._prepare_qualification_employee_lines(
|
||||
body["qualification_employee"])
|
||||
if "certification_employee" in body:
|
||||
vals["certification_employee"] = [(5, 0, 0)]
|
||||
vals["certification_employee"] += self._prepare_certification_employee_lines(
|
||||
body["certification_employee"])
|
||||
|
||||
req.write(vals)
|
||||
updated_data = self._get_request_return_data(req)
|
||||
return http_helper.response(
|
||||
message=_("Request updated successfully"),
|
||||
data=updated_data
|
||||
)
|
||||
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.error("Error updating request: %s", str(e))
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Unexpected error while updating request")
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
# --------------------------------------------
|
||||
# 3.5 Delete Request (DELETE)
|
||||
# /rest_api/v2/employee_other_request/<int:req_id>
|
||||
# --------------------------------------------
|
||||
@http.route(['/rest_api/v2/employee_other_request/<int:req_id>'],
|
||||
type='http', auth='none', csrf=False, methods=['DELETE'])
|
||||
def delete_request(self, req_id, **kw):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(
|
||||
code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False
|
||||
)
|
||||
|
||||
try:
|
||||
with request.env.cr.savepoint():
|
||||
req = request.env["employee.other.request"].sudo().search([("id", "=", req_id)], limit=1)
|
||||
if not req:
|
||||
return http_helper.response(code=404, message="Request not found", success=False)
|
||||
|
||||
req.unlink()
|
||||
return http_helper.response(
|
||||
message=_("Request deleted successfully"),
|
||||
data={"id": req_id}
|
||||
)
|
||||
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.error("Error deleting request: %s", str(e))
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Unexpected error while deleting request")
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# 4. Related Models (Read-Only)
|
||||
# 4.1 Salary Destination
|
||||
# 4.2 Get Qualifications
|
||||
# 4.3 Get Employee Dependents
|
||||
# 4.4 Get Certifications
|
||||
# --------------------------------------------
|
||||
|
||||
class EmployeeOtherRequestRelatedModelsController(http.Controller):
|
||||
"""
|
||||
Minimal endpoints for related models used in employee.other.request
|
||||
"""
|
||||
def get_lable_selection(self, rec, field_name, state):
|
||||
return dict(rec._fields[field_name]._description_selection(http.request.env)).get(state)
|
||||
# 4.1 Salary Destination (salary.destination)
|
||||
@http.route(['/rest_api/v2/salary_destination'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_salary_destination_list(self, **kw):
|
||||
"""
|
||||
GET /rest_api/v2/salary_destination
|
||||
Return a list of salary.destination records
|
||||
"""
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# If this is publicly available, skip token check or do it similarly
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
|
||||
try:
|
||||
destinations = request.env['salary.destination'].sudo().search([])
|
||||
data = []
|
||||
for dest in destinations:
|
||||
data.append({
|
||||
"id": dest.id,
|
||||
"name": dest.name,
|
||||
"english_name": dest.english_name,
|
||||
})
|
||||
return http_helper.response(message="Salary Destination List", data=data)
|
||||
|
||||
except Exception as e:
|
||||
_logger.exception("Error listing salary destinations")
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
|
||||
@http.route(['/api/salary_destination/<int:dest_id>'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_salary_destination_detail(self, dest_id, **kw):
|
||||
"""
|
||||
GET /api/salary_destination/<id>
|
||||
Return the detail of a specific salary.destination record
|
||||
(Note: endpoint path from your specification)
|
||||
"""
|
||||
# If you want token checks, add them
|
||||
dest = request.env['salary.destination'].sudo().search([('id', '=', dest_id)], limit=1)
|
||||
if not dest:
|
||||
return http_helper.response(code=404, message="Salary destination not found", success=False)
|
||||
data = {
|
||||
"id": dest.id,
|
||||
"name": dest.name,
|
||||
"english_name": dest.english_name,
|
||||
}
|
||||
return http_helper.response(message="Salary Destination Detail", data=data)
|
||||
|
||||
# 4.2 Get Qualifications (Read-Only)
|
||||
@http.route(['/rest_api/v2/qualifications'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_qualifications_list(self, **kw):
|
||||
"""
|
||||
GET /rest_api/v2/qualifications
|
||||
Retrieve a paginated list of qualifications
|
||||
Query Params:
|
||||
page, limit, sort, filters
|
||||
"""
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# If needed, check token:
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
|
||||
try:
|
||||
page = int(kw.get("page", 1))
|
||||
limit = int(kw.get("limit", 10))
|
||||
sort = kw.get("sort", "") # e.g. '-comp_date'
|
||||
filters_str = kw.get("filters", "")
|
||||
|
||||
domain = []
|
||||
if filters_str:
|
||||
for part in filters_str.split(";"):
|
||||
if "=" in part:
|
||||
k, v = part.split("=", 1)
|
||||
domain.append((k.strip(), "=", v.strip()))
|
||||
|
||||
offset = (page - 1) * limit if page > 0 else 0
|
||||
order = False
|
||||
if sort:
|
||||
if sort.startswith("-"):
|
||||
order = sort[1:] + " desc"
|
||||
else:
|
||||
order = sort + " asc"
|
||||
|
||||
Qualification = request.env["hr.qualification"].sudo()
|
||||
total_count = Qualification.search_count(domain)
|
||||
records = Qualification.search(domain, offset=offset, limit=limit, order=order)
|
||||
|
||||
qual_list = []
|
||||
for q in records:
|
||||
qual_list.append({
|
||||
"id": q.id,
|
||||
"uni_name": q.uni_name.id if q.uni_name else None, # or q.uni_name.name?
|
||||
"col_name": q.col_name.id if q.col_name else None,
|
||||
"prg_status": q.prg_status or "",
|
||||
"comp_date": q.comp_date or "",
|
||||
"qualification_degree": q.qualification_degree or "",
|
||||
"country_name": q.country_name.id if q.country_name else None,
|
||||
"attachment": None,
|
||||
})
|
||||
qual_list = convert_dates_in_data(qual_list)
|
||||
data = {
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
"total_records": total_count,
|
||||
"qualifications": qual_list,
|
||||
}
|
||||
return http_helper.response(message="Qualifications retrieved", data=data)
|
||||
|
||||
except Exception as e:
|
||||
_logger.exception("Error listing qualifications")
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
|
||||
# 4.3 Get Employee Dependents (Read-Only)
|
||||
@http.route(['/rest_api/v2/employee_dependents'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_employee_dependents_list(self, **kw):
|
||||
"""
|
||||
GET /rest_api/v2/employee_dependents
|
||||
Paginated list of dependents
|
||||
Query Params:
|
||||
page, limit, filters
|
||||
"""
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# If needed, check token:
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
|
||||
try:
|
||||
page = int(kw.get("page", 1))
|
||||
limit = int(kw.get("limit", 10))
|
||||
filters_str = kw.get("filters", "")
|
||||
|
||||
domain = []
|
||||
if filters_str:
|
||||
for part in filters_str.split(";"):
|
||||
if "=" in part:
|
||||
k, v = part.split("=", 1)
|
||||
domain.append((k.strip(), "=", v.strip()))
|
||||
|
||||
offset = (page - 1) * limit if page > 0 else 0
|
||||
|
||||
DependentModel = request.env["hr.employee.dependent"].sudo()
|
||||
total_count = DependentModel.search_count(domain)
|
||||
records = DependentModel.search(domain, offset=offset, limit=limit)
|
||||
|
||||
dep_list = []
|
||||
for d in records:
|
||||
dep_list.append({
|
||||
"id": d.id,
|
||||
"name": d.name,
|
||||
"birthday": d.birthday,
|
||||
"age": d.age,
|
||||
"gender": d.gender,
|
||||
"relation": d.relation,
|
||||
"nationality": d.nationality.name if d.nationality else "",
|
||||
"passport_no": d.passport_no,
|
||||
"passport_issue_date": d.passport_issue_date,
|
||||
"passport_expire_date": d.passport_expire_date,
|
||||
"remarks": d.remarks,
|
||||
"has_ticket": d.has_ticket,
|
||||
})
|
||||
|
||||
data = {
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
"total_records": total_count,
|
||||
"dependents": dep_list,
|
||||
}
|
||||
return http_helper.response(message="Dependents retrieved", data=data)
|
||||
|
||||
except Exception as e:
|
||||
_logger.exception("Error listing employee dependents")
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
|
||||
# 4.4 Get Certifications (Read-Only)
|
||||
@http.route(['/rest_api/v2/certifications'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_certifications_list(self, **kw):
|
||||
"""
|
||||
GET /rest_api/v2/certifications
|
||||
Paginated list of certifications
|
||||
Query Params:
|
||||
page, limit, filters
|
||||
"""
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# If needed, check token:
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
|
||||
try:
|
||||
page = int(kw.get("page", 1))
|
||||
limit = int(kw.get("limit", 10))
|
||||
filters_str = kw.get("filters", "")
|
||||
|
||||
domain = []
|
||||
if filters_str:
|
||||
for part in filters_str.split(";"):
|
||||
if "=" in part:
|
||||
k, v = part.split("=", 1)
|
||||
domain.append((k.strip(), "=", v.strip()))
|
||||
|
||||
offset = (page - 1) * limit if page > 0 else 0
|
||||
|
||||
CertificationModel = request.env["hr.certification"].sudo()
|
||||
total_count = CertificationModel.search_count(domain)
|
||||
records = CertificationModel.search(domain, offset=offset, limit=limit)
|
||||
|
||||
cert_list = []
|
||||
for c in records:
|
||||
cert_list.append({
|
||||
"id": c.id,
|
||||
"car_name": c.car_name or "", # or maybe c.certification_name in your DB
|
||||
"issue_org": c.issue_org or "",
|
||||
"issue_date": c.issue_date or "",
|
||||
"exp_date": c.exp_date or "",
|
||||
"regis_no": c.regis_no or "",
|
||||
"certification_degree": c.certification_degree or "",
|
||||
"contact_name": c.contact_name or "",
|
||||
"contact_phn": c.contact_phn or "",
|
||||
"contact_email": c.contact_email or "",
|
||||
"country_name": c.country_name.name if c.country_name else "",
|
||||
"attachment": None,
|
||||
})
|
||||
cert_list = convert_dates_in_data(cert_list)
|
||||
|
||||
data = {
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
"total_records": total_count,
|
||||
"certifications": cert_list,
|
||||
}
|
||||
return http_helper.response(message="Certifications retrieved", data=data)
|
||||
|
||||
except Exception as e:
|
||||
_logger.exception("Error listing certifications")
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import werkzeug
|
||||
from odoo import http, tools
|
||||
from odoo.http import request, Response
|
||||
from odoo.exceptions import UserError
|
||||
import base64
|
||||
from ...validator import validator
|
||||
from ...http_helper import http_helper
|
||||
from odoo.tools.translate import _
|
||||
import json
|
||||
import logging
|
||||
import traceback
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EmployeeOtherRequest(http.Controller):
|
||||
|
||||
def get_lable_selection(self, rec, field_name, state):
|
||||
return dict(rec._fields[field_name]._description_selection(http.request.env)).get(state)
|
||||
|
||||
@http.route(['/old/rest_api/v2/employeeRequest/types', '/rest_api/v2/employeeRequest/types/<string:key>'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_employee_other_request_type(self, key=None):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400, message=_("You are not allowed to perform this operation. please check with one of your team admins"), success=False)
|
||||
employee = http.request.env['hr.employee'].search(
|
||||
[('user_id', '=', user.id)], limit=1)
|
||||
if not employee:
|
||||
return http_helper.response(code=400, message=_("You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
|
||||
try:
|
||||
data = {"other_request_types": dict(http.request.env['employee.other.request']._fields['request_type']._description_selection(http.request.env)),
|
||||
"salary_request_print_type": dict(http.request.env['employee.other.request']._fields['print_type']._description_selection(http.request.env)),
|
||||
"salary_request_state": dict(http.request.env['employee.other.request']._fields['state']._description_selection(http.request.env)),
|
||||
"certification_degree": dict(http.request.env['hr.certification']._fields['certification_degree']._description_selection(http.request.env)),
|
||||
"qualification_degree": dict(http.request.env['hr.qualification']._fields['qualification_degree']._description_selection(http.request.env)),
|
||||
"gender": dict(http.request.env['hr.employee.dependent']._fields['gender']._description_selection(http.request.env)),
|
||||
"relation": dict(http.request.env['hr.employee.dependent']._fields['relation']._description_selection(http.request.env)),
|
||||
"nationality": request.env['res.country'].sudo().search([]).read(['id', 'name']),
|
||||
"uni_name_UniversityName": request.env['office.office'].sudo().search([]).read(['id', 'name']),
|
||||
"col_name_College": request.env['hr.college'].sudo().search([]).read(['id', 'name']),
|
||||
"hr_qualification_name": request.env['hr.qualification.name'].sudo().search([]).read(['id', 'name']),
|
||||
"qualification_specification": request.env['qualification.specification'].sudo().search([('type', '=', 'qualification')]).read(['id', 'name']),
|
||||
"certificate_specification": request.env['qualification.specification'].sudo().search([("type", "=", "certificate")]).read(['id', 'name']),
|
||||
"membership_type": request.env['membership.types'].sudo().search([]).read(['id', 'name']),
|
||||
"membership_categorys": request.env['membership.categorys'].sudo().search([]).read(['id', 'name']),
|
||||
}
|
||||
if key:
|
||||
data = {key: data[key]}
|
||||
return http_helper.response(message="Data Found", data=data)
|
||||
except Exception as e:
|
||||
_logger.error(str(e))
|
||||
_logger.error(traceback.format_exc())
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=403, message=message)
|
||||
|
||||
@http.route(['/old/rest_api/v2/employeeRequests/', '/rest_api/v2/employeeRequests/<int:id>'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_employee_other_requests(self, id=None, approvel=None, page=None, **kw):
|
||||
page = page if page else 1
|
||||
page, offset, limit, prev = validator.get_page_pagination(page)
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400, message=_("You are not allowed to perform this operation. please check with one of your team admins"), success=False)
|
||||
employee = http.request.env['hr.employee'].search([('user_id', '=', user.id)], limit=1)
|
||||
if not employee:
|
||||
return http_helper.response(code=400, message=_("You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
|
||||
try:
|
||||
if approvel:
|
||||
domain = [('state', '!=', 'draft'),('employee_id', '!=', employee.id)]
|
||||
emp_requests = http.request.env['employee.other.request'].search(domain, order='date desc', offset=offset, limit=limit)
|
||||
count = http.request.env['employee.other.request'].search_count(domain)
|
||||
else:
|
||||
emp_requests = http.request.env['employee.other.request'].search([('employee_id', '=', employee.id)], order='date desc', offset=offset, limit = limit)
|
||||
count = http.request.env['employee.other.request'].search_count([('employee_id', '=', employee.id)])
|
||||
if id:
|
||||
emp_requests = http.request.env['employee.other.request'].search([('id', '=', int(id))], order='date desc')
|
||||
count = http.request.env['employee.other.request'].search_count([('id', '=', int(id))])
|
||||
employeeRequests = []
|
||||
if emp_requests:
|
||||
for s in emp_requests:
|
||||
value = {
|
||||
'id': s.id,
|
||||
'employee_id': s.employee_id.name,
|
||||
'department_id': s.department_id.name,
|
||||
'destination': s.destination,
|
||||
'comment': s.comment,
|
||||
'request_type': s.request_type,
|
||||
'request_type_lable': self.get_lable_selection(s, 'request_type', s.request_type),
|
||||
'state': s.state,
|
||||
'state_lable': self.get_lable_selection(s, 'state', s.state),
|
||||
}
|
||||
employee_dependant = []
|
||||
for dep in s.employee_dependant:
|
||||
dep_val = {
|
||||
'name': dep.name or '',
|
||||
'age': dep.age or '',
|
||||
'birthday': str(dep.birthday or ''),
|
||||
'gender': dep.gender or '',
|
||||
'gender_lable': self.get_lable_selection(dep, 'gender', dep.gender),
|
||||
'relation': dep.relation or '',
|
||||
'relation_lable': self.get_lable_selection(dep, 'relation', dep.relation),
|
||||
'nationality': dep.nationality.read(['id', 'name'])[0] or {},
|
||||
'passport_no': dep.passport_no or '',
|
||||
'passport_issue_date': str(dep.passport_issue_date or ''),
|
||||
'passport_expire_date': str(dep.passport_expire_date or ''),
|
||||
# 'remarks': dep.remarks,
|
||||
'degree_medical_insu': dep.degree_medical_insu or '',
|
||||
'medical_insurance_num': dep.medical_insurance_num or '',
|
||||
'identity_num': dep.identity_num or '',
|
||||
'has_ticket': dep.has_ticket,
|
||||
# 'attachment': dep.attachment,
|
||||
|
||||
}
|
||||
employee_dependant.append(dep_val)
|
||||
if s.employee_dependant:
|
||||
value['employee_dependant'] = employee_dependant
|
||||
qualification_employee = []
|
||||
for qua in s.qualification_employee:
|
||||
qua_val = {
|
||||
'uni_name_UniversityName': qua.uni_name.read(['id', 'name'])[0] or {},
|
||||
'col_name_CollegeName': qua.col_name.read(['id', 'name'])[0] or {},
|
||||
'prg_status': qua.prg_status or '',
|
||||
'comp_date': str(qua.comp_date or ''),
|
||||
'end_date': str(qua.end_date or ''),
|
||||
'degree': qua.degree or 0.0,
|
||||
'contact_name': qua.contact_name or '',
|
||||
'contact_phn': qua.contact_phn or '',
|
||||
'contact_email': qua.contact_email or '',
|
||||
'country_name': qua.country_name.read(['id', 'name'])[0] or {},
|
||||
'qualification_degree': qua.qualification_degree or '',
|
||||
'qualification_degree_lable': self.get_lable_selection(qua, 'qualification_degree', qua.qualification_degree),
|
||||
'qualification_specification_id': qua.qualification_specification_id.read(['id', 'name'])[0] or {},
|
||||
'qualification_id': qua.qualification_id.read(['id', 'name'])[0] or {},
|
||||
# 'attachment': qua.attachment,
|
||||
|
||||
}
|
||||
qualification_employee.append(qua_val)
|
||||
if s.qualification_employee:
|
||||
value['qualification_employee'] = qualification_employee
|
||||
certification_employee = []
|
||||
for cer in s.certification_employee:
|
||||
cer_val = {
|
||||
'id': cer.id,
|
||||
'cer_name': cer.car_name or '',
|
||||
'certification_specification': cer.certification_specification_id.name or '',
|
||||
'issue_org': cer.issue_org or '',
|
||||
'certification_degree': cer.certification_degree or '',
|
||||
'certification_degree_lable': self.get_lable_selection(cer, 'certification_degree', cer.certification_degree),
|
||||
'issue_date': str(cer.issue_date or ''),
|
||||
'exp_date': str(cer.exp_date or ''),
|
||||
'country_id': cer.country_name.read(['id', 'name'])[0] or {},
|
||||
}
|
||||
certification_employee.append(cer_val)
|
||||
if s.certification_employee:
|
||||
value['certification_employee'] = certification_employee
|
||||
|
||||
employeeRequests.append(value)
|
||||
next = validator.get_page_pagination_next(page, count)
|
||||
url = "/rest_api/v2/employeeRequests?approvel=%s&page=%s" % ( approvel, next) if next else False
|
||||
prev_url = "/rest_api/v2/employeeRequests?approvel=%s&page=%s" % ( approvel, prev) if prev else False
|
||||
data = {'links': {'prev': prev_url, 'next': url, },
|
||||
'count': count,
|
||||
'results': {'employeeRequests': employeeRequests, }}
|
||||
return http_helper.response(message="Data Found", data=data)
|
||||
|
||||
except Exception as e:
|
||||
_logger.error(str(e))
|
||||
_logger.error(traceback.format_exc())
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=403, message=message)
|
||||
|
||||
@http.route([
|
||||
'/old/rest_api/v2/report/<reportname>/<docids>',
|
||||
'/rest_api/v2/report/',
|
||||
], type='http', auth='none')
|
||||
def report_routes(self, reportname=None, docids=None, **data):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400, message=_("You are not allowed to perform this operation. please check with one of your team admins"), success=False)
|
||||
employee = http.request.env['hr.employee'].search([('user_id', '=', user.id)], limit=1)
|
||||
if not employee:
|
||||
return http_helper.response(code=400, message=_("You Have issue in your employee profile. please check with one of your team admins"), success=False)
|
||||
if not reportname:
|
||||
return http_helper.response(code=400, message=_("please sent report name . please check with one of your team admins"), success=False)
|
||||
report = request.env['ir.actions.report']._get_report_from_name(reportname)
|
||||
if docids:
|
||||
docids = [int(i) for i in docids.split(',')]
|
||||
else:
|
||||
return http_helper.response(code=400, message=_("please sent id recrod print report. please check with one of your team admins"), success=False)
|
||||
if report:
|
||||
model = report.model_id.model or report.model
|
||||
if len(request.env[model].search([('id', 'in', docids)])) < len(docids):
|
||||
return http_helper.response(code=400, message=_("You Have issue in your data not found. please check with one of your team admins"), success=False)
|
||||
else:
|
||||
return http_helper.response(code=400, message=_("You Have issue in your report not found. please check with one of your team admins"), success=False)
|
||||
try:
|
||||
context = dict(request.env.context)
|
||||
pdf = report.with_context(context)._render_qweb_pdf(docids, data=data)[0]
|
||||
pdfhttpheaders = [('Content-Type', 'application/pdf'),('Content-Length', len(pdf))]
|
||||
return request.make_response(pdf, headers=pdfhttpheaders)
|
||||
except Exception as e:
|
||||
_logger.error(str(e))
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=403, message=message)
|
||||
|
|
@ -0,0 +1,665 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
|
||||
from odoo import http, _
|
||||
from odoo.exceptions import UserError, AccessError, ValidationError
|
||||
from odoo.http import request
|
||||
from ...http_helper import http_helper
|
||||
from ...validator import validator
|
||||
from datetime import date, datetime
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def convert_dates_in_data(data):
|
||||
if isinstance(data, dict):
|
||||
for key, value in data.items():
|
||||
data[key] = convert_dates_in_data(value)
|
||||
return data
|
||||
elif isinstance(data, list):
|
||||
return [convert_dates_in_data(item) for item in data]
|
||||
elif isinstance(data, (date, datetime)):
|
||||
return data.isoformat()
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
class HrOfficialMissionController(http.Controller):
|
||||
"""
|
||||
Example Controller for HR Official Mission CRUD Endpoints:
|
||||
1.1. Create Mission (POST /rest_api/v2/hr_official_mission)
|
||||
1.2. Get All Missions (Paginate) (GET /rest_api/v2/hr_official_mission)
|
||||
1.3. Get Mission by ID (GET /rest_api/v2/hr_official_mission/<id>)
|
||||
1.4. Update Mission (PATCH /rest_api/v2/hr_official_mission/<id>)
|
||||
1.5. Delete Mission (DELETE /rest_api/v2/hr_official_mission/<id>)
|
||||
"""
|
||||
|
||||
def get_lable_selection(self, rec, field_name, state):
|
||||
return dict(rec._fields[field_name]._description_selection(http.request.env)).get(state)
|
||||
|
||||
def _get_mission_return_data(self, mission):
|
||||
"""
|
||||
Build the dictionary of fields to return in mission responses.
|
||||
This can be expanded according to your business needs.
|
||||
"""
|
||||
res = {
|
||||
"id": mission.id,
|
||||
"date": mission.date or False,
|
||||
"move_type_selection": dict(
|
||||
mission._fields['move_type']._description_selection(
|
||||
http.request.env)),
|
||||
"date_from": mission.date_from or False,
|
||||
"date_to": mission.date_to or False,
|
||||
"hour_from": mission.hour_from or 0.0,
|
||||
"hour_to": mission.hour_to or 0.0,
|
||||
"date_duration": mission.date_duration or 0.0,
|
||||
"duration_type": mission.duration_type or "",
|
||||
"hour_duration": mission.hour_duration or 0.0,
|
||||
"balance": mission.balance or 0.0,
|
||||
"early_exit": mission.early_exit or False,
|
||||
"mission_purpose": mission.mission_purpose or "",
|
||||
"state": mission.state or "",
|
||||
'state_name': self.get_lable_selection(mission, 'state', mission.state),
|
||||
"move_type": mission.move_type or "",
|
||||
"move_type_name": self.get_lable_selection(mission, 'move_type', mission.move_type),
|
||||
"department_id": mission.department_id.ids,
|
||||
"employee_ids": [],
|
||||
"approved_by": mission.approved_by.id if mission.approved_by else None,
|
||||
"approved_by_name": mission.approved_by.name if mission.approved_by else None,
|
||||
"refused_by": mission.refused_by.id if mission.refused_by else None,
|
||||
"refused_by_name": mission.refused_by.name if mission.refused_by else None,
|
||||
"mission_type": mission.mission_type.id if mission.mission_type else None,
|
||||
"mission_type_name": mission.mission_type.name if mission.mission_type else None,
|
||||
"country_id": mission.country_id.id if mission.country_id else None,
|
||||
"country_name": mission.country_id.name if mission.country_id else None,
|
||||
"ticket_insurance": mission.ticket_insurance or "",
|
||||
"car_insurance": mission.car_insurance or "",
|
||||
"self_car": mission.self_car or "",
|
||||
"car_type": mission.car_type or "",
|
||||
"rent_days": mission.rent_days or 0,
|
||||
"max_rent": mission.max_rent or 0,
|
||||
"visa": mission.visa or "",
|
||||
"note": mission.note or "",
|
||||
"course_name": mission.course_name.id if mission.course_name else None,
|
||||
"course_name_name": mission.course_name.name if mission.course_name else None,
|
||||
"process_type": mission.process_type or "",
|
||||
"train_category": mission.train_category or "",
|
||||
"partner_id": mission.partner_id.id if mission.partner_id else None,
|
||||
"partner_name": mission.partner_id.name if mission.partner_id else None,
|
||||
"destination": mission.destination.id if mission.destination else None,
|
||||
"destination_name": mission.destination.name if mission.destination else None,
|
||||
"issuing_ticket": mission.issuing_ticket or "",
|
||||
"ticket_cash_request_type": mission.ticket_cash_request_type.id if mission.ticket_cash_request_type else None,
|
||||
"ticket_cash_request_type_name": mission.ticket_cash_request_type.name if mission.ticket_cash_request_type else None,
|
||||
"ticket_cash_request_for": mission.ticket_cash_request_for or "",
|
||||
"Training_cost": mission.Training_cost or 0.0,
|
||||
"appraisal_check": mission.appraisal_check or False,
|
||||
"Tra_cost_invo_id": mission.Tra_cost_invo_id.id if mission.Tra_cost_invo_id else None,
|
||||
"max_of_employee": mission.max_of_employee or 0,
|
||||
"min_of_employee": mission.min_of_employee or 0,
|
||||
"employee_id": mission.employee_id.id if mission.employee_id else None,
|
||||
"employee_name": mission.employee_id.name if mission.employee_id else None,
|
||||
"reference": mission.reference or "",
|
||||
"company_id": mission.company_id.id if mission.company_id else None,
|
||||
"company_name": mission.company_id.name if mission.company_id else None,
|
||||
}
|
||||
res = convert_dates_in_data(res)
|
||||
|
||||
# Build One2many list (hr.official.mission.employee)
|
||||
employee_lines = []
|
||||
for line in mission.employee_ids:
|
||||
employee_lines.append({
|
||||
"date_from": line.date_from or False,
|
||||
"date_to": line.date_to or False,
|
||||
"days": line.days or 0,
|
||||
"hour_from": line.hour_from or 0,
|
||||
"hour_to": line.hour_to or 0,
|
||||
"hours": line.hours or 0,
|
||||
"day_price": line.day_price or 0,
|
||||
"hour_price": line.hour_price or 0,
|
||||
"amount": line.amount or 0,
|
||||
"fees_amount": line.fees_amount or 0,
|
||||
"appraisal_id": line.appraisal_id.id if line.appraisal_id else None,
|
||||
"appraisal_name": line.appraisal_id.name if line.appraisal_id else None,
|
||||
"appraisal_result": line.appraisal_result.id if line.appraisal_result else None,
|
||||
"employee_id": line.employee_id.id if line.employee_id else None,
|
||||
"employee_name": line.employee_id.name if line.employee_id else None,
|
||||
"account_move_id": line.account_move_id.id if line.account_move_id else None,
|
||||
"advantage_id": line.advantage_id.id if line.advantage_id else None,
|
||||
"train_cost_emp": line.train_cost_emp or 0,
|
||||
"total_hours": line.total_hours or 0,
|
||||
})
|
||||
employee_lines = convert_dates_in_data(employee_lines)
|
||||
res["employee_ids"] = employee_lines
|
||||
|
||||
return res
|
||||
|
||||
def _prepare_employee_ids(self, employee_ids_list):
|
||||
"""
|
||||
Convert the list of dictionaries (employee lines) from the request body
|
||||
into the Odoo-compliant One2many / Many2many commands.
|
||||
Each line => (0, 0, {...fields...}).
|
||||
"""
|
||||
commands = []
|
||||
for line in employee_ids_list or []:
|
||||
cmd_vals = {
|
||||
"date_from": line.get("date_from"),
|
||||
"date_to": line.get("date_to"),
|
||||
"days": line.get("days", 0),
|
||||
"hour_from": line.get("hour_from", 0),
|
||||
"hour_to": line.get("hour_to", 0),
|
||||
"hours": line.get("hours", 0),
|
||||
"day_price": line.get("day_price", 0),
|
||||
"hour_price": line.get("hour_price", 0),
|
||||
"amount": line.get("amount", 0),
|
||||
"fees_amount": line.get("fees_amount", 0),
|
||||
"appraisal_id": line.get("appraisal_id") or False,
|
||||
"appraisal_result": line.get("appraisal_result") or False,
|
||||
"employee_id": line.get("employee_id") or False,
|
||||
"account_move_id": line.get("account_move_id") or False,
|
||||
"advantage_id": line.get("advantage_id") or False,
|
||||
"train_cost_emp": line.get("train_cost_emp", 0),
|
||||
"total_hours": line.get("total_hours", 0),
|
||||
}
|
||||
cmd_vals = convert_dates_in_data(cmd_vals)
|
||||
commands.append((0, 0, cmd_vals))
|
||||
return commands
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 1.1 Create Mission (POST)
|
||||
# ----------------------------------------------------------
|
||||
@http.route(['/rest_api/v2/hr_official_mission'],
|
||||
type='http', auth='none', csrf=False, methods=['POST'])
|
||||
def create_mission(self, **kw):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False)
|
||||
employee = request.env['hr.employee'].sudo().search([('user_id', '=', user.id)], limit=1)
|
||||
# 2) Validate/Parse Body
|
||||
# Required fields check, e.g. 'date_from', 'date_to', etc.
|
||||
required_fields = ["date", "date_from", "date_to", "hour_from", "hour_to",
|
||||
"mission_type"]
|
||||
missing_fields = [f for f in required_fields if f not in body]
|
||||
if missing_fields:
|
||||
return http_helper.response(
|
||||
code=400,
|
||||
message=_("Missing required fields: %s") % ", ".join(missing_fields),
|
||||
success=False
|
||||
)
|
||||
|
||||
# 3) Create the record in Odoo
|
||||
try:
|
||||
with request.env.cr.savepoint():
|
||||
# Convert department_id from a list to commands if needed
|
||||
# department_ids = body.get("department_id", [])
|
||||
# if department_ids and isinstance(department_ids, list):
|
||||
# # For many2many, use [(6, 0, list_of_ids)]
|
||||
# department_val = [(6, 0, department_ids)]
|
||||
# else:
|
||||
# department_val = False
|
||||
|
||||
# Convert employee_ids to one2many lines
|
||||
# employee_lines = self._prepare_employee_ids(body.get("employee_ids", []))
|
||||
|
||||
# vals = {
|
||||
# "date": body["date"],
|
||||
# "date_from": body["date_from"],
|
||||
# "date_to": body["date_to"],
|
||||
# "hour_from": body["hour_from"],
|
||||
# "hour_to": body["hour_to"],
|
||||
# "date_duration": body.get("date_duration", 0),
|
||||
# "hour_duration": body.get("hour_duration", 0),
|
||||
# "balance": body.get("balance", 0),
|
||||
# "early_exit": body.get("early_exit", False),
|
||||
# "mission_purpose": body.get("mission_purpose", ""),
|
||||
# # "move_type": body["move_type"],
|
||||
# "department_id": department_val,
|
||||
# "employee_ids": employee_lines,
|
||||
# "approved_by": int(body.get("approved_by")) if body.get("approved_by") else False,
|
||||
# "refused_by": int(body.get("refused_by")) if body.get("refused_by") else False,
|
||||
# "mission_type": int(body["mission_type"]),
|
||||
# "country_id": int(body.get("country_id")) if body.get("country_id") else False,
|
||||
# "ticket_insurance": body.get("ticket_insurance", ""),
|
||||
# "car_insurance": body.get("car_insurance", ""),
|
||||
# "self_car": body.get("self_car", ""),
|
||||
# "car_type": body.get("car_type", ""),
|
||||
# "rent_days": body.get("rent_days", 0),
|
||||
# "max_rent": body.get("max_rent", 0),
|
||||
# "visa": body.get("visa", ""),
|
||||
# "note": body.get("note", ""),
|
||||
# "course_name": body.get("course_name") or False,
|
||||
# "process_type": body.get("process_type", ""),
|
||||
# "train_category": body.get("train_category", ""),
|
||||
# "partner_id": int(body.get("partner_id")) if body.get("partner_id") else False,
|
||||
# "issuing_ticket": body.get("issuing_ticket", ""),
|
||||
# "ticket_cash_request_type": body.get("ticket_cash_request_type") or False,
|
||||
# "ticket_cash_request_for": body.get("ticket_cash_request_for", ""),
|
||||
# "Training_cost": body.get("Training_cost", 0.0),
|
||||
# "appraisal_check": body.get("appraisal_check", False),
|
||||
# "Tra_cost_invo_id": int(body.get("Tra_cost_invo_id")) if body.get("Tra_cost_invo_id") else False,
|
||||
# "max_of_employee": body.get("max_of_employee", 0),
|
||||
# "min_of_employee": body.get("min_of_employee", 0),
|
||||
# "employee_id": employee.id,
|
||||
# "reference": body.get("reference", ""),
|
||||
# "company_id": 1,
|
||||
# # attachments? see example below
|
||||
# }
|
||||
|
||||
# Create the record
|
||||
# Prepare the response
|
||||
|
||||
mission_type = kw.get('mission_type')
|
||||
date_from = kw.get('date_from')
|
||||
date_to = kw.get('date_to')
|
||||
hour_from = kw.get('hour_from', 8)
|
||||
hour_to = kw.get('hour_to', 16)
|
||||
destination_type = kw.get('destination')
|
||||
try:
|
||||
hour_from = float(kw.get('hour_from') or 8)
|
||||
except:
|
||||
hour_from = 8.0
|
||||
|
||||
try:
|
||||
hour_to = float(kw.get('hour_to') or 16)
|
||||
except:
|
||||
hour_to = 16.0
|
||||
|
||||
mission = request.env['hr.official.mission'].sudo().create({
|
||||
'mission_type': int(mission_type),
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'hour_from': hour_from,
|
||||
'hour_to': hour_to,
|
||||
'destination': int(destination_type),
|
||||
'employee_id': employee.id,
|
||||
'process_type': 'especially_hours',
|
||||
})
|
||||
|
||||
request.env['hr.official.mission.employee'].sudo().create({
|
||||
'employee_id': employee.id,
|
||||
'official_mission_id': mission.id,
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'hour_from': hour_from,
|
||||
'hour_to': hour_to,
|
||||
'days': mission.date_duration,
|
||||
'hours': mission.hour_duration,
|
||||
})
|
||||
|
||||
mis = request.env['hr.official.mission'].sudo().search([('id', '=', mission.id)])
|
||||
|
||||
data = self._get_mission_return_data(mis)
|
||||
# Return success
|
||||
return http_helper.response(
|
||||
message=_("Mission created successfully"),
|
||||
data=data
|
||||
)
|
||||
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Error creating mission: %s", e)
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 1.2 Get All Missions (List with Pagination)
|
||||
# ----------------------------------------------------------
|
||||
@http.route(['/rest_api/v2/hr_official_mission'],
|
||||
type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_all_missions(self, **kw):
|
||||
"""
|
||||
Query parameters:
|
||||
page (optional, default=1)
|
||||
limit (optional, default=10)
|
||||
sort (optional, e.g. 'date_from', '-state', etc.)
|
||||
filters (optional, e.g. 'state=draft' or multiple conditions you parse)
|
||||
"""
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False)
|
||||
|
||||
try:
|
||||
# 2) Build domain & pagination
|
||||
page = int(kw.get('page', 1))
|
||||
approvel = kw.get('approvel', 0)
|
||||
sort = kw.get('sort') # e.g. 'date_from' or '-state'
|
||||
filters_str = kw.get('filters')
|
||||
page, offset, limit, prev = validator.get_page_pagination(page)
|
||||
|
||||
domain = []
|
||||
if approvel:
|
||||
domain.append(('state', '!=', 'draft'))
|
||||
|
||||
if filters_str:
|
||||
# Very basic parse; adapt as you like.
|
||||
parts = filters_str.split(';')
|
||||
for p in parts:
|
||||
if '=' in p:
|
||||
key, val = p.split('=', 1)
|
||||
domain.append((key.strip(), '=', val.strip()))
|
||||
domain.append(('process_type', '=', 'especially_hours'))
|
||||
|
||||
offset = (page - 1) * limit if page > 0 else 0
|
||||
order = "create_date desc"
|
||||
if sort:
|
||||
# if user specified '-field', interpret as descending
|
||||
if sort.startswith('-'):
|
||||
order = sort[1:] + " desc"
|
||||
else:
|
||||
order = sort + " asc"
|
||||
|
||||
# 3) Search & count
|
||||
Mission = request.env['hr.official.mission'].with_user(user.id)
|
||||
missions = Mission.search(domain, offset=offset, limit=limit, order=order)
|
||||
all_missions = Mission.search_count(domain)
|
||||
# 4) Build response data
|
||||
data_list = []
|
||||
for mis in missions:
|
||||
print("process_type", mis.process_type)
|
||||
data_list.append(self._get_mission_return_data(mis))
|
||||
data_list = convert_dates_in_data(data_list)
|
||||
|
||||
next_page = validator.get_page_pagination_next(page, all_missions)
|
||||
next_url = "/rest_api/v2/employee_other_request?approvel=%s&page=%s" % (
|
||||
approvel, next_page) if next_page else False
|
||||
prev_url = "/rest_api/v2/employee_other_request?approvel=%s&page=%s" % (approvel, prev) if prev else False
|
||||
data = {
|
||||
'links': {
|
||||
'prev': prev_url,
|
||||
'next': next_url,
|
||||
},
|
||||
'count': limit,
|
||||
'results': {
|
||||
'officialMission': data_list,
|
||||
}
|
||||
}
|
||||
return http_helper.response(
|
||||
message=_("All missions retrieved."),
|
||||
data=data
|
||||
)
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Error getting missions list: %s", e)
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 1.3 Get Mission by ID
|
||||
# ----------------------------------------------------------
|
||||
@http.route(['/rest_api/v2/hr_official_mission/<int:mission_id>'],
|
||||
type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_mission_by_id(self, mission_id, **kw):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False)
|
||||
|
||||
try:
|
||||
mission = request.env['hr.official.mission'].sudo().search([('id', '=', mission_id)], limit=1)
|
||||
if not mission:
|
||||
return http_helper.response(code=404, message="Mission not found", success=False)
|
||||
|
||||
data = self._get_mission_return_data(mission)
|
||||
return http_helper.response(
|
||||
message=_("Mission retrieved successfully"),
|
||||
data=data
|
||||
)
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Error getting mission by ID: %s", e)
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 1.4 Update Mission (PATCH)
|
||||
# ----------------------------------------------------------
|
||||
@http.route(['/rest_api/v2/hr_official_mission/<int:mission_id>'],
|
||||
type='http', auth='none', csrf=False, methods=['PATCH'])
|
||||
def update_mission(self, mission_id, **kw):
|
||||
"""
|
||||
Allows partial update of fields, only updates fields included in the request body.
|
||||
Example body:
|
||||
{
|
||||
"date_to": "2025-02-10",
|
||||
"hour_to": 18,
|
||||
"balance": 120,
|
||||
"mission_purpose": "Updated purpose for the mission."
|
||||
}
|
||||
"""
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False)
|
||||
|
||||
try:
|
||||
with request.env.cr.savepoint():
|
||||
mission = request.env['hr.official.mission'].sudo().search([('id', '=', mission_id)], limit=1)
|
||||
if not mission:
|
||||
return http_helper.response(code=404, message="Mission not found", success=False)
|
||||
|
||||
# Build vals only from the body keys we actually have
|
||||
vals = {}
|
||||
updatable_fields = [
|
||||
"date", "date_from", "date_to", "hour_from", "hour_to",
|
||||
"date_duration", "hour_duration", "balance", "early_exit",
|
||||
"mission_purpose", "state", "move_type", "approved_by",
|
||||
"refused_by", "mission_type", "country_id", "ticket_insurance",
|
||||
"car_insurance", "self_car", "car_type", "rent_days",
|
||||
"max_rent", "visa", "note", "course_name", "process_type",
|
||||
"train_category", "partner_id", "destination", "issuing_ticket",
|
||||
"ticket_cash_request_type", "ticket_cash_request_for",
|
||||
"Training_cost", "appraisal_check", "Tra_cost_invo_id",
|
||||
"max_of_employee", "min_of_employee", "employee_id", "reference",
|
||||
"company_id",
|
||||
]
|
||||
# If you need to handle department_id (many2many) or employee_ids (one2many) updates,
|
||||
# you can handle them separately or the same way.
|
||||
# e.g. if "department_id" in body: create the many2many commands.
|
||||
# e.g. if "employee_ids" in body: parse them with _prepare_employee_ids.
|
||||
|
||||
for field_name in updatable_fields:
|
||||
if field_name in body:
|
||||
vals[field_name] = body[field_name]
|
||||
|
||||
# example for department_id (many2many):
|
||||
if "department_id" in body:
|
||||
dep_ids = body["department_id"]
|
||||
if isinstance(dep_ids, list):
|
||||
vals["department_id"] = [(6, 0, dep_ids)]
|
||||
|
||||
# example for employee_ids (one2many lines):
|
||||
if "employee_ids" in body and isinstance(body["employee_ids"], list):
|
||||
vals["employee_ids"] = [(5, 0, 0)] # remove existing lines
|
||||
vals["employee_ids"] += self._prepare_employee_ids(body["employee_ids"])
|
||||
|
||||
mission.write(vals)
|
||||
|
||||
# Return the updated record
|
||||
data = self._get_mission_return_data(mission)
|
||||
return http_helper.response(
|
||||
message=_("Mission updated successfully"),
|
||||
data=data
|
||||
)
|
||||
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Error updating mission: %s", e)
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 1.5 Delete Mission (DELETE)
|
||||
# ----------------------------------------------------------
|
||||
@http.route(['/rest_api/v2/hr_official_mission/<int:mission_id>'],
|
||||
type='http', auth='none', csrf=False, methods=['DELETE'])
|
||||
def delete_mission(self, mission_id, **kw):
|
||||
http_method, body, headers, token = http_helper.parse_request()
|
||||
# 1) Check Token
|
||||
result = validator.verify_token(token)
|
||||
if not result['status']:
|
||||
return http_helper.errcode(code=result['code'], message=result['message'])
|
||||
user = validator.verify(token)
|
||||
if not user:
|
||||
return http_helper.response(code=400,
|
||||
message=_("Authentication failed or user is not allowed."),
|
||||
success=False)
|
||||
|
||||
try:
|
||||
with request.env.cr.savepoint():
|
||||
mission = request.env['hr.official.mission'].sudo().search([('id', '=', mission_id)], limit=1)
|
||||
if not mission:
|
||||
return http_helper.response(code=404, message="Mission not found", success=False)
|
||||
|
||||
mission.unlink()
|
||||
return http_helper.response(
|
||||
message=_("Mission deleted successfully"),
|
||||
data={"id": mission_id}
|
||||
)
|
||||
except (UserError, AccessError, ValidationError) as e:
|
||||
request.env.cr.rollback()
|
||||
return http_helper.response(code=400, message=str(e), success=False)
|
||||
except Exception as e:
|
||||
request.env.cr.rollback()
|
||||
_logger.exception("Error deleting mission: %s", e)
|
||||
message = validator.get_server_error(e, user)
|
||||
return http_helper.errcode(code=500, message=message)
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 2. Related Models (Read-Only)
|
||||
# 2.1 Mission Type (hr.official.mission.type)
|
||||
# 2.2 Mission Destination (mission.destination)
|
||||
# 2.3 Employee Course Name (employee.course.name)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
class HrOfficialMissionRelatedModelsController(http.Controller):
|
||||
"""
|
||||
Minimal read-only endpoints to retrieve valid IDs from related models
|
||||
(mission_type, mission_destination, course_name, etc.)
|
||||
"""
|
||||
|
||||
# 2.1 Mission Type
|
||||
@http.route(['/api/mission_type'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_mission_type_list(self, **kw):
|
||||
# No token check here if it is publicly available; otherwise, do similar token checks
|
||||
|
||||
domain = [('special_hours', '=', True)]
|
||||
mission_types = request.env["hr.official.mission.type"].sudo().search(domain)
|
||||
data = []
|
||||
for mt in mission_types:
|
||||
data.append({
|
||||
"id": mt.id,
|
||||
"name": mt.name,
|
||||
"duration_type": mt.duration_type,
|
||||
"maximum_days": mt.maximum_days,
|
||||
"related_with_financial": mt.related_with_financial,
|
||||
"day_price": mt.day_price,
|
||||
"work_state": mt.work_state,
|
||||
})
|
||||
return http_helper.response(message="Mission Types", data=data)
|
||||
|
||||
@http.route(['/api/mission_type/<int:mt_id>'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_mission_type_detail(self, mt_id, **kw):
|
||||
mt = request.env["hr.official.mission.type"].sudo().search([('id', '=', mt_id)], limit=1)
|
||||
if not mt:
|
||||
return http_helper.response(code=404, message="Mission Type not found", success=False)
|
||||
data = {
|
||||
"id": mt.id,
|
||||
"name": mt.name,
|
||||
"duration_type": mt.duration_type,
|
||||
"maximum_days": mt.maximum_days,
|
||||
"related_with_financial": mt.related_with_financial,
|
||||
"day_price": mt.day_price,
|
||||
"work_state": mt.work_state,
|
||||
}
|
||||
return http_helper.response(message="Mission Type Detail", data=data)
|
||||
|
||||
# 2.2 Mission Destination
|
||||
@http.route(['/api/mission_destination'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_mission_destination_list(self, **kw):
|
||||
destinations = request.env["mission.destination"].sudo().search([])
|
||||
data = []
|
||||
for dest in destinations:
|
||||
data.append({
|
||||
"id": dest.id,
|
||||
"name": dest.name,
|
||||
"code": dest.code,
|
||||
"country_id": dest.country_id.id if dest.country_id else None,
|
||||
})
|
||||
return http_helper.response(message="Mission Destinations", data=data)
|
||||
|
||||
@http.route(['/api/mission_destination/<int:dest_id>'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_mission_destination_detail(self, dest_id, **kw):
|
||||
dest = request.env["mission.destination"].sudo().search([('id', '=', dest_id)], limit=1)
|
||||
if not dest:
|
||||
return http_helper.response(code=404, message="Destination not found", success=False)
|
||||
data = {
|
||||
"id": dest.id,
|
||||
"name": dest.name,
|
||||
"code": dest.code,
|
||||
"country_id": dest.country_id.id if dest.country_id else None,
|
||||
}
|
||||
return http_helper.response(message="Destination Detail", data=data)
|
||||
|
||||
# 2.3 Employee Course Name
|
||||
@http.route(['/api/course_name'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_course_name_list(self, **kw):
|
||||
courses = request.env["employee.course.name"].sudo().search([])
|
||||
data = []
|
||||
for c in courses:
|
||||
data.append({
|
||||
"id": c.id,
|
||||
"name": c.name,
|
||||
"code": c.code,
|
||||
})
|
||||
return http_helper.response(message="Course Names", data=data)
|
||||
|
||||
@http.route(['/api/course_name/<int:course_id>'], type='http', auth='none', csrf=False, methods=['GET'])
|
||||
def get_course_name_detail(self, course_id, **kw):
|
||||
course = request.env["employee.course.name"].sudo().search([('id', '=', course_id)], limit=1)
|
||||
if not course:
|
||||
return http_helper.response(code=404, message="Course not found", success=False)
|
||||
data = {
|
||||
"id": course.id,
|
||||
"name": course.name,
|
||||
"code": course.code,
|
||||
}
|
||||
return http_helper.response(message="Course Detail", data=data)
|
||||
Loading…
Reference in New Issue