public async Task <DomainValidationResult <Clan> > CreateClanAsync(UserId userId, string name) { var result = new DomainValidationResult <Clan>(); if (await _clanRepository.IsMemberAsync(userId)) { result.AddFailedPreconditionError("User already in a clan."); } if (await _clanRepository.ExistsAsync(name)) { result.AddFailedPreconditionError("Clan with the same name already exist"); } if (result.IsValid) { var clan = new Clan(name, userId); _clanRepository.Create(clan); await _clanRepository.UnitOfWork.CommitAsync(); return(clan); } return(result); }
public async Task <DomainValidationResult <Candidature> > SendCandidatureAsync(UserId userId, ClanId clanId) { var result = new DomainValidationResult <Candidature>(); if (await _clanRepository.IsMemberAsync(userId)) { result.AddFailedPreconditionError("User already in a clan."); } if (await _candidatureRepository.ExistsAsync(userId, clanId)) { result.AddFailedPreconditionError("The candidature of this member for that clan already exist."); } if (result.IsValid) { var candidature = new Candidature(userId, clanId); _candidatureRepository.Create(candidature); await _candidatureRepository.UnitOfWork.CommitAsync(); return(candidature); } return(result); }
public async Task <DomainValidationResult <Member> > KickMemberFromClanAsync(Clan clan, UserId userId, MemberId memberId) { var result = new DomainValidationResult <Member>(); if (!clan.MemberIsOwner(userId)) { result.AddFailedPreconditionError($"The user ({userId}) isn't the clan owner."); } if (!clan.HasMember(memberId)) { result.AddFailedPreconditionError($"The memberId ({memberId}) isn't a member of the clan '{clan.Name}'."); } if (result.IsValid) { var member = clan.FindMember(memberId); clan.Kick(member); await _clanRepository.UnitOfWork.CommitAsync(); return(member); } return(result); }
public async Task <DomainValidationResult <Promotion> > CancelPromotionAsync(Promotion promotion, IDateTimeProvider canceledAt) { var result = new DomainValidationResult <Promotion>(); if (promotion.IsCanceled()) { result.AddFailedPreconditionError("The promotional code is canceled"); } if (promotion.IsExpired()) { result.AddFailedPreconditionError("The promotional code is expired"); } if (result.IsValid) { promotion.Cancel(canceledAt); await _promotionRepository.CommitAsync(); return(promotion); } return(result); }
public async Task <DomainValidationResult <Promotion> > RedeemPromotionAsync(Promotion promotion, UserId userId, IDateTimeProvider redeemedAt) { var result = new DomainValidationResult <Promotion>(); var user = new User(userId); var recipient = new PromotionRecipient(user, redeemedAt); if (promotion.IsExpired()) { result.AddFailedPreconditionError("The promotional code is expired"); } if (!promotion.IsActive()) { result.AddFailedPreconditionError("The promotional code is invalid"); } if (promotion.IsRedeemBy(recipient)) { result.AddFailedPreconditionError("The promotional code is already redeemed"); } if (result.IsValid) { promotion.Redeem(recipient); await _promotionRepository.CommitAsync(); return(promotion); } return(result); }
private async Task <DomainValidationResult <ITransaction> > CreateDepositTransactionAsync( ITokenAccount account, Token token, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <ITransaction>(); var transactionBundles = await this.FetchTransactionBundlesAsync(EnumTransactionType.Deposit, EnumCurrencyType.Token); if (transactionBundles.All(deposit => deposit.Currency.Amount != token.Amount)) { result.AddFailedPreconditionError( $"The amount of {nameof(Token)} is invalid. These are valid amounts: [{string.Join(", ", transactionBundles.Select(deposit => deposit.Currency.Amount))}]."); } if (!account.IsDepositAvailable()) { result.AddFailedPreconditionError( $"Buying tokens is unavailable until {account.LastDeposit?.Add(TokenAccountDecorator.DepositInterval)}. For security reason we limit the number of financial transaction that can be done in {TokenAccountDecorator.DepositInterval.TotalHours} hours."); } if (result.IsValid) { var transaction = account.Deposit(token); await _accountRepository.CommitAsync(true, cancellationToken); return(transaction.Cast <Transaction>()); } return(result); }
public async Task <DomainValidationResult <Division> > CreateDivisionAsync( Clan clan, UserId userId, string name, string description ) { var result = new DomainValidationResult <Division>(); if (!clan.MemberIsOwner(userId)) { result.AddFailedPreconditionError($"The user ({userId}) isn't the clan owner."); } if (result.IsValid) { var division = new Division(clan.Id, name, description); clan.CreateDivision(division); await _clanRepository.UnitOfWork.CommitAsync(); return(division); } return(result); }
public async Task <DomainValidationResult <Clan> > LeaveClanAsync(Clan clan, UserId userId) { var result = new DomainValidationResult <Clan>(); if (!clan.HasMember(userId)) { result.AddFailedPreconditionError($"The user ({userId}) isn't a member of the clan '{clan.Name}'."); } if (result.IsValid) { var member = clan.FindMember(userId); clan.Leave(member); await _clanRepository.UnitOfWork.CommitAsync(); if (clan.Deleted) { await this.DeleteClanAsync(clan); } return(clan); } return(result); }
public async Task <DomainValidationResult <UserProfile> > CreateProfileAsync( User user, string firstName, string lastName, Gender gender ) { var result = new DomainValidationResult <UserProfile>(); if (user.Profile != null) { result.AddFailedPreconditionError("The user's profile has already been created."); } if (result.IsValid) { var profile = new UserProfile(firstName, lastName, gender); user.Create(profile); //await this.UpdateSecurityStampAsync(user); await this.UpdateUserAsync(user); await _publisher.PublishUserProfileChangedIntegrationEventAsync(UserId.FromGuid(user.Id), profile); return(profile); } return(result); }
public async Task <DomainValidationResult <PaymentMethod> > AttachPaymentMethodAsync( string paymentMethodId, string customerId, bool defaultPaymentMethod = false ) { var result = new DomainValidationResult <PaymentMethod>(); var paymentMethodCardLimit = Options.PaymentMethod.Card.Limit; if (await this.PaymentMethodCountAsync(customerId) >= paymentMethodCardLimit) { result.AddFailedPreconditionError( $"You can have a maximum of {paymentMethodCardLimit} card{(paymentMethodCardLimit > 1 ? "s" : string.Empty)} as a payment method"); } if (result.IsValid) { var options = new PaymentMethodAttachOptions { Customer = customerId }; var paymentMethod = await this.AttachAsync(paymentMethodId, options); if (defaultPaymentMethod || !await _stripeCustomerService.HasDefaultPaymentMethodAsync(customerId)) { await _stripeCustomerService.SetDefaultPaymentMethodAsync(customerId, paymentMethodId); } return(paymentMethod); } return(result); }
public async Task <DomainValidationResult <Participant> > SnapshotChallengeParticipantAsync( IChallenge challenge, PlayerId gamePlayerId, IDateTimeProvider synchronizedAt, Func <IScoring, IImmutableSet <Match> > snapshotMatches, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <Participant>(); if (!challenge.ParticipantExists(gamePlayerId)) { result.AddFailedPreconditionError("Participant doesn't exists."); } if (result.IsValid) { var participant = challenge.FindParticipant(gamePlayerId); var matches = snapshotMatches(challenge.Scoring); participant.Snapshot(matches, synchronizedAt); await _challengeRepository.CommitAsync(true, cancellationToken); return(participant); } return(result); }
public override async Task <DomainValidationResult <object> > GenerateAuthenticationAsync(UserId userId, LeagueOfLegendsRequest request) { try { var result = new DomainValidationResult <object>(); var summoner = await _leagueOfLegendsService.Summoner.GetSummonerByNameAsync(Region.Na, request.SummonerName); if (await _gameCredentialRepository.CredentialExistsAsync(PlayerId.Parse(summoner.AccountId), Game)) { result.AddFailedPreconditionError("Summoner's name is already linked by another eDoxa account"); } if (result.IsValid) { if (await _gameAuthenticationRepository.AuthenticationExistsAsync(userId, Game)) { await _gameAuthenticationRepository.RemoveAuthenticationAsync(userId, Game); } var gameAuthentication = await this.GenerateAuthFactor(summoner); await _gameAuthenticationRepository.AddAuthenticationAsync(userId, Game, gameAuthentication); return(gameAuthentication.Factor); } return(result); } catch (RiotSharpException) { return(DomainValidationResult <object> .Failure("Summoner name is invalid")); } }
private async Task <DomainValidationResult <ITransaction> > CreateChargeTransactionAsync( ITokenAccount account, Token token, TransactionMetadata?metadata = null, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <ITransaction>(); if (!account.HaveSufficientMoney(token)) { result.AddFailedPreconditionError("Insufficient funds."); } if (result.IsValid) { var transaction = account.Charge(token, metadata); await _accountRepository.CommitAsync(true, cancellationToken); return(transaction.Cast <Transaction>()); } return(result); }
public async Task <DomainValidationResult <ITransaction> > MarkAccountTransactionAsCanceledAsync( IAccount account, TransactionMetadata metadata, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <ITransaction>(); if (!account.TransactionExists(metadata)) { result.AddFailedPreconditionError("Transaction does not exists."); } if (result.IsValid) { var transaction = account.FindTransaction(metadata); transaction.MarkAsCanceled(); await _accountRepository.CommitAsync(true, cancellationToken); return(transaction.Cast <Transaction>()); } return(result); }
public async Task <DomainValidationResult <Invitation> > SendInvitationAsync(ClanId clanId, UserId userId, UserId ownerId) { var result = new DomainValidationResult <Invitation>(); if (!await _clanRepository.IsOwnerAsync(clanId, ownerId)) { result.AddDebugError("Permission required."); } if (await _clanRepository.IsMemberAsync(userId)) { result.AddDebugError("Target already in a clan."); } if (await _invitationRepository.ExistsAsync(ownerId, clanId)) { result.AddFailedPreconditionError("The invitation from this clan to that member already exist."); } if (result.IsValid) { var invitation = new Invitation(userId, clanId); _invitationRepository.Create(invitation); await _invitationRepository.UnitOfWork.CommitAsync(); return(invitation); } return(result); }
public async Task <DomainValidationResult <Promotion> > CreatePromotionAsync( string promotionalCode, Currency currency, TimeSpan duration, DateTime expiredAt ) { var result = new DomainValidationResult <Promotion>(); if (!await _promotionRepository.IsPromotionalCodeAvailableAsync(promotionalCode)) { result.AddFailedPreconditionError("The promotional code isn't available"); } if (result.IsValid) { var promotion = new Promotion( promotionalCode, currency, duration, new DateTimeProvider(expiredAt)); _promotionRepository.Create(promotion); await _promotionRepository.CommitAsync(); return(promotion); } return(result); }
public async Task <DomainValidationResult <ITransaction> > CreateTransactionAsync( IAccount account, int bundleId, TransactionMetadata?metadata = null, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <ITransaction>(); if (!await this.TransactionBundleExistsAsync(bundleId)) { result.AddFailedPreconditionError($"Transaction bundle with id of '{bundleId}' wasn't found."); } if (result.IsValid) { var transactionBundle = await this.FindTransactionBundleAsync(bundleId); return(await this.CreateTransactionAsync( account, transactionBundle.Currency.Amount, transactionBundle.Currency.Type.ToEnumeration <CurrencyType>(), transactionBundle.Type.ToEnumeration <TransactionType>(), metadata, cancellationToken)); } return(result); }
public async Task <DomainValidationResult <Credential> > LinkCredentialAsync(UserId userId, Game game) { var result = new DomainValidationResult <Credential>(); if (await _gameCredentialRepository.CredentialExistsAsync(userId, game)) { return(result.AddFailedPreconditionError($"{game} credential are already linked.")); } if (!await _gameAuthenticationService.AuthenticationExistsAsync(userId, game)) { return(result.AddFailedPreconditionError($"{game} authentication process not started.")); } var authFactor = await _gameAuthenticationService.FindAuthenticationAsync(userId, game); var authResult = await _gameAuthenticationService.ValidateAuthenticationAsync(userId, game, authFactor); if (!authResult.IsValid) { foreach (var error in authResult.Errors) { result.AddFailedPreconditionError(error.ErrorMessage); } } if (result.IsValid) { var credential = new Credential( userId, game, authFactor.PlayerId, new UtcNowDateTimeProvider()); _gameCredentialRepository.CreateCredential(credential); await _gameCredentialRepository.UnitOfWork.CommitAsync(); return(credential); } return(result); }
public async Task <DomainValidationResult <Participant> > RegisterChallengeParticipantAsync( IChallenge challenge, UserId userId, ParticipantId participantId, PlayerId playerId, IDateTimeProvider registeredAt, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <Participant>(); if (challenge.SoldOut) { result.AddFailedPreconditionError("The challenge was sold out."); } if (challenge.ParticipantExists(userId)) { result.AddFailedPreconditionError("The user already is registered."); } if (result.IsValid) { var participant = new Participant( participantId, userId, playerId, registeredAt); challenge.Register(participant); if (challenge.SoldOut) { challenge.Start(registeredAt); } await _challengeRepository.CommitAsync(true, cancellationToken); return(participant); } return(result); }
private async Task <DomainValidationResult <ITransaction> > CreateWithdrawTransactionAsync( IMoneyAccount account, Money money, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <ITransaction>(); var transactionBundles = await this.FetchTransactionBundlesAsync(EnumTransactionType.Withdraw, EnumCurrencyType.Money); if (transactionBundles.All(withdraw => withdraw.Currency.Amount != money.Amount)) { result.AddFailedPreconditionError( $"The amount of {nameof(Money)} is invalid. These are valid amounts: [{string.Join(", ", transactionBundles.Select(deposit => deposit.Currency.Amount))}]."); } if (!account.HaveSufficientMoney(money)) { result.AddFailedPreconditionError("Insufficient funds."); } if (!account.IsWithdrawAvailable()) { result.AddFailedPreconditionError( $"Withdraw is unavailable until {account.LastWithdraw?.Add(MoneyAccountDecorator.WithdrawInterval)}. For security reason we limit the number of financial transaction that can be done in {MoneyAccountDecorator.WithdrawInterval.TotalHours} hours."); } if (result.IsValid) { var transaction = account.Withdraw(money); await _accountRepository.CommitAsync(true, cancellationToken); return(transaction.Cast <Transaction>()); } return(result); }
public override async Task <DomainValidationResult <GameAuthentication> > ValidateAuthenticationAsync(UserId userId, LeagueOfLegendsGameAuthentication gameAuthentication) { var result = new DomainValidationResult <GameAuthentication>(); await _gameAuthenticationRepository.RemoveAuthenticationAsync(userId, Game); var summoner = await _leagueOfLegendsService.Summoner.GetSummonerByAccountIdAsync(Region.Na, gameAuthentication.PlayerId); if (summoner.ProfileIconId != gameAuthentication.Factor.ExpectedSummonerProfileIconId) { result.AddFailedPreconditionError($"{Game} authentication process failed."); } return(result); }
public async Task <DomainValidationResult <IChallenge> > CreateChallengeAsync( ChallengeId challengeId, ChallengePayoutEntries payoutEntries, EntryFee entryFee, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <IChallenge>(); var strategy = _challengePayoutFactory.CreateInstance(); if (payoutEntries == 0) { return(result.AddFailedPreconditionError("Challenge payout entries cannot be zero.")); } var payout = strategy.GetChallengePayout(payoutEntries, entryFee); if (payout == null) { return(result.AddFailedPreconditionError("Invalid payout structure. Payout entries doesn't match the chart.")); } if (result.IsValid) { var challenge = new Challenge(challengeId, payout !); _challengeRepository.Create(challenge); await _challengeRepository.CommitAsync(true, cancellationToken); return(challenge); } return(result); }
public async Task <DomainValidationResult <IChallenge> > DeleteChallengeAsync(IChallenge challenge, CancellationToken cancellationToken = default) { var result = new DomainValidationResult <IChallenge>(); if (!challenge.CanDelete()) { result.AddFailedPreconditionError("Challenge can't be deleted."); } if (result.IsValid) { _challengeRepository.Delete(challenge); await _challengeRepository.CommitAsync(true, cancellationToken); return(challenge.Cast <Challenge>()); } return(result); }
public async Task <DomainValidationResult <Division> > DeleteDivisionAsync(Clan clan, UserId userId, DivisionId divisionId) { var result = new DomainValidationResult <Division>(); if (!clan.MemberIsOwner(userId)) { result.AddFailedPreconditionError($"The user ({userId}) isn't the clan owner."); } if (result.IsValid) { var division = clan.RemoveDivision(divisionId); await _clanRepository.UnitOfWork.CommitAsync(); return(division); } return(result); }
public async Task <DomainValidationResult <Clan> > UpdateClanAsync(Clan clan, UserId userId, string?summary) { var result = new DomainValidationResult <Clan>(); if (!clan.MemberIsOwner(userId)) { result.AddFailedPreconditionError($"The user ({userId}) isn't the clan owner."); } if (result.IsValid) { clan.Update(summary); await _clanRepository.UnitOfWork.CommitAsync(); return(clan); } return(result); }
public async Task <DomainValidationResult <Address> > AddAddressAsync( UserId userId, Country country, string line1, string?line2, string city, string?state, string?postalCode ) { var result = new DomainValidationResult <Address>(); var addressBookLimit = Options.Static.AddressBook.Limit; if (await _addressRepository.AddressCountAsync(userId) >= addressBookLimit) { result.AddFailedPreconditionError($"You can have a maximum of {addressBookLimit} addresses in your address book"); } if (result.IsValid) { var address = new Address( userId, country, line1, line2, city, state, postalCode); _addressRepository.Create(address); await _addressRepository.UnitOfWork.CommitAsync(); await _serviceBusPublisher.PublishUserAddressChangedIntegrationEventAsync(userId, address); return(address); } return(result); }
public async Task <DomainValidationResult <IChallenge> > SynchronizeChallengeAsync( IChallenge challenge, IDateTimeProvider synchronizedAt, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <IChallenge>(); if (!challenge.CanSynchronize()) { result.AddFailedPreconditionError("Challenge wasn't synchronized due to is current state."); } if (result.IsValid) { challenge.Synchronize(synchronizedAt); await _challengeRepository.CommitAsync(true, cancellationToken); return(challenge.Cast <Challenge>()); } return(result); }
public async Task <DomainValidationResult <UserProfile> > UpdateProfileAsync(User user, string firstName) { var result = new DomainValidationResult <UserProfile>(); if (user.Profile == null) { result.AddFailedPreconditionError("The user's personal informations does not exist."); } if (result.IsValid) { user.Update(firstName); await this.UpdateSecurityStampAsync(user); await this.UpdateUserAsync(user); await _publisher.PublishUserProfileChangedIntegrationEventAsync(UserId.FromGuid(user.Id), user.Profile !); return(user.Profile !); } return(result); }
public async Task <DomainValidationResult <Credential> > UnlinkCredentialAsync(Credential credential) { var result = new DomainValidationResult <Credential>(); if (credential.Timestamp > DateTime.UtcNow.AddMonths(-1)) { result.AddFailedPreconditionError($"You will have the right to unlink your {credential.Game.DisplayName} credentials in {(credential.Timestamp - DateTime.UtcNow.AddMonths(-1)).Days} days."); } if (result.IsValid) { credential.Delete(); await _gameCredentialRepository.UnitOfWork.CommitAsync(); _gameCredentialRepository.DeleteCredential(credential); await _gameCredentialRepository.UnitOfWork.CommitAsync(); return(credential); } return(result); }
public async Task <DomainValidationResult <IChallenge> > CloseChallengeAsync( IChallenge challenge, IDateTimeProvider provider, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <IChallenge>(); if (!challenge.CanClose()) { result.AddFailedPreconditionError("Challenge can't be closed."); } if (result.IsValid) { challenge.Close(provider); await _challengeRepository.CommitAsync(true, cancellationToken); return(challenge.Cast <Challenge>()); } return(result); }