Skip to content

Commit be085ee

Browse files
refactor(billing): use plan migration extensions in UpcomingInvoiceHandler
1 parent c27ba68 commit be085ee

1 file changed

Lines changed: 5 additions & 16 deletions

File tree

src/Billing/Services/Implementations/UpcomingInvoiceHandler.cs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Bit.Core.Billing.Constants;
77
using Bit.Core.Billing.Enums;
88
using Bit.Core.Billing.Extensions;
9+
using Bit.Core.Billing.Organizations.PlanMigration;
910
using Bit.Core.Billing.Organizations.PlanMigration.Entities;
1011
using Bit.Core.Billing.Organizations.PlanMigration.Enums;
1112
using Bit.Core.Billing.Organizations.PlanMigration.Repositories;
@@ -509,25 +510,13 @@ private static string FormatCurrency(decimal amount, CultureInfo culture) =>
509510
private async Task<int> ResolveSeatCountAsync(
510511
Subscription subscription, Plan sourcePlan, Organization organization, SeatCountPolicy seatCountPolicy)
511512
{
512-
// A packaged source has no per-seat line, so the fallback below would quote organization.Seats (the
513-
// bundle cap). Match the billed quantity instead: the org's actual occupied seats, floored at 1.
514-
if (sourcePlan.HasNonSeatBasedPasswordManagerPlan())
515-
{
516-
var occupied = await organizationRepository.GetOccupiedSeatCountByOrganizationIdAsync(organization.Id);
517-
return Math.Max(1, occupied.Total);
518-
}
519-
520-
// ActualUsage (e.g. Teams 2019): a Packaged source's seat line only counts overage beyond the
521-
// base, so the quote must match what the scheduler bills — occupied seats below the base
522-
// (unused headroom disappears), otherwise the purchased seat count. Mirrors
523-
// PriceIncreaseScheduler.CalculateTargetPlanSeatCountAsync.
524-
if (seatCountPolicy == SeatCountPolicy.ActualUsage)
513+
// A Packaged source's line items don't reflect the true seat total, so resolve the quote from
514+
// actual usage to match what the scheduler bills.
515+
if (sourcePlan.IsPackagedMigrationSource(seatCountPolicy))
525516
{
526517
var occupied = (await organizationRepository
527518
.GetOccupiedSeatCountByOrganizationIdAsync(organization.Id)).Total;
528-
return occupied < sourcePlan.PasswordManager.BaseSeats
529-
? occupied
530-
: organization.Seats ?? occupied;
519+
return sourcePlan.ResolveMigratedSeatCount(occupied, organization.Seats);
531520
}
532521

533522
var seatItem = subscription.Items.Data

0 commit comments

Comments
 (0)