001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.control.user.warehouse.server.command;
018
019import com.echothree.control.user.warehouse.common.edit.LocationNameElementEdit;
020import com.echothree.control.user.warehouse.common.edit.WarehouseEditFactory;
021import com.echothree.control.user.warehouse.common.form.EditLocationNameElementForm;
022import com.echothree.control.user.warehouse.common.result.EditLocationNameElementResult;
023import com.echothree.control.user.warehouse.common.result.WarehouseResultFactory;
024import com.echothree.control.user.warehouse.common.spec.LocationNameElementSpec;
025import com.echothree.model.control.party.common.PartyTypes;
026import com.echothree.model.control.security.common.SecurityRoleGroups;
027import com.echothree.model.control.security.common.SecurityRoles;
028import com.echothree.model.control.warehouse.server.control.WarehouseControl;
029import com.echothree.model.data.party.server.entity.Party;
030import com.echothree.model.data.user.common.pk.UserVisitPK;
031import com.echothree.model.data.warehouse.server.entity.LocationNameElement;
032import com.echothree.model.data.warehouse.server.entity.LocationNameElementDescription;
033import com.echothree.model.data.warehouse.server.entity.LocationNameElementDetail;
034import com.echothree.model.data.warehouse.server.entity.LocationType;
035import com.echothree.model.data.warehouse.server.entity.Warehouse;
036import com.echothree.model.data.warehouse.server.value.LocationNameElementDescriptionValue;
037import com.echothree.model.data.warehouse.server.value.LocationNameElementDetailValue;
038import com.echothree.util.common.command.BaseResult;
039import com.echothree.util.common.command.EditMode;
040import com.echothree.util.common.message.ExecutionErrors;
041import com.echothree.util.common.validation.FieldDefinition;
042import com.echothree.util.common.validation.FieldType;
043import com.echothree.util.server.control.BaseEditCommand;
044import com.echothree.util.server.control.CommandSecurityDefinition;
045import com.echothree.util.server.control.PartyTypeDefinition;
046import com.echothree.util.server.control.SecurityRoleDefinition;
047import com.echothree.util.server.persistence.Session;
048import java.util.Arrays;
049import java.util.Collections;
050import java.util.List;
051
052public class EditLocationNameElementCommand
053        extends BaseEditCommand<LocationNameElementSpec, LocationNameElementEdit> {
054
055    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
056    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
057    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
058    
059    static {
060        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
061                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
062                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
063                        new SecurityRoleDefinition(SecurityRoleGroups.LocationNameElement.name(), SecurityRoles.Edit.name())
064                ))
065        ));
066
067        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
068            new FieldDefinition("WarehouseName", FieldType.ENTITY_NAME, true, null, null),
069            new FieldDefinition("LocationTypeName", FieldType.ENTITY_NAME, true, null, null),
070            new FieldDefinition("LocationNameElementName", FieldType.ENTITY_NAME, true, null, null)
071        ));
072        
073        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
074            new FieldDefinition("LocationNameElementName", FieldType.ENTITY_NAME, true, null, null),
075            new FieldDefinition("Offset", FieldType.UNSIGNED_INTEGER, true, null, null),
076            new FieldDefinition("Length", FieldType.UNSIGNED_INTEGER, true, null, null),
077            new FieldDefinition("ValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
078            new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
079        ));
080    }
081
082    /** Creates a new instance of EditLocationNameElementCommand */
083    public EditLocationNameElementCommand(UserVisitPK userVisitPK, EditLocationNameElementForm form) {
084        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
085    }
086    
087    @Override
088    protected BaseResult execute() {
089        var warehouseControl = Session.getModelController(WarehouseControl.class);
090        EditLocationNameElementResult result = WarehouseResultFactory.getEditLocationNameElementResult();
091        String warehouseName = spec.getWarehouseName();
092        Warehouse warehouse = warehouseControl.getWarehouseByName(warehouseName);
093        
094        if(warehouse != null) {
095            Party warehouseParty = warehouse.getParty();
096            String locationTypeName = spec.getLocationTypeName();
097            LocationType locationType = warehouseControl.getLocationTypeByName(warehouseParty, locationTypeName);
098            
099            if(locationType != null) {
100                if(editMode.equals(EditMode.LOCK)) {
101                    String locationNameElementName = spec.getLocationNameElementName();
102                    LocationNameElement locationNameElement = warehouseControl.getLocationNameElementByName(locationType, locationNameElementName);
103                    
104                    if(locationNameElement != null) {
105                        result.setLocationNameElement(warehouseControl.getLocationNameElementTransfer(getUserVisit(), locationNameElement));
106                        
107                        if(lockEntity(locationNameElement)) {
108                            LocationNameElementDescription locationNameElementDescription = warehouseControl.getLocationNameElementDescription(locationNameElement, getPreferredLanguage());
109                            LocationNameElementEdit edit = WarehouseEditFactory.getLocationNameElementEdit();
110                            LocationNameElementDetail locationNameElementDetail = locationNameElement.getLastDetail();
111                            
112                            result.setEdit(edit);
113                            edit.setLocationNameElementName(locationNameElementDetail.getLocationNameElementName());
114                            edit.setOffset(locationNameElementDetail.getOffset().toString());
115                            edit.setLength(locationNameElementDetail.getLength().toString());
116                            edit.setValidationPattern(locationNameElementDetail.getValidationPattern());
117                            
118                            if(locationNameElementDescription != null)
119                                edit.setDescription(locationNameElementDescription.getDescription());
120                        } else {
121                            addExecutionError(ExecutionErrors.EntityLockFailed.name());
122                        }
123                        
124                        result.setEntityLock(getEntityLockTransfer(locationNameElement));
125                    } else {
126                        addExecutionError(ExecutionErrors.UnknownLocationNameElementName.name(), locationNameElementName);
127                    }
128                } else if(editMode.equals(EditMode.UPDATE)) {
129                    String locationNameElementName = spec.getLocationNameElementName();
130                    LocationNameElement locationNameElement = warehouseControl.getLocationNameElementByNameForUpdate(locationType, locationNameElementName);
131                    
132                    if(locationNameElement != null) {
133                        locationNameElementName = edit.getLocationNameElementName();
134                        LocationNameElement duplicateLocationNameElement = warehouseControl.getLocationNameElementByName(locationType, locationNameElementName);
135                        
136                        if(duplicateLocationNameElement == null || locationNameElement.equals(duplicateLocationNameElement)) {
137                            if(lockEntityForUpdate(locationNameElement)) {
138                                try {
139                                    var partyPK = getPartyPK();
140                                    LocationNameElementDetailValue locationNameElementDetailValue = warehouseControl.getLocationNameElementDetailValueForUpdate(locationNameElement);
141                                    LocationNameElementDescription locationNameElementDescription = warehouseControl.getLocationNameElementDescriptionForUpdate(locationNameElement, getPreferredLanguage());
142                                    String description = edit.getDescription();
143                                    
144                                    locationNameElementDetailValue.setLocationNameElementName(edit.getLocationNameElementName());
145                                    locationNameElementDetailValue.setOffset(Integer.valueOf(edit.getOffset()));
146                                    locationNameElementDetailValue.setLength(Integer.valueOf(edit.getLength()));
147                                    locationNameElementDetailValue.setValidationPattern(edit.getValidationPattern());
148                                    
149                                    warehouseControl.updateLocationNameElementFromValue(locationNameElementDetailValue, partyPK);
150                                    
151                                    if(locationNameElementDescription == null && description != null) {
152                                        warehouseControl.createLocationNameElementDescription(locationNameElement, getPreferredLanguage(), description, partyPK);
153                                    } else if(locationNameElementDescription != null && description == null) {
154                                        warehouseControl.deleteLocationNameElementDescription(locationNameElementDescription, partyPK);
155                                    } else if(locationNameElementDescription != null && description != null) {
156                                        LocationNameElementDescriptionValue locationNameElementDescriptionValue = warehouseControl.getLocationNameElementDescriptionValue(locationNameElementDescription);
157                                        
158                                        locationNameElementDescriptionValue.setDescription(description);
159                                        warehouseControl.updateLocationNameElementDescriptionFromValue(locationNameElementDescriptionValue, partyPK);
160                                    }
161                                } finally {
162                                    unlockEntity(locationNameElement);
163                                }
164                            } else {
165                                addExecutionError(ExecutionErrors.EntityLockStale.name());
166                            }
167                        } else {
168                            addExecutionError(ExecutionErrors.DuplicateLocationNameElementName.name(), locationNameElementName);
169                        }
170                    } else {
171                        addExecutionError(ExecutionErrors.UnknownLocationNameElementName.name(), locationNameElementName);
172                    }
173                }
174            } else {
175                addExecutionError(ExecutionErrors.UnknownLocationTypeName.name(), locationTypeName);
176            }
177        } else {
178            addExecutionError(ExecutionErrors.UnknownWarehouseName.name(), warehouseName);
179        }
180        
181        return result;
182    }
183    
184}