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.order.server.search;
018
019import com.echothree.model.control.core.common.ComponentVendors;
020import com.echothree.model.control.core.common.EntityTypes;
021import com.echothree.model.control.order.server.control.OrderAliasControl;
022import com.echothree.model.control.order.server.control.OrderControl;
023import com.echothree.model.control.search.server.search.BaseSearchEvaluator;
024import com.echothree.model.control.search.server.search.EntityInstancePKHolder;
025import com.echothree.model.data.accounting.server.entity.Currency;
026import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy;
027import com.echothree.model.data.core.server.factory.EntityInstanceFactory;
028import com.echothree.model.data.order.server.entity.Order;
029import com.echothree.model.data.order.server.entity.OrderAlias;
030import com.echothree.model.data.order.server.entity.OrderAliasType;
031import com.echothree.model.data.order.server.entity.OrderPriority;
032import com.echothree.model.data.order.server.entity.OrderType;
033import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy;
034import com.echothree.model.data.search.server.entity.SearchDefaultOperator;
035import com.echothree.model.data.search.server.entity.SearchSortDirection;
036import com.echothree.model.data.search.server.entity.SearchSortOrder;
037import com.echothree.model.data.search.server.entity.SearchType;
038import com.echothree.model.data.term.server.entity.Term;
039import com.echothree.model.data.user.server.entity.UserVisit;
040import com.echothree.model.data.workflow.server.entity.WorkflowStep;
041import com.echothree.util.server.message.ExecutionErrorAccumulator;
042import com.echothree.util.server.persistence.Session;
043
044public class OrderSearchEvaluator
045        extends BaseSearchEvaluator {
046    
047    protected OrderType orderType;
048    private WorkflowStep orderStatusWorkflowStep;
049    private String orderName;
050    private OrderAliasType orderAliasType;
051    private String alias;
052    private OrderPriority orderPriority;
053    private Currency currency;
054    private Term term;
055    private String reference;
056    private CancellationPolicy cancellationPolicy;
057    private ReturnPolicy returnPolicy;
058    
059    protected OrderSearchEvaluator(UserVisit userVisit, SearchType searchType, SearchDefaultOperator searchDefaultOperator, SearchSortOrder searchSortOrder,
060            SearchSortDirection searchSortDirection, OrderType orderType) {
061        super(userVisit, searchDefaultOperator, searchType, searchSortOrder, searchSortDirection, null, ComponentVendors.ECHO_THREE.name(),
062                EntityTypes.Order.name(), null, null, null);
063        
064        this.orderType = orderType;
065    }
066    
067    public WorkflowStep getOrderStatusWorkflowStep() {
068        return orderStatusWorkflowStep;
069    }
070
071    public void setOrderStatusWorkflowStep(WorkflowStep orderStatusWorkflowStep) {
072        this.orderStatusWorkflowStep = orderStatusWorkflowStep;
073    }
074    
075    public String getOrderName() {
076        return orderName;
077    }
078
079    public void setOrderName(String orderName) {
080        this.orderName = orderName;
081    }
082
083    public OrderAliasType getOrderAliasType() {
084        return orderAliasType;
085    }
086
087    public void setOrderAliasType(OrderAliasType orderAliasType) {
088        this.orderAliasType = orderAliasType;
089    }
090
091    public String getAlias() {
092        return alias;
093    }
094
095    public void setAlias(String alias) {
096        this.alias = alias;
097    }
098    
099    public OrderPriority getOrderPriority() {
100        return orderPriority;
101    }
102
103    public void setOrderPriority(OrderPriority orderPriority) {
104        this.orderPriority = orderPriority;
105    }
106
107    public Currency getCurrency() {
108        return currency;
109    }
110
111    public void setCurrency(Currency currency) {
112        this.currency = currency;
113    }
114
115    public Term getTerm() {
116        return term;
117    }
118
119    public void setTerm(Term term) {
120        this.term = term;
121    }
122
123    public String getReference() {
124        return reference;
125    }
126
127    public void setReference(String reference) {
128        this.reference = reference;
129    }
130
131    public CancellationPolicy getCancellationPolicy() {
132        return cancellationPolicy;
133    }
134
135    public void setCancellationPolicy(CancellationPolicy cancellationPolicy) {
136        this.cancellationPolicy = cancellationPolicy;
137    }
138
139    public ReturnPolicy getReturnPolicy() {
140        return returnPolicy;
141    }
142
143    public void setReturnPolicy(ReturnPolicy returnPolicy) {
144        this.returnPolicy = returnPolicy;
145    }
146
147    /** Counts the number of search parameters, not including orderType. */
148    @Override
149    protected int countParameters() {
150        return super.countParameters() + (orderStatusWorkflowStep == null ? 0 : 1) + (orderName == null ? 0 : 1) + (orderAliasType == null ? 0 : 1)
151                + (alias == null ? 0 : 1) + (orderPriority == null ? 0 : 1) + (currency == null ? 0 : 1) + (term == null ? 0 : 1) + (reference == null ? 0 : 1)
152                + (cancellationPolicy == null ? 0 : 1) + (returnPolicy == null ? 0 : 1);
153    }
154
155    public EntityInstancePKHolder getEntityInstancePKHolderByOrderType(OrderType orderType) {
156        return getEntityInstancePKHolderFromQuery(EntityInstanceFactory.getInstance().prepareStatement(
157                "SELECT _PK_ "
158                + "FROM entityinstances, orderes, orderdetails "
159                + "WHERE ord_activedetailid = orddt_orderdetailid "
160                + "AND orddt_ordtyp_ordertypeid = ? "
161                + "AND eni_ent_entitytypeid = ? AND ord_orderid = eni_entityuniqueid"),
162                orderType, entityType);
163    }
164    
165    public EntityInstancePKHolder getEntityInstancePKHolderByOrderStatusWorkflowStep(WorkflowStep orderStatusWorkflowStep) {
166        return getEntityInstancePKHolderFromQuery(EntityInstanceFactory.getInstance().prepareStatement(
167                "SELECT _PK_ "
168                + "FROM entityinstances, orderes, orderdetails, workflowentitystatuses "
169                + "WHERE ord_activedetailid = orddt_orderdetailid "
170                + "AND orddt_ordtyp_ordertypeid = ? "
171                + "AND eni_ent_entitytypeid = ? AND ord_orderid = eni_entityuniqueid "
172                + "AND eni_entityinstanceid = wkfles_eni_entityinstanceid AND wkfles_wkfls_workflowstepid = ? AND wkfles_thrutime = ?"),
173                orderType, entityType, orderStatusWorkflowStep, Session.MAX_TIME);
174    }
175 
176    public EntityInstancePKHolder getEntityInstancePKHolderByOrderPriority(OrderPriority orderPriority) {
177        return getEntityInstancePKHolderFromQuery(EntityInstanceFactory.getInstance().prepareStatement(
178                "SELECT _PK_ "
179                + "FROM entityinstances, orderes, orderdetails "
180                + "WHERE ord_activedetailid = orddt_orderdetailid "
181                + "AND orddt_ordtyp_ordertypeid = ? AND orddt_ordpr_orderpriorityid = ? "
182                + "AND eni_ent_entitytypeid = ? AND ord_orderid = eni_entityuniqueid"),
183                orderType, orderPriority, entityType);
184    }
185    
186    public EntityInstancePKHolder getEntityInstancePKHolderByCurrency(Currency currency) {
187        return getEntityInstancePKHolderFromQuery(EntityInstanceFactory.getInstance().prepareStatement(
188                "SELECT _PK_ "
189                + "FROM entityinstances, orderes, orderdetails "
190                + "WHERE ord_activedetailid = orddt_orderdetailid "
191                + "AND orddt_ordtyp_ordertypeid = ? AND orddt_cur_currencyid = ? "
192                + "AND eni_ent_entitytypeid = ? AND ord_orderid = eni_entityuniqueid"),
193                orderType, currency, entityType);
194    }
195    
196    public EntityInstancePKHolder getEntityInstancePKHolderByTerm(Term term) {
197        return getEntityInstancePKHolderFromQuery(EntityInstanceFactory.getInstance().prepareStatement(
198                "SELECT _PK_ "
199                + "FROM entityinstances, orderes, orderdetails "
200                + "WHERE ord_activedetailid = orddt_orderdetailid "
201                + "AND orddt_ordtyp_ordertypeid = ? AND orddt_trm_termid = ? "
202                + "AND eni_ent_entitytypeid = ? AND ord_orderid = eni_entityuniqueid"),
203                orderType, term, entityType);
204    }
205    
206    public EntityInstancePKHolder getEntityInstancePKHolderByReference(String reference) {
207        return getEntityInstancePKHolderFromQuery(EntityInstanceFactory.getInstance().prepareStatement(
208                "SELECT _PK_ "
209                + "FROM entityinstances, orderes, orderdetails "
210                + "WHERE ord_activedetailid = orddt_orderdetailid "
211                + "AND orddt_ordtyp_ordertypeid = ? AND orddt_reference = ? "
212                + "AND eni_ent_entitytypeid = ? AND ord_orderid = eni_entityuniqueid"),
213                orderType, reference, entityType);
214    }
215    
216    public EntityInstancePKHolder getEntityInstancePKHolderByCancellationPolicy(CancellationPolicy cancellationPolicy) {
217        return getEntityInstancePKHolderFromQuery(EntityInstanceFactory.getInstance().prepareStatement(
218                "SELECT _PK_ "
219                + "FROM entityinstances, orderes, orderdetails "
220                + "WHERE ord_activedetailid = orddt_orderdetailid "
221                + "AND orddt_ordtyp_ordertypeid = ? AND orddt_cnclplcy_cancellationpolicyid = ? "
222                + "AND eni_ent_entitytypeid = ? AND ord_orderid = eni_entityuniqueid"),
223                orderType, cancellationPolicy, entityType);
224    }
225    
226    public EntityInstancePKHolder getEntityInstancePKHolderByReturnPolicy(ReturnPolicy returnPolicy) {
227        return getEntityInstancePKHolderFromQuery(EntityInstanceFactory.getInstance().prepareStatement(
228                "SELECT _PK_ "
229                + "FROM entityinstances, orderes, orderdetails "
230                + "WHERE ord_activedetailid = orddt_orderdetailid "
231                + "AND orddt_ordtyp_ordertypeid = ? AND orddt_rtnplcy_returnpolicyid = ? "
232                + "AND eni_ent_entitytypeid = ? AND ord_orderid = eni_entityuniqueid"),
233                orderType, returnPolicy, entityType);
234    }
235    
236    /** Subclasses should override and always call their super's executeSearch() */
237    @Override
238    protected EntityInstancePKHolder executeSearch(final ExecutionErrorAccumulator eea) {
239        EntityInstancePKHolder resultSet = null;
240        var parameterCount = (orderName == null ? 0 : 1) + (alias == null ? 0 : 1);
241
242        if(parameterCount == 0) {
243            resultSet = super.executeSearch(eea);
244            
245            if(orderStatusWorkflowStep != null && (resultSet == null || resultSet.size() > 0)) {
246                EntityInstancePKHolder entityInstancePKHolder = getEntityInstancePKHolderByOrderStatusWorkflowStep(orderStatusWorkflowStep);
247
248                if(resultSet == null) {
249                    resultSet = entityInstancePKHolder;
250                } else {
251                    resultSet.retainAll(entityInstancePKHolder);
252                }
253            }
254            
255            if(orderPriority != null && (resultSet == null || resultSet.size() > 0)) {
256                EntityInstancePKHolder entityInstancePKHolder = getEntityInstancePKHolderByOrderPriority(orderPriority);
257
258                if(resultSet == null) {
259                    resultSet = entityInstancePKHolder;
260                } else {
261                    resultSet.retainAll(entityInstancePKHolder);
262                }
263            }
264            
265            if(currency != null && (resultSet == null || resultSet.size() > 0)) {
266                EntityInstancePKHolder entityInstancePKHolder = getEntityInstancePKHolderByCurrency(currency);
267
268                if(resultSet == null) {
269                    resultSet = entityInstancePKHolder;
270                } else {
271                    resultSet.retainAll(entityInstancePKHolder);
272                }
273            }
274            
275            if(term != null && (resultSet == null || resultSet.size() > 0)) {
276                EntityInstancePKHolder entityInstancePKHolder = getEntityInstancePKHolderByTerm(term);
277
278                if(resultSet == null) {
279                    resultSet = entityInstancePKHolder;
280                } else {
281                    resultSet.retainAll(entityInstancePKHolder);
282                }
283            }
284            
285            if(reference != null && (resultSet == null || resultSet.size() > 0)) {
286                EntityInstancePKHolder entityInstancePKHolder = getEntityInstancePKHolderByReference(reference);
287
288                if(resultSet == null) {
289                    resultSet = entityInstancePKHolder;
290                } else {
291                    resultSet.retainAll(entityInstancePKHolder);
292                }
293            }
294            
295            if(cancellationPolicy != null && (resultSet == null || resultSet.size() > 0)) {
296                EntityInstancePKHolder entityInstancePKHolder = getEntityInstancePKHolderByCancellationPolicy(cancellationPolicy);
297
298                if(resultSet == null) {
299                    resultSet = entityInstancePKHolder;
300                } else {
301                    resultSet.retainAll(entityInstancePKHolder);
302                }
303            }
304            
305            if(returnPolicy != null && (resultSet == null || resultSet.size() > 0)) {
306                EntityInstancePKHolder entityInstancePKHolder = getEntityInstancePKHolderByReturnPolicy(returnPolicy);
307
308                if(resultSet == null) {
309                    resultSet = entityInstancePKHolder;
310                } else {
311                    resultSet.retainAll(entityInstancePKHolder);
312                }
313            }
314            
315            if(countParameters() == 0 && (resultSet == null || resultSet.size() > 0)) {
316                EntityInstancePKHolder entityInstancePKHolder = getEntityInstancePKHolderByOrderType(orderType);
317
318                if(resultSet == null) {
319                    resultSet = entityInstancePKHolder;
320                } else {
321                    resultSet.retainAll(entityInstancePKHolder);
322                }
323            }
324        } else {
325            Order order = null;
326
327            if(parameterCount == 1) {
328                var orderAliasControl = Session.getModelController(OrderAliasControl.class);
329
330                if(orderAliasType == null) {
331                    orderAliasType = orderAliasControl.getDefaultOrderAliasType(orderType);
332                }
333
334                if(orderAliasType != null) {
335                    OrderAlias orderAlias = orderAliasControl.getOrderAliasByAlias(orderAliasType, alias);
336                    
337                    order = orderAlias == null ? null : orderAlias.getOrder();
338                }
339
340                if(orderName != null) {
341                    var orderControl = Session.getModelController(OrderControl.class);
342
343                    order = orderControl.getOrderByName(orderType, orderName);
344                }
345
346                if(order != null) {
347                    resultSet = new EntityInstancePKHolder(1);
348                    resultSet.add(getCoreControl().getEntityInstanceByBasePK(order.getPrimaryKey()).getPrimaryKey(), null);
349                }
350            }
351        }
352        
353        return resultSet;
354    }
355
356}