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.filter.server.control.FilterKindControl;
030import com.echothree.model.control.filter.server.control.FilterTypeControl;
031import com.echothree.model.control.party.common.PartyTypes;
032import com.echothree.model.control.security.common.SecurityRoleGroups;
033import com.echothree.model.control.security.common.SecurityRoles;
034import com.echothree.model.control.subscription.common.SubscriptionConstants;
035import com.echothree.model.control.subscription.server.control.SubscriptionControl;
036import com.echothree.model.data.filter.server.entity.Filter;
037import com.echothree.model.data.user.common.pk.UserVisitPK;
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 java.util.List;
048import javax.enterprise.context.Dependent;
049import javax.inject.Inject;
050
051@Dependent
052public class EditClubCommand
053        extends BaseEditCommand<ClubSpec, ClubEdit> {
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.Club.name(), SecurityRoles.Edit.name())
064                ))
065        ));
066
067        SPEC_FIELD_DEFINITIONS = List.of(
068                new FieldDefinition("ClubName", FieldType.ENTITY_NAME, true, null, null)
069        );
070        
071        EDIT_FIELD_DEFINITIONS = List.of(
072                new FieldDefinition("ClubName", FieldType.ENTITY_NAME, true, null, null),
073                new FieldDefinition("SubscriptionTypeName", FieldType.ENTITY_NAME, true, null, null),
074                new FieldDefinition("ClubPriceFilterName", FieldType.ENTITY_NAME, false, null, null),
075                new FieldDefinition("CurrencyIsoName", FieldType.ENTITY_NAME, false, null, null),
076                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
077                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
078                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
079        );
080    }
081
082    @Inject
083    AccountingControl accountingControl;
084
085    @Inject
086    ClubControl clubControl;
087
088    @Inject
089    FilterControl filterControl;
090
091    @Inject
092    FilterKindControl filterKindControl;
093
094    @Inject
095    FilterTypeControl filterTypeControl;
096
097    @Inject
098    SubscriptionControl subscriptionControl;
099
100    
101    /** Creates a new instance of EditClubCommand */
102    public EditClubCommand() {
103        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
104    }
105    
106    @Override
107    protected BaseResult execute() {
108        var result = ClubResultFactory.getEditClubResult();
109        
110        if(editMode.equals(EditMode.LOCK)) {
111            var clubName = spec.getClubName();
112            var club = clubControl.getClubByName(clubName);
113            
114            if(club != null) {
115                result.setClub(clubControl.getClubTransfer(getUserVisit(), club));
116                
117                if(lockEntity(club)) {
118                    var clubDescription = clubControl.getClubDescription(club, getPreferredLanguage());
119                    var edit = ClubEditFactory.getClubEdit();
120                    var clubDetail = club.getLastDetail();
121                    var clubPriceFilter = clubDetail.getClubPriceFilter();
122                    var currency = clubDetail.getCurrency();
123                    
124                    result.setEdit(edit);
125                    edit.setClubName(clubDetail.getClubName());
126                    edit.setSubscriptionTypeName(clubDetail.getSubscriptionType().getLastDetail().getSubscriptionTypeName());
127                    edit.setClubPriceFilterName(clubPriceFilter == null? null: clubPriceFilter.getLastDetail().getFilterName());
128                    edit.setCurrencyIsoName(currency.getCurrencyIsoName());
129                    edit.setIsDefault(clubDetail.getIsDefault().toString());
130                    edit.setSortOrder(clubDetail.getSortOrder().toString());
131                    
132                    if(clubDescription != null) {
133                        edit.setDescription(clubDescription.getDescription());
134                    }
135                } else {
136                    addExecutionError(ExecutionErrors.EntityLockFailed.name());
137                }
138                
139                result.setEntityLock(getEntityLockTransfer(club));
140            } else {
141                addExecutionError(ExecutionErrors.UnknownClubName.name(), clubName);
142            }
143        } else if(editMode.equals(EditMode.UPDATE)) {
144            var clubName = spec.getClubName();
145            var club = clubControl.getClubByNameForUpdate(clubName);
146            
147            if(club != null) {
148                clubName = edit.getClubName();
149                var duplicateClub = clubControl.getClubByName(clubName);
150                
151                if(duplicateClub == null || club.equals(duplicateClub)) {
152                    var subscriptionKind = subscriptionControl.getSubscriptionKindByName(SubscriptionConstants.SubscriptionKind_CLUB);
153                    var subscriptionTypeName = edit.getSubscriptionTypeName();
154                    var subscriptionType = subscriptionControl.getSubscriptionTypeByName(subscriptionKind, subscriptionTypeName);
155                    
156                    if(subscriptionType != null) {
157                        club = clubControl.getClubBySubscriptionType(subscriptionType);
158                        
159                        if(club == null) {
160                            var clubPriceFilterName = edit.getClubPriceFilterName();
161                            Filter clubPriceFilter = null;
162                            
163                            if(clubPriceFilterName != null) {
164                                var filterKind = filterKindControl.getFilterKindByName(FilterKinds.PRICE.name());
165                                var filterType = filterTypeControl.getFilterTypeByName(filterKind, FilterTypes.CLUB.name());
166                                
167                                if(filterType != null) {
168                                    clubPriceFilter = filterControl.getFilterByName(filterType, clubPriceFilterName);
169                                }
170                            }
171                            
172                            if(clubPriceFilterName == null || clubPriceFilter != null) {
173                                var currencyIsoName = edit.getCurrencyIsoName();
174                                var currency = currencyIsoName == null? null: accountingControl.getCurrencyByIsoName(currencyIsoName);
175                                
176                                if(currencyIsoName == null || currency != null) {
177                                    if(lockEntityForUpdate(club)) {
178                                        try {
179                                            var partyPK = getPartyPK();
180                                            var clubDetailValue = clubControl.getClubDetailValueForUpdate(club);
181                                            var clubDescription = clubControl.getClubDescriptionForUpdate(club, getPreferredLanguage());
182                                            var description = edit.getDescription();
183                                            
184                                            clubDetailValue.setClubName(edit.getClubName());
185                                            clubDetailValue.setSubscriptionTypePK(subscriptionType.getPrimaryKey());
186                                            clubDetailValue.setClubPriceFilterPK(clubPriceFilter == null? null: clubPriceFilter.getPrimaryKey());
187                                            clubDetailValue.setCurrencyPK(currency.getPrimaryKey());
188                                            clubDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
189                                            clubDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
190                                            
191                                            clubControl.updateClubFromValue(clubDetailValue, partyPK);
192                                            
193                                            if(clubDescription == null && description != null) {
194                                                clubControl.createClubDescription(club, getPreferredLanguage(), description, partyPK);
195                                            } else if(clubDescription != null && description == null) {
196                                                clubControl.deleteClubDescription(clubDescription, partyPK);
197                                            } else if(clubDescription != null && description != null) {
198                                                var clubDescriptionValue = clubControl.getClubDescriptionValue(clubDescription);
199                                                
200                                                clubDescriptionValue.setDescription(description);
201                                                clubControl.updateClubDescriptionFromValue(clubDescriptionValue, partyPK);
202                                            }
203                                        } finally {
204                                            unlockEntity(club);
205                                        }
206                                    } else {
207                                        addExecutionError(ExecutionErrors.EntityLockStale.name());
208                                    }
209                                } else {
210                                    addExecutionError(ExecutionErrors.UnknownCurrencyIsoName.name(), currencyIsoName);
211                                }
212                            } else {
213                                addExecutionError(ExecutionErrors.UnknownClubPriceFilterName.name(), clubPriceFilterName);
214                            }
215                        } else {
216                            addExecutionError(ExecutionErrors.DuplicateSubscriptionType.name());
217                        }
218                    } else {
219                        addExecutionError(ExecutionErrors.UnknownSubscriptionTypeName.name(), subscriptionTypeName);
220                    }
221                } else {
222                    addExecutionError(ExecutionErrors.DuplicateClubName.name(), clubName);
223                }
224            } else {
225                addExecutionError(ExecutionErrors.UnknownClubName.name(), clubName);
226            }
227        }
228        
229        return result;
230    }
231    
232}