Adding synthetic source ID to BillingEvent.OneTime

Synthetic BillingEvent.OneTimes need to have a pointer to their source Recurring event, in order to match up properly against Cancellations.

Also improving the exception message for mismatched Flag.SYNTHETIC and syntheticCreationTime.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=122155636
This commit is contained in:
ctingue 2016-05-12 07:32:26 -07:00 committed by Justine Tunney
parent 51362722cd
commit a8544100fa
2 changed files with 44 additions and 3 deletions

View file

@ -225,6 +225,13 @@ public abstract class BillingEvent extends ImmutableObject
@Index @Index
DateTime syntheticCreationTime; DateTime syntheticCreationTime;
/**
* For {@link Flag#SYNTHETIC} events, the {@link BillingEvent} from which this OneTime was
* created. This is needed in order to properly match billing events against
* {@link Cancellation}s.
*/
Long cancellationTargetId;
public Money getCost() { public Money getCost() {
return cost; return cost;
} }
@ -241,6 +248,10 @@ public abstract class BillingEvent extends ImmutableObject
return syntheticCreationTime; return syntheticCreationTime;
} }
public Long getCancellationTargetId() {
return cancellationTargetId;
}
@Override @Override
public Builder asBuilder() { public Builder asBuilder() {
return new Builder(clone(this)); return new Builder(clone(this));
@ -277,6 +288,11 @@ public abstract class BillingEvent extends ImmutableObject
return this; return this;
} }
public Builder setCancellationTargetId(Long cancellationTargetId) {
getInstance().cancellationTargetId = cancellationTargetId;
return this;
}
@Override @Override
public OneTime build() { public OneTime build() {
OneTime instance = getInstance(); OneTime instance = getInstance();
@ -291,7 +307,11 @@ public abstract class BillingEvent extends ImmutableObject
checkState( checkState(
instance.getFlags().contains(Flag.SYNTHETIC) instance.getFlags().contains(Flag.SYNTHETIC)
== (instance.syntheticCreationTime != null), == (instance.syntheticCreationTime != null),
"Billing events with SYNTHETIC flag set must have a synthetic creation time."); "Synthetic creation time must be set if and only if the SYNTHETIC flag is set.");
checkState(
instance.getFlags().contains(Flag.SYNTHETIC)
== (instance.cancellationTargetId != null),
"Cancellation target ID must be set if and only if the SYNTHETIC flag is set.");
return super.build(); return super.build();
} }
} }

View file

@ -91,6 +91,7 @@ public class BillingEventTest extends EntityTestCase {
.setReason(Reason.CREATE) .setReason(Reason.CREATE)
.setFlags(ImmutableSet.of(BillingEvent.Flag.ANCHOR_TENANT, BillingEvent.Flag.SYNTHETIC)) .setFlags(ImmutableSet.of(BillingEvent.Flag.ANCHOR_TENANT, BillingEvent.Flag.SYNTHETIC))
.setSyntheticCreationTime(now.plusDays(10)) .setSyntheticCreationTime(now.plusDays(10))
.setCancellationTargetId(1L)
.setPeriodYears(2) .setPeriodYears(2)
.setCost(Money.of(USD, 1)) .setCost(Money.of(USD, 1))
.setEventTime(now) .setEventTime(now)
@ -179,7 +180,7 @@ public class BillingEventTest extends EntityTestCase {
public void testFailure_syntheticFlagWithoutCreationTime() { public void testFailure_syntheticFlagWithoutCreationTime() {
thrown.expect( thrown.expect(
IllegalStateException.class, IllegalStateException.class,
"Billing events with SYNTHETIC flag set must have a synthetic creation time"); "Synthetic creation time must be set if and only if the SYNTHETIC flag is set.");
oneTime.asBuilder() oneTime.asBuilder()
.setFlags(ImmutableSet.of(BillingEvent.Flag.SYNTHETIC)) .setFlags(ImmutableSet.of(BillingEvent.Flag.SYNTHETIC))
.build(); .build();
@ -189,12 +190,32 @@ public class BillingEventTest extends EntityTestCase {
public void testFailure_syntheticCreationTimeWithoutFlag() { public void testFailure_syntheticCreationTimeWithoutFlag() {
thrown.expect( thrown.expect(
IllegalStateException.class, IllegalStateException.class,
"Billing events with SYNTHETIC flag set must have a synthetic creation time"); "Synthetic creation time must be set if and only if the SYNTHETIC flag is set");
oneTime.asBuilder() oneTime.asBuilder()
.setSyntheticCreationTime(now.plusDays(10)) .setSyntheticCreationTime(now.plusDays(10))
.build(); .build();
} }
@Test
public void testFailure_syntheticFlagWithoutCancellationTargetId() {
thrown.expect(
IllegalStateException.class,
"Synthetic creation time must be set if and only if the SYNTHETIC flag is set.");
oneTime.asBuilder()
.setFlags(ImmutableSet.of(BillingEvent.Flag.SYNTHETIC))
.build();
}
@Test
public void testFailure_cancellationTargetIdWithoutFlag() {
thrown.expect(
IllegalStateException.class,
"Cancellation target ID must be set if and only if the SYNTHETIC flag is set");
oneTime.asBuilder()
.setCancellationTargetId(2L)
.build();
}
@Test @Test
public void testSuccess_cancellation_forGracePeriod_withOneTime() { public void testSuccess_cancellation_forGracePeriod_withOneTime() {
BillingEvent.Cancellation newCancellation = BillingEvent.Cancellation.forGracePeriod( BillingEvent.Cancellation newCancellation = BillingEvent.Cancellation.forGracePeriod(