Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WI #557: Preview - Refinement of FOCUS Columns Normative Requirements #664

Open
wants to merge 38 commits into
base: working_draft
Choose a base branch
from

Conversation

ijurica
Copy link
Contributor

@ijurica ijurica commented Dec 10, 2024

This PR serves solely as a preview and discussion base and is not intended for merging into the working draft.

It includes both the original version and the candidate version of normative requirements across all existing columns to facilitate a clear comparison (before/after) for review and feedback.

The goal of this PR is to provide a comprehensive context for discussing potential updates to normative requirements across the specification. It aims to ensure that the impact of proposed changes on all column definitions is thoroughly reviewed and debated.

Please use this PR as a collaborative tool, keeping in mind that it is not finalized content and should not be merged into the working draft.


Instructions for Reviewing and Providing Feedback

If you wish to contribute to the refinement of Normative Requirements, please follow the steps below to review the current progress and provide your feedback.

1. Select Columns to Review:

  • In this spreadsheet, 24.12.07 Normative Requirements Cookbook, on the Overview sheet, you’ll find a list of FOCUS Columns requiring review.

  • As a first step, select one or more columns to validate and add your name to the "Assignee" column in the sheet (please focus on those marked with Initial Pass status).

2. Review proposed changes and provide feedback for the specific column you’ve selected

  • If you have concerns or suggestions related to the proposed changes for that column’s Normative Requirements, please add comments or provide alternative proposal using GitHub comments or suggestions to the specific file/change.
  • If you agree with the proposed changes for that column, approve them by adding an explicit approval using GitHub comment to the corresponding file/change.
  • If you identify any discrepancies or ambiguities that need further discussion (either in a meeting or offline), please flag them, and we'll add them to the list of Discussion Topics.

Notes:

  • While feedback on the overall PR is welcome, please ensure that feedback and approvals are provided at the individual column level for the columns you’ve selected.
  • At this stage, we are primarily seeking feedback on columns marked with the status Initial Pass, where alternative Normative Requirements have been proposed (provided in this PR). By January 14th, alternative proposals will also be added for the remaining columns.
  • This PR includes both the original version and a new candidate version of the Normative Requirements specifications for multiple FOCUS columns. It is not intended to be merged into the working draft. Instead, it is meant to support collaborative efforts in consolidating and improving the Normative Requirements for all FOCUS columns

