public static SubscriptionPayment Buy( PayerId payerId, SubscriptionPeriod period, string countryCode, MoneyValue priceOffer, PriceList priceList) { var priceInPriceList = priceList.GetPrice(countryCode, period, PriceListItemCategory.New); CheckRule(new PriceOfferMustMatchPriceInPriceListRule(priceOffer, priceInPriceList)); var subscriptionPayment = new SubscriptionPayment(); var subscriptionPaymentCreated = new SubscriptionPaymentCreatedDomainEvent( Guid.NewGuid(), payerId.Value, period.Code, countryCode, SubscriptionPaymentStatus.WaitingForPayment.Code, priceOffer.Value, priceOffer.Currency); subscriptionPayment.Apply(subscriptionPaymentCreated); subscriptionPayment.AddDomainEvent(subscriptionPaymentCreated); return(subscriptionPayment); }
private void When(PriceListItemAttributesChangedDomainEvent @event) { this._countryCode = @event.CountryCode; this._subscriptionPeriod = SubscriptionPeriod.Of(@event.SubscriptionPeriodCode); this._category = PriceListItemCategory.Of(@event.CategoryCode); this._price = MoneyValue.Of(@event.Price, @event.Currency); }
public async Task <Guid> Handle(BuySubscriptionRenewalCommand command, CancellationToken cancellationToken) { var priceList = await PriceListProvider.GetPriceList(_sqlConnectionFactory.GetOpenConnection()); var subscriptionId = new SubscriptionId(command.SubscriptionId); var subscription = await _aggregateStore.Load(new SubscriptionId(command.SubscriptionId)); if (subscription == null) { throw new InvalidCommandException(new List <string> { "Subscription for renewal must exist." }); } var subscriptionRenewalPayment = SubscriptionRenewalPayment.Buy( _payerContext.PayerId, subscriptionId, SubscriptionPeriod.Of(command.SubscriptionTypeCode), command.CountryCode, MoneyValue.Of(command.Value, command.Currency), priceList); _aggregateStore.AppendChanges(subscriptionRenewalPayment); return(subscriptionRenewalPayment.Id); }
public MoneyValue GetPrice(string countryCode, SubscriptionPeriod subscriptionPeriod, PriceListItemCategory category) { var priceListItem = _items.Single(x => x.CountryCode == countryCode && x.SubscriptionPeriod == subscriptionPeriod && x.Category == category); return(priceListItem.Value - _discountValue); }
private void When(PriceListItemCreatedDomainEvent @event) { this.Id = @event.PriceListItemId; _countryCode = @event.CountryCode; _subscriptionPeriod = SubscriptionPeriod.Of(@event.SubscriptionPeriodCode); _category = PriceListItemCategory.Of(@event.CategoryCode); _price = MoneyValue.Of(@event.Price, @event.Currency); _isActive = true; }
public PriceForSubscriptionMustBeDefined( string countryCode, SubscriptionPeriod subscriptionPeriod, IList <PriceListItemData> priceListItems) { _countryCode = countryCode; _subscriptionPeriod = subscriptionPeriod; _priceListItems = priceListItems; }
private void When(SubscriptionPaymentCreatedDomainEvent @event) { this.Id = @event.SubscriptionPaymentId; _payerId = new PayerId(@event.PayerId); _subscriptionPeriod = SubscriptionPeriod.Of(@event.SubscriptionPeriodCode); _countryCode = @event.CountryCode; _subscriptionPaymentStatus = SubscriptionPaymentStatus.Of(@event.Status); _value = MoneyValue.Of(@event.Value, @event.Currency); }
public MoneyValue GetPrice( string countryCode, SubscriptionPeriod subscriptionPeriod, PriceListItemCategory category) { CheckRule(new PriceForSubscriptionMustBeDefinedRule(countryCode, subscriptionPeriod, _items, category)); return(_pricingStrategy.GetPrice(countryCode, subscriptionPeriod, category)); }
public SubscriptionRenewalPaymentSnapshot( SubscriptionRenewalPaymentId id, PayerId payerId, SubscriptionPeriod subscriptionPeriod, string countryCode) { PayerId = payerId; SubscriptionPeriod = subscriptionPeriod; CountryCode = countryCode; Id = id; }
public PriceForSubscriptionMustBeDefinedRule( string countryCode, SubscriptionPeriod subscriptionPeriod, IList <PriceListItemData> priceListItems, PriceListItemCategory category) { _countryCode = countryCode; _subscriptionPeriod = subscriptionPeriod; _priceListItems = priceListItems; _category = category; }
public void ChangeAttributes( string countryCode, SubscriptionPeriod subscriptionPeriod, PriceListItemCategory category, MoneyValue price) { var priceListItemChangedDomainEvent = new PriceListItemAttributesChangedDomainEvent(this.Id, countryCode, subscriptionPeriod.Code, category.Code, price.Value, price.Currency); this.Apply(priceListItemChangedDomainEvent); this.AddDomainEvent(priceListItemChangedDomainEvent); }
public PriceListItemData( string countryCode, SubscriptionPeriod subscriptionPeriod, MoneyValue value, PriceListItemCategory category) { CountryCode = countryCode; Value = value; Category = category; SubscriptionPeriod = subscriptionPeriod; }
public Task <Guid> Handle(CreatePriceListItemCommand command, CancellationToken cancellationToken) { var priceListItem = PriceListItem.Create( command.CountryCode, SubscriptionPeriod.Of(command.SubscriptionPeriodCode), PriceListItemCategory.Of(command.CategoryCode), MoneyValue.Of(command.PriceValue, command.PriceCurrency)); _aggregateStore.AppendChanges(priceListItem); return(Task.FromResult(priceListItem.Id)); }
public MoneyValue GetPrice( string countryCode, SubscriptionPeriod subscriptionPeriod, PriceListItemCategory category) { CheckRule(new PriceForSubscriptionMustBeDefined(countryCode, subscriptionPeriod, _items, category)); var priceListItem = _items.Single(x => x.CountryCode == countryCode && x.SubscriptionPeriod == subscriptionPeriod && x.Category == category); return(priceListItem.Value); }
public async Task <Unit> Handle(ChangePriceListItemAttributesCommand command, CancellationToken cancellationToken) { var priceListItem = await _aggregateStore.Load(new PriceListItemId(command.PriceListItemId)); priceListItem.ChangeAttributes( command.CountryCode, SubscriptionPeriod.Of(command.SubscriptionPeriodCode), PriceListItemCategory.Of(command.CategoryCode), MoneyValue.Of(command.PriceValue, command.PriceCurrency)); _aggregateStore.AppendChanges(priceListItem); return(Unit.Value); }
public void CalculateForNew_WhenPeriodHalfYearIsSelected_Test() { // Arrange SubscriptionPeriod period = SubscriptionPeriod.HalfYear; SystemClock.Set(new DateTime(2020, 5, 11)); // Act DateTime expirationDate = SubscriptionDateExpirationCalculator.CalculateForNew(period); // Assert Assert.That(expirationDate, Is.EqualTo(new DateTime(2020, 11, 11))); }
public static async Task <PriceList> GetPriceList(IDbConnection connection) { var priceListItemList = await GetPriceListItems(connection); return(PriceList.CreateFromItems( priceListItemList .Select(x => new PriceListItemData( x.CountryCode, SubscriptionPeriod.Of(x.SubscriptionPeriodCode), MoneyValue.Of(x.MoneyValue, x.MoneyCurrency), PriceListItemCategory.Of(x.CategoryCode))) .ToList())); }
public void CalculateForRenewal_WhenPeriodMonthIsSelected_AndExpireDatePassed_ThenMonthsAreAddedToNow() { // Arrange SubscriptionPeriod period = SubscriptionPeriod.Month; SystemClock.Set(new DateTime(2020, 5, 11)); DateTime expirationDate = new DateTime(2020, 4, 1); // Act expirationDate = SubscriptionDateExpirationCalculator.CalculateForRenewal(expirationDate, period); // Assert Assert.That(expirationDate, Is.EqualTo(new DateTime(2020, 6, 11))); }
public async Task <Guid> Handle(BuySubscriptionCommand command, CancellationToken cancellationToken) { var priceList = await PriceListProvider.GetPriceList(_sqlConnectionFactory.GetOpenConnection()); var subscription = SubscriptionPayment.Buy( _payerContext.PayerId, SubscriptionPeriod.Of(command.SubscriptionTypeCode), command.CountryCode, MoneyValue.Of(command.Value, command.Currency), priceList); _aggregateStore.AppendChanges(subscription); return(subscription.Id); }
private PeriodType ToPeriodType(SubscriptionPeriod periodType) { switch (periodType) { case SubscriptionPeriod.Monthly: return(PeriodType.Month); case SubscriptionPeriod.Daily: return(PeriodType.Day); case SubscriptionPeriod.Yearly: return(PeriodType.Year); default: throw new InvalidOperationException($"Can't convert {nameof(SubscriptionPeriod)} to {nameof(PeriodType)}"); } }
private async Task When(SubscriptionCreatedDomainEvent subscriptionCreated) { var period = SubscriptionPeriod.GetName(subscriptionCreated.SubscriptionPeriodCode); await _connection.ExecuteScalarAsync("INSERT INTO payments.SubscriptionDetails " + "([Id], [Period], [Status], [CountryCode], [ExpirationDate]) " + "VALUES (@SubscriptionId, @Period, @Status, @CountryCode, @ExpirationDate)", new { subscriptionCreated.SubscriptionId, period, subscriptionCreated.Status, subscriptionCreated.CountryCode, subscriptionCreated.ExpirationDate }); }
private async Task When(SubscriptionRenewedDomainEvent subscriptionRenewed) { var period = SubscriptionPeriod.GetName(subscriptionRenewed.SubscriptionPeriodCode); await _connection.ExecuteScalarAsync("UPDATE payments.SubscriptionDetails " + "SET " + "[Status] = @Status, " + "[ExpirationDate] = @ExpirationDate, " + "[Period] = @Period " + "WHERE [Id] = @SubscriptionId", new { subscriptionRenewed.SubscriptionId, subscriptionRenewed.Status, subscriptionRenewed.ExpirationDate, period }); }
public async Task <Unit> Handle(ChangePriceListItemAttributesCommand command, CancellationToken cancellationToken) { var priceListItem = await _aggregateStore.Load(new PriceListItemId(command.PriceListItemId)); if (priceListItem == null) { throw new InvalidCommandException(new List <string> { "Pricelist item for changing must exist." }); } priceListItem.ChangeAttributes( command.CountryCode, SubscriptionPeriod.Of(command.SubscriptionPeriodCode), PriceListItemCategory.Of(command.CategoryCode), MoneyValue.Of(command.PriceValue, command.PriceCurrency)); _aggregateStore.AppendChanges(priceListItem); return(Unit.Value); }
public static async Task <PriceList> CreatePriceList(IDbConnection connection) { var priceListItemList = await GetPriceListItems(connection); var priceListItems = priceListItemList .Select(x => new PriceListItemData( x.CountryCode, SubscriptionPeriod.Of(x.SubscriptionPeriodCode), MoneyValue.Of(x.MoneyValue, x.MoneyCurrency), PriceListItemCategory.Of(x.CategoryCode))) .ToList(); // This is place for selecting pricing strategy based on provided data and the system state. IPricingStrategy pricingStrategy = new DirectValueFromPriceListPricingStrategy(priceListItems); return(PriceList.Create( priceListItems, pricingStrategy)); }
private async Task When(SubscriptionPaymentCreatedDomainEvent subscriptionPaymentCreated) { string period = SubscriptionPeriod.GetName(subscriptionPaymentCreated.SubscriptionPeriodCode); await _connection.ExecuteScalarAsync( "INSERT INTO payments.SubscriptionPayments " + "([PaymentId], [PayerId], [Type], [Status], [Period], [Date], " + "[SubscriptionId], [MoneyValue], [MoneyCurrency]) " + "VALUES (@SubscriptionPaymentId, @PayerId, @Type, @Status, @Period, " + "@OccurredOn, NULL, @Value, @Currency)", new { subscriptionPaymentCreated.SubscriptionPaymentId, subscriptionPaymentCreated.PayerId, Type = "Initial Payment", subscriptionPaymentCreated.Status, period, subscriptionPaymentCreated.OccurredOn, subscriptionPaymentCreated.Value, subscriptionPaymentCreated.Currency }); }
public static PriceListItem Create( string countryCode, SubscriptionPeriod subscriptionPeriod, PriceListItemCategory category, MoneyValue price) { var priceListItem = new PriceListItem(); var priceListItemCreatedEvent = new PriceListItemCreatedDomainEvent( Guid.NewGuid(), countryCode, subscriptionPeriod.Code, category.Code, price.Value, price.Currency, isActive: true); priceListItem.Apply(priceListItemCreatedEvent); priceListItem.AddDomainEvent(priceListItemCreatedEvent); return(priceListItem); }
public MoneyValue GetPrice(string countryCode, SubscriptionPeriod subscriptionPeriod, PriceListItemCategory category) { return(_directValue); }
public async Task Subscription_Buy_ThenRenew_ThenExpire_Test() { await PriceListHelper.AddPriceListItems(PaymentsModule); DateTime referenceDate = new DateTime(2020, 6, 15); SystemClock.Set(referenceDate); var subscriptionPaymentId = await PaymentsModule.ExecuteCommandAsync( new BuySubscriptionCommand( "Month", "PL", 60, "PLN")); var subscriptionPayments = await GetEventually( new GetSubscriptionPaymentsProbe(PaymentsModule, ExecutionContext.UserId, x => true), 10000); var subscriptionPayment = subscriptionPayments.Single(x => x.PaymentId == subscriptionPaymentId); Assert.That(subscriptionPayment.Status, Is.EqualTo(SubscriptionPaymentStatus.WaitingForPayment.Code)); await PaymentsModule.ExecuteCommandAsync( new MarkSubscriptionPaymentAsPaidCommand(subscriptionPaymentId)); subscriptionPayments = await GetEventually( new GetSubscriptionPaymentsProbe(PaymentsModule, ExecutionContext.UserId, x => x.Any(y => y.Status == SubscriptionPaymentStatus.Paid.Code && y.SubscriptionId.HasValue)), 10000); subscriptionPayment = subscriptionPayments.Single(x => x.PaymentId == subscriptionPaymentId); var subscriptionId = subscriptionPayment.SubscriptionId.GetValueOrDefault(); var subscription = await GetEventually( new GetSubscriptionDetailsProbe( PaymentsModule, subscriptionId, x => x.SubscriptionId == subscriptionId && x.Status == SubscriptionStatus.Active.Code && x.Period == SubscriptionPeriod.Month.Code), 5000); Assert.That(subscriptionPayments[0].Status, Is.EqualTo(SubscriptionPaymentStatus.Paid.Code)); Assert.That(subscription.ExpirationDate, Is.EqualTo(referenceDate.AddMonths(1))); var subscriptionRenewalPaymentId = await PaymentsModule.ExecuteCommandAsync( new BuySubscriptionRenewalCommand( subscriptionId, "HalfYear", "PL", 320, "PLN")); subscriptionPayments = await GetEventually( new GetSubscriptionPaymentsProbe(PaymentsModule, ExecutionContext.UserId, x => true), 10000); var renewalPayment = subscriptionPayments .Single(x => x.PaymentId == subscriptionRenewalPaymentId); Assert.That(renewalPayment.Status, Is.EqualTo(SubscriptionRenewalPaymentStatus.WaitingForPayment.Code)); await PaymentsModule.ExecuteCommandAsync( new MarkSubscriptionRenewalPaymentAsPaidCommand(subscriptionRenewalPaymentId)); subscriptionPayments = await GetEventually( new GetSubscriptionPaymentsProbe(PaymentsModule, ExecutionContext.UserId, x => x.Any(y => y.PaymentId == subscriptionRenewalPaymentId)), 10000); renewalPayment = subscriptionPayments .Single(x => x.PaymentId == subscriptionRenewalPaymentId); subscription = await GetEventually( new GetSubscriptionDetailsProbe( PaymentsModule, subscriptionId, x => x.SubscriptionId == subscriptionId && x.Period == SubscriptionPeriod.GetName(SubscriptionPeriod.HalfYear.Code) && x.Status == SubscriptionStatus.Active.Code ), 5000); Assert.That(renewalPayment.Status, Is.EqualTo(SubscriptionRenewalPaymentStatus.Paid.Code)); Assert.That(subscription.ExpirationDate, Is.EqualTo(referenceDate.AddMonths(7))); SystemClock.Set(referenceDate.AddMonths(7).AddDays(1)); await PaymentsModule.ExecuteCommandAsync(new ExpireSubscriptionsCommand()); subscription = await GetEventually( new GetSubscriptionDetailsProbe( PaymentsModule, subscriptionId, x => x.SubscriptionId == subscriptionId && x.Status == SubscriptionStatus.Expired.Code), 10000); Assert.That(subscription, Is.Not.Null); }