File size: 2,079 Bytes
16cdcb7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package patch

import (
	"github.com/openmeterio/openmeter/openmeter/subscription"
)

type PatchUnscheduleEdit struct{}

func (p PatchUnscheduleEdit) Op() subscription.PatchOperation {
	return subscription.PatchOperationUnschedule
}

func (p PatchUnscheduleEdit) Path() subscription.SpecPath {
	return subscription.NewPhasePath("")
}

func (p PatchUnscheduleEdit) Validate() error {
	if err := p.Op().Validate(); err != nil {
		return err
	}

	return nil
}

var _ subscription.Patch = PatchUnscheduleEdit{}

// "Unscheduling an edit" is a concept that might intuitively makes sense for clients:
// 1. Making some edit to a subscription
// 2. You want to do another edit
// 3. Your edit discards the previous edit
//
// However, this is not really a behavior that makes sense from a server perspective.
// The compromise we make is that, for most cases, when a client wants to unschedule an edit,
// all they really want to do is get rid of any future changes to the subscription.
//
// As editing future phases doesn't create multiple versions of the items (see AddItem and RemoveItem),
// we only tackle editing the current phase.
//
// UnscheduleEdit simply removes all scheduled versions of the items in the current phase.
func (p PatchUnscheduleEdit) ApplyTo(spec *subscription.SubscriptionSpec, actx subscription.ApplyContext) error {
	currentPhase, exists := spec.GetCurrentPhaseAt(actx.CurrentTime)
	if !exists {
		return &subscription.PatchConflictError{Msg: "current phase doesn't exist, cannot unschedule edits"}
	}

	currentPhaseCadence, err := spec.GetPhaseCadence(currentPhase.PhaseKey)
	if err != nil {
		return err
	}

	for iK, items := range currentPhase.ItemsByKey {
		for i := len(items) - 1; i >= 0; i-- {
			if c := items[i].GetCadence(currentPhaseCadence); c.IsActiveAt(actx.CurrentTime) {
				// Let's make sure there is no scheduled end time
				currentPhase.ItemsByKey[iK][i].ActiveToOverrideRelativeToPhaseStart = nil

				break
			}

			// Let's remove the item at index i from the array
			currentPhase.ItemsByKey[iK] = items[:i]
		}
	}

	return nil
}