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.control.user.content.server.command;
018
019import com.echothree.control.user.content.common.form.CreateContentCategoryForm;
020import com.echothree.control.user.content.common.result.ContentResultFactory;
021import com.echothree.model.control.content.common.ContentCategories;
022import com.echothree.model.control.content.server.control.ContentControl;
023import com.echothree.model.control.offer.server.control.OfferControl;
024import com.echothree.model.control.offer.server.control.OfferUseControl;
025import com.echothree.model.control.offer.server.control.SourceControl;
026import com.echothree.model.control.offer.server.control.UseControl;
027import com.echothree.model.control.party.common.PartyTypes;
028import com.echothree.model.control.party.server.control.PartyControl;
029import com.echothree.model.control.security.common.SecurityRoleGroups;
030import com.echothree.model.control.security.common.SecurityRoles;
031import com.echothree.model.control.selector.common.SelectorKinds;
032import com.echothree.model.control.selector.common.SelectorTypes;
033import com.echothree.model.control.selector.server.control.SelectorControl;
034import com.echothree.model.data.content.server.entity.ContentCategory;
035import com.echothree.model.data.offer.server.entity.OfferUse;
036import com.echothree.model.data.selector.server.entity.Selector;
037import com.echothree.model.data.user.common.pk.UserVisitPK;
038import com.echothree.util.common.command.BaseResult;
039import com.echothree.util.common.message.ExecutionErrors;
040import com.echothree.util.common.validation.FieldDefinition;
041import com.echothree.util.common.validation.FieldType;
042import com.echothree.util.server.control.BaseSimpleCommand;
043import com.echothree.util.server.control.CommandSecurityDefinition;
044import com.echothree.util.server.control.PartyTypeDefinition;
045import com.echothree.util.server.control.SecurityRoleDefinition;
046import java.util.List;
047import javax.enterprise.context.Dependent;
048import javax.inject.Inject;
049
050@Dependent
051public class CreateContentCategoryCommand
052        extends BaseSimpleCommand<CreateContentCategoryForm> {
053    
054    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
055    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
056    
057    static {
058        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
059                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
060                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
061                        new SecurityRoleDefinition(SecurityRoleGroups.ContentCategory.name(), SecurityRoles.Create.name())
062                ))
063        ));
064        
065        FORM_FIELD_DEFINITIONS = List.of(
066                new FieldDefinition("ContentCollectionName", FieldType.ENTITY_NAME, true, null, null),
067                new FieldDefinition("ContentCatalogName", FieldType.ENTITY_NAME, true, null, null),
068                new FieldDefinition("ContentCategoryName", FieldType.ENTITY_NAME, true, null, null),
069                new FieldDefinition("ParentContentCategoryName", FieldType.ENTITY_NAME, false, null, null),
070                new FieldDefinition("DefaultOfferName", FieldType.ENTITY_NAME, false, null, null),
071                new FieldDefinition("DefaultUseName", FieldType.ENTITY_NAME, false, null, null),
072                new FieldDefinition("DefaultSourceName", FieldType.ENTITY_NAME, false, null, null),
073                new FieldDefinition("ContentCategoryItemSelectorName", FieldType.ENTITY_NAME, false, null, null),
074                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
075                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
076                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
077        );
078    }
079
080    @Inject
081    ContentControl contentControl;
082
083    @Inject
084    OfferControl offerControl;
085
086    @Inject
087    OfferUseControl offerUseControl;
088
089    @Inject
090    PartyControl partyControl;
091
092    @Inject
093    SelectorControl selectorControl;
094
095    @Inject
096    SourceControl sourceControl;
097
098    @Inject
099    UseControl useControl;
100
101    
102    /** Creates a new instance of CreateContentCategoryCommand */
103    public CreateContentCategoryCommand() {
104        super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
105    }
106    
107    @Override
108    protected BaseResult execute() {
109        var result = ContentResultFactory.getCreateContentCategoryResult();
110        var contentCollectionName = form.getContentCollectionName();
111        var contentCollection = contentControl.getContentCollectionByName(contentCollectionName);
112        ContentCategory contentCategory = null;
113        
114        if(contentCollection != null) {
115            var contentCatalogName = form.getContentCatalogName();
116            var contentCatalog = contentControl.getContentCatalogByName(contentCollection, contentCatalogName);
117            
118            if(contentCatalog != null) {
119                var contentCategoryName = form.getContentCategoryName();
120                
121                contentCategory = contentControl.getContentCategoryByName(contentCatalog, contentCategoryName);
122                
123                if(contentCategory == null) {
124                    var parentContentCategoryName = form.getParentContentCategoryName();
125                    
126                    if(parentContentCategoryName == null)
127                        parentContentCategoryName = ContentCategories.ROOT.toString();
128
129                    var parentContentCategory = parentContentCategoryName == null? null: contentControl.getContentCategoryByName(contentCatalog,
130                            parentContentCategoryName);
131                    
132                    if(parentContentCategory == null) {
133                        addExecutionError(ExecutionErrors.UnknownParentContentCategoryName.name(), parentContentCategoryName);
134                    } else {
135                        var defaultOfferName = form.getDefaultOfferName();
136                        var defaultUseName = form.getDefaultUseName();
137                        var defaultSourceName = form.getDefaultSourceName();
138                        OfferUse defaultOfferUse = null;
139                        var invalidDefaultOfferOrSourceSpecification = false;
140                        
141                        if(defaultOfferName != null && defaultUseName != null && defaultSourceName == null) {
142                            var defaultOffer = offerControl.getOfferByName(defaultOfferName);
143                            
144                            if(defaultOffer != null) {
145                                var defaultUse = useControl.getUseByName(defaultUseName);
146                                
147                                if(defaultUse != null) {
148                                    defaultOfferUse = offerUseControl.getOfferUse(defaultOffer, defaultUse);
149                                    
150                                    if(defaultOfferUse == null) {
151                                        addExecutionError(ExecutionErrors.UnknownDefaultOfferUse.name());
152                                    }
153                                }  else {
154                                    addExecutionError(ExecutionErrors.UnknownDefaultUseName.name(), defaultUseName);
155                                }
156                            } else {
157                                addExecutionError(ExecutionErrors.UnknownDefaultOfferName.name(), defaultOfferName);
158                            }
159                        } else if(defaultOfferName == null && defaultUseName == null && defaultSourceName != null) {
160                            var source = sourceControl.getSourceByName(defaultSourceName);
161                            
162                            if(source != null) {
163                                defaultOfferUse = source.getLastDetail().getOfferUse();
164                            } else {
165                                addExecutionError(ExecutionErrors.UnknownDefaultSourceName.name(), defaultSourceName);
166                            }
167                        } else if(defaultOfferName == null && defaultUseName == null && defaultSourceName == null) {
168                            // nothing
169                        } else {
170                            addExecutionError(ExecutionErrors.InvalidDefaultOfferOrSourceSpecification.name());
171                            invalidDefaultOfferOrSourceSpecification = true;
172                        }
173                        
174                        if(!invalidDefaultOfferOrSourceSpecification) {
175                            var invalidOfferCompany = false;
176                            
177                            if(defaultOfferUse != null) {
178                                var defaultOffer = defaultOfferUse.getLastDetail().getOffer();
179                                var defaultPartyDepartment = partyControl.getPartyDepartment(defaultOffer.getLastDetail().getDepartmentParty());
180                                var defaultPartyDivision = partyControl.getPartyDivision(defaultPartyDepartment.getDivisionParty());
181                                var defaultPartyCompany = partyControl.getPartyCompany(defaultPartyDivision.getCompanyParty());
182
183                                var catalogOffer = contentCatalog.getLastDetail().getDefaultOfferUse().getLastDetail().getOffer();
184                                var catalogPartyDepartment = partyControl.getPartyDepartment(catalogOffer.getLastDetail().getDepartmentParty());
185                                var catalogPartyDivision = partyControl.getPartyDivision(catalogPartyDepartment.getDivisionParty());
186                                var catalogPartyCompany = partyControl.getPartyCompany(catalogPartyDivision.getCompanyParty());
187                                
188                                if(!defaultPartyCompany.equals(catalogPartyCompany)) {
189                                    invalidOfferCompany = true;
190                                }
191                            }
192                            
193                            if(!invalidOfferCompany) {
194                                var contentCategoryItemSelectorName = form.getContentCategoryItemSelectorName();
195                                Selector contentCategoryItemSelector = null;
196                                
197                                if(contentCategoryItemSelectorName != null) {
198                                    var selectorKind = selectorControl.getSelectorKindByName(SelectorKinds.ITEM.name());
199                                    
200                                    if(selectorKind != null) {
201                                        var selectorType = selectorControl.getSelectorTypeByName(selectorKind, SelectorTypes.CONTENT_CATEGORY.name());
202                                        
203                                        if(selectorType != null) {
204                                            contentCategoryItemSelector = selectorControl.getSelectorByName(selectorType, contentCategoryItemSelectorName);
205                                        } else {
206                                            addExecutionError(ExecutionErrors.UnknownSelectorTypeName.name(), SelectorTypes.CONTENT_CATEGORY.name());
207                                        }
208                                    } else {
209                                        addExecutionError(ExecutionErrors.UnknownSelectorKindName.name(), SelectorKinds.ITEM.name());
210                                    }
211                                }
212                                
213                                if(contentCategoryItemSelectorName != null && contentCategoryItemSelector == null) {
214                                    addExecutionError(ExecutionErrors.UnknownContentCategoryItemSelectorName.name(), contentCategoryItemSelectorName);
215                                } else {
216                                    var isDefault = Boolean.valueOf(form.getIsDefault());
217                                    var sortOrder = Integer.valueOf(form.getSortOrder());
218                                    var description = form.getDescription();
219                                    var createdBy = getPartyPK();
220                                    
221                                    contentCategory = contentControl.createContentCategory(contentCatalog, contentCategoryName,
222                                            parentContentCategory, defaultOfferUse, contentCategoryItemSelector, isDefault,
223                                            sortOrder, createdBy);
224                                    
225                                    if(description != null) {
226                                        contentControl.createContentCategoryDescription(contentCategory, getPreferredLanguage(),
227                                                description, createdBy);
228                                    }
229                                }
230                            } else {
231                                addExecutionError(ExecutionErrors.InvalidOfferCompany.name());
232                            }
233                        }
234                    }
235                } else {
236                    addExecutionError(ExecutionErrors.DuplicateContentCategoryName.name(), contentCategoryName);
237                }
238            } else {
239                addExecutionError(ExecutionErrors.UnknownContentCatalogName.name(), contentCatalogName);
240            }
241        } else {
242            addExecutionError(ExecutionErrors.UnknownContentCollectionName.name(), contentCollectionName);
243        }
244
245        if(contentCategory != null) {
246            var contentCategoryDetail = contentCategory.getLastDetail();
247            var contentCatalogDetail = contentCategoryDetail.getContentCatalog().getLastDetail();
248
249            result.setContentCollectionName(contentCatalogDetail.getContentCollection().getLastDetail().getContentCollectionName());
250            result.setContentCatalogName(contentCatalogDetail.getContentCatalogName());
251            result.setContentCategoryName(contentCategoryDetail.getContentCategoryName());
252            result.setEntityRef(contentCategory.getPrimaryKey().getEntityRef());
253        }
254
255        return result;
256    }
257    
258}