001// --------------------------------------------------------------------------------
002// Copyright 2002-2026 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.security.server.logic;
018
019import com.echothree.model.control.security.common.exception.UnknownPartySecurityRoleTemplateNameException;
020import com.echothree.model.control.security.server.control.SecurityControl;
021import com.echothree.model.control.training.common.training.PartyTrainingClassStatusConstants;
022import com.echothree.model.control.training.server.control.TrainingControl;
023import com.echothree.model.control.training.server.logic.PartyTrainingClassLogic;
024import com.echothree.model.control.training.server.logic.PartyTrainingClassLogic.PreparedPartyTrainingClass;
025import com.echothree.model.data.security.server.entity.PartySecurityRoleTemplate;
026import com.echothree.model.data.security.server.entity.PartySecurityRoleTemplateRole;
027import com.echothree.model.data.security.server.entity.PartySecurityRoleTemplateTrainingClass;
028import com.echothree.model.data.security.server.entity.SecurityRole;
029import com.echothree.model.data.training.server.entity.TrainingClass;
030import com.echothree.util.common.message.ExecutionErrors;
031import com.echothree.util.common.persistence.BasePK;
032import com.echothree.util.server.control.BaseLogic;
033import com.echothree.util.server.message.ExecutionErrorAccumulator;
034import com.echothree.util.server.persistence.EntityPermission;
035import com.echothree.util.server.persistence.Session;
036import java.util.HashSet;
037import java.util.List;
038import java.util.Set;
039import javax.enterprise.context.ApplicationScoped;
040import javax.inject.Inject;
041
042@ApplicationScoped
043public class PartySecurityRoleTemplateLogic
044        extends BaseLogic {
045
046    @Inject
047    protected SecurityControl securityControl;
048
049    @Inject
050    protected TrainingControl trainingControl;
051
052    @Inject
053    PartyTrainingClassLogic partyTrainingClassLogic;
054
055    protected PartySecurityRoleTemplateLogic() {
056        super();
057    }
058
059    // --------------------------------------------------------------------------------
060    //   Party Security Role Templates
061    // --------------------------------------------------------------------------------
062
063    public PartySecurityRoleTemplate getPartySecurityRoleTemplateByName(final ExecutionErrorAccumulator eea, final String partySecurityRoleTemplateName,
064            final EntityPermission entityPermission) {
065        var partySecurityRoleTemplate = securityControl.getPartySecurityRoleTemplateByName(partySecurityRoleTemplateName, entityPermission);
066
067        if(partySecurityRoleTemplate == null) {
068            handleExecutionError(UnknownPartySecurityRoleTemplateNameException.class, eea, ExecutionErrors.UnknownPartySecurityRoleTemplateName.name(), partySecurityRoleTemplateName);
069        }
070
071        return partySecurityRoleTemplate;
072    }
073
074    public PartySecurityRoleTemplate getPartySecurityRoleTemplateByName(final ExecutionErrorAccumulator eea, final String partySecurityRoleTemplateName) {
075        return getPartySecurityRoleTemplateByName(eea, partySecurityRoleTemplateName, EntityPermission.READ_ONLY);
076    }
077
078    public PartySecurityRoleTemplate getPartySecurityRoleTemplateByNameForUpdate(final ExecutionErrorAccumulator eea, final String partySecurityRoleTemplateName) {
079        return getPartySecurityRoleTemplateByName(eea, partySecurityRoleTemplateName, EntityPermission.READ_WRITE);
080    }
081
082    // --------------------------------------------------------------------------------
083    //   Party Security Role Template Roles
084    // --------------------------------------------------------------------------------
085
086    public PartySecurityRoleTemplateRole createPartySecurityRoleTemplateRole(final PartySecurityRoleTemplate partySecurityRoleTemplate,
087            final SecurityRole securityRole, final BasePK createdBy) {
088        var partySecurityRoleTemplateRole = securityControl.createPartySecurityRoleTemplateRole(partySecurityRoleTemplate,
089                securityRole, createdBy);
090
091        // Add SecurityRole to any Parties that are currently assigned to the PartySecurityRoleTemplate.
092        var partySecurityRoleTemplateUses = securityControl.getPartySecurityRoleTemplateUsesByPartySecurityRoleTemplate(partySecurityRoleTemplate);
093        partySecurityRoleTemplateUses.stream().map((partySecurityRoleTemplateUse) -> partySecurityRoleTemplateUse.getParty()).filter((party) -> (securityControl.getPartySecurityRole(party, securityRole) == null)).forEach((party) -> {
094            securityControl.createPartySecurityRole(party, securityRole, createdBy);
095        });
096
097        return partySecurityRoleTemplateRole;
098    }
099
100    public void deletePartySecurityRoleTemplateRole(final PartySecurityRoleTemplateRole partySecurityRoleTemplateRole, final BasePK deletedBy) {
101        var partySecurityRoleTemplate = partySecurityRoleTemplateRole.getPartySecurityRoleTemplate();
102
103        securityControl.deletePartySecurityRoleTemplateRole(partySecurityRoleTemplateRole, deletedBy);
104
105        // Remove SecurityRole from any Parties that may be assigned to its PartySecurityRoleTemplate.
106        var partySecurityRoleTemplateUses = securityControl.getPartySecurityRoleTemplateUsesByPartySecurityRoleTemplate(partySecurityRoleTemplate);
107        if(partySecurityRoleTemplateUses.size() > 0) {
108            var securityRole = partySecurityRoleTemplateRole.getSecurityRole();
109
110            partySecurityRoleTemplateUses.stream().map((partySecurityRoleTemplateUse) -> partySecurityRoleTemplateUse.getParty()).map((party) -> securityControl.getPartySecurityRoleForUpdate(party, securityRole)).filter((partySecurityRole) -> (partySecurityRole != null)).forEach((partySecurityRole) -> {
111                securityControl.deletePartySecurityRole(partySecurityRole, deletedBy);
112            });
113        }
114    }
115    
116    public void deletePartySecurityRoleTemplateRoles(final List<PartySecurityRoleTemplateRole> partySecurityRoleTemplateRoles, final BasePK deletedBy) {
117        partySecurityRoleTemplateRoles.forEach((partySecurityRoleTemplateRole) -> 
118                deletePartySecurityRoleTemplateRole(partySecurityRoleTemplateRole, deletedBy)
119        );
120    }
121
122    public void deletePartySecurityRoleTemplateRoleByPartySecurityRoleTemplate(final PartySecurityRoleTemplate partySecurityRoleTemplate, final BasePK deletedBy) {
123        deletePartySecurityRoleTemplateRoles(securityControl.getPartySecurityRoleTemplateRolesForUpdate(partySecurityRoleTemplate), deletedBy);
124    }
125
126    public void deletePartySecurityRoleTemplateRolesBySecurityRole(final SecurityRole securityRole, final BasePK deletedBy) {
127        deletePartySecurityRoleTemplateRoles(securityControl.getPartySecurityRoleTemplateRolesBySecurityRoleForUpdate(securityRole), deletedBy);
128    }
129
130    // --------------------------------------------------------------------------------
131    //   Party Security Role Template Training Classes
132    // --------------------------------------------------------------------------------
133
134    public static class PreparedPartySecurityRoleTemplateTrainingClass {
135
136        private PartySecurityRoleTemplate partySecurityRoleTemplate;
137        private TrainingClass trainingClass;
138        private Set<PreparedPartyTrainingClass> preparedPartyTrainingClasses;
139
140        public PartySecurityRoleTemplate getPartySecurityRoleTemplate() {
141            return partySecurityRoleTemplate;
142        }
143
144        public void setPartySecurityRoleTemplate(PartySecurityRoleTemplate partySecurityRoleTemplate) {
145            this.partySecurityRoleTemplate = partySecurityRoleTemplate;
146        }
147
148        public TrainingClass getTrainingClass() {
149            return trainingClass;
150        }
151
152        public void setTrainingClass(TrainingClass trainingClass) {
153            this.trainingClass = trainingClass;
154        }
155
156        public Set<PreparedPartyTrainingClass> getPreparedPartyTrainingClasses() {
157            return preparedPartyTrainingClasses;
158        }
159
160        public void setPreparedPartyTrainingClasses(Set<PreparedPartyTrainingClass> preparedPartyTrainingClasses) {
161            this.preparedPartyTrainingClasses = preparedPartyTrainingClasses;
162        }
163
164    }
165
166    public PreparedPartySecurityRoleTemplateTrainingClass preparePartySecurityRoleTemplateTrainingClass(final ExecutionErrorAccumulator eea,
167            final PartySecurityRoleTemplate partySecurityRoleTemplate, final TrainingClass trainingClass) {
168        var preparedPartySecurityRoleTemplateTrainingClass = new PreparedPartySecurityRoleTemplateTrainingClass();
169
170        preparedPartySecurityRoleTemplateTrainingClass.setPartySecurityRoleTemplate(partySecurityRoleTemplate);
171        preparedPartySecurityRoleTemplateTrainingClass.setTrainingClass(trainingClass);
172
173        // If Party does not have a PartyTrainingClass for this TrainingClass in either ASSIGNED or TRAINING, then assign it to them.
174        var partySecurityRoleTemplateUses = securityControl.getPartySecurityRoleTemplateUsesByPartySecurityRoleTemplate(partySecurityRoleTemplate);
175        Set<PreparedPartyTrainingClass> preparedPartyTrainingClasses = new HashSet<>();
176        if(partySecurityRoleTemplateUses.size() > 0) {
177            for(var partySecurityRoleTemplateUse : partySecurityRoleTemplateUses) {
178                var party = partySecurityRoleTemplateUse.getParty();
179                var partyTrainingClasses = trainingControl.getPartyTrainingClassesByStatuses(party, trainingClass,
180                        PartyTrainingClassStatusConstants.WorkflowStep_ASSIGNED, PartyTrainingClassStatusConstants.WorkflowStep_TRAINING);
181
182                if(partyTrainingClasses.isEmpty()) {
183                    preparedPartyTrainingClasses.add(partyTrainingClassLogic.preparePartyTrainingClass(eea, party, trainingClass, null, null));
184                }
185
186                if(eea.hasExecutionErrors()) {
187                    break;
188                }
189            }
190        }
191
192        preparedPartySecurityRoleTemplateTrainingClass.setPreparedPartyTrainingClasses(preparedPartyTrainingClasses);
193
194        return preparedPartySecurityRoleTemplateTrainingClass;
195    }
196
197    public PartySecurityRoleTemplateTrainingClass createPartySecurityRoleTemplateTrainingClass(final Session session,
198            final PreparedPartySecurityRoleTemplateTrainingClass preparedPartySecurityRoleTemplateTrainingClass, final BasePK createdBy) {
199        var trainingClass = preparedPartySecurityRoleTemplateTrainingClass.getTrainingClass();
200        var partySecurityRoleTemplateTrainingClass = securityControl.createPartySecurityRoleTemplateTrainingClass(preparedPartySecurityRoleTemplateTrainingClass.partySecurityRoleTemplate,
201            trainingClass, createdBy);
202
203        // If Party does not have a PartyTrainingClass for this TrainingClass in either ASSIGNED or TRAINING, then assign it to them.
204        preparedPartySecurityRoleTemplateTrainingClass.getPreparedPartyTrainingClasses().forEach((preparedPartyTrainingClass) -> {
205            partyTrainingClassLogic.createPartyTrainingClass(session, preparedPartyTrainingClass, createdBy);
206        });
207
208        return partySecurityRoleTemplateTrainingClass;
209    }
210
211    public void deletePartySecurityRoleTemplateTrainingClass(final PartySecurityRoleTemplateTrainingClass partySecurityRoleTemplateTrainingClass,
212            final BasePK deletedBy) {
213        var partySecurityRoleTemplate = partySecurityRoleTemplateTrainingClass.getPartySecurityRoleTemplate();
214
215        securityControl.deletePartySecurityRoleTemplateTrainingClass(partySecurityRoleTemplateTrainingClass, deletedBy);
216
217        // If Party has a PartyTrainingClass in ASSIGNED status for this TrainingClass, then delete it.
218        var partySecurityRoleTemplateUses = securityControl.getPartySecurityRoleTemplateUsesByPartySecurityRoleTemplate(partySecurityRoleTemplate);
219        if(partySecurityRoleTemplateUses.size() > 0) {
220            var trainingClass = partySecurityRoleTemplateTrainingClass.getTrainingClass();
221
222            partySecurityRoleTemplateUses.stream().map((partySecurityRoleTemplateUse) -> partySecurityRoleTemplateUse.getParty()).map((party) -> trainingControl.getPartyTrainingClassesByStatusesForUpdate(party, trainingClass,
223                    PartyTrainingClassStatusConstants.WorkflowStep_ASSIGNED)).filter((partyTrainingClasses) -> (partyTrainingClasses.size() > 0)).forEach((partyTrainingClasses) -> {
224                        partyTrainingClasses.forEach((partyTrainingClass) -> {
225                            partyTrainingClassLogic.deletePartyTrainingClass(partyTrainingClass, deletedBy);
226                });
227            });
228        }
229    }
230
231    public void deletePartySecurityRoleTemplateTrainingClasses(final List<PartySecurityRoleTemplateTrainingClass> partySecurityRoleTemplateTrainingClasses,
232            final BasePK deletedBy) {
233        partySecurityRoleTemplateTrainingClasses.forEach((partySecurityRoleTemplateTrainingClass) -> 
234                deletePartySecurityRoleTemplateTrainingClass(partySecurityRoleTemplateTrainingClass, deletedBy)
235        );
236    }
237
238    public void deletePartySecurityRoleTemplateTrainingClassByPartySecurityRoleTemplate(final PartySecurityRoleTemplate partySecurityRoleTemplate,
239            final BasePK deletedBy) {
240        deletePartySecurityRoleTemplateTrainingClasses(securityControl.getPartySecurityRoleTemplateTrainingClassesForUpdate(partySecurityRoleTemplate), deletedBy);
241    }
242
243    public void deletePartySecurityRoleTemplateTrainingClassesByTrainingClass(final TrainingClass trainingClass, final BasePK deletedBy) {
244        deletePartySecurityRoleTemplateTrainingClasses(securityControl.getPartySecurityRoleTemplateTrainingClassesByTrainingClassForUpdate(trainingClass), deletedBy);
245    }
246
247}