@ijurica ijurica requested a review from a team as a code owner December 10, 2024 13:04
* AvailabilityZone is RECOMMENDED to be present in a [*FOCUS dataset*](#glossary:FOCUS-dataset) when the provider supports deploying resources or services within an *availability zone*.
* If present, the column MUST conform to the following additional requirements:
* AvailabilityZone MUST be of type String.
* AvailabilityZone MUST conform to [String Handling](#stringhandling) requirements.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* AvailabilityZone MUST conform to [String Handling](#stringhandling) requirements.

Discussed in Dec 10 TF1. Propose postponing adding such requirements until lower-hanging fruit of consistency is collected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have missed something. Why is linking attributes contentious?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to Irena - she suggested postponing this due to provider conformance concerns.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we discuss this in the TF-1 meeting. This sheet can serve as the basis for our discussion.

* RegionId MUST be of type String.
* RegionId MUST conform to [String Handling](#stringhandling) requirements.
* RegionId MUST NOT be null when a *resource* or *service* is operated in or managed from a distinct region by the Provider.
* RegionId MAY be null when a *resource* or *service* is not restricted to an isolated geographic area.
Copy link

@davehatcher davehatcher Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the previous line, with a MUST NOT be NULL condition - we say 'operated in or managed from a distinct region'
in this line where it MAY be NULL we say 'not restricted to an isolated geographical area'.

would the 2nd line be clearer as follows:

Suggested change
* RegionId MAY be null when a *resource* or *service* is not restricted to an isolated geographic area.
* RegionId MAY be null when a *resource* or *service* is not operated in or managed from a distinct region.

Copy link
Contributor Author

@ijurica ijurica Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current version (using identical wording in both requirements):

  • RegionId MUST NOT be null when a resource or service is operated in or managed from a distinct region.
  • RegionId MAY be null when a resource or service is operated in or managed from a distinct region.

Suggestions:

  • Add 'region' as an additional term in the glossary.

* AvailabilityZone is RECOMMENDED to be present in a [*FOCUS dataset*](#glossary:FOCUS-dataset) when the provider supports deploying resources or services within an *availability zone*.
* If present, the column MUST conform to the following additional requirements:
* AvailabilityZone MUST be of type String.
* AvailabilityZone MUST conform to [String Handling](#stringhandling) requirements.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have missed something. Why is linking attributes contentious?

The AvailabilityZone column adheres to the following requirements:

* AvailabilityZone is RECOMMENDED to be present in a [*FOCUS dataset*](#glossary:FOCUS-dataset) when the provider supports deploying resources or services within an *availability zone*.
* If present, the column adheres to the following additional requirements:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Personally, I would rather not have this line and keep all requirements at the root level. The requirements are all valid whether the column is present or not, so I'm not sure what the value of nesting these requirements is.

specification/columns/billedcost.md Show resolved Hide resolved
* ChargeClass MUST be present in a [*FOCUS dataset*](#glossary:FOCUS-dataset).
* ChargeClass MUST be of type String.
* ChargeClass MUST be null when the row does not represent a correction or when it represents a correction within the current *billing period*.
* When the row represents a correction to a previously invoiced *billing period*, the following applies:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be "If"? Also aligning to a previous suggestion...

Suggested change
* When the row represents a correction to a previously invoiced *billing period*, the following applies:
* If the row represents a correction to a previously invoiced *billing period*, the column adheres to the following additional requirements:

specification/columns/commitmentdiscountcategory.md Outdated Show resolved Hide resolved
specification/columns/commitmentdiscountname.md Outdated Show resolved Hide resolved
specification/columns/commitmentdiscountstatus.md Outdated Show resolved Hide resolved
specification/columns/pricingcategory.md Outdated Show resolved Hide resolved
* ServiceSubcategory MUST NOT be null.
* ServiceSubcategory MUST be one of the allowed values.
* ServiceSubcategory MUST have one and only one parent ServiceCategory as specified in the allowed values below.
* Though a given *service* can have multiple purposes, each *service* SHOULD have one and only one ServiceSubcategory that best aligns with its primary purpose
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a confusing requirement. We have allowed values, so it should be a MUST. If this is context on the allowed values requirement, I would rather see it nested under that and remove the "SHOULD".

Copy link
Contributor Author

@ijurica ijurica Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to Michael's comment,

  • I suggest moving this requirement to the ServiceName column definition, as it is one of the normative requirements for ServiceName.
  • Furthermore, considering that ServiceSubcategory is currently RECOMMENDED, I propose adding two explicit and easily verifiable requirements to the ServiceName column: one defining its relationship with ServiceSubcategory, and another for its relationship with ServiceCategory.
  • Additionally, I would like to establish a consistent pattern for column relationship-related requirements.

PREFERRED PATTERN:

  • XY MUST be associated with one and only one parent MN ...

SkuPriceId:

BEFORE:

  • SkuPriceId MUST be associated with one and only one SkuId, except ...

AFTER:

  • SkuPriceId MUST be associated with one and only one parent SkuId, except ...

ServiceCategory:

The Service Category is the highest-level classification of a service based on the core function of the service. Each service should have one and only one category that best aligns with its primary purpose.

ServiceSubcategory:

BEFORE:

The Service Subcategory is a secondary classification of the Service Category for a service based on its core function.
...

  • ServiceSubcategory MUST have one and only one parent ServiceCategory as specified in the allowed values below.
  • Though a given service can have multiple purposes, each service SHOULD have one and only one ServiceSubcategory that best aligns with its primary purpose

AFTER:

The Service Subcategory is a secondary classification of the Service Category for a service based on its core function.
...

  • ServiceSubcategory MUST be associated with one and only one parent ServiceCategory as specified in the allowed values below.

ServiceName (for discussion in a meeting):

BEFORE:

A service represents an offering that can be purchased from a provider...
...
The Service Name is a display name for the offering that was purchased...

AFTER:

A service represents an offering that can be purchased from a provider...
...
The Service Name is a display name for the offering that was purchased...
...

  • Each service SHOULD be associated with one and only one parent ServiceCategory that best aligns with its primary purpose.
  • Each service SHOULD be associated with one and only one parent ServiceSubcategory that best aligns with its primary purpose if ServiceSubcategory is present.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @ijurica on this

@ijurica
Copy link
Contributor Author

ijurica commented Jan 7, 2025

Instructions for Reviewing and Providing Feedback

If you wish to contribute to the refinement of Normative Requirements, please follow the steps below to review the current progress and provide your feedback.

1. Select Columns to Review:

  • In this spreadsheet, 24.12.07 Normative Requirements Cookbook, on the Overview sheet, you’ll find a list of FOCUS Columns requiring review.

  • As a first step, select one or more columns to validate and add your name to the "Assignee" column in the sheet (please focus on those marked with Initial Pass status).

2. Review proposed changes and provide feedback for the specific column you’ve selected

  • If you have concerns or suggestions related to the proposed changes for that column’s Normative Requirements, please add comments or provide alternative proposal using GitHub comments or suggestions to the specific file/change.
  • If you agree with the proposed changes for that column, approve them by adding an explicit approval using GitHub comment to the corresponding file/change.
  • If you identify any discrepancies or ambiguities that need further discussion (either in a meeting or offline), please flag them, and we'll add them to the list of Discussion Topics.

Notes:

  • While feedback on the overall PR is welcome, please ensure that feedback and approvals are provided at the individual column level for the columns you’ve selected.
  • At this stage, we are primarily seeking feedback on columns marked with the status Initial Pass, where alternative Normative Requirements have been proposed (provided in this PR). By January 14th, alternative proposals will also be added for the remaining columns.
  • This PR includes both the original version and a new candidate version of the Normative Requirements specifications for multiple FOCUS columns. It is not intended to be merged into the working draft. Instead, it is meant to support collaborative efforts in consolidating and improving the Normative Requirements for all FOCUS columns

specification/columns/billingaccountid.md Outdated Show resolved Hide resolved
specification/columns/billingaccountname.md Outdated Show resolved Hide resolved
specification/columns/subaccountid.md Outdated Show resolved Hide resolved
specification/columns/subaccountid.md Show resolved Hide resolved
specification/columns/subaccountname.md Show resolved Hide resolved
specification/columns/resourcetype.md Outdated Show resolved Hide resolved
specification/columns/servicecategory.md Outdated Show resolved Hide resolved
specification/columns/servicename.md Outdated Show resolved Hide resolved
* ServiceSubcategory MUST NOT be null.
* ServiceSubcategory MUST be one of the allowed values.
* ServiceSubcategory MUST have one and only one parent ServiceCategory as specified in the allowed values below.
* Though a given *service* can have multiple purposes, each *service* SHOULD have one and only one ServiceSubcategory that best aligns with its primary purpose
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @ijurica on this

specification/columns/billingcurrency.md Outdated Show resolved Hide resolved
ijurica and others added 2 commits January 14, 2025 16:54
Co-authored-by: Larry Advey <104788770+ljadvey@users.noreply.github.com>
@ijurica ijurica self-assigned this Jan 16, 2025
@ijurica ijurica added the 1.2 Agreed scope for release 1.2 label Jan 16, 2025
Comment on lines +21 to +26
* If ChargeCategory is "Purchase", CommitmentDiscountQuantity adheres to the following additional requirements:
* CommitmentDiscountQuantity MUST be the quantity of CommitmentDiscountUnits, paid fully or partially upfront, that is eligible for consumption over the *commitment discount's* *term* if [ChargeFrequency](#chargefrequency) is "One-Time".
* CommitmentDiscountQuantity MUST be the quantity of CommitmentDiscountUnits that is eligible for consumption for each *charge period* that corresponds with the purchase if ChargeFrequency is "Recurring".
* If ChargeCategory is "Usage", CommitmentDiscountQuantity adheres to the following additional requirements:
* CommitmentDiscountQuantity MUST be the metered quantity of CommitmentDiscountUnits that is consumed over the *row's* *charge period* if [CommitmentDiscountStatus](#commitmentdiscountstatus) is "Used".
* CommitmentDiscountQuantity MUST be the remaining, unused quantity of CommitmentDiscountUnits for the *row's* *charge period* if CommitmentDiscountStatus is "Unused".
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ijurica Revisit

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the word "positive" was removed from the new description. Was this intentional? I am not sure if it can/should be negative...

* If CommitmentDiscountUnit is not null, CommitmentDiscountUnit adheres to the following additional requirements:
* CommitmentDiscountUnit MUST remain consistent over time for a given CommitmentDiscountId.
* CommitmentDiscountUnit MUST represent the unit used to measure the *commitment discount*.
* When accounting for [*commitment discount flexibility*](#glossary:commitment-discount-flexibility), the CommitmentDiscountUnit value SHOULD reflect this consideration.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ijurica Revisit

* EffectiveCost MUST be 0 if [ChargeCategory](#chargecategory) is "Purchase" and the purchase is intended to cover future eligible charges.
* EffectiveCost MUST be denominated in the BillingCurrency.
* The sum of EffectiveCost for *rows* in a given *billing period* may not match the sum of the invoices received for the same *billing period* for a [*billing account*](#glossary:billing-account).
* When CommitmentDiscountStatus is "Unused", the EffectiveCost MUST be the total committed cost consumed for the given charge period minus related usage charges.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ijurica Revisit

* EffectiveCost MUST be a valid decimal value.
* EffectiveCost MUST be 0 if [ChargeCategory](#chargecategory) is "Purchase" and the purchase is intended to cover future eligible charges.
* EffectiveCost MUST be denominated in the BillingCurrency.
* The sum of EffectiveCost for *rows* in a given *billing period* may not match the sum of the invoices received for the same *billing period* for a [*billing account*](#glossary:billing-account).
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording more or less aligned with BilledCost, BillingPeriodEnd, BillingPeridStart

ORIG: The sum of EffectiveCost for a billing period may not match the charge received on the invoice for the same billing period.

* Else CommitmentDiscountUnit adheres to the following additional requirement:
* CommitmentDiscountUnit MUST be null.
* If CommitmentDiscountUnit is not null, CommitmentDiscountUnit adheres to the following additional requirements:
* CommitmentDiscountUnit MUST remain consistent over time for a given CommitmentDiscountId.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preferring 'CommitmentDiscountUnit MUST remain consistent over time for a given CommitmentDiscountId' over the original (i.e., 'CommitmentDiscountUnit MUST be the same across all rows with the same CommitmentDiscountId') because "be the same across all rows" limits the scope to a single dataset. If the intention is to restrict the requirement to a single dataset, we can revert...

* SkuPriceId MAY be null in all other cases.
* SkuPriceId MUST be associated with one and only one [SkuId](#skuid), except in cases of [commitment discount flexibility](#glossary:commitment-discount-flexibility).
* SkuPriceId MUST define a single unit price used for calculating the charge.
* [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published price list.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ijurica Revisit this

Comment on lines +6 to +22
The ListUnitPrice column adheres to the following requirements:

* ListUnitPrice MUST be present in a [*FOCUS dataset*](#glossary:FOCUS-dataset) when the provider publishes unit prices exclusive of discounts.
* If present, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST be of type Decimal.
* ListUnitPrice MUST conform to [Numeric Format](#numericformat) requirements.
* If [ChargeCategory](#chargecategory) is "Tax", ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MUST be null.
* Else if ChargeCategory is "Usage" or "Purchase" and [ChargeClass](#chargeclass) is not "Correction", ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MUST NOT be null.
* Else ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MAY be null.
* If ListUnitPrice is not null, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST be a non-negative decimal value.
* ListUnitPrice MUST be denominated in the BillingCurrency.
* The product of ListUnitPrice and [PricingQuantity](#pricingquantity) MUST match the [ListCost](#listcost) if PricingQuantity is not null and ChargeClass is not "Correction".
* Discrepancies in ListUnitPrice, ListCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".
Copy link
Contributor Author

@ijurica ijurica Jan 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding 'if not null', where applicable, and position these requirements after specifying nullability.

CANDIDATE ORDERING:

  1. Data Type: Establishes a foundational expectation, ensuring all subsequent rules align with this type.
  2. Nullability: Clarifies when the value can or cannot exist, which influences the applicability of format and range rules.
  3. Value Format: Ensures the value (if present) adheres to specific structural or syntactic rules.
  4. Value Range: Applies further constraints on valid values, assuming the format is already correct.

IF NOT NULL WORDING

A) If XY is not null, XY adheres to the following additional requirements:
B) If not null, XY adheres to the following additional requirements:
C) If XY is not null, the column adheres to the following additional requirements:


  • ListUnitPrice MUST be present in a FOCUS dataset when the provider publishes unit prices exclusive of discounts.
  • If present, ListUnitPrice adheres to the following additional requirements:
    • ListUnitPrice MUST be of type Decimal.
    • ListUnitPrice MUST conform to Numeric Format requirements. <-- from here
    • If ChargeCategory is "Tax", ListUnitPrice adheres to the following additional requirement:
      • ListUnitPrice MUST be null.
    • Else if ChargeCategory is "Usage" or "Purchase" and ChargeClass is not "Correction", ListUnitPrice adheres to the following additional requirement:
      • ListUnitPrice MUST NOT be null.
    • Else ListUnitPrice adheres to the following additional requirement:
      • ListUnitPrice MAY be null.
    • If ListUnitPrice is not null, ListUnitPrice adheres to the following additional requirements:
      • ListUnitPrice MUST conform to Numeric Format requirements. <-- to here
      • ListUnitPrice MUST be a non-negative decimal value.
      • ListUnitPrice MUST be denominated in the BillingCurrency.
      • The product of ListUnitPrice and PricingQuantity MUST match the ListCost if PricingQuantity is not null and ChargeClass is not "Correction".
    • Discrepancies in ListUnitPrice, ListCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".

Suggested change
The ListUnitPrice column adheres to the following requirements:
* ListUnitPrice MUST be present in a [*FOCUS dataset*](#glossary:FOCUS-dataset) when the provider publishes unit prices exclusive of discounts.
* If present, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST be of type Decimal.
* ListUnitPrice MUST conform to [Numeric Format](#numericformat) requirements.
* If [ChargeCategory](#chargecategory) is "Tax", ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MUST be null.
* Else if ChargeCategory is "Usage" or "Purchase" and [ChargeClass](#chargeclass) is not "Correction", ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MUST NOT be null.
* Else ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MAY be null.
* If ListUnitPrice is not null, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST be a non-negative decimal value.
* ListUnitPrice MUST be denominated in the BillingCurrency.
* The product of ListUnitPrice and [PricingQuantity](#pricingquantity) MUST match the [ListCost](#listcost) if PricingQuantity is not null and ChargeClass is not "Correction".
* Discrepancies in ListUnitPrice, ListCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".
* ListUnitPrice MUST be present in a [*FOCUS dataset*](#glossary:FOCUS-dataset) when the provider publishes unit prices exclusive of discounts.
* If present, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST be of type Decimal.
* If [ChargeCategory](#chargecategory) is "Tax", ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MUST be null.
* Else if ChargeCategory is "Usage" or "Purchase" and [ChargeClass](#chargeclass) is not "Correction", ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MUST NOT be null.
* Else ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MAY be null.
* If ListUnitPrice is not null, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST conform to [Numeric Format](#numericformat) requirements.
* ListUnitPrice MUST be a non-negative decimal value.
* ListUnitPrice MUST be denominated in the BillingCurrency.
* The product of ListUnitPrice and [PricingQuantity](#pricingquantity) MUST match the [ListCost](#listcost) if PricingQuantity is not null and ChargeClass is not "Correction".
* Discrepancies in ListUnitPrice, ListCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".

Copy link
Contributor

@shawnalpay shawnalpay Jan 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ijurica @cnharris10
Based on today's TF1 discussion, the existing proposals, the cookbook, and this new definition of guidelines based on that work so far, I propose the following revision to ListUnitPrice:

Suggested change
The ListUnitPrice column adheres to the following requirements:
* ListUnitPrice MUST be present in a [*FOCUS dataset*](#glossary:FOCUS-dataset) when the provider publishes unit prices exclusive of discounts.
* If present, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST be of type Decimal.
* ListUnitPrice MUST conform to [Numeric Format](#numericformat) requirements.
* If [ChargeCategory](#chargecategory) is "Tax", ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MUST be null.
* Else if ChargeCategory is "Usage" or "Purchase" and [ChargeClass](#chargeclass) is not "Correction", ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MUST NOT be null.
* Else ListUnitPrice adheres to the following additional requirement:
* ListUnitPrice MAY be null.
* If ListUnitPrice is not null, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST be a non-negative decimal value.
* ListUnitPrice MUST be denominated in the BillingCurrency.
* The product of ListUnitPrice and [PricingQuantity](#pricingquantity) MUST match the [ListCost](#listcost) if PricingQuantity is not null and ChargeClass is not "Correction".
* Discrepancies in ListUnitPrice, ListCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".
The ListUnitPrice column adheres to the following requirements:
* ListUnitPrice MUST be present in a FOCUS dataset when the provider publishes unit prices exclusive of discounts.
* ListUnitPrice MUST be of type Decimal.
* ListUnitPrice nullability is defined as follows:
* ListUnitPrice MUST be null when ChargeCategory is "Tax".
* ListUnitPrice MUST NOT be null when ChargeCategory is "Usage" or "Purchase" and ChargeClass is not "Correction".
* ListUnitPrice MAY be null in all other cases.
* When ListUnitPrice is not null, ListUnitPrice adheres to the following additional requirements:
* ListUnitPrice MUST conform to Numeric Format requirements.
* ListUnitPrice MUST be a non-negative decimal value.
* ListUnitPrice MUST be denominated in the BillingCurrency.
* The product of ListUnitPrice and PricingQuantity MUST match the ListCost if PricingQuantity is not null and ChargeClass is not "Correction".
* Discrepancies in ListUnitPrice, ListCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".

@cnharris10
Copy link
Contributor

cnharris10 commented Jan 28, 2025

Especially for more complicated columns, I would definitely prefer a more top-level approach (Option 2) over a nested approach (Option 1). I think stating general requirements then special scenarios (i.e. In X case, the following applies) after flows nicer for readers to comprehend.

Option 1 pulled from ListUnitPrice and transformed in Option 2 below:

Option 1: (original)

- ListUnitPrice MUST be present in a FOCUS dataset when the provider publishes unit prices exclusive of discounts.
- If present, ListUnitPrice adheres to the following additional requirements:
	- ListUnitPrice MUST be of type Decimal.
	- ListUnitPrice MUST conform to Numeric Format requirements. <-- from here
	- If ChargeCategory is "Tax", ListUnitPrice adheres to the following additional requirement:
		- ListUnitPrice MUST be null.
	- Else if ChargeCategory is "Usage" or "Purchase" and ChargeClass is not "Correction", ListUnitPrice adheres to the following additional requirement:
		- ListUnitPrice MUST NOT be null.
	- Else ListUnitPrice adheres to the following additional requirement:
		- ListUnitPrice MAY be null.
	- If ListUnitPrice is not null, ListUnitPrice adheres to the following additional requirements:
		- ListUnitPrice MUST conform to Numeric Format requirements. <-- to here
		- ListUnitPrice MUST be a non-negative decimal value.
		- ListUnitPrice MUST be denominated in the BillingCurrency.
		- The product of ListUnitPrice and PricingQuantity MUST match the ListCost if PricingQuantity is not null and ChargeClass is not "Correction".
	- Discrepancies in ListUnitPrice, ListCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".


==========================================================================================

Option 2: (proposed)

- ListUnitPrice MUST be present in a FOCUS dataset when the provider publishes unit prices exclusive of discounts.
- ListUnitPrice MUST be of type Decimal.
- ListUnitPrice MUST conform to Numeric Format requirements. <-- from here
- Discrepancies in ListUnitPrice, ListCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".

Across various ChargeCategory values, ListUnitPrice adheres to the following additional requirements:

- When ChargeCategory is "Tax", ListUnitPrice MUST be null.
- When ChargeCategory is "Usage" or "Purchase" and ChargeClass is not "Correction", ListUnitPrice MUST NOT be null.
- In all other cases, ListUnitPrice MAY be null.

When ListUnitPrice is null, ListUnitPrice adheres to the following additional requirements:

- ListUnitPrice MUST conform to Numeric Format requirements. <-- to here
- ListUnitPrice MUST be a non-negative decimal value.
- ListUnitPrice MUST be denominated in the BillingCurrency.
- The product of ListUnitPrice and PricingQuantity MUST match the ListCost if PricingQuantity is not null and ChargeClass is not "Correction".

* SubAccountName MUST be of type String.
* SubAccountName MUST conform to [String Handling](#stringhandling) requirements.
* SubAccountName MUST be null if [SubAccountId](#subaccountid) is null.
* SubAccountName MUST NOT be null if SubAccountId is not null.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* SubAccountName MUST NOT be null if SubAccountId is not null.
* SubAccountName SHOULD NOT be null if SubAccountId is not null.

* SkuId MAY be null in all other cases.
* SkuId MUST equal SkuPriceId when a provider does not support an overarching SKU ID construct.

---

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

* SkuPriceId MUST define a single unit price used for calculating the charge.
* [ListUnitPrice](#listunitprice) MUST be associated with the SkuPriceId in the provider published price list.
* When a provider does not have a SkuPriceId and wants to include information in columns linked to SkuPriceId such as ListUnitPrice or [SkuPriceDetails](#skupricedetails), the SkuId MAY be used in the SkuPriceId column as long as it adheres to the above conditions.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

Comment on lines +21 to +26
* If ChargeCategory is "Purchase", CommitmentDiscountQuantity adheres to the following additional requirements:
* CommitmentDiscountQuantity MUST be the quantity of CommitmentDiscountUnits, paid fully or partially upfront, that is eligible for consumption over the *commitment discount's* *term* if [ChargeFrequency](#chargefrequency) is "One-Time".
* CommitmentDiscountQuantity MUST be the quantity of CommitmentDiscountUnits that is eligible for consumption for each *charge period* that corresponds with the purchase if ChargeFrequency is "Recurring".
* If ChargeCategory is "Usage", CommitmentDiscountQuantity adheres to the following additional requirements:
* CommitmentDiscountQuantity MUST be the metered quantity of CommitmentDiscountUnits that is consumed over the *row's* *charge period* if [CommitmentDiscountStatus](#commitmentdiscountstatus) is "Used".
* CommitmentDiscountQuantity MUST be the remaining, unused quantity of CommitmentDiscountUnits for the *row's* *charge period* if CommitmentDiscountStatus is "Unused".

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the word "positive" was removed from the new description. Was this intentional? I am not sure if it can/should be negative...

* CommitmentDiscountUnit MUST represent the unit used to measure the *commitment discount*.
* When accounting for [*commitment discount flexibility*](#glossary:commitment-discount-flexibility), the CommitmentDiscountUnit value SHOULD reflect this consideration.

---

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

* The product of ContractedUnitPrice and PricingQuantity and MUST match the ContractedCost if ContractedUnitPrice is present and not null, PricingQuantity is not null, and [ChargeClass](#chargeclass) is not "Correction".
* Discrepancies in ContractedCost, ContractedUnitPrice, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".

---

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

* ContractedUnitPrice MUST be denominated in the BillingCurrency.
* The product of ContractedUnitPrice and [PricingQuantity](#pricingquantity) MUST match the [ContractedCost](#contractedcost) if PricingQuantity is not null and ChargeClass is not "Correction".
* Discrepancies in ContractedUnitPrice, ContractedCost, or PricingQuantity MAY be addressed independently if ChargeClass is "Correction".

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

@shawnalpay shawnalpay changed the title FOCUS #557: Preview - Refinement of FOCUS Columns Normative Requirements WI #557: Preview - Refinement of FOCUS Columns Normative Requirements Feb 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.2 Agreed scope for release 1.2
Projects
Status: W.I.P
Development

Successfully merging this pull request may close these issues.

[Work_Item] Refine normative requirements for all existing spec content
10 participants