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.club.server.command;
018
019import com.echothree.control.user.club.common.edit.ClubEdit;
020import com.echothree.control.user.club.common.edit.ClubEditFactory;
021import com.echothree.control.user.club.common.form.EditClubForm;
022import com.echothree.control.user.club.common.result.ClubResultFactory;
023import com.echothree.control.user.club.common.spec.ClubSpec;
024import com.echothree.model.control.accounting.server.control.AccountingControl;
025import com.echothree.model.control.club.server.control.ClubControl;
026import com.echothree.model.control.filter.common.FilterKinds;
027import com.echothree.model.control.filter.common.FilterTypes;
028import com.echothree.model.control.filter.server.control.FilterControl;
029import com.echothree.model.control.subscription.common.SubscriptionConstants;
030import com.echothree.model.control.subscription.server.control.SubscriptionControl;
031import com.echothree.model.data.filter.server.entity.Filter;
032import com.echothree.model.data.user.common.pk.UserVisitPK;
033import com.echothree.util.common.command.BaseResult;
034import com.echothree.util.common.command.EditMode;
035import com.echothree.util.common.message.ExecutionErrors;
036import com.echothree.util.common.validation.FieldDefinition;
037import com.echothree.util.common.validation.FieldType;
038import com.echothree.util.server.control.BaseEditCommand;
039import com.echothree.util.server.persistence.Session;
040import java.util.List;
041import javax.enterprise.context.Dependent;
042
043@Dependent
044public class EditClubCommand
045        extends BaseEditCommand<ClubSpec, ClubEdit> {
046    
047    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
048    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
049    
050    static {
051        SPEC_FIELD_DEFINITIONS = List.of(
052            new FieldDefinition("ClubName", FieldType.ENTITY_NAME, true, null, null)
053        );
054        
055        EDIT_FIELD_DEFINITIONS = List.of(
056            new FieldDefinition("ClubName", FieldType.ENTITY_NAME, true, null, null),
057            new FieldDefinition("SubscriptionTypeName", FieldType.ENTITY_NAME, true, null, null),
058            new FieldDefinition("ClubPriceFilterName", FieldType.ENTITY_NAME, false, null, null),
059            new FieldDefinition("CurrencyIsoName", FieldType.ENTITY_NAME, false, null, null),
060            new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
061            new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
062            new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
063        );
064    }
065    
066    /** Creates a new instance of EditClubCommand */
067    public EditClubCommand() {
068        super(null, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
069    }
070    
071    @Override
072    protected BaseResult execute() {
073        var clubControl = Session.getModelController(ClubControl.class);
074        var result = ClubResultFactory.getEditClubResult();
075        
076        if(editMode.equals(EditMode.LOCK)) {
077            var clubName = spec.getClubName();
078            var club = clubControl.getClubByName(clubName);
079            
080            if(club != null) {
081                result.setClub(clubControl.getClubTransfer(getUserVisit(), club));
082                
083                if(lockEntity(club)) {
084                    var clubDescription = clubControl.getClubDescription(club, getPreferredLanguage());
085                    var edit = ClubEditFactory.getClubEdit();
086                    var clubDetail = club.getLastDetail();
087                    var clubPriceFilter = clubDetail.getClubPriceFilter();
088                    var currency = clubDetail.getCurrency();
089                    
090                    result.setEdit(edit);
091                    edit.setClubName(clubDetail.getClubName());
092                    edit.setSubscriptionTypeName(clubDetail.getSubscriptionType().getLastDetail().getSubscriptionTypeName());
093                    edit.setClubPriceFilterName(clubPriceFilter == null? null: clubPriceFilter.getLastDetail().getFilterName());
094                    edit.setCurrencyIsoName(currency.getCurrencyIsoName());
095                    edit.setIsDefault(clubDetail.getIsDefault().toString());
096                    edit.setSortOrder(clubDetail.getSortOrder().toString());
097                    
098                    if(clubDescription != null) {
099                        edit.setDescription(clubDescription.getDescription());
100                    }
101                } else {
102                    addExecutionError(ExecutionErrors.EntityLockFailed.name());
103                }
104                
105                result.setEntityLock(getEntityLockTransfer(club));
106            } else {
107                addExecutionError(ExecutionErrors.UnknownClubName.name(), clubName);
108            }
109        } else if(editMode.equals(EditMode.UPDATE)) {
110            var clubName = spec.getClubName();
111            var club = clubControl.getClubByNameForUpdate(clubName);
112            
113            if(club != null) {
114                clubName = edit.getClubName();
115                var duplicateClub = clubControl.getClubByName(clubName);
116                
117                if(duplicateClub == null || club.equals(duplicateClub)) {
118                    var subscriptionControl = Session.getModelController(SubscriptionControl.class);
119                    var subscriptionKind = subscriptionControl.getSubscriptionKindByName(SubscriptionConstants.SubscriptionKind_CLUB);
120                    var subscriptionTypeName = edit.getSubscriptionTypeName();
121                    var subscriptionType = subscriptionControl.getSubscriptionTypeByName(subscriptionKind, subscriptionTypeName);
122                    
123                    if(subscriptionType != null) {
124                        club = clubControl.getClubBySubscriptionType(subscriptionType);
125                        
126                        if(club == null) {
127                            var clubPriceFilterName = edit.getClubPriceFilterName();
128                            Filter clubPriceFilter = null;
129                            
130                            if(clubPriceFilterName != null) {
131                                var filterControl = Session.getModelController(FilterControl.class);
132                                var filterKind = filterControl.getFilterKindByName(FilterKinds.PRICE.name());
133                                var filterType = filterControl.getFilterTypeByName(filterKind, FilterTypes.CLUB.name());
134                                
135                                if(filterType != null) {
136                                    clubPriceFilter = filterControl.getFilterByName(filterType, clubPriceFilterName);
137                                }
138                            }
139                            
140                            if(clubPriceFilterName == null || clubPriceFilter != null) {
141                                var accountingControl = Session.getModelController(AccountingControl.class);
142                                var currencyIsoName = edit.getCurrencyIsoName();
143                                var currency = currencyIsoName == null? null: accountingControl.getCurrencyByIsoName(currencyIsoName);
144                                
145                                if(currencyIsoName == null || currency != null) {
146                                    if(lockEntityForUpdate(club)) {
147                                        try {
148                                            var partyPK = getPartyPK();
149                                            var clubDetailValue = clubControl.getClubDetailValueForUpdate(club);
150                                            var clubDescription = clubControl.getClubDescriptionForUpdate(club, getPreferredLanguage());
151                                            var description = edit.getDescription();
152                                            
153                                            clubDetailValue.setClubName(edit.getClubName());
154                                            clubDetailValue.setSubscriptionTypePK(subscriptionType.getPrimaryKey());
155                                            clubDetailValue.setClubPriceFilterPK(clubPriceFilter == null? null: clubPriceFilter.getPrimaryKey());
156                                            clubDetailValue.setCurrencyPK(currency.getPrimaryKey());
157                                            clubDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
158                                            clubDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
159                                            
160                                            clubControl.updateClubFromValue(clubDetailValue, partyPK);
161                                            
162                                            if(clubDescription == null && description != null) {
163                                                clubControl.createClubDescription(club, getPreferredLanguage(), description, partyPK);
164                                            } else if(clubDescription != null && description == null) {
165                                                clubControl.deleteClubDescription(clubDescription, partyPK);
166                                            } else if(clubDescription != null && description != null) {
167                                                var clubDescriptionValue = clubControl.getClubDescriptionValue(clubDescription);
168                                                
169                                                clubDescriptionValue.setDescription(description);
170                                                clubControl.updateClubDescriptionFromValue(clubDescriptionValue, partyPK);
171                                            }
172                                        } finally {
173                                            unlockEntity(club);
174                                        }
175                                    } else {
176                                        addExecutionError(ExecutionErrors.EntityLockStale.name());
177                                    }
178                                } else {
179                                    addExecutionError(ExecutionErrors.UnknownCurrencyIsoName.name(), currencyIsoName);
180                                }
181                            } else {
182                                addExecutionError(ExecutionErrors.UnknownClubPriceFilterName.name(), clubPriceFilterName);
183                            }
184                        } else {
185                            addExecutionError(ExecutionErrors.DuplicateSubscriptionType.name());
186                        }
187                    } else {
188                        addExecutionError(ExecutionErrors.UnknownSubscriptionTypeName.name(), subscriptionTypeName);
189                    }
190                } else {
191                    addExecutionError(ExecutionErrors.DuplicateClubName.name(), clubName);
192                }
193            } else {
194                addExecutionError(ExecutionErrors.UnknownClubName.name(), clubName);
195            }
196        }
197        
198        return result;
199    }
200    
201}