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