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.party.server.command;
018
019import com.echothree.control.user.party.common.form.CreateCustomerWithLoginForm;
020import com.echothree.control.user.party.common.result.CreateCustomerWithLoginResult;
021import com.echothree.control.user.party.common.result.PartyResultFactory;
022import com.echothree.model.control.accounting.common.AccountingConstants;
023import com.echothree.model.control.accounting.server.control.AccountingControl;
024import com.echothree.model.control.cancellationpolicy.common.CancellationKinds;
025import com.echothree.model.control.cancellationpolicy.server.control.CancellationPolicyControl;
026import com.echothree.model.control.contact.common.ContactMechanismPurposes;
027import com.echothree.model.control.contact.server.logic.ContactEmailAddressLogic;
028import com.echothree.model.control.contactlist.server.logic.ContactListLogic;
029import com.echothree.model.control.customer.common.workflow.CustomerCreditStatusConstants;
030import com.echothree.model.control.customer.common.workflow.CustomerStatusConstants;
031import com.echothree.model.control.customer.server.control.CustomerControl;
032import com.echothree.model.control.offer.server.control.OfferControl;
033import com.echothree.model.control.offer.server.control.OfferUseControl;
034import com.echothree.model.control.offer.server.control.SourceControl;
035import com.echothree.model.control.offer.server.control.UseControl;
036import com.echothree.model.control.party.common.PartyTypes;
037import com.echothree.model.control.party.server.control.PartyControl;
038import com.echothree.model.control.party.server.logic.PartyChainLogic;
039import com.echothree.model.control.party.server.logic.PasswordStringPolicyLogic;
040import com.echothree.model.control.returnpolicy.common.ReturnKinds;
041import com.echothree.model.control.returnpolicy.server.control.ReturnPolicyControl;
042import com.echothree.model.control.term.server.control.TermControl;
043import com.echothree.model.control.user.common.UserConstants;
044import com.echothree.model.control.user.server.control.UserControl;
045import com.echothree.model.control.workflow.server.control.WorkflowControl;
046import com.echothree.model.data.accounting.server.entity.Currency;
047import com.echothree.model.data.accounting.server.entity.GlAccount;
048import com.echothree.model.data.cancellationpolicy.server.entity.CancellationKind;
049import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy;
050import com.echothree.model.data.core.server.entity.EntityInstance;
051import com.echothree.model.data.customer.server.entity.Customer;
052import com.echothree.model.data.customer.server.entity.CustomerType;
053import com.echothree.model.data.customer.server.entity.CustomerTypeDetail;
054import com.echothree.model.data.offer.server.entity.Offer;
055import com.echothree.model.data.offer.server.entity.OfferUse;
056import com.echothree.model.data.offer.server.entity.Source;
057import com.echothree.model.data.offer.server.entity.Use;
058import com.echothree.model.data.party.server.entity.DateTimeFormat;
059import com.echothree.model.data.party.server.entity.Language;
060import com.echothree.model.data.party.server.entity.NameSuffix;
061import com.echothree.model.data.party.server.entity.Party;
062import com.echothree.model.data.party.server.entity.PartyType;
063import com.echothree.model.data.party.server.entity.PartyTypePasswordStringPolicy;
064import com.echothree.model.data.party.server.entity.PersonalTitle;
065import com.echothree.model.data.party.server.entity.TimeZone;
066import com.echothree.model.data.returnpolicy.server.entity.ReturnKind;
067import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy;
068import com.echothree.model.data.term.server.entity.CustomerTypeCreditLimit;
069import com.echothree.model.data.term.server.entity.Term;
070import com.echothree.model.data.user.common.pk.UserVisitPK;
071import com.echothree.model.data.user.server.entity.RecoveryQuestion;
072import com.echothree.model.data.user.server.entity.UserLogin;
073import com.echothree.model.data.user.server.entity.UserLoginPassword;
074import com.echothree.model.data.user.server.entity.UserLoginPasswordType;
075import com.echothree.model.data.user.server.entity.UserLoginStatus;
076import com.echothree.model.data.workflow.server.entity.Workflow;
077import com.echothree.model.data.workflow.server.entity.WorkflowEntrance;
078import com.echothree.util.common.command.BaseResult;
079import com.echothree.util.common.form.ValidationResult;
080import com.echothree.util.common.message.ExecutionErrors;
081import com.echothree.util.common.persistence.BasePK;
082import com.echothree.util.common.validation.FieldDefinition;
083import com.echothree.util.common.validation.FieldType;
084import com.echothree.util.server.control.BaseSimpleCommand;
085import com.echothree.util.server.persistence.EntityPermission;
086import com.echothree.util.server.persistence.Session;
087import com.echothree.util.server.validation.Validator;
088import java.util.Arrays;
089import java.util.Collections;
090import java.util.List;
091import org.apache.commons.codec.language.Soundex;
092
093public class CreateCustomerWithLoginCommand
094        extends BaseSimpleCommand<CreateCustomerWithLoginForm> {
095    
096    // No COMMAND_SECURITY_DEFINITION, anyone may execute this command.
097    private final static List<FieldDefinition> customerFormFieldDefinitions;
098    private final static List<FieldDefinition> otherFormFieldDefinitions;
099    
100    static {
101        // customerFormFieldDefinitions differs from otherFormFieldDefinitions in that when the PartyType
102        // executing this command is null, or equal to CUSTOMER, FirstName and LastName are required fields.
103        // For all other PartyTypes, that requirement is relaxed.
104        customerFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
105                new FieldDefinition("CustomerTypeName", FieldType.ENTITY_NAME, false, null, null),
106                new FieldDefinition("CancellationPolicyName", FieldType.ENTITY_NAME, false, null, null),
107                new FieldDefinition("ReturnPolicyName", FieldType.ENTITY_NAME, false, null, null),
108                new FieldDefinition("ArGlAccountName", FieldType.ENTITY_NAME, false, null, null),
109                new FieldDefinition("InitialOfferName", FieldType.ENTITY_NAME, false, null, null),
110                new FieldDefinition("InitialUseName", FieldType.ENTITY_NAME, false, null, null),
111                new FieldDefinition("InitialSourceName", FieldType.ENTITY_NAME, false, null, null),
112                new FieldDefinition("PersonalTitleId", FieldType.ID, false, null, null),
113                new FieldDefinition("FirstName", FieldType.STRING, true, 1L, 20L),
114                new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L),
115                new FieldDefinition("LastName", FieldType.STRING, true, 1L, 20L),
116                new FieldDefinition("NameSuffixId", FieldType.ID, false, null, null),
117                new FieldDefinition("Name", FieldType.STRING, false, 1L, 60L),
118                new FieldDefinition("PreferredLanguageIsoName", FieldType.ENTITY_NAME, false, null, null),
119                new FieldDefinition("PreferredCurrencyIsoName", FieldType.ENTITY_NAME, false, null, null),
120                new FieldDefinition("PreferredJavaTimeZoneName", FieldType.TIME_ZONE_NAME, false, null, null),
121                new FieldDefinition("PreferredDateTimeFormatName", FieldType.ENTITY_NAME, false, null, null),
122                new FieldDefinition("EmailAddress", FieldType.EMAIL_ADDRESS, true, null, null),
123                new FieldDefinition("AllowSolicitation", FieldType.BOOLEAN, true, null, null),
124                new FieldDefinition("Username", FieldType.STRING, true, 1L, 80L),
125                new FieldDefinition("Password1", FieldType.STRING, true, 1L, 40L),
126                new FieldDefinition("Password2", FieldType.STRING, true, 1L, 40L),
127                new FieldDefinition("RecoveryQuestionName", FieldType.ENTITY_NAME, true, null, null),
128                new FieldDefinition("Answer", FieldType.STRING, true, 1L, 40L),
129                new FieldDefinition("CustomerStatusChoice", FieldType.ENTITY_NAME, false, null, null),
130                new FieldDefinition("CustomerCreditStatusChoice", FieldType.ENTITY_NAME, false, null, null)
131                ));
132        
133        otherFormFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
134                new FieldDefinition("CustomerTypeName", FieldType.ENTITY_NAME, false, null, null),
135                new FieldDefinition("CancellationPolicyName", FieldType.ENTITY_NAME, false, null, null),
136                new FieldDefinition("ReturnPolicyName", FieldType.ENTITY_NAME, false, null, null),
137                new FieldDefinition("ArGlAccountName", FieldType.ENTITY_NAME, false, null, null),
138                new FieldDefinition("InitialOfferName", FieldType.ENTITY_NAME, false, null, null),
139                new FieldDefinition("InitialUseName", FieldType.ENTITY_NAME, false, null, null),
140                new FieldDefinition("InitialSourceName", FieldType.ENTITY_NAME, false, null, null),
141                new FieldDefinition("PersonalTitleId", FieldType.ID, false, null, null),
142                new FieldDefinition("FirstName", FieldType.STRING, false, 1L, 20L),
143                new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L),
144                new FieldDefinition("LastName", FieldType.STRING, false, 1L, 20L),
145                new FieldDefinition("NameSuffixId", FieldType.ID, false, null, null),
146                new FieldDefinition("Name", FieldType.STRING, false, 1L, 60L),
147                new FieldDefinition("PreferredLanguageIsoName", FieldType.ENTITY_NAME, false, null, null),
148                new FieldDefinition("PreferredCurrencyIsoName", FieldType.ENTITY_NAME, false, null, null),
149                new FieldDefinition("PreferredJavaTimeZoneName", FieldType.TIME_ZONE_NAME, false, null, null),
150                new FieldDefinition("PreferredDateTimeFormatName", FieldType.ENTITY_NAME, false, null, null),
151                new FieldDefinition("EmailAddress", FieldType.EMAIL_ADDRESS, true, null, null),
152                new FieldDefinition("AllowSolicitation", FieldType.BOOLEAN, true, null, null),
153                new FieldDefinition("Username", FieldType.STRING, true, 1L, 80L),
154                new FieldDefinition("Password1", FieldType.STRING, true, 1L, 40L),
155                new FieldDefinition("Password2", FieldType.STRING, true, 1L, 40L),
156                new FieldDefinition("RecoveryQuestionName", FieldType.ENTITY_NAME, true, null, null),
157                new FieldDefinition("Answer", FieldType.STRING, true, 1L, 40L),
158                new FieldDefinition("CustomerStatusChoice", FieldType.ENTITY_NAME, false, null, null),
159                new FieldDefinition("CustomerCreditStatusChoice", FieldType.ENTITY_NAME, false, null, null)
160                ));
161    }
162    
163    /** Creates a new instance of CreateCustomerWithLoginCommand */
164    public CreateCustomerWithLoginCommand(UserVisitPK userVisitPK, CreateCustomerWithLoginForm form) {
165        super(userVisitPK, form, null, null, false);
166    }
167    
168    @Override
169    protected ValidationResult validate() {
170        String partyTypeName = getPartyTypeName();
171        List<FieldDefinition> FORM_FIELD_DEFINITIONS = partyTypeName == null || partyTypeName.equals(PartyTypes.CUSTOMER.name())? customerFormFieldDefinitions: otherFormFieldDefinitions;
172        Validator validator = new Validator(this);
173        ValidationResult validationResult = validator.validate(form, FORM_FIELD_DEFINITIONS);
174        
175        return validationResult;
176    }
177    
178    @Override
179    protected BaseResult execute() {
180        UserControl userControl = getUserControl();
181        CreateCustomerWithLoginResult result = PartyResultFactory.getCreateCustomerWithLoginResult();
182        var customerControl = Session.getModelController(CustomerControl.class);
183        Customer customer = null;
184        String username = form.getUsername();
185        UserLogin userLogin = userControl.getUserLoginByUsername(username);
186
187        if(userLogin == null) {
188            String password1 = form.getPassword1();
189            String password2 = form.getPassword2();
190
191            if(password1.equals(password2)) {
192                var partyControl = Session.getModelController(PartyControl.class);
193                PartyType partyType = partyControl.getPartyTypeByName(PartyTypes.CUSTOMER.name());
194                PartyTypePasswordStringPolicy partyTypePasswordStringPolicy = PasswordStringPolicyLogic.getInstance().checkStringPassword(session,
195                        getUserVisit(), this, partyType, null, null, password1);
196
197                if(!hasExecutionErrors()) {
198                    String customerTypeName = form.getCustomerTypeName();
199                    CustomerType customerType = customerTypeName == null ? customerControl.getDefaultCustomerType() : customerControl.getCustomerTypeByName(customerTypeName);
200
201                    if(customerType != null) {
202                        String cancellationPolicyName = form.getCancellationPolicyName();
203                        CancellationPolicy cancellationPolicy = null;
204
205                        if(cancellationPolicyName != null) {
206                            var cancellationPolicyControl = Session.getModelController(CancellationPolicyControl.class);
207                            CancellationKind returnKind = cancellationPolicyControl.getCancellationKindByName(CancellationKinds.CUSTOMER_CANCELLATION.name());
208
209                            cancellationPolicy = cancellationPolicyControl.getCancellationPolicyByName(returnKind, cancellationPolicyName);
210                        }
211
212                        if(cancellationPolicyName == null || cancellationPolicy != null) {
213                            String returnPolicyName = form.getReturnPolicyName();
214                            ReturnPolicy returnPolicy = null;
215
216                            if(returnPolicyName != null) {
217                                var returnPolicyControl = Session.getModelController(ReturnPolicyControl.class);
218                                ReturnKind returnKind = returnPolicyControl.getReturnKindByName(ReturnKinds.CUSTOMER_RETURN.name());
219
220                                returnPolicy = returnPolicyControl.getReturnPolicyByName(returnKind, returnPolicyName);
221                            }
222
223                            if(returnPolicyName == null || returnPolicy != null) {
224                                var accountingControl = Session.getModelController(AccountingControl.class);
225                                String arGlAccountName = form.getArGlAccountName();
226                                GlAccount arGlAccount = arGlAccountName == null ? null : accountingControl.getGlAccountByName(arGlAccountName);
227
228                                if(arGlAccountName == null || arGlAccount != null) {
229                                    String glAccountCategoryName = arGlAccount == null ? null
230                                            : arGlAccount.getLastDetail().getGlAccountCategory().getLastDetail().getGlAccountCategoryName();
231
232                                    if(glAccountCategoryName == null || glAccountCategoryName.equals(AccountingConstants.GlAccountCategory_ACCOUNTS_RECEIVABLE)) {
233                                        var termControl = Session.getModelController(TermControl.class);
234                                        CustomerTypeDetail customerTypeDetail = customerType.getLastDetail();
235                                        Term term = customerTypeDetail.getDefaultTerm();
236
237                                        if(term == null) {
238                                            term = termControl.getDefaultTerm();
239                                        }
240
241                                        if(term != null) {
242                                            String initialOfferName = form.getInitialOfferName();
243                                            String initialUseName = form.getInitialUseName();
244                                            String initialSourceName = form.getInitialSourceName();
245                                            OfferUse initialOfferUse = null;
246                                            boolean invalidInitialOfferOrSourceSpecification = false;
247
248                                            if(initialOfferName != null && initialUseName != null && initialSourceName == null) {
249                                                var offerControl = Session.getModelController(OfferControl.class);
250                                                Offer initialOffer = offerControl.getOfferByName(initialOfferName);
251
252                                                if(initialOffer != null) {
253                                                    var useControl = Session.getModelController(UseControl.class);
254                                                    Use initialUse = useControl.getUseByName(initialUseName);
255
256                                                    if(initialUse != null) {
257                                                        var offerUseControl = Session.getModelController(OfferUseControl.class);
258                                                        initialOfferUse = offerUseControl.getOfferUse(initialOffer, initialUse);
259
260                                                        if(initialOfferUse == null) {
261                                                            addExecutionError(ExecutionErrors.UnknownInitialOfferUse.name());
262                                                        }
263                                                    } else {
264                                                        addExecutionError(ExecutionErrors.UnknownInitialUseName.name(), initialUseName);
265                                                    }
266                                                } else {
267                                                    addExecutionError(ExecutionErrors.UnknownInitialOfferName.name(), initialOfferName);
268                                                }
269                                            } else {
270                                                var sourceControl = Session.getModelController(SourceControl.class);
271
272                                                if(initialOfferName == null && initialUseName == null && initialSourceName != null) {
273                                                    Source source = sourceControl.getSourceByName(initialSourceName);
274
275                                                    if(source != null) {
276                                                        initialOfferUse = source.getLastDetail().getOfferUse();
277                                                    } else {
278                                                        addExecutionError(ExecutionErrors.UnknownInitialSourceName.name(), initialSourceName);
279                                                    }
280                                                } else {
281                                                    initialOfferUse = getUserVisit().getOfferUse();
282
283                                                    if(initialOfferUse == null) {
284                                                        // If all three parameters are null, then try to get the default Source and use its OfferUse.
285                                                        Source source = sourceControl.getDefaultSource();
286
287                                                        if(source != null) {
288                                                            initialOfferUse = source.getLastDetail().getOfferUse();
289                                                        } else {
290                                                            addExecutionError(ExecutionErrors.InvalidInitialOfferOrSourceSpecification.name());
291                                                            invalidInitialOfferOrSourceSpecification = true;
292                                                        }
293                                                    }
294                                                }
295                                            }
296
297                                            if(initialOfferUse != null) {
298                                                String preferredLanguageIsoName = form.getPreferredLanguageIsoName();
299                                                Language preferredLanguage = preferredLanguageIsoName == null ? null : partyControl.getLanguageByIsoName(preferredLanguageIsoName);
300
301                                                if(preferredLanguageIsoName == null || (preferredLanguage != null)) {
302                                                    String preferredJavaTimeZoneName = form.getPreferredJavaTimeZoneName();
303                                                    TimeZone preferredTimeZone = preferredJavaTimeZoneName == null ? null : partyControl.getTimeZoneByJavaName(preferredJavaTimeZoneName);
304
305                                                    if(preferredJavaTimeZoneName == null || (preferredTimeZone != null)) {
306                                                        String preferredDateTimeFormatName = form.getPreferredDateTimeFormatName();
307                                                        DateTimeFormat preferredDateTimeFormat = preferredDateTimeFormatName == null ? null
308                                                                : partyControl.getDateTimeFormatByName(preferredDateTimeFormatName);
309
310                                                        if(preferredDateTimeFormatName == null || (preferredDateTimeFormat != null)) {
311                                                            String preferredCurrencyIsoName = form.getPreferredCurrencyIsoName();
312                                                            Currency preferredCurrency;
313
314                                                            if(preferredCurrencyIsoName == null) {
315                                                                preferredCurrency = null;
316                                                            } else {
317                                                                preferredCurrency = accountingControl.getCurrencyByIsoName(preferredCurrencyIsoName);
318                                                            }
319
320                                                            if(preferredCurrencyIsoName == null || (preferredCurrency != null)) {
321                                                                String recoveryQuestionName = form.getRecoveryQuestionName();
322                                                                RecoveryQuestion recoveryQuestion = userControl.getRecoveryQuestionByName(recoveryQuestionName);
323
324                                                                if(recoveryQuestion != null) {
325                                                                    var workflowControl = Session.getModelController(WorkflowControl.class);
326                                                                    Soundex soundex = new Soundex();
327                                                                    BasePK createdBy = getPartyPK();
328                                                                    String personalTitleId = form.getPersonalTitleId();
329                                                                    PersonalTitle personalTitle = personalTitleId == null ? null
330                                                                            : partyControl.convertPersonalTitleIdToEntity(personalTitleId, EntityPermission.READ_ONLY);
331                                                                    String firstName = form.getFirstName();
332                                                                    String middleName = form.getMiddleName();
333                                                                    String lastName = form.getLastName();
334                                                                    String nameSuffixId = form.getNameSuffixId();
335                                                                    NameSuffix nameSuffix = nameSuffixId == null ? null
336                                                                            : partyControl.convertNameSuffixIdToEntity(nameSuffixId, EntityPermission.READ_ONLY);
337                                                                    String name = form.getName();
338                                                                    String emailAddress = form.getEmailAddress();
339                                                                    Boolean allowSolicitation = Boolean.valueOf(form.getAllowSolicitation());
340
341                                                                    String firstNameSdx;
342                                                                    try {
343                                                                        firstNameSdx = firstName == null ? null : soundex.encode(firstName);
344                                                                    } catch(IllegalArgumentException iae) {
345                                                                        firstNameSdx = null;
346                                                                    }
347
348                                                                    String middleNameSdx;
349                                                                    try {
350                                                                        middleNameSdx = middleName == null ? null : soundex.encode(middleName);
351                                                                    } catch(IllegalArgumentException iae) {
352                                                                        middleNameSdx = null;
353                                                                    }
354
355                                                                    String lastNameSdx;
356                                                                    try {
357                                                                        lastNameSdx = lastName == null ? null : soundex.encode(lastName);
358                                                                    } catch(IllegalArgumentException iae) {
359                                                                        lastNameSdx = null;
360                                                                    }
361
362                                                                    Party party = partyControl.createParty(null, partyType, preferredLanguage, preferredCurrency, preferredTimeZone, preferredDateTimeFormat,
363                                                                            createdBy);
364
365                                                                    if(createdBy == null) {
366                                                                        createdBy = party.getPrimaryKey();
367                                                                    }
368                                                                    if(personalTitle != null || firstName != null || middleName != null || lastName != null || nameSuffix != null) {
369                                                                        partyControl.createPerson(party, personalTitle, firstName, firstNameSdx, middleName,
370                                                                                middleNameSdx, lastName, lastNameSdx, nameSuffix, createdBy);
371                                                                    }
372
373                                                                    if(name != null) {
374                                                                        partyControl.createPartyGroup(party, name, createdBy);
375                                                                    }
376
377                                                                    customer = customerControl.createCustomer(party, customerType, initialOfferUse, cancellationPolicy, returnPolicy, arGlAccount,
378                                                                            customerTypeDetail.getDefaultHoldUntilComplete(), customerTypeDetail.getDefaultAllowBackorders(),
379                                                                            customerTypeDetail.getDefaultAllowSubstitutions(), customerTypeDetail.getDefaultAllowCombiningShipments(),
380                                                                            customerTypeDetail.getDefaultRequireReference(), customerTypeDetail.getDefaultAllowReferenceDuplicates(),
381                                                                            customerTypeDetail.getDefaultReferenceValidationPattern(), createdBy);
382                                                                    userControl.createUserLogin(party, username, createdBy);
383
384                                                                    ContactEmailAddressLogic.getInstance().createContactEmailAddress(party,
385                                                                            emailAddress, allowSolicitation, null,
386                                                                            ContactMechanismPurposes.PRIMARY_EMAIL.name(),
387                                                                            createdBy);
388
389                                                                    termControl.createPartyTerm(party, term, customerTypeDetail.getDefaultTaxable(), createdBy);
390
391                                                                    for(CustomerTypeCreditLimit customerTypeCreditLimit : termControl.getCustomerTypeCreditLimitsByCustomerType(customerType)) {
392                                                                        Currency currency = customerTypeCreditLimit.getCurrency();
393                                                                        Long creditLimit = customerTypeCreditLimit.getCreditLimit();
394                                                                        Long potentialCreditLimit = customerTypeCreditLimit.getPotentialCreditLimit();
395
396                                                                        termControl.createPartyCreditLimit(party, currency, creditLimit, potentialCreditLimit, createdBy);
397                                                                    }
398
399                                                                    UserLoginPasswordType userLoginPasswordType = userControl.getUserLoginPasswordTypeByName(UserConstants.UserLoginPasswordType_STRING);
400                                                                    UserLoginPassword userLoginPassword = userControl.createUserLoginPassword(party, userLoginPasswordType, createdBy);
401                                                                    userControl.createUserLoginPasswordString(userLoginPassword, password1, session.START_TIME_LONG, Boolean.FALSE, createdBy);
402
403                                                                    if(partyTypePasswordStringPolicy != null && partyTypePasswordStringPolicy.getLastDetail().getForceChangeAfterCreate()) {
404                                                                        UserLoginStatus userLoginStatus = userControl.getUserLoginStatusForUpdate(party);
405
406                                                                        userLoginStatus.setForceChange(Boolean.TRUE);
407                                                                    }
408
409                                                                    String answer = form.getAnswer();
410                                                                    userControl.createRecoveryAnswer(party, recoveryQuestion, answer, createdBy);
411
412                                                                    // TODO: error checking for unknown customerStatusChoice
413                                                                    String customerStatusChoice = form.getCustomerStatusChoice();
414                                                                    Workflow customerStatusWorkflow = workflowControl.getWorkflowByName(CustomerStatusConstants.Workflow_CUSTOMER_STATUS);
415                                                                    WorkflowEntrance customerStatusWorkflowEntrance = customerStatusChoice == null ? customerTypeDetail.getDefaultCustomerStatus()
416                                                                            : workflowControl.getWorkflowEntranceByName(customerStatusWorkflow, customerStatusChoice);
417
418                                                                    if(customerStatusWorkflowEntrance == null) {
419                                                                        customerStatusWorkflowEntrance = workflowControl.getDefaultWorkflowEntrance(customerStatusWorkflow);
420                                                                    }
421
422                                                                    // TODO: error checking for unknown customerCreditStatusChoice
423                                                                    String customerCreditStatusChoice = form.getCustomerCreditStatusChoice();
424                                                                    Workflow customerCreditStatusWorkflow = workflowControl.getWorkflowByName(CustomerCreditStatusConstants.Workflow_CUSTOMER_CREDIT_STATUS);
425                                                                    WorkflowEntrance customerCreditStatusWorkflowEntrance = customerCreditStatusChoice == null
426                                                                            ? customerTypeDetail.getDefaultCustomerCreditStatus()
427                                                                            : workflowControl.getWorkflowEntranceByName(customerCreditStatusWorkflow, customerCreditStatusChoice);
428
429                                                                    if(customerCreditStatusWorkflowEntrance == null) {
430                                                                        customerCreditStatusWorkflowEntrance = workflowControl.getDefaultWorkflowEntrance(customerCreditStatusWorkflow);
431                                                                    }
432
433                                                                    EntityInstance entityInstance = getCoreControl().getEntityInstanceByBasePK(party.getPrimaryKey());
434                                                                    workflowControl.addEntityToWorkflow(customerStatusWorkflowEntrance, entityInstance, null, null, createdBy);
435                                                                    workflowControl.addEntityToWorkflow(customerCreditStatusWorkflowEntrance, entityInstance, null, null, createdBy);
436
437                                                                    ContactListLogic.getInstance().setupInitialContactLists(this, party, createdBy);
438                                                                    
439                                                                    // ExecutionErrorAccumulator is passed in as null so that an Exception will be thrown if there is an error.
440                                                                    PartyChainLogic.getInstance().createPartyWelcomeChainInstance(null, party, createdBy);
441                                                                } else {
442                                                                    addExecutionError(ExecutionErrors.UnknownRecoveryQuestionName.name(), recoveryQuestionName);
443                                                                }
444                                                            } else {
445                                                                addExecutionError(ExecutionErrors.UnknownCurrencyIsoName.name(), preferredCurrencyIsoName);
446                                                            }
447                                                        } else {
448                                                            addExecutionError(ExecutionErrors.UnknownDateTimeFormatName.name(), preferredDateTimeFormatName);
449                                                        }
450                                                    } else {
451                                                        addExecutionError(ExecutionErrors.UnknownJavaTimeZoneName.name(), preferredJavaTimeZoneName);
452                                                    }
453                                                } else {
454                                                    addExecutionError(ExecutionErrors.UnknownLanguageIsoName.name(), preferredLanguageIsoName);
455                                                }
456                                            }
457                                        } else {
458                                            addExecutionError(ExecutionErrors.UnknownDefaultTerm.name());
459                                        }
460                                    } else {
461                                        addExecutionError(ExecutionErrors.InvalidGlAccountCategory.name(), glAccountCategoryName);
462                                    }
463                                } else {
464                                    addExecutionError(ExecutionErrors.UnknownArGlAccountName.name(), arGlAccountName);
465                                }
466                            } else {
467                                addExecutionError(ExecutionErrors.UnknownReturnPolicyName.name(), returnPolicyName);
468                            }
469                        } else {
470                            addExecutionError(ExecutionErrors.UnknownCancellationPolicyName.name(), cancellationPolicyName);
471                        }
472                    } else {
473                        if(customerTypeName != null) {
474                            addExecutionError(ExecutionErrors.UnknownCustomerTypeName.name(), customerTypeName);
475                        } else {
476                            addExecutionError(ExecutionErrors.UnknownDefaultCustomerType.name());
477                        }
478                    }
479                }
480            } else {
481                addExecutionError(ExecutionErrors.MismatchedPasswords.name());
482            }
483        } else {
484            addExecutionError(ExecutionErrors.DuplicateUsername.name());
485
486            Party party = userLogin.getParty();
487            customer = customerControl.getCustomer(party);
488        }
489
490        if(customer != null) {
491            Party party = customer.getParty();
492
493            result.setEntityRef(party.getPrimaryKey().getEntityRef());
494            result.setCustomerName(customer.getCustomerName());
495            result.setPartyName(party.getLastDetail().getPartyName());
496        }
497
498        return result;
499    }
500    
501}