Employee's manager/supervisor table in the database
Hello
We currently developing the solution for the integrations from IFS, part of the data we want to extract is Employee’s Manager/Supervisor, but due to technical limitations we only able to use table and not views or API calls. Is there a TABLE in IFS database which contains employee’s manager/supervisor or at least a path via few tables which could provide this information? Thanks
Page 1 / 1
@ArturasVit if you would have had access to DB views, then this would have been easy.
Just querying the sup_emp_no from DB View company_person_all.
The tricky part is figuring the result of the getter. It is quite complex. Below you have the code for the PL/SQL procedure. Good luck.
PROCEDURE Get_Direct_Supervisor_List ( person_id_list_ OUT VARCHAR2, name_list_ OUT VARCHAR2, id_name_list_ OUT VARCHAR2, company_id_ IN VARCHAR2, emp_no_ IN VARCHAR2, valid_from_ IN DATE DEFAULT SYSDATE, return_pos_code_ IN VARCHAR2 DEFAULT NULL, formatted_ IN VARCHAR2 DEFAULT NULL, org_code_ IN VARCHAR2 DEFAULT NULL, pos_code_ IN VARCHAR2 DEFAULT NULL, return_name_ IN VARCHAR2 DEFAULT NULL, max_value_ IN VARCHAR2 DEFAULT NULL) IS account_date_ DATE; --Bug 144954, start sup_name_ VARCHAR2(10000); sup_person_ VARCHAR2(10000) := '^'; sup_person_id_name_ VARCHAR2(10000) := '^'; sup_person_name_ VARCHAR2(10000) := '^'; --Bug 144954, end found_ BOOLEAN := FALSE; struct_id_ business_unit_tab.business_unit_code%TYPE; struct_type_ business_unit_tab.business_unit_type%TYPE; emp_pos_code_ company_pers_assign_tab.pos_code%TYPE; sup_pos_code_ company_pers_assign_tab.pos_code%TYPE; emp_org_code_ company_pers_assign_tab.org_code%TYPE; bus_unit_assignment_ company_pers_assign_tab.bus_unit_assignment%TYPE; emp_org_bu_id_ business_unit_tab.business_unit_id%TYPE; emp_person_id_ VARCHAR2(30); struct_bu_id_ business_unit_tab.business_unit_id%TYPE; dir_sup_logic_ VARCHAR2(10); is_rel_valid_ BOOLEAN; CURSOR get_primary_asst IS SELECT pos_code, org_code, bus_unit_assignment FROM company_pers_assign_tab WHERE company_id = company_id_ AND emp_no = emp_no_ AND account_date_ BETWEEN valid_from AND valid_to AND primary = '1';
CURSOR get_org_pos IS SELECT pos_code, org_code, bus_unit_assignment FROM company_pers_assign_tab WHERE company_id = company_id_ AND emp_no = emp_no_ AND org_code LIKE nvl(org_code_, '%') AND pos_code LIKE nvl(pos_code_, '%') AND account_date_ BETWEEN valid_from AND valid_to;
CURSOR get_struct_id IS SELECT b2.business_unit_code, org.struct_bu_id FROM company_org_tab org, business_unit_tab b2 WHERE org.company_id = company_id_ AND org.org_code = emp_org_code_ AND b2.business_unit_id = org.struct_bu_id;
CURSOR get_sup IS SELECT DISTINCT person_id, relation_id, relation_type FROM bu_access_temp_tab WHERE org_bu_id = emp_org_bu_id_ AND pos_code = sup_pos_code_ AND account_date_ BETWEEN valid_from AND valid_to AND account_date_ BETWEEN trans_from AND trans_to AND person_id <> emp_person_id_;
CURSOR get_all_children_matrixes(org_bu_id_ IN VARCHAR2) IS SELECT DISTINCT org_bu_id business_unit_id, valid_from, valid_to FROM org_structure_matrix START WITH sup_org_bu_id = org_bu_id_ AND trunc(account_date_) <= valid_to CONNECT BY NOCYCLE PRIOR org_bu_id = sup_org_bu_id AND PRIOR valid_from <= valid_to AND PRIOR valid_to >= valid_from;
CURSOR get_all_children_companies(org_bu_id_ IN VARCHAR2) IS SELECT DISTINCT org_bu_id business_unit_id, valid_from, valid_to FROM org_structure_company START WITH ((sup_org_bu_id is null and struct_bu_id = org_bu_id_) OR (sup_org_bu_id = org_bu_id_)) AND trunc(account_date_) <= valid_to CONNECT BY NOCYCLE PRIOR org_bu_id = sup_org_bu_id AND PRIOR valid_from <= valid_to AND PRIOR valid_to >= valid_from; -- New Direct Supervisor Logic CURSOR get_sup_new IS SELECT * FROM TABLE(Company_Pers_Assign_API.Get_Direct_Supervisor_Table(company_id_, emp_no_, valid_from_, org_code_, pos_code_)); BEGIN General_SYS.Init_Method(Company_Pers_Assign_API.lu_name_, 'Company_Pers_Assign_API', 'Get_Direct_Supervisor_List'); account_date_ := TRUNC(valid_from_); person_id_list_ := NULL; name_list_ := NULL; id_name_list_ := NULL; emp_person_id_ := Company_Person_API.Get_Person_Id(company_id_, emp_no_);
IF (pos_code_ IS NULL) AND (org_code_ IS NULL) THEN OPEN get_primary_asst; FETCH get_primary_asst INTO emp_pos_code_, emp_org_code_, bus_unit_assignment_; CLOSE get_primary_asst; ELSE OPEN get_org_pos; FETCH get_org_pos INTO emp_pos_code_, emp_org_code_, bus_unit_assignment_; CLOSE get_org_pos; END IF;
IF (emp_pos_code_ IS NOT NULL) AND (emp_org_code_ IS NOT NULL) THEN IF bus_unit_assignment_ = 'TRUE' THEN OPEN get_struct_id; FETCH get_struct_id INTO struct_id_, struct_bu_id_; CLOSE get_struct_id; struct_type_ := 'CUSTOM'; emp_org_bu_id_ := Business_Unit_API.Get_Bus_Unit_Id_By_Type(company_id_, 'CUSTOM', emp_org_code_, struct_bu_id_); ELSE struct_id_ := company_id_; struct_type_ := 'COMPANY'; emp_org_bu_id_ := Business_Unit_API.Get_Bus_Unit_Id_By_Type(company_id_, 'ORGANIZATION', emp_org_code_, struct_bu_id_); END IF;
IF struct_id_ IS NOT NULL THEN sup_pos_code_ := Position_Util_API.Get_Sup_Pos_Code(struct_id_, emp_pos_code_, account_date_, struct_type_);
FOR sup_ IN get_sup LOOP IF (INSTR(sup_person_, (sup_.person_id || '^')) = 0) THEN found_ := TRUE; is_rel_valid_ := FALSE; IF lengthb(sup_person_ || sup_.person_id || '^') > 4000 AND max_value_ = 'TRUE' THEN EXIT; ELSE IF Business_Unit_Relation_API.Get_Business_Unit_Id(sup_.relation_id) != emp_org_bu_id_ AND sup_.relation_type = 'OPERATIONAL' THEN FOR rec_ IN get_all_children_matrixes(Business_Unit_Relation_API.Get_Business_Unit_Id(sup_.relation_id)) LOOP IF rec_.business_unit_id = emp_org_bu_id_ THEN is_rel_valid_ := TRUE; EXIT; END IF; END LOOP; IF is_rel_valid_ = FALSE THEN FOR rec_ IN get_all_children_companies(Business_Unit_Relation_API.Get_Business_Unit_Id(sup_.relation_id)) LOOP IF rec_.business_unit_id = emp_org_bu_id_ THEN is_rel_valid_ := TRUE; EXIT; END IF; END LOOP; END IF; ELSE is_rel_valid_ := TRUE; END IF; IF is_rel_valid_ THEN sup_person_ := sup_person_ || sup_.person_id || '^'; END IF; END IF;
IF return_name_ = 'TRUE' THEN IF is_rel_valid_ THEN sup_name_ := Pers_API.Get_Internal_Display_Name(sup_.person_id); END IF; -- Bug 147930, Start IF lengthb(sup_person_id_name_ || sup_.person_id || ' - ' || sup_name_ || '^') > 4000 AND max_value_ = 'TRUE' THEN EXIT; ELSE IF is_rel_valid_ THEN sup_person_name_ := sup_person_name_ || sup_name_ || '^'; sup_person_id_name_ := sup_person_id_name_ || sup_.person_id || ' - ' || sup_name_ || '^'; END IF; END IF; -- Bug 147930, End END IF; END IF; END LOOP; ELSE -- New Direct Supervisor Logic FOR rec_ IN get_sup_new LOOP IF (INSTR(sup_person_, (rec_.person_id || '^')) = 0) THEN found_ := TRUE; IF lengthb(sup_person_ || rec_.person_id || '^') > 4000 AND max_value_ = 'TRUE' THEN EXIT; ELSE sup_person_ := sup_person_ || rec_.person_id || '^'; END IF;
sup_pos_code_ := rec_.pos_code;
IF return_name_ = 'TRUE' THEN sup_name_ := Pers_API.Get_Internal_Display_Name(rec_.person_id); IF lengthb(sup_person_id_name_ || rec_.person_id || ' - ' || sup_name_ || '^') > 4000 AND max_value_ = 'TRUE' THEN EXIT; ELSE sup_person_name_ := sup_person_name_ || sup_name_ || '^'; sup_person_id_name_ := sup_person_id_name_ || rec_.person_id || ' - ' || sup_name_ || '^'; END IF; END IF; END IF; END LOOP; END IF; END IF; -- Bug 148777, End END IF; END IF;
IF found_ = TRUE THEN IF formatted_ = 'TRUE' THEN person_id_list_ := substr(sup_person_, 2, length(sup_person_) - 2); ELSE person_id_list_ := sup_person_; END IF; id_name_list_ := substr(sup_person_id_name_, 2, length(sup_person_id_name_) - 2); name_list_ := substr(sup_person_name_, 2, length(sup_person_name_) - 2); ELSIF return_pos_code_ = 'TRUE' THEN person_id_list_ := sup_pos_code_; END IF; END Get_Direct_Supervisor_List;
In the end we have decided to use different approach and only look for employee’s superior position holder. While this does not make someone a manager in IFS (OU access additionally needs to be granted), it does actually fit the positional structure of our organization.
If anyone comes accross this there are a few ways to play around this. There can be multiple direct supervisors based on the set up, orgs, positions, etc.
select * from table(ifsapp.company_pers_assign_api.Get_Direct_Supervisor_Table(company_, emp_no_))
This will retrieve the list of “direct” supervisor(s) (meaning the first available person(s) above in the hiearchy based on structure setup)
(Here, DIRECT_SUB being set to FALSE is because this supervisor is not in the direct position above the employee I’m querying, but there is no one actually set in that above position, so IFS automatically goes to the next position/org up).
I’ve created a little quick and dirty recursive PLSQL Method to be able to feed two person IDs and get a result to know if someone is a supervisor of another, even indirectly (so in effect, feeding the CEO person ID into the supervisor argument would always return TRUE). This is basically a way to check two person’s reporting lines “intersect”. (I use this in some Mods to prevent some actions being taken on objects unless the user is part of the reporting line of some person recorded in the object, for example, preventing a user from modifying a Service Contract unless the user is the Service Contract Coordinator or one of the Coordinator’s supervisors, their supervisors’ supervisors’, etc. up the chain to CEO)
There might have been an easier way to achieve this or there might even be an out of the box function that does this, but I couldn’t find one =p
function is_supervisor(person_id_ in varchar2, supervisor_id_ in varchar2) RETURN VARCHAR2
cursor get_emp_rec(person_id_ in varchar2) IS select company, employee_id from ifsapp.company_emp_tab t where t.person_id = person_id_;
break_loop_ BOOLEAN := FALSE;
function supervisor_check(company_id_ in varchar2, emp_no_ in varchar2, supervisor_id_ in varchar2) RETURN BOOLEAN IS
dummy_ boolean;
cursor sups(company_id_ in varchar2, emp_no_ in varchar2) IS select * from table(ifsapp.company_pers_assign_api.Get_Direct_Supervisor_Table(company_id_, emp_no_));
BEGIN
for rec_ in sups(company_id_, emp_no_) LOOP
if rec_.person_id = supervisor_id_ then break_loop_ := TRUE; else dummy_ := supervisor_check(rec_.company_id, rec_.emp_no, supervisor_id_); end if;