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