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.control.user.search.server.command;
018
019import com.echothree.control.user.search.common.form.SearchItemsForm;
020import com.echothree.control.user.search.common.result.SearchItemsResult;
021import com.echothree.control.user.search.common.result.SearchResultFactory;
022import com.echothree.model.control.item.server.logic.ItemLogic;
023import com.echothree.model.control.party.server.logic.LanguageLogic;
024import com.echothree.model.control.search.common.SearchKinds;
025import com.echothree.model.control.search.server.control.SearchControl;
026import com.echothree.model.control.item.server.search.ItemSearchEvaluator;
027import com.echothree.model.control.search.server.logic.SearchLogic;
028import com.echothree.model.control.item.common.workflow.ItemStatusConstants;
029import com.echothree.model.control.workflow.server.logic.WorkflowLogic;
030import com.echothree.model.control.workflow.server.logic.WorkflowStepLogic;
031import com.echothree.model.data.item.server.entity.ItemType;
032import com.echothree.model.data.item.server.entity.ItemUseType;
033import com.echothree.model.data.party.server.entity.Language;
034import com.echothree.model.data.party.server.entity.Party;
035import com.echothree.model.data.search.server.entity.PartySearchTypePreference;
036import com.echothree.model.data.search.server.entity.PartySearchTypePreferenceDetail;
037import com.echothree.model.data.search.server.entity.SearchDefaultOperator;
038import com.echothree.model.data.search.server.entity.SearchKind;
039import com.echothree.model.data.search.server.entity.SearchSortDirection;
040import com.echothree.model.data.search.server.entity.SearchSortOrder;
041import com.echothree.model.data.search.server.entity.SearchType;
042import com.echothree.model.data.search.server.entity.SearchUseType;
043import com.echothree.model.data.user.common.pk.UserVisitPK;
044import com.echothree.model.data.user.server.entity.UserVisit;
045import com.echothree.model.data.workflow.server.entity.WorkflowStep;
046import com.echothree.util.common.message.ExecutionErrors;
047import com.echothree.util.common.validation.FieldDefinition;
048import com.echothree.util.common.validation.FieldType;
049import com.echothree.util.common.command.BaseResult;
050import com.echothree.util.server.persistence.Session;
051import com.google.common.base.Splitter;
052import java.util.ArrayList;
053import java.util.Arrays;
054import java.util.Collections;
055import java.util.List;
056
057public class SearchItemsCommand
058        extends BaseSearchCommand<SearchItemsForm, SearchItemsResult> {
059    
060    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
061
062    static {
063        FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
064                new FieldDefinition("LanguageIsoName", FieldType.ENTITY_NAME, false, null, null),
065                new FieldDefinition("SearchDefaultOperatorName", FieldType.ENTITY_NAME, false, null, null),
066                new FieldDefinition("SearchSortDirectionName", FieldType.ENTITY_NAME, false, null, null),
067                new FieldDefinition("SearchTypeName", FieldType.ENTITY_NAME, true, null, null),
068                new FieldDefinition("SearchSortOrderName", FieldType.ENTITY_NAME, false, null, null),
069                new FieldDefinition("ItemNameOrAlias", FieldType.ENTITY_NAME, false, null, null),
070                new FieldDefinition("Description", FieldType.STRING, false, null, null),
071                new FieldDefinition("ItemTypeName", FieldType.ENTITY_NAME, false, null, null),
072                new FieldDefinition("ItemUseTypeName", FieldType.ENTITY_NAME, false, null, null),
073                new FieldDefinition("ItemStatusChoice", FieldType.ENTITY_NAME, false, null, null),
074                new FieldDefinition("ItemStatusChoices", FieldType.ENTITY_NAMES, false, null, null),
075                new FieldDefinition("CreatedSince", FieldType.DATE_TIME, false, null, null),
076                new FieldDefinition("ModifiedSince", FieldType.DATE_TIME, false, null, null),
077                new FieldDefinition("Fields", FieldType.STRING, false, null, null),
078                new FieldDefinition("RememberPreferences", FieldType.BOOLEAN, false, null, null),
079                new FieldDefinition("SearchUseTypeName", FieldType.ENTITY_NAME, false, null, null)
080                ));
081    }
082
083    /** Creates a new instance of SearchItemsCommand */
084    public SearchItemsCommand(UserVisitPK userVisitPK, SearchItemsForm form) {
085        super(userVisitPK, form, null, FORM_FIELD_DEFINITIONS, false);
086    }
087    
088    @Override
089    protected BaseResult execute() {
090        SearchItemsResult result = SearchResultFactory.getSearchItemsResult();
091        String itemStatusChoice = form.getItemStatusChoice();
092        String itemStatusChoices = form.getItemStatusChoices();
093        var parameterCount = (itemStatusChoice == null ? 0 : 1) + (itemStatusChoices == null ? 0 : 1);
094        
095        if(parameterCount < 2) {
096            SearchLogic searchLogic = SearchLogic.getInstance();
097            SearchKind searchKind = searchLogic.getSearchKindByName(null, SearchKinds.ITEM.name());
098
099            if(!hasExecutionErrors()) {
100                String searchTypeName = form.getSearchTypeName();
101                SearchType searchType = searchLogic.getSearchTypeByName(this, searchKind, searchTypeName);
102
103                if(!hasExecutionErrors()) {
104                    String languageIsoName = form.getLanguageIsoName();
105                    Language language = languageIsoName == null ? null : LanguageLogic.getInstance().getLanguageByName(this, languageIsoName);
106
107                    if(!hasExecutionErrors()) {
108                        var searchControl = Session.getModelController(SearchControl.class);
109                        PartySearchTypePreference partySearchTypePreference = getPartySearchTypePreference(searchControl, searchType);
110                        PartySearchTypePreferenceDetail partySearchTypePreferenceDetail = partySearchTypePreference == null ? null : partySearchTypePreference.getLastDetail();
111                        boolean rememberPreferences = Boolean.valueOf(form.getRememberPreferences());
112                        String searchDefaultOperatorName = form.getSearchDefaultOperatorName();
113                        SearchDefaultOperator searchDefaultOperator = searchDefaultOperatorName == null 
114                                ? getDefaultSearchDefaultOperator(searchLogic, rememberPreferences, partySearchTypePreferenceDetail)
115                                : searchLogic.getSearchDefaultOperatorByName(this, searchDefaultOperatorName);
116
117                        if(!hasExecutionErrors()) {
118                            String searchSortOrderName = form.getSearchSortOrderName();
119                            SearchSortOrder searchSortOrder = searchSortOrderName == null
120                                    ? getDefaultSearchSortOrder(searchLogic, rememberPreferences, searchKind, partySearchTypePreferenceDetail)
121                                    : searchLogic.getSearchSortOrderByName(this, searchKind, searchSortOrderName);
122
123                            if(!hasExecutionErrors()) {
124                                String searchSortDirectionName = form.getSearchSortDirectionName();
125                                SearchSortDirection searchSortDirection = searchSortDirectionName == null
126                                        ? getDefaultSearchSortDirection(searchLogic, rememberPreferences, partySearchTypePreferenceDetail)
127                                        : searchLogic.getSearchSortDirectionByName(this, searchSortDirectionName);
128
129                                if(!hasExecutionErrors()) {
130                                    String searchUseTypeName = form.getSearchUseTypeName();
131                                    SearchUseType searchUseType = searchUseTypeName == null ? null : SearchLogic.getInstance().getSearchUseTypeByName(this, searchUseTypeName);
132
133                                    if(!hasExecutionErrors()) {
134                                        ItemLogic itemLogic = ItemLogic.getInstance();
135                                        String itemTypeName = form.getItemTypeName();
136                                        ItemType itemType = itemTypeName == null ? null : itemLogic.getItemTypeByName(this, itemTypeName);
137
138                                        if(!hasExecutionErrors()) {
139                                            String itemUseTypeName = form.getItemUseTypeName();
140                                            ItemUseType itemUseType = itemUseTypeName == null ? null : itemLogic.getItemUseTypeByName(this, itemUseTypeName);
141
142                                            if(!hasExecutionErrors()) {
143                                                WorkflowStep itemStatusWorkflowStep = null;
144                                                List<WorkflowStep> itemStatusWorkflowSteps = null;
145
146                                                if(itemStatusChoice != null || itemStatusChoices != null) {
147                                                    var workflow = WorkflowLogic.getInstance().getWorkflowByName(this, ItemStatusConstants.Workflow_ITEM_STATUS);
148
149                                                    if(!hasExecutionErrors()) {
150                                                        WorkflowStepLogic workflowStepLogic = WorkflowStepLogic.getInstance();
151
152                                                        if(itemStatusChoice != null) {
153                                                            itemStatusWorkflowStep = workflowStepLogic.getWorkflowStepByName(this, workflow, itemStatusChoice);
154                                                        } else {
155                                                            String []workflowStepNames = Splitter.on(':').trimResults().omitEmptyStrings().splitToList(itemStatusChoices).toArray(new String[0]);
156
157                                                            itemStatusWorkflowSteps = new ArrayList<>(workflowStepNames.length);
158                                                            for(int i = 0; i < workflowStepNames.length; i++) {
159                                                                WorkflowStep workflowStep = workflowStepLogic.getWorkflowStepByName(this, workflow, workflowStepNames[i]);
160
161                                                                if(!hasExecutionErrors()) {
162                                                                    itemStatusWorkflowSteps.add(workflowStep);
163                                                                }
164                                                            }
165                                                        }
166                                                    }
167                                                }
168
169                                                if(!hasExecutionErrors()) {
170                                                    UserVisit userVisit = getUserVisit();
171                                                    String createdSince = form.getCreatedSince();
172                                                    String modifiedSince = form.getModifiedSince();
173                                                    String fields = form.getFields();
174
175                                                    if(rememberPreferences) {
176                                                        Party party = getParty();
177
178                                                        if(party != null) {
179                                                            updatePartySearchTypePreferences(searchControl, searchType, partySearchTypePreference, searchDefaultOperator,
180                                                                    searchSortOrder, searchSortDirection, party);
181                                                        }
182                                                    }
183
184                                                    ItemSearchEvaluator itemSearchEvaluator = new ItemSearchEvaluator(userVisit, language, searchType,
185                                                            searchDefaultOperator, searchSortOrder, searchSortDirection, searchUseType);
186
187                                                    itemSearchEvaluator.setItemNameOrAlias(form.getItemNameOrAlias());
188                                                    itemSearchEvaluator.setQ(this, form.getDescription());
189                                                    itemSearchEvaluator.setItemType(itemType);
190                                                    itemSearchEvaluator.setItemUseType(itemUseType);
191                                                    itemSearchEvaluator.setItemStatusWorkflowStep(itemStatusWorkflowStep);
192                                                    itemSearchEvaluator.setItemStatusWorkflowSteps(itemStatusWorkflowSteps);
193                                                    itemSearchEvaluator.setCreatedSince(createdSince == null ? null : Long.valueOf(createdSince));
194                                                    itemSearchEvaluator.setModifiedSince(modifiedSince == null ? null : Long.valueOf(modifiedSince));
195                                                    itemSearchEvaluator.setFields(fields == null ? null : Splitter.on(':').trimResults().omitEmptyStrings().splitToList(fields).toArray(new String[0]));
196
197                                                    if(!hasExecutionErrors()) {
198                                                        result.setCount(itemSearchEvaluator.execute(this));
199                                                    }
200                                                } else {
201                                                    addExecutionError(ExecutionErrors.UnknownItemStatusChoice.name(), itemStatusChoice);
202                                                }
203                                            }
204                                        }
205                                    }
206                                }
207                            }
208                        }
209                    }
210                }
211            }
212        } else {
213            addExecutionError(ExecutionErrors.InvalidParameterCount.name());
214        }
215        
216        return result;
217    }
218}