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.control.user.selector.server.command;
018
019import com.echothree.control.user.selector.common.form.CreateSelectorNodeForm;
020import com.echothree.model.control.accounting.server.control.AccountingControl;
021import com.echothree.model.control.core.server.control.CoreControl;
022import com.echothree.model.control.employee.server.control.EmployeeControl;
023import com.echothree.model.control.geo.server.control.GeoControl;
024import com.echothree.model.control.item.server.control.ItemControl;
025import com.echothree.model.control.payment.server.control.PaymentMethodControl;
026import com.echothree.model.control.payment.server.control.PaymentProcessorControl;
027import com.echothree.model.control.selector.common.SelectorNodeTypes;
028import com.echothree.model.control.selector.server.control.SelectorControl;
029import com.echothree.model.control.selector.server.logic.SelectorNodeTypeLogic;
030import com.echothree.model.control.training.server.control.TrainingControl;
031import com.echothree.model.control.vendor.server.control.VendorControl;
032import com.echothree.model.control.workflow.server.control.WorkflowControl;
033import com.echothree.model.data.accounting.server.entity.ItemAccountingCategory;
034import com.echothree.model.data.core.server.entity.EntityListItem;
035import com.echothree.model.data.employee.server.entity.ResponsibilityType;
036import com.echothree.model.data.employee.server.entity.SkillType;
037import com.echothree.model.data.geo.server.entity.GeoCode;
038import com.echothree.model.data.item.server.entity.ItemCategory;
039import com.echothree.model.data.party.common.pk.PartyPK;
040import com.echothree.model.data.payment.server.entity.PaymentMethod;
041import com.echothree.model.data.payment.server.entity.PaymentProcessor;
042import com.echothree.model.data.selector.server.entity.Selector;
043import com.echothree.model.data.selector.server.entity.SelectorBooleanType;
044import com.echothree.model.data.selector.server.entity.SelectorNode;
045import com.echothree.model.data.selector.server.entity.SelectorNodeType;
046import com.echothree.model.data.training.server.entity.TrainingClass;
047import com.echothree.model.data.user.common.pk.UserVisitPK;
048import com.echothree.model.data.vendor.server.entity.ItemPurchasingCategory;
049import com.echothree.model.data.workflow.server.entity.WorkflowStep;
050import com.echothree.util.common.command.BaseResult;
051import com.echothree.util.common.form.ValidationResult;
052import com.echothree.util.common.message.ExecutionErrors;
053import com.echothree.util.common.validation.FieldDefinition;
054import com.echothree.util.common.validation.FieldType;
055import com.echothree.util.server.control.BaseSimpleCommand;
056import com.echothree.util.server.persistence.Session;
057import com.echothree.util.server.validation.Validator;
058import java.util.Arrays;
059import java.util.Collections;
060import java.util.List;
061import javax.enterprise.context.RequestScoped;
062
063@RequestScoped
064public class CreateSelectorNodeCommand
065        extends BaseSimpleCommand<CreateSelectorNodeForm> {
066    
067    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
068    private final static List<FieldDefinition> booleanFormFieldDefinitions;
069    private final static List<FieldDefinition> entityListItemFormFieldDefinitions;
070    private final static List<FieldDefinition> responsibilityTypeFormFieldDefinitions;
071    private final static List<FieldDefinition> skillTypeFormFieldDefinitions;
072    private final static List<FieldDefinition> trainingClassFormFieldDefinitions;
073    private final static List<FieldDefinition> workflowStepFormFieldDefinitions;
074    private final static List<FieldDefinition> itemCategoryFormFieldDefinitions;
075    private final static List<FieldDefinition> itemAccountingCategoryFormFieldDefinitions;
076    private final static List<FieldDefinition> itemPurchasingCategoryFormFieldDefinitions;
077    private final static List<FieldDefinition> paymentMethodFormFieldDefinitions;
078    private final static List<FieldDefinition> paymentProcessorFormFieldDefinitions;
079    private final static List<FieldDefinition> geoCodeFormFieldDefinitions;
080    
081    static {
082        FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
083                new FieldDefinition("SelectorKindName", FieldType.ENTITY_NAME, true, null, null),
084                new FieldDefinition("SelectorTypeName", FieldType.ENTITY_NAME, true, null, null),
085                new FieldDefinition("SelectorName", FieldType.ENTITY_NAME, true, null, null),
086                new FieldDefinition("SelectorNodeName", FieldType.ENTITY_NAME, true, null, null),
087                new FieldDefinition("IsRootSelectorNode", FieldType.BOOLEAN, true, null, null),
088                new FieldDefinition("SelectorNodeTypeName", FieldType.ENTITY_NAME, true, null, null),
089                new FieldDefinition("Negate", FieldType.BOOLEAN, true, null, null),
090                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
091                ));
092        
093        booleanFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
094                new FieldDefinition("SelectorBooleanTypeName", FieldType.ENTITY_NAME, true, null, null),
095                new FieldDefinition("LeftSelectorNodeName", FieldType.ENTITY_NAME, true, null, null),
096                new FieldDefinition("RightSelectorNodeName", FieldType.ENTITY_NAME, true, null, null)
097                ));
098        
099        entityListItemFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
100                new FieldDefinition("ComponentVendorName", FieldType.ENTITY_NAME, true, null, null),
101                new FieldDefinition("EntityTypeName", FieldType.ENTITY_TYPE_NAME, true, null, null),
102                new FieldDefinition("EntityAttributeName", FieldType.ENTITY_NAME, true, null, null),
103                new FieldDefinition("EntityListItemName", FieldType.ENTITY_NAME, true, null, null)
104                ));
105        
106        responsibilityTypeFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
107                new FieldDefinition("ResponsibilityTypeName", FieldType.ENTITY_NAME, true, null, null)
108                ));
109        
110        skillTypeFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
111                new FieldDefinition("SkillTypeName", FieldType.ENTITY_NAME, true, null, null)
112                ));
113        
114        trainingClassFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
115                new FieldDefinition("TrainingClassName", FieldType.ENTITY_NAME, true, null, null)
116                ));
117        
118        workflowStepFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
119                new FieldDefinition("WorkflowName", FieldType.ENTITY_NAME, true, null, null),
120                new FieldDefinition("WorkflowStepName", FieldType.ENTITY_NAME, true, null, null)
121                ));
122        
123        itemCategoryFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
124                new FieldDefinition("ItemCategoryName", FieldType.ENTITY_NAME, true, null, null),
125                new FieldDefinition("CheckParents", FieldType.BOOLEAN, true, null, null)
126                ));
127        
128        itemAccountingCategoryFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
129                new FieldDefinition("ItemAccountingCategoryName", FieldType.ENTITY_NAME, true, null, null),
130                new FieldDefinition("CheckParents", FieldType.BOOLEAN, true, null, null)
131                ));
132        
133        itemPurchasingCategoryFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
134                new FieldDefinition("ItemPurchasingCategoryName", FieldType.ENTITY_NAME, true, null, null),
135                new FieldDefinition("CheckParents", FieldType.BOOLEAN, true, null, null)
136                ));
137        
138        paymentMethodFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
139                new FieldDefinition("PaymentMethodName", FieldType.ENTITY_NAME, true, null, null)
140                ));
141        
142        paymentProcessorFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
143                new FieldDefinition("PaymentProcessorName", FieldType.ENTITY_NAME, true, null, null)
144                ));
145        
146        geoCodeFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
147                new FieldDefinition("GeoCodeName", FieldType.ENTITY_NAME, false, null, null),
148                new FieldDefinition("CountryName", FieldType.ENTITY_NAME, false, null, null)
149                ));
150    }
151    
152    /** Creates a new instance of CreateSelectorNodeCommand */
153    public CreateSelectorNodeCommand() {
154        super(null, FORM_FIELD_DEFINITIONS, false);
155    }
156    
157    @Override
158    protected ValidationResult validate() {
159        var validator = new Validator(this);
160        var validationResult = validator.validate(form, FORM_FIELD_DEFINITIONS);
161        
162        if(!validationResult.getHasErrors()) {
163            var selectorNodeType = SelectorNodeTypeLogic.getInstance().getSelectorNodeTypeByName(this, form.getSelectorNodeTypeName());
164            
165            if(!hasExecutionErrors()) {
166                var selectorNodeTypeEnum = SelectorNodeTypes.valueOf(selectorNodeType.getSelectorNodeTypeName());
167
168                switch(selectorNodeTypeEnum) {
169                    case BOOLEAN ->
170                            validationResult = validator.validate(form, booleanFormFieldDefinitions);
171                    case ENTITY_LIST_ITEM ->
172                            validationResult = validator.validate(form, entityListItemFormFieldDefinitions);
173                    case RESPONSIBILITY_TYPE ->
174                            validationResult = validator.validate(form, responsibilityTypeFormFieldDefinitions);
175                    case SKILL_TYPE ->
176                            validationResult = validator.validate(form, skillTypeFormFieldDefinitions);
177                    case TRAINING_CLASS ->
178                            validationResult = validator.validate(form, trainingClassFormFieldDefinitions);
179                    case WORKFLOW_STEP ->
180                            validationResult = validator.validate(form, workflowStepFormFieldDefinitions);
181                    case ITEM_CATEGORY ->
182                            validationResult = validator.validate(form, itemCategoryFormFieldDefinitions);
183                    case ITEM_ACCOUNTING_CATEGORY ->
184                            validationResult = validator.validate(form, itemAccountingCategoryFormFieldDefinitions);
185                    case ITEM_PURCHASING_CATEGORY ->
186                            validationResult = validator.validate(form, itemPurchasingCategoryFormFieldDefinitions);
187                    case PAYMENT_METHOD ->
188                            validationResult = validator.validate(form, paymentMethodFormFieldDefinitions);
189                    case PAYMENT_PROCESSOR ->
190                            validationResult = validator.validate(form, paymentProcessorFormFieldDefinitions);
191                    case GEO_CODE ->
192                            validationResult = validator.validate(form, geoCodeFormFieldDefinitions);
193                    default -> {
194                    }
195                }
196            }
197        }
198        
199        return validationResult;
200    }
201    
202    private abstract class BaseSelectorNodeType {
203        SelectorControl selectorControl;
204        SelectorNodeType selectorNodeType;
205        
206        private BaseSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
207            this.selectorControl = selectorControl;
208            selectorNodeType = selectorControl.getSelectorNodeTypeByName(selectorNodeTypeName);
209            
210            if(selectorNodeType == null) {
211                addExecutionError(ExecutionErrors.UnknownSelectorNodeTypeName.name(), selectorNodeTypeName);
212            }
213        }
214        
215        abstract void execute(SelectorNode selectorNode, PartyPK partyPK);
216    }
217    
218    private abstract class AccountingSelectorNodeType
219        extends BaseSelectorNodeType {
220        AccountingControl accountingControl = Session.getModelController(AccountingControl.class);
221
222        private AccountingSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
223            super(selectorControl, selectorNodeTypeName);
224        }
225    }
226    
227    private abstract class CoreSelectorNodeType
228        extends BaseSelectorNodeType {
229        private CoreSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
230            super(selectorControl, selectorNodeTypeName);
231        }
232    }
233    
234    private abstract class EmployeeSelectorNodeType
235        extends BaseSelectorNodeType {
236        EmployeeControl employeeControl = Session.getModelController(EmployeeControl.class);
237
238        private EmployeeSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
239            super(selectorControl, selectorNodeTypeName);
240        }
241    }
242    
243    private abstract class GeoSelectorNodeType
244        extends BaseSelectorNodeType {
245        GeoControl geoControl = Session.getModelController(GeoControl.class);
246
247        private GeoSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
248            super(selectorControl, selectorNodeTypeName);
249        }
250    }
251    
252    private abstract class ItemSelectorNodeType
253        extends BaseSelectorNodeType {
254        ItemControl itemControl = Session.getModelController(ItemControl.class);
255
256        private ItemSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
257            super(selectorControl, selectorNodeTypeName);
258        }
259    }
260
261    private abstract class PaymentProcessorSelectorNodeType
262            extends BaseSelectorNodeType {
263        PaymentProcessorControl paymentProcessorControl = Session.getModelController(PaymentProcessorControl.class);
264
265        private PaymentProcessorSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
266            super(selectorControl, selectorNodeTypeName);
267        }
268    }
269
270    private abstract class PaymentMethodSelectorNodeType
271            extends BaseSelectorNodeType {
272        PaymentMethodControl paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
273
274        private PaymentMethodSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
275            super(selectorControl, selectorNodeTypeName);
276        }
277    }
278
279    private abstract class TrainingSelectorNodeType
280        extends BaseSelectorNodeType {
281        TrainingControl trainingControl = Session.getModelController(TrainingControl.class);
282
283        private TrainingSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
284            super(selectorControl, selectorNodeTypeName);
285        }
286    }
287    
288    private abstract class VendorSelectorNodeType
289        extends BaseSelectorNodeType {
290        VendorControl vendorControl = Session.getModelController(VendorControl.class);
291
292        private VendorSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
293            super(selectorControl, selectorNodeTypeName);
294        }
295    }
296    
297    private abstract class WorkSelectorNodeType
298        extends BaseSelectorNodeType {
299        WorkflowControl workflowControl = Session.getModelController(WorkflowControl.class);
300
301        private WorkSelectorNodeType(SelectorControl selectorControl, String selectorNodeTypeName) {
302            super(selectorControl, selectorNodeTypeName);
303        }
304    }
305    
306    private class BooleanNodeType
307        extends BaseSelectorNodeType {
308        SelectorBooleanType selectorBooleanType = null;
309        SelectorNode leftSelectorNode = null;
310        SelectorNode rightSelectorNode = null;
311        
312        private BooleanNodeType(SelectorControl selectorControl, Selector selector) {
313            super(selectorControl, SelectorNodeTypes.BOOLEAN.name());
314            
315            if(!hasExecutionErrors()) {
316                var selectorBooleanTypeName = form.getSelectorBooleanTypeName();
317                selectorBooleanType = selectorControl.getSelectorBooleanTypeByName(selectorBooleanTypeName);
318                
319                if(selectorBooleanType != null) {
320                    var leftSelectorNodeName = form.getLeftSelectorNodeName();
321                    leftSelectorNode = selectorControl.getSelectorNodeByName(selector, leftSelectorNodeName);
322                    
323                    if(leftSelectorNode != null) {
324                        var rightSelectorNodeName = form.getRightSelectorNodeName();
325                        rightSelectorNode = selectorControl.getSelectorNodeByName(selector, rightSelectorNodeName);
326                        
327                        if(rightSelectorNode != null) {
328                            if(rightSelectorNode.equals(leftSelectorNode)) {
329                                addExecutionError(ExecutionErrors.IdenticalLeftAndRightSelectorNodes.name(), leftSelectorNodeName, rightSelectorNodeName);
330                            }
331                            
332                            // TODO: Circular Node Check
333                            // TODO: Sensible Root Node Check
334                        } else {
335                            addExecutionError(ExecutionErrors.UnknownRightSelectorNodeName.name(), rightSelectorNodeName);
336                        }
337                    } else {
338                        addExecutionError(ExecutionErrors.UnknownLeftSelectorNodeName.name(), leftSelectorNodeName);
339                    }
340                } else {
341                    addExecutionError(ExecutionErrors.UnknownSelectorBooleanTypeName.name(), selectorBooleanTypeName);
342                }
343            }
344        }
345        
346        @Override
347        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
348            selectorControl.createSelectorNodeBoolean(selectorNode, selectorBooleanType, leftSelectorNode, rightSelectorNode,
349                    partyPK);
350        }
351    }
352    
353    private class EntityListItemNodeType
354        extends CoreSelectorNodeType {
355        EntityListItem entityListItem = null;
356        
357        private EntityListItemNodeType(SelectorControl selectorControl) {
358            super(selectorControl, SelectorNodeTypes.ENTITY_LIST_ITEM.name());
359            
360            if(!hasExecutionErrors()) {
361                var componentVendorName = form.getComponentVendorName();
362                var componentVendor = componentControl.getComponentVendorByName(componentVendorName);
363                
364                if(componentVendor != null) {
365                    var entityTypeName = form.getEntityTypeName();
366                    var entityType = entityTypeControl.getEntityTypeByName(componentVendor, entityTypeName);
367                    
368                    if(entityType != null) {
369                        var entityAttributeName = form.getEntityAttributeName();
370                        var entityAttribute = coreControl.getEntityAttributeByName(entityType, entityAttributeName);
371                        
372                        if(entityAttribute != null) {
373                            var entityListItemName = form.getEntityListItemName();
374                            entityListItem = coreControl.getEntityListItemByName(entityAttribute, entityListItemName);
375                            
376                            if(entityListItem == null) {
377                                addExecutionError(ExecutionErrors.UnknownEntityListItemName.name(), entityListItemName);
378                            }
379                        } else {
380                            addExecutionError(ExecutionErrors.UnknownEntityAttributeName.name(), entityAttributeName);
381                        }
382                    } else {
383                        addExecutionError(ExecutionErrors.UnknownEntityTypeName.name(), entityTypeName);
384                    }
385                } else {
386                    addExecutionError(ExecutionErrors.UnknownComponentVendorName.name(), componentVendorName);
387                }
388            }
389        }
390        
391        @Override
392        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
393            selectorControl.createSelectorNodeEntityListItem(selectorNode, entityListItem, partyPK);
394        }
395    }
396    
397    private class ResponsibilityNodeType
398        extends EmployeeSelectorNodeType {
399        private ResponsibilityType responsiblityType = null;
400
401        private ResponsibilityNodeType(SelectorControl selectorControl) {
402            super(selectorControl, SelectorNodeTypes.RESPONSIBILITY_TYPE.name());
403            
404            if(!hasExecutionErrors()) {
405                var responsiblityTypeName = form.getResponsibilityTypeName();
406                
407                responsiblityType = employeeControl.getResponsibilityTypeByName(responsiblityTypeName);
408                
409                if(responsiblityType == null) {
410                    addExecutionError(ExecutionErrors.UnknownResponsibilityTypeName.name(), responsiblityTypeName);
411                }
412            }
413        }
414        
415        @Override
416        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
417            selectorControl.createSelectorNodeResponsibilityType(selectorNode, responsiblityType, partyPK);
418        }
419    }
420    
421    private class SkillNodeType
422        extends EmployeeSelectorNodeType {
423        private SkillType skillType = null;
424        
425        private SkillNodeType(SelectorControl selectorControl) {
426            super(selectorControl, SelectorNodeTypes.SKILL_TYPE.name());
427            
428            if(!hasExecutionErrors()) {
429                var skillTypeName = form.getSkillTypeName();
430                
431                skillType = employeeControl.getSkillTypeByName(skillTypeName);
432                
433                if(skillType == null) {
434                    addExecutionError(ExecutionErrors.UnknownSkillTypeName.name(), skillTypeName);
435                }
436            }
437        }
438        
439        @Override
440        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
441            selectorControl.createSelectorNodeSkillType(selectorNode, skillType, partyPK);
442        }
443    }
444    
445    private class TrainingClassNodeType
446        extends TrainingSelectorNodeType {
447        private TrainingClass trainingClass = null;
448
449        private TrainingClassNodeType(SelectorControl selectorControl) {
450            super(selectorControl, SelectorNodeTypes.TRAINING_CLASS.name());
451            
452            if(!hasExecutionErrors()) {
453                var trainingClassName = form.getTrainingClassName();
454                
455                trainingClass = trainingControl.getTrainingClassByName(trainingClassName);
456                
457                if(trainingClass == null) {
458                    addExecutionError(ExecutionErrors.UnknownTrainingClassName.name(), trainingClassName);
459                }
460            }
461        }
462        
463        @Override
464        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
465            selectorControl.createSelectorNodeTrainingClass(selectorNode, trainingClass, partyPK);
466        }
467    }
468    
469    private class WorkflowStepNodeType
470        extends WorkSelectorNodeType {
471        private WorkflowStep workflowStep = null;
472
473        private WorkflowStepNodeType(SelectorControl selectorControl) {
474            super(selectorControl, SelectorNodeTypes.TRAINING_CLASS.name());
475            
476            if(!hasExecutionErrors()) {
477                var workflowName = form.getWorkflowName();
478                var workflow = workflowControl.getWorkflowByName(workflowName);
479                
480                if(workflow != null) {
481                    var workflowStepName = form.getWorkflowStepName();
482                    
483                    workflowStep = workflowControl.getWorkflowStepByName(workflow, workflowStepName);
484                    
485                    if(workflowStep == null) {
486                        addExecutionError(ExecutionErrors.UnknownWorkflowStepName.name(), workflowStepName);
487                    }
488                } else {
489                    addExecutionError(ExecutionErrors.UnknownWorkflowName.name(), workflowName);
490                }
491            }
492        }
493        
494        @Override
495        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
496            selectorControl.createSelectorNodeWorkflowStep(selectorNode, workflowStep, partyPK);
497        }
498    }
499    
500    private class ItemCategoryNodeType
501        extends ItemSelectorNodeType {
502        private ItemCategory itemCategory = null;
503
504        private ItemCategoryNodeType(SelectorControl selectorControl) {
505            super(selectorControl, SelectorNodeTypes.ITEM_CATEGORY.name());
506            
507            if(!hasExecutionErrors()) {
508                var itemCategoryName = form.getItemCategoryName();
509                
510                itemCategory = itemControl.getItemCategoryByName(itemCategoryName);
511                
512                if(itemCategory == null) {
513                    addExecutionError(ExecutionErrors.UnknownItemCategoryName.name(), itemCategoryName);
514                }
515            }
516        }
517        
518        @Override
519        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
520            var checkParents = Boolean.valueOf(form.getCheckParents());
521            
522            selectorControl.createSelectorNodeItemCategory(selectorNode, itemCategory, checkParents, partyPK);
523        }
524    }
525    
526    private class ItemAccountingCategoryNodeType
527        extends AccountingSelectorNodeType {
528        private ItemAccountingCategory itemAccountingCategory = null;
529
530        private ItemAccountingCategoryNodeType(SelectorControl selectorControl) {
531            super(selectorControl, SelectorNodeTypes.ITEM_ACCOUNTING_CATEGORY.name());
532            
533            if(!hasExecutionErrors()) {
534                var itemAccountingCategoryName = form.getItemAccountingCategoryName();
535                
536                itemAccountingCategory = accountingControl.getItemAccountingCategoryByName(itemAccountingCategoryName);
537                
538                if(itemAccountingCategory == null) {
539                    addExecutionError(ExecutionErrors.UnknownItemAccountingCategoryName.name(), itemAccountingCategoryName);
540                }
541            }
542        }
543        
544        @Override
545        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
546            var checkParents = Boolean.valueOf(form.getCheckParents());
547            
548            selectorControl.createSelectorNodeItemAccountingCategory(selectorNode, itemAccountingCategory, checkParents, partyPK);
549        }
550    }
551    
552    private class ItemPurchasingCategoryNodeType
553        extends VendorSelectorNodeType {
554        private ItemPurchasingCategory itemPurchasingCategory = null;
555        
556        private ItemPurchasingCategoryNodeType(SelectorControl selectorControl) {
557            super(selectorControl, SelectorNodeTypes.ITEM_PURCHASING_CATEGORY.name());
558            
559            if(!hasExecutionErrors()) {
560                var itemPurchasingCategoryName = form.getItemPurchasingCategoryName();
561                
562                itemPurchasingCategory = vendorControl.getItemPurchasingCategoryByName(itemPurchasingCategoryName);
563                
564                if(itemPurchasingCategory == null) {
565                    addExecutionError(ExecutionErrors.UnknownItemPurchasingCategoryName.name(), itemPurchasingCategoryName);
566                }
567            }
568        }
569        
570        @Override
571        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
572            var checkParents = Boolean.valueOf(form.getCheckParents());
573            
574            selectorControl.createSelectorNodeItemPurchasingCategory(selectorNode, itemPurchasingCategory, checkParents, partyPK);
575        }
576    }
577    
578    private class PaymentMethodNodeType
579        extends PaymentMethodSelectorNodeType {
580        private PaymentMethod paymentMethod = null;
581
582        private PaymentMethodNodeType(SelectorControl selectorControl) {
583            super(selectorControl, SelectorNodeTypes.PAYMENT_METHOD.name());
584            
585            if(!hasExecutionErrors()) {
586                var paymentMethodName = form.getPaymentMethodName();
587                
588                paymentMethod = paymentMethodControl.getPaymentMethodByName(paymentMethodName);
589                
590                if(paymentMethod == null) {
591                    addExecutionError(ExecutionErrors.UnknownPaymentMethodName.name(), paymentMethodName);
592                }
593            }
594        }
595        
596        @Override
597        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
598            selectorControl.createSelectorNodePaymentMethod(selectorNode, paymentMethod, partyPK);
599        }
600    }
601    
602    private class PaymentProcessorNodeType
603        extends PaymentProcessorSelectorNodeType {
604        private PaymentProcessor paymentProcessor = null;
605
606        private PaymentProcessorNodeType(SelectorControl selectorControl) {
607            super(selectorControl, SelectorNodeTypes.PAYMENT_PROCESSOR.name());
608            
609            if(!hasExecutionErrors()) {
610                var paymentProcessorName = form.getPaymentProcessorName();
611                
612                paymentProcessor = paymentProcessorControl.getPaymentProcessorByName(paymentProcessorName);
613                
614                if(paymentProcessor == null) {
615                    addExecutionError(ExecutionErrors.UnknownPaymentProcessorName.name(), paymentProcessorName);
616                }
617            }
618        }
619        
620        @Override
621        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
622            selectorControl.createSelectorNodePaymentProcessor(selectorNode, paymentProcessor, partyPK);
623        }
624    }
625    
626    private class GeoCodeNodeType
627        extends GeoSelectorNodeType {
628        private GeoCode geoCode = null;
629
630        private GeoCodeNodeType(SelectorControl selectorControl) {
631            super(selectorControl, SelectorNodeTypes.PAYMENT_PROCESSOR.name());
632            
633            if(!hasExecutionErrors()) {
634                var geoCodeName = form.getGeoCodeName();
635                var countryName = form.getCountryName();
636                var parameterCount = (geoCodeName == null ? 0 : 1) + (countryName == null ? 0 : 1);
637                
638                if(parameterCount == 1) {
639                    if(countryName != null) {
640                        geoCode = geoControl.getCountryByAlias(countryName);
641                        
642                        if(geoCode == null) {
643                            addExecutionError(ExecutionErrors.UnknownCountryName.name(), countryName);
644                        }
645                    } else {
646                        geoCode = geoControl.getGeoCodeByName(geoCodeName);
647                        
648                        if(geoCode == null) {
649                            addExecutionError(ExecutionErrors.UnknownGeoCodeName.name(), geoCodeName);
650                        }
651                    }
652                } else {
653                    addExecutionError(ExecutionErrors.InvalidParameterCount.name());
654                }
655            }
656        }
657        
658        @Override
659        public void execute(SelectorNode selectorNode, PartyPK partyPK) {
660            selectorControl.createSelectorNodeGeoCode(selectorNode, geoCode, partyPK);
661        }
662    }
663    
664    @Override
665    protected BaseResult execute() {
666        if(!hasExecutionErrors()) {
667            var selectorControl = Session.getModelController(SelectorControl.class);
668            var selectorKindName = form.getSelectorKindName();
669            var selectorKind = selectorControl.getSelectorKindByName(selectorKindName);
670
671            if(selectorKind != null) {
672                var selectorTypeName = form.getSelectorTypeName();
673                var selectorType = selectorControl.getSelectorTypeByName(selectorKind, selectorTypeName);
674
675                if(selectorType != null) {
676                    var selectorName = form.getSelectorName();
677                    var selector = selectorControl.getSelectorByName(selectorType, selectorName);
678
679                    if(selector != null) {
680                        var selectorNodeName = form.getSelectorNodeName();
681                        var selectorNode = selectorControl.getSelectorNodeByName(selector, selectorNodeName);
682
683                        if(selectorNode == null) {
684                            var selectorNodeTypeName = form.getSelectorNodeTypeName();
685                            var selectorNodeType = selectorControl.getSelectorNodeTypeByName(selectorNodeTypeName);
686
687                            if(selectorNodeType != null) {
688                                selectorNodeTypeName = selectorNodeType.getSelectorNodeTypeName();
689                                
690                                if(selectorControl.getSelectorNodeTypeUse(selectorKind, selectorNodeType) != null) {
691                                    var selectorNodeTypeEnum = SelectorNodeTypes.valueOf(selectorNodeTypeName);
692                                    BaseSelectorNodeType baseSelectorNodeType = null;
693
694                                    switch(selectorNodeTypeEnum) {
695                                        case BOOLEAN ->
696                                                baseSelectorNodeType = new BooleanNodeType(selectorControl, selector);
697                                        case ENTITY_LIST_ITEM ->
698                                                baseSelectorNodeType = new EntityListItemNodeType(selectorControl);
699                                        case RESPONSIBILITY_TYPE ->
700                                                baseSelectorNodeType = new ResponsibilityNodeType(selectorControl);
701                                        case SKILL_TYPE ->
702                                                baseSelectorNodeType = new SkillNodeType(selectorControl);
703                                        case TRAINING_CLASS ->
704                                                baseSelectorNodeType = new TrainingClassNodeType(selectorControl);
705                                        case WORKFLOW_STEP ->
706                                                baseSelectorNodeType = new WorkflowStepNodeType(selectorControl);
707                                        case ITEM_CATEGORY ->
708                                                baseSelectorNodeType = new ItemCategoryNodeType(selectorControl);
709                                        case ITEM_ACCOUNTING_CATEGORY ->
710                                                baseSelectorNodeType = new ItemAccountingCategoryNodeType(selectorControl);
711                                        case ITEM_PURCHASING_CATEGORY ->
712                                                baseSelectorNodeType = new ItemPurchasingCategoryNodeType(selectorControl);
713                                        case PAYMENT_METHOD ->
714                                                baseSelectorNodeType = new PaymentMethodNodeType(selectorControl);
715                                        case PAYMENT_PROCESSOR ->
716                                                baseSelectorNodeType = new PaymentProcessorNodeType(selectorControl);
717                                        case GEO_CODE ->
718                                                baseSelectorNodeType = new GeoCodeNodeType(selectorControl);
719                                        default -> {
720                                        }
721                                    }
722
723                                    if(!hasExecutionErrors()) {
724                                        var partyPK = getPartyPK();
725                                        var isRootSelectorNode = Boolean.valueOf(form.getIsRootSelectorNode());
726                                        var negate = Boolean.valueOf(form.getNegate());
727                                        var description = form.getDescription();
728
729                                        selectorNode = selectorControl.createSelectorNode(selector, selectorNodeName, isRootSelectorNode,
730                                                selectorNodeType, negate, partyPK);
731
732                                        baseSelectorNodeType.execute(selectorNode, partyPK);
733
734                                        if(description != null) {
735                                            var language = getPreferredLanguage();
736
737                                            selectorControl.createSelectorNodeDescription(selectorNode, language, description, partyPK);
738                                        }
739                                    }
740                                } else {
741                                    addExecutionError(ExecutionErrors.UnknownSelectorNodeTypeUse.name(), selectorKindName, selectorNodeTypeName);
742                                }
743                            } else {
744                                addExecutionError(ExecutionErrors.UnknownSelectorTypeName.name(), selectorTypeName);
745                            }
746                        } else {
747                            addExecutionError(ExecutionErrors.DuplicateSelectorNodeName.name(), selectorNodeName);
748                        }
749                    } else {
750                        addExecutionError(ExecutionErrors.UnknownSelectorName.name(), selectorName);
751                    }
752                } else {
753                    addExecutionError(ExecutionErrors.UnknownSelectorTypeName.name(), selectorTypeName);
754                }
755            } else {
756                addExecutionError(ExecutionErrors.UnknownSelectorKindName.name(), selectorKindName);
757            }
758        }
759        
760        return null;
761    }
762    
763}