Skip to content

Commit 582b3d1

Browse files
authored
fix: invalid error on period correction (#3173)
1 parent a79e33f commit 582b3d1

File tree

1 file changed

+50
-28
lines changed
  • openmeter/billing/worker/subscription

1 file changed

+50
-28
lines changed

openmeter/billing/worker/subscription/sync.go

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,18 @@ func (h *Handler) correctPeriodStartForUpcomingLines(ctx context.Context, subscr
349349
continue
350350
}
351351

352+
// We are not correcting periods for lines that are already ignored
353+
if existingCurrentLine, ok := existingLinesByUniqueID[line.UniqueID]; ok {
354+
hasAnnotation, err := h.lineOrHierarchyHasSubscriptionSyncIgnoreAnnotation(existingCurrentLine)
355+
if err != nil {
356+
return nil, fmt.Errorf("checking if line has subscription sync ignore annotation: %w", err)
357+
}
358+
359+
if hasAnnotation {
360+
continue
361+
}
362+
}
363+
352364
previousPeriodUniqueID := strings.Join([]string{
353365
subscriptionID,
354366
line.PhaseKey,
@@ -363,27 +375,12 @@ func (h *Handler) correctPeriodStartForUpcomingLines(ctx context.Context, subscr
363375
continue
364376
}
365377

366-
switch existingPreviousLine.Type() {
367-
case billing.LineOrHierarchyTypeLine:
368-
previousLine, err := existingPreviousLine.AsLine()
369-
if err != nil {
370-
return nil, fmt.Errorf("getting previous line: %w", err)
371-
}
372-
373-
if !h.isLineInScopeForPeriodCorrection(previousLine) {
374-
continue
375-
}
376-
case billing.LineOrHierarchyTypeHierarchy:
377-
hierarchy, err := existingPreviousLine.AsHierarchy()
378-
if err != nil {
379-
return nil, fmt.Errorf("getting previous hierarchy: %w", err)
380-
}
381-
382-
if !h.isHierarchyInScopeForPeriodCorrection(hierarchy) {
383-
continue
384-
}
378+
existingPreviousLineHasAnnotation, err := h.lineOrHierarchyHasSubscriptionSyncIgnoreAnnotation(existingPreviousLine)
379+
if err != nil {
380+
return nil, fmt.Errorf("checking if previous line has subscription sync ignore annotation: %w", err)
381+
}
385382

386-
default:
383+
if !existingPreviousLineHasAnnotation {
387384
continue
388385
}
389386

@@ -394,21 +391,46 @@ func (h *Handler) correctPeriodStartForUpcomingLines(ctx context.Context, subscr
394391
continue
395392
}
396393

397-
// Should not happen as this line is never the first line
398-
// TODO: harmonize truncation logic here!
399-
if !line.ServicePeriod.Start.Equal(line.BillingPeriod.Start) || !line.FullServicePeriod.Start.Equal(line.BillingPeriod.Start) {
400-
return nil, fmt.Errorf("line[%s] service period start does not match billing period start or full service period start", line.UniqueID)
394+
if !line.ServicePeriod.Start.Equal(line.FullServicePeriod.Start) {
395+
// These should match otherwise any pro-rating logic will be invalid (we are never truncating the start of the service period so this should never happen)
396+
return nil, fmt.Errorf("line[%s] service period and full service period start does not match", line.UniqueID)
401397
}
402398

399+
// We are not overriding the billing period start as that is only used to determine the invoiceAt for inAdvance items
403400
inScopeLines[idx].ServicePeriod.Start = previousServicePeriod.End
404-
inScopeLines[idx].BillingPeriod.Start = previousServicePeriod.End
405401
inScopeLines[idx].FullServicePeriod.Start = previousServicePeriod.End
402+
403+
if line.FullServicePeriod.Start.Equal(line.BillingPeriod.Start) {
404+
// If the billing period is not truncated, we can update the line's billing period start too
405+
inScopeLines[idx].BillingPeriod.Start = previousServicePeriod.End
406+
}
406407
}
407408

408409
return inScopeLines, nil
409410
}
410411

411-
func (h *Handler) isLineInScopeForPeriodCorrection(line *billing.Line) bool {
412+
func (h *Handler) lineOrHierarchyHasSubscriptionSyncIgnoreAnnotation(lineOrHierarchy billing.LineOrHierarchy) (bool, error) {
413+
switch lineOrHierarchy.Type() {
414+
case billing.LineOrHierarchyTypeLine:
415+
previousLine, err := lineOrHierarchy.AsLine()
416+
if err != nil {
417+
return false, fmt.Errorf("getting previous line: %w", err)
418+
}
419+
420+
return h.lineHasSubscriptionSyncIgnoreAnnotation(previousLine), nil
421+
case billing.LineOrHierarchyTypeHierarchy:
422+
hierarchy, err := lineOrHierarchy.AsHierarchy()
423+
if err != nil {
424+
return false, fmt.Errorf("getting previous hierarchy: %w", err)
425+
}
426+
427+
return h.hierarchyHasSubscriptionSyncIgnoreAnnotation(hierarchy), nil
428+
default:
429+
return false, nil
430+
}
431+
}
432+
433+
func (h *Handler) lineHasSubscriptionSyncIgnoreAnnotation(line *billing.Line) bool {
412434
if line.ManagedBy != billing.SubscriptionManagedLine {
413435
// We only correct the period start for subscription managed lines, for manual edits
414436
// we should not apply this logic, as the user might have created a setup where the period start
@@ -434,13 +456,13 @@ func (h *Handler) isLineInScopeForPeriodCorrection(line *billing.Line) bool {
434456
return boolVal
435457
}
436458

437-
func (h *Handler) isHierarchyInScopeForPeriodCorrection(hierarchy *billing.SplitLineHierarchy) bool {
459+
func (h *Handler) hierarchyHasSubscriptionSyncIgnoreAnnotation(hierarchy *billing.SplitLineHierarchy) bool {
438460
servicePeriod := hierarchy.Group.ServicePeriod
439461

440462
// The correction can only happen if the last line the progressively billed group is in scope for the period correction
441463
for _, line := range hierarchy.Lines {
442464
if line.Line.Period.End.Equal(servicePeriod.End) {
443-
return h.isLineInScopeForPeriodCorrection(line.Line)
465+
return h.lineHasSubscriptionSyncIgnoreAnnotation(line.Line)
444466
}
445467
}
446468

0 commit comments

Comments
 (0)