diff --git a/core/src/main/java/google/registry/beam/invoicing/sql/billing_events.sql b/core/src/main/java/google/registry/beam/invoicing/sql/billing_events.sql index 2fabfde82..c5bdb635d 100644 --- a/core/src/main/java/google/registry/beam/invoicing/sql/billing_events.sql +++ b/core/src/main/java/google/registry/beam/invoicing/sql/billing_events.sql @@ -56,7 +56,8 @@ FROM ( `%PROJECT_ID%.%DATASTORE_EXPORT_DATA_SET%.%REGISTRY_TABLE%` WHERE -- TODO(b/18092292): Add a filter for tldState (not PDT/PREDELEGATION) - tldType = 'REAL') ) AS BillingEvent + tldType = 'REAL' + AND disableInvoicing is not TRUE) ) AS BillingEvent -- Gather billing ID from registrar table -- This is a 'JOIN' as opposed to 'LEFT JOIN' to filter out -- non-billable registrars diff --git a/core/src/main/java/google/registry/model/registry/Registry.java b/core/src/main/java/google/registry/model/registry/Registry.java index 85f341ce5..859da9e65 100644 --- a/core/src/main/java/google/registry/model/registry/Registry.java +++ b/core/src/main/java/google/registry/model/registry/Registry.java @@ -339,6 +339,14 @@ public class Registry extends ImmutableObject implements Buildable { /** The type of the TLD, whether it's real or for testing. */ TldType tldType = TldType.REAL; + /** + * Whether to disable invoicing for a {@link TldType#REAL} TLD. + * + *

Note that invoicing is always disabled for {@link TldType#TEST} TLDs. Setting this field has + * no effect for {@link TldType#TEST} TLDs. + */ + boolean disableInvoicing = false; + /** * A property that transitions to different TldStates at different times. Stored as a list of * TldStateTransition embedded objects using the @Mapify annotation. @@ -637,6 +645,11 @@ public class Registry extends ImmutableObject implements Buildable { return this; } + public Builder setDisableInvoicing(boolean disableInvoicing) { + getInstance().disableInvoicing = disableInvoicing; + return this; + } + /** Sets the TLD state to transition to the specified states at the specified times. */ public Builder setTldStateTransitions(ImmutableSortedMap tldStatesMap) { checkNotNull(tldStatesMap, "TLD states map cannot be null"); diff --git a/core/src/main/java/google/registry/tools/CreateOrUpdateTldCommand.java b/core/src/main/java/google/registry/tools/CreateOrUpdateTldCommand.java index e31c2cc92..ae408ce90 100644 --- a/core/src/main/java/google/registry/tools/CreateOrUpdateTldCommand.java +++ b/core/src/main/java/google/registry/tools/CreateOrUpdateTldCommand.java @@ -116,6 +116,13 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand { description = "Tld type (REAL or TEST)") private TldType tldType; + @Nullable + @Parameter( + names = "--disable_invoicing", + description = "Whether invoicing is disabled for a REAL tld.", + arity = 1) + private Boolean disableInvoicing; + @Nullable @Parameter( names = "--create_billing_cost", @@ -320,6 +327,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand { Optional.ofNullable(serverStatusChangeCost) .ifPresent(builder::setServerStatusChangeBillingCost); Optional.ofNullable(tldType).ifPresent(builder::setTldType); + Optional.ofNullable(disableInvoicing).ifPresent(builder::setDisableInvoicing); Optional.ofNullable(lordnUsername).ifPresent(u -> builder.setLordnUsername(u.orElse(null))); Optional.ofNullable(claimsPeriodEnd).ifPresent(builder::setClaimsPeriodEnd); Optional.ofNullable(numDnsPublishShards).ifPresent(builder::setNumDnsPublishLocks); diff --git a/core/src/test/resources/google/registry/beam/invoicing/billing_events_test.sql b/core/src/test/resources/google/registry/beam/invoicing/billing_events_test.sql index 04bc8cfd2..e9b36e5b9 100644 --- a/core/src/test/resources/google/registry/beam/invoicing/billing_events_test.sql +++ b/core/src/test/resources/google/registry/beam/invoicing/billing_events_test.sql @@ -56,7 +56,8 @@ FROM ( `my-project-id.latest_datastore_export.Registry` WHERE -- TODO(b/18092292): Add a filter for tldState (not PDT/PREDELEGATION) - tldType = 'REAL') ) AS BillingEvent + tldType = 'REAL' + AND disableInvoicing is not TRUE) ) AS BillingEvent -- Gather billing ID from registrar table -- This is a 'JOIN' as opposed to 'LEFT JOIN' to filter out -- non-billable registrars diff --git a/core/src/test/resources/google/registry/model/schema.txt b/core/src/test/resources/google/registry/model/schema.txt index bdea2a8f0..8b30be587 100644 --- a/core/src/test/resources/google/registry/model/schema.txt +++ b/core/src/test/resources/google/registry/model/schema.txt @@ -494,6 +494,7 @@ enum google.registry.model.registrar.RegistrarContact$Type { class google.registry.model.registry.Registry { @Id java.lang.String tldStrId; @Parent com.googlecode.objectify.Key parent; + boolean disableInvoicing; boolean dnsPaused; boolean escrowEnabled; com.googlecode.objectify.Key premiumList;