001// -------------------------------------------------------------------------------- 002// Copyright 2002-2024 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.PartyCompany; 033import com.echothree.model.data.party.server.entity.PartyDepartment; 034import com.echothree.model.data.party.server.entity.PartyDivision; 035import com.echothree.model.data.party.server.entity.PartyRelationship; 036import com.echothree.model.data.party.server.entity.PartyRelationshipType; 037import com.echothree.model.data.party.server.entity.RoleType; 038import com.echothree.util.common.message.ExecutionErrors; 039import com.echothree.util.common.persistence.BasePK; 040import com.echothree.util.server.control.BaseLogic; 041import com.echothree.util.server.message.ExecutionErrorAccumulator; 042import com.echothree.util.server.persistence.Session; 043import java.util.List; 044 045public class PartyRelationshipLogic 046 extends BaseLogic { 047 048 private PartyRelationshipLogic() { 049 super(); 050 } 051 052 private static class PartyRelationshipLogicHolder { 053 static PartyRelationshipLogic instance = new PartyRelationshipLogic(); 054 } 055 056 public static PartyRelationshipLogic getInstance() { 057 return PartyRelationshipLogicHolder.instance; 058 } 059 060 public PartyRelationshipType getPartyRelationshipTypeByName(final ExecutionErrorAccumulator eea, final String partyRelationshipTypeName) { 061 var partyControl = Session.getModelController(PartyControl.class); 062 PartyRelationshipType partyRelationshipType = partyControl.getPartyRelationshipTypeByName(partyRelationshipTypeName); 063 064 if(partyRelationshipType == null) { 065 handleExecutionError(UnknownPartyRelationshipTypeNameException.class, eea, ExecutionErrors.UnknownPartyRelationshipTypeName.name(), partyRelationshipTypeName); 066 } 067 068 return partyRelationshipType; 069 } 070 071 public RoleType getRoleTypeByName(final ExecutionErrorAccumulator eea, final String roleTypeName) { 072 var partyControl = Session.getModelController(PartyControl.class); 073 RoleType roleType = partyControl.getRoleTypeByName(roleTypeName); 074 075 if(roleType == null) { 076 handleExecutionError(UnknownRoleTypeNameException.class, eea, ExecutionErrors.UnknownRoleTypeName.name(), roleTypeName); 077 } 078 079 return roleType; 080 } 081 082 public PartyRelationship createPartyRelationship(final ExecutionErrorAccumulator eea, final PartyRelationshipType partyRelationshipType, 083 final Party fromParty, final RoleType fromRoleType, final Party toParty, final RoleType toRoleType, final BasePK createdBy) { 084 var partyControl = Session.getModelController(PartyControl.class); 085 PartyRelationship partyRelationship = partyControl.getPartyRelationship(partyRelationshipType, fromParty, fromRoleType, toParty, toRoleType); 086 087 if(partyRelationship == null) { 088 partyControl.createPartyRelationship(partyRelationshipType, fromParty, fromRoleType, toParty, toRoleType, createdBy); 089 } else { 090 handleExecutionError(DuplicatePartyRelationshipException.class, eea, ExecutionErrors.DuplicatePartyRelationship.name(), 091 partyRelationshipType.getPartyRelationshipTypeName(), 092 fromParty.getLastDetail().getPartyName(), fromRoleType.getRoleTypeName(), 093 toParty.getLastDetail().getPartyName(), toRoleType.getRoleTypeName()); 094 } 095 096 return partyRelationship; 097 } 098 099 public void deletePartyRelationship(final ExecutionErrorAccumulator eea, final PartyRelationshipType partyRelationshipType, final Party fromParty, 100 final RoleType fromRoleType, final Party toParty, final RoleType toRoleType, final BasePK deletedBy) { 101 var partyControl = Session.getModelController(PartyControl.class); 102 PartyRelationship partyRelationship = partyControl.getPartyRelationshipForUpdate(partyRelationshipType, fromParty, fromRoleType, toParty, toRoleType); 103 104 if(partyRelationship == null) { 105 handleExecutionError(UnknownPartyRelationshipException.class, eea, ExecutionErrors.UnknownPartyRelationship.name(), 106 partyRelationshipType.getPartyRelationshipTypeName(), 107 fromParty.getLastDetail().getPartyName(), fromRoleType.getRoleTypeName(), 108 toParty.getLastDetail().getPartyName(), toRoleType.getRoleTypeName()); 109 } else { 110 UserKeyLogic.getInstance().clearUserKeysByPartyRelationship(partyRelationship); 111 UserSessionLogic.getInstance().deleteUserSessionsByPartyRelationship(partyRelationship); 112 partyControl.deletePartyRelationship(partyRelationship, deletedBy); 113 } 114 } 115 116 public boolean isEmployeeOfCompany(final ExecutionErrorAccumulator eea, final Party company, final Party employee) { 117 boolean result = false; 118 119 PartyLogic.getInstance().checkPartyType(eea, company, PartyTypes.COMPANY.name()); 120 PartyLogic.getInstance().checkPartyType(eea, employee, PartyTypes.EMPLOYEE.name()); 121 122 if(!hasExecutionErrors(eea)) { 123 var partyControl = Session.getModelController(PartyControl.class); 124 125 result = partyControl.countPartyRelationships(getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 126 company, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 127 employee, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name())) == 1; 128 } 129 130 return result; 131 } 132 133 public PartyRelationship addEmployeeToCompany(final ExecutionErrorAccumulator eea, final Party companyParty, final Party employeeParty, final BasePK createdBy) { 134 PartyRelationship partyRelationship = null; 135 136 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 137 PartyLogic.getInstance().checkPartyType(eea, companyParty, PartyTypes.COMPANY.name()); 138 139 if(!hasExecutionErrors(eea)) { 140 partyRelationship = createPartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 141 companyParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 142 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), createdBy); 143 } 144 145 return partyRelationship; 146 } 147 148 public void removeEmployeeFromCompany(final ExecutionErrorAccumulator eea, final Party companyParty, final Party employeeParty, final BasePK deletedBy) { 149 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 150 PartyLogic.getInstance().checkPartyType(eea, companyParty, PartyTypes.COMPANY.name()); 151 152 if(!hasExecutionErrors(eea)) { 153 removeEmployeeFromCompanysDivisions(eea, companyParty, employeeParty, deletedBy); 154 155 deletePartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 156 companyParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 157 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), deletedBy); 158 } 159 } 160 161 public boolean isEmployeeOfDivision(final ExecutionErrorAccumulator eea, final Party division, final Party employee) { 162 boolean result = false; 163 164 PartyLogic.getInstance().checkPartyType(eea, division, PartyTypes.DIVISION.name()); 165 PartyLogic.getInstance().checkPartyType(eea, employee, PartyTypes.EMPLOYEE.name()); 166 167 if(!hasExecutionErrors(eea)) { 168 var partyControl = Session.getModelController(PartyControl.class); 169 170 result = partyControl.countPartyRelationships(getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 171 division, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 172 employee, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name())) == 1; 173 } 174 175 return result; 176 } 177 178 public PartyRelationship addEmployeeToDivision(final ExecutionErrorAccumulator eea, final Party divisionParty, final Party employeeParty, final BasePK createdBy) { 179 PartyRelationship partyRelationship = null; 180 181 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 182 PartyLogic.getInstance().checkPartyType(eea, divisionParty, PartyTypes.DIVISION.name()); 183 184 if(!hasExecutionErrors(eea)) { 185 var partyControl = Session.getModelController(PartyControl.class); 186 PartyDivision partyDivision = partyControl.getPartyDivision(divisionParty); 187 PartyCompany partyCompany = partyControl.getPartyCompany(partyDivision.getCompanyParty()); 188 Party companyParty = partyCompany.getParty(); 189 190 if(isEmployeeOfCompany(eea, companyParty, employeeParty)) { 191 partyRelationship = createPartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 192 divisionParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 193 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), createdBy); 194 } else { 195 handleExecutionError(NotAnEmployeeOfDivisionsCompanyException.class, eea, ExecutionErrors.NotAnEmployeeOfDivisionsCompany.name(), 196 partyCompany.getPartyCompanyName(), employeeParty.getLastDetail().getPartyName()); 197 } 198 } 199 200 return partyRelationship; 201 } 202 203 public void removeEmployeeFromCompanysDivisions(final ExecutionErrorAccumulator eea, final Party companyParty, final Party employeeParty, final BasePK deletedBy) { 204 var partyControl = Session.getModelController(PartyControl.class); 205 List<PartyDivision> partyDivisions = partyControl.getDivisionsByCompany(companyParty); 206 207 partyDivisions.stream().map((partyDivision) -> partyDivision.getParty()).filter((divisionParty) -> isEmployeeOfDivision(eea, divisionParty, employeeParty)).forEach((divisionParty) -> { 208 removeEmployeeFromDivisionsDepartments(eea, employeeParty, employeeParty, deletedBy); 209 removeEmployeeFromDivision(eea, divisionParty, employeeParty, deletedBy); 210 }); 211 } 212 213 public void removeEmployeeFromDivision(final ExecutionErrorAccumulator eea, final Party divisionParty, final Party employeeParty, final BasePK deletedBy) { 214 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 215 PartyLogic.getInstance().checkPartyType(eea, divisionParty, PartyTypes.DIVISION.name()); 216 217 if(!hasExecutionErrors(eea)) { 218 removeEmployeeFromDivisionsDepartments(eea, divisionParty, employeeParty, deletedBy); 219 220 deletePartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 221 divisionParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 222 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), deletedBy); 223 } 224 } 225 226 public boolean isEmployeeOfDepartment(final ExecutionErrorAccumulator eea, final Party department, final Party employee) { 227 boolean result = false; 228 229 PartyLogic.getInstance().checkPartyType(eea, department, PartyTypes.DEPARTMENT.name()); 230 PartyLogic.getInstance().checkPartyType(eea, employee, PartyTypes.EMPLOYEE.name()); 231 232 if(!hasExecutionErrors(eea)) { 233 var partyControl = Session.getModelController(PartyControl.class); 234 235 result = partyControl.countPartyRelationships(getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 236 department, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 237 employee, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name())) == 1; 238 } 239 240 return result; 241 } 242 243 public PartyRelationship addEmployeeToDepartment(final ExecutionErrorAccumulator eea, final Party departmentParty, final Party employeeParty, final BasePK createdBy) { 244 PartyRelationship partyRelationship = null; 245 246 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 247 PartyLogic.getInstance().checkPartyType(eea, departmentParty, PartyTypes.DEPARTMENT.name()); 248 249 if(!hasExecutionErrors(eea)) { 250 var partyControl = Session.getModelController(PartyControl.class); 251 PartyDepartment partyDepartment = partyControl.getPartyDepartment(departmentParty); 252 PartyDivision partyDivision = partyControl.getPartyDivision(partyDepartment.getDivisionParty()); 253 PartyCompany partyCompany = partyControl.getPartyCompany(partyDivision.getCompanyParty()); 254 Party divisionParty = partyDivision.getParty(); 255 256 if(isEmployeeOfDivision(eea, divisionParty, employeeParty)) { 257 partyRelationship = createPartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 258 departmentParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 259 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), createdBy); 260 } else { 261 handleExecutionError(NotAnEmployeeOfDepartmentsDivisionException.class, eea, ExecutionErrors.NotAnEmployeeOfDepartmentsDivision.name(), 262 partyCompany.getPartyCompanyName(), partyDivision.getPartyDivisionName(), employeeParty.getLastDetail().getPartyName()); 263 } 264 } 265 266 return partyRelationship; 267 } 268 269 public void removeEmployeeFromDivisionsDepartments(final ExecutionErrorAccumulator eea, final Party divisionParty, final Party employeeParty, final BasePK deletedBy) { 270 var partyControl = Session.getModelController(PartyControl.class); 271 List<PartyDepartment> partyDepartments = partyControl.getDepartmentsByDivision(divisionParty); 272 273 partyDepartments.stream().map((partyDepartment) -> partyDepartment.getParty()).filter((departmentParty) -> isEmployeeOfDepartment(eea, departmentParty, employeeParty)).forEach((departmentParty) -> { 274 removeEmployeeFromDepartment(eea, departmentParty, employeeParty, deletedBy); 275 }); 276 } 277 278 public void removeEmployeeFromDepartment(final ExecutionErrorAccumulator eea, final Party departmentParty, final Party employeeParty, final BasePK deletedBy) { 279 PartyLogic.getInstance().checkPartyType(eea, employeeParty, PartyTypes.EMPLOYEE.name()); 280 PartyLogic.getInstance().checkPartyType(eea, departmentParty, PartyTypes.DEPARTMENT.name()); 281 282 if(!hasExecutionErrors(eea)) { 283 deletePartyRelationship(eea, getPartyRelationshipTypeByName(eea, PartyRelationshipTypes.EMPLOYMENT.name()), 284 departmentParty, getRoleTypeByName(eea, RoleTypes.EMPLOYER.name()), 285 employeeParty, getRoleTypeByName(eea, PartyTypes.EMPLOYEE.name()), deletedBy); 286 } 287 } 288 289}