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