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