001// -------------------------------------------------------------------------------- 002// Copyright 2002-2025 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.model.control.party.server.logic; 018 019import com.echothree.model.control.party.common.PartyRelationshipTypes; 020import com.echothree.model.control.party.common.PartyTypes; 021import com.echothree.model.control.party.common.RoleTypes; 022import com.echothree.model.control.party.common.exception.DuplicatePartyRelationshipException; 023import com.echothree.model.control.party.common.exception.NotAnEmployeeOfDepartmentsDivisionException; 024import com.echothree.model.control.party.common.exception.NotAnEmployeeOfDivisionsCompanyException; 025import com.echothree.model.control.party.common.exception.UnknownPartyRelationshipException; 026import com.echothree.model.control.party.common.exception.UnknownPartyRelationshipTypeNameException; 027import com.echothree.model.control.party.common.exception.UnknownRoleTypeNameException; 028import com.echothree.model.control.party.server.control.PartyControl; 029import com.echothree.model.control.user.server.logic.UserKeyLogic; 030import com.echothree.model.control.user.server.logic.UserSessionLogic; 031import com.echothree.model.data.party.server.entity.Party; 032import com.echothree.model.data.party.server.entity.PartyRelationship; 033import com.echothree.model.data.party.server.entity.PartyRelationshipType; 034import com.echothree.model.data.party.server.entity.RoleType; 035import com.echothree.util.common.message.ExecutionErrors; 036import com.echothree.util.common.persistence.BasePK; 037import com.echothree.util.server.control.BaseLogic; 038import com.echothree.util.server.message.ExecutionErrorAccumulator; 039import com.echothree.util.server.persistence.Session; 040import javax.enterprise.context.ApplicationScoped; 041import javax.enterprise.inject.spi.CDI; 042 043@ApplicationScoped 044public class PartyRelationshipLogic 045 extends BaseLogic { 046 047 protected PartyRelationshipLogic() { 048 super(); 049 } 050 051 public static PartyRelationshipLogic getInstance() { 052 return CDI.current().select(PartyRelationshipLogic.class).get(); 053 } 054 055 public PartyRelationshipType getPartyRelationshipTypeByName(final ExecutionErrorAccumulator eea, final String partyRelationshipTypeName) { 056 var partyControl = Session.getModelController(PartyControl.class); 057 var partyRelationshipType = partyControl.getPartyRelationshipTypeByName(partyRelationshipTypeName); 058 059 if(partyRelationshipType == null) { 060 handleExecutionError(UnknownPartyRelationshipTypeNameException.class, eea, ExecutionErrors.UnknownPartyRelationshipTypeName.name(), partyRelationshipTypeName); 061 } 062 063 return partyRelationshipType; 064 } 065 066 public RoleType getRoleTypeByName(final ExecutionErrorAccumulator eea, final String roleTypeName) { 067 var partyControl = Session.getModelController(PartyControl.class); 068 var roleType = partyControl.getRoleTypeByName(roleTypeName); 069 070 if(roleType == null) { 071 handleExecutionError(UnknownRoleTypeNameException.class, eea, ExecutionErrors.UnknownRoleTypeName.name(), roleTypeName); 072 } 073 074 return roleType; 075 } 076 077 public PartyRelationship createPartyRelationship(final ExecutionErrorAccumulator eea, final PartyRelationshipType partyRelationshipType, 078 final Party fromParty, final RoleType fromRoleType, final Party toParty, final RoleType toRoleType, final BasePK createdBy) { 079 var partyControl = Session.getModelController(PartyControl.class); 080 var partyRelationship = partyControl.getPartyRelationship(partyRelationshipType, fromParty, fromRoleType, toParty, toRoleType); 081 082 if(partyRelationship == null) { 083 partyControl.createPartyRelationship(partyRelationshipType, fromParty, fromRoleType, toParty, toRoleType, createdBy); 084 } else { 085 handleExecutionError(DuplicatePartyRelationshipException.class, eea, ExecutionErrors.DuplicatePartyRelationship.name(), 086 partyRelationshipType.getPartyRelationshipTypeName(), 087 fromParty.getLastDetail().getPartyName(), fromRoleType.getRoleTypeName(), 088 toParty.getLastDetail().getPartyName(), toRoleType.getRoleTypeName()); 089 } 090 091 return partyRelationship; 092 } 093 094 public void deletePartyRelationship(final ExecutionErrorAccumulator eea, final PartyRelationshipType partyRelationshipType, final Party fromParty, 095 final RoleType fromRoleType, final Party toParty, final RoleType toRoleType, final BasePK deletedBy) { 096 var partyControl = Session.getModelController(PartyControl.class); 097 var partyRelationship = partyControl.getPartyRelationshipForUpdate(partyRelationshipType, fromParty, fromRoleType, toParty, toRoleType); 098 099 if(partyRelationship == null) { 100 handleExecutionError(UnknownPartyRelationshipException.class, eea, ExecutionErrors.UnknownPartyRelationship.name(), 101 partyRelationshipType.getPartyRelationshipTypeName(), 102 fromParty.getLastDetail().getPartyName(), fromRoleType.getRoleTypeName(), 103 toParty.getLastDetail().getPartyName(), toRoleType.getRoleTypeName()); 104 } else { 105 UserKeyLogic.getInstance().clearUserKeysByPartyRelationship(partyRelationship); 106 UserSessionLogic.getInstance().deleteUserSessionsByPartyRelationship(partyRelationship); 107 partyControl.deletePartyRelationship(partyRelationship, deletedBy); 108 } 109 } 110 111 public boolean isEmployeeOfCompany(final ExecutionErrorAccumulator eea, final Party company, final Party employee) { 112 var result = false; 113 114 PartyLogic.getInstance().checkPartyType(eea, company, PartyTypes.COMPANY.name()); 115 PartyLogic.getInstance().checkPartyType(eea, employee, PartyTypes.EMPLOYEE.name()); 116 117 if(!hasExecutionErrors(eea)) { 118 var partyControl = Session.getModelController(PartyControl.class); 119 120 result = partyControl.countPartyRelationships(getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 121 company, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 122 employee, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name())) == 1; 123 } 124 125 return result; 126 } 127 128 public PartyRelationship addEmployeeToCompany(final ExecutionErrorAccumulator eea, final Party companyParty, final Party employeeParty, final BasePK createdBy) { 129 PartyRelationship partyRelationship = null; 130 131 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 132 PartyLogic.getInstance().checkPartyType(eea, companyParty, PartyTypes.COMPANY.name()); 133 134 if(!hasExecutionErrors(eea)) { 135 partyRelationship = createPartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 136 companyParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 137 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), createdBy); 138 } 139 140 return partyRelationship; 141 } 142 143 public void removeEmployeeFromCompany(final ExecutionErrorAccumulator eea, final Party companyParty, final Party employeeParty, final BasePK deletedBy) { 144 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 145 PartyLogic.getInstance().checkPartyType(eea, companyParty, PartyTypes.COMPANY.name()); 146 147 if(!hasExecutionErrors(eea)) { 148 removeEmployeeFromCompanysDivisions(eea, companyParty, employeeParty, deletedBy); 149 150 deletePartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 151 companyParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 152 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), deletedBy); 153 } 154 } 155 156 public boolean isEmployeeOfDivision(final ExecutionErrorAccumulator eea, final Party division, final Party employee) { 157 var result = false; 158 159 PartyLogic.getInstance().checkPartyType(eea, division, PartyTypes.DIVISION.name()); 160 PartyLogic.getInstance().checkPartyType(eea, employee, PartyTypes.EMPLOYEE.name()); 161 162 if(!hasExecutionErrors(eea)) { 163 var partyControl = Session.getModelController(PartyControl.class); 164 165 result = partyControl.countPartyRelationships(getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 166 division, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 167 employee, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name())) == 1; 168 } 169 170 return result; 171 } 172 173 public PartyRelationship addEmployeeToDivision(final ExecutionErrorAccumulator eea, final Party divisionParty, final Party employeeParty, final BasePK createdBy) { 174 PartyRelationship partyRelationship = null; 175 176 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 177 PartyLogic.getInstance().checkPartyType(eea, divisionParty, PartyTypes.DIVISION.name()); 178 179 if(!hasExecutionErrors(eea)) { 180 var partyControl = Session.getModelController(PartyControl.class); 181 var partyDivision = partyControl.getPartyDivision(divisionParty); 182 var partyCompany = partyControl.getPartyCompany(partyDivision.getCompanyParty()); 183 var companyParty = partyCompany.getParty(); 184 185 if(isEmployeeOfCompany(eea, companyParty, employeeParty)) { 186 partyRelationship = createPartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 187 divisionParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 188 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), createdBy); 189 } else { 190 handleExecutionError(NotAnEmployeeOfDivisionsCompanyException.class, eea, ExecutionErrors.NotAnEmployeeOfDivisionsCompany.name(), 191 partyCompany.getPartyCompanyName(), employeeParty.getLastDetail().getPartyName()); 192 } 193 } 194 195 return partyRelationship; 196 } 197 198 public void removeEmployeeFromCompanysDivisions(final ExecutionErrorAccumulator eea, final Party companyParty, final Party employeeParty, final BasePK deletedBy) { 199 var partyControl = Session.getModelController(PartyControl.class); 200 var partyDivisions = partyControl.getDivisionsByCompany(companyParty); 201 202 partyDivisions.stream().map((partyDivision) -> partyDivision.getParty()).filter((divisionParty) -> isEmployeeOfDivision(eea, divisionParty, employeeParty)).forEach((divisionParty) -> { 203 removeEmployeeFromDivisionsDepartments(eea, employeeParty, employeeParty, deletedBy); 204 removeEmployeeFromDivision(eea, divisionParty, employeeParty, deletedBy); 205 }); 206 } 207 208 public void removeEmployeeFromDivision(final ExecutionErrorAccumulator eea, final Party divisionParty, final Party employeeParty, final BasePK deletedBy) { 209 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 210 PartyLogic.getInstance().checkPartyType(eea, divisionParty, PartyTypes.DIVISION.name()); 211 212 if(!hasExecutionErrors(eea)) { 213 removeEmployeeFromDivisionsDepartments(eea, divisionParty, employeeParty, deletedBy); 214 215 deletePartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 216 divisionParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 217 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), deletedBy); 218 } 219 } 220 221 public boolean isEmployeeOfDepartment(final ExecutionErrorAccumulator eea, final Party department, final Party employee) { 222 var result = false; 223 224 PartyLogic.getInstance().checkPartyType(eea, department, PartyTypes.DEPARTMENT.name()); 225 PartyLogic.getInstance().checkPartyType(eea, employee, PartyTypes.EMPLOYEE.name()); 226 227 if(!hasExecutionErrors(eea)) { 228 var partyControl = Session.getModelController(PartyControl.class); 229 230 result = partyControl.countPartyRelationships(getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 231 department, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 232 employee, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name())) == 1; 233 } 234 235 return result; 236 } 237 238 public PartyRelationship addEmployeeToDepartment(final ExecutionErrorAccumulator eea, final Party departmentParty, final Party employeeParty, final BasePK createdBy) { 239 PartyRelationship partyRelationship = null; 240 241 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 242 PartyLogic.getInstance().checkPartyType(eea, departmentParty, PartyTypes.DEPARTMENT.name()); 243 244 if(!hasExecutionErrors(eea)) { 245 var partyControl = Session.getModelController(PartyControl.class); 246 var partyDepartment = partyControl.getPartyDepartment(departmentParty); 247 var partyDivision = partyControl.getPartyDivision(partyDepartment.getDivisionParty()); 248 var partyCompany = partyControl.getPartyCompany(partyDivision.getCompanyParty()); 249 var divisionParty = partyDivision.getParty(); 250 251 if(isEmployeeOfDivision(eea, divisionParty, employeeParty)) { 252 partyRelationship = createPartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 253 departmentParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 254 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), createdBy); 255 } else { 256 handleExecutionError(NotAnEmployeeOfDepartmentsDivisionException.class, eea, ExecutionErrors.NotAnEmployeeOfDepartmentsDivision.name(), 257 partyCompany.getPartyCompanyName(), partyDivision.getPartyDivisionName(), employeeParty.getLastDetail().getPartyName()); 258 } 259 } 260 261 return partyRelationship; 262 } 263 264 public void removeEmployeeFromDivisionsDepartments(final ExecutionErrorAccumulator eea, final Party divisionParty, final Party employeeParty, final BasePK deletedBy) { 265 var partyControl = Session.getModelController(PartyControl.class); 266 var partyDepartments = partyControl.getDepartmentsByDivision(divisionParty); 267 268 partyDepartments.stream().map((partyDepartment) -> partyDepartment.getParty()).filter((departmentParty) -> isEmployeeOfDepartment(eea, departmentParty, employeeParty)).forEach((departmentParty) -> { 269 removeEmployeeFromDepartment(eea, departmentParty, employeeParty, deletedBy); 270 }); 271 } 272 273 public void removeEmployeeFromDepartment(final ExecutionErrorAccumulator eea, final Party departmentParty, final Party employeeParty, final BasePK deletedBy) { 274 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 275 PartyLogic.getInstance().checkPartyType(eea, departmentParty, PartyTypes.DEPARTMENT.name()); 276 277 if(!hasExecutionErrors(eea)) { 278 deletePartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 279 departmentParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 280 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), deletedBy); 281 } 282 } 283 284}