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

line item enhanced updates #98

Merged
merged 11 commits into from
Dec 10, 2024
Merged

Conversation

fivetran-avinash
Copy link
Contributor

@fivetran-avinash fivetran-avinash commented Nov 6, 2024

PR Overview

This PR will address the following Issue/Feature: [#93]

This PR will result in the following new package version: 0.15.1

No schema changes--we are modifying the logic significantly to correct for bug issues, but this is in a good spot.

Please provide the finalized CHANGELOG entry which details the relevant changes included in this PR:

  • Updated the logic in stripe__line_item_enhanced to properly bring in refund data by adjusting the joins on balance transactions, refunds and charges.
    • Since charges and refunds are both types of balance transactions, included an additional join between refunds and balance transactions to bring in refunds at the same level as charges.
    • Fixed fee_amount logic to sum together charge and refund amounts.
    • Updated transaction_type logic to not only bring in refund, but return charge+refund if the balance transaction has a charge and a refund associated with it.
    • Updated conditional logic for invoice-only records to bring in only non-zero rather than not null fee_amounts, as summing charge and refund amounts together brings in only not null fee_amount values.

Under the Hood

  • Modified the consistency tests to better compare differences between production and development rows.

PR Checklist

Basic Validation

Please acknowledge that you have successfully performed the following commands locally:

  • dbt run –full-refresh && dbt test
  • [NA] dbt run (if incremental models are present) && dbt test

Before marking this PR as "ready for review" the following have been applied:

  • The appropriate issue has been linked, tagged, and properly assigned
  • All necessary documentation and version upgrades have been applied
  • docs were regenerated (unless this PR does not include any code or yml updates)
  • BuildKite integration tests are passing
  • Detailed validation steps have been provided below

Detailed Validation

Please share any and all of your validation steps:

Was able to pass through refund amounts to the dev models, which were previously not populating because of the join on balance transactions.

All validation tests passed, with exclusions on the consistency_line_item_enhanced model on the tables who saw their underlying logic changed (fee_amount, and transaction_type) or had the join changed to bring in not null data (refund_amount).

Screenshot 2024-11-26 at 3 10 44 AM

If you had to summarize this PR in an emoji, which would it be?

⌨️

@fivetran-avinash fivetran-avinash self-assigned this Nov 26, 2024
@fivetran-avinash fivetran-avinash marked this pull request as ready for review November 26, 2024 12:15
Copy link
Contributor

@fivetran-jamie fivetran-jamie left a comment

Choose a reason for hiding this comment

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

looks pretty good but left some questions and suggestions!

CHANGELOG.md Outdated
- Since charges and refunds are both types of balance transactions, included an additional join between refunds and balance transactions to bring in refunds at the same level as charges.
- Fixed `fee_amount` logic to sum together charge and refund amounts.
- Updated `transaction_type` logic to not only bring in `refund`, but return `charge+refund` if the balance transaction has a charge and a refund associated with it.
- Updated conditional logic for invoice-only records to bring in only non-zero rather than not null `fee_amounts`, as summing charge and refund amounts together brings in only not null `fee_amount` values.
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
- Updated conditional logic for invoice-only records to bring in only non-zero rather than not null `fee_amounts`, as summing charge and refund amounts together brings in only not null `fee_amount` values.
- Updated conditional logic for invoice-only records to bring in only non-zero rather than not null `fee_amount`, as summing charge and refund amounts together brings in only not null `fee_amount` values.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is the update about the filter or about us coalescing fee_amount with 0 now for non-header rows?

Copy link
Contributor Author

@fivetran-avinash fivetran-avinash Nov 26, 2024

Choose a reason for hiding this comment

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

Both. Before it was possible for fee_amount to be null because of the left join. Because we are summing, summing a null with a not null would make the value null, which is not what we would want. So I coalesced to zero, meaning it could only be zero or not zero, so the filter had to change too.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, then I would make it clearer that we added a coalesce with 0 for non-header rows before getting into this filter logic

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, cleaned up the CHANGELOG.

CHANGELOG.md Outdated
- Updated the logic in `stripe__line_item_enhanced` to properly bring in refund data by adjusting the joins on balance transactions, refunds and charges.
- Since charges and refunds are both types of balance transactions, included an additional join between refunds and balance transactions to bring in refunds at the same level as charges.
- Fixed `fee_amount` logic to sum together charge and refund amounts.
- Updated `transaction_type` logic to not only bring in `refund`, but return `charge+refund` if the balance transaction has a charge and a refund associated with it.
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
- Updated `transaction_type` logic to not only bring in `refund`, but return `charge+refund` if the balance transaction has a charge and a refund associated with it.
- Updated `transaction_type` logic to not only bring in `charge`, but also return `charge + refund` if the balance transaction has a charge and a refund associated with it.

Unless we also want to return refund?

Copy link
Contributor Author

@fivetran-avinash fivetran-avinash Nov 26, 2024

Choose a reason for hiding this comment

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

Fixed.

I don't believe a refund can exist in Stripe without a charge so for now won't add refund in (documentation)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding payment intent + refund as a transaction type based on Jamie's research.

models/standardized_models/stripe__line_item_enhanced.sql Outdated Show resolved Hide resolved
Comment on lines 182 to 183
on bt_charge.connected_account_id = connected_account.account_id
and bt_charge.source_relation = connected_account.source_relation
Copy link
Contributor

Choose a reason for hiding this comment

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

I am wondering if the adding the following would offer more coverage:

Suggested change
on bt_charge.connected_account_id = connected_account.account_id
and bt_charge.source_relation = connected_account.source_relation
on coalesce(bt_charge.connected_account_id, bt_refund.connected_account_id) = connected_account.account_id
and coalesce(bt_charge.source_relation, bt_refund.source_relation) = connected_account.source_relation

Copy link
Contributor Author

@fivetran-avinash fivetran-avinash Nov 26, 2024

Choose a reason for hiding this comment

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

Wouldn't they be the same value? bt_charge and bt_refund are both from the balance_transaction source, so the connected_account_id values would be the same.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah but their join conditions are different -- bt_charge joins with the charge table and bt_refund joins with the refund table. So there could be cases where one is null and the other is not, right? It sounds like a refund can exist without a charge if it is associated with a payment intent instead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This makes sense, went ahead and added.

@@ -33,7 +33,7 @@ models:
- name: product_type
description: Product type
- name: transaction_type
description: Balance transaction type
description: Balance transaction type. If refunds and charges are tied to one invoice, it's designated as 'refund+charge'.
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
description: Balance transaction type. If refunds and charges are tied to one invoice, it's designated as 'refund+charge'.
description: Balance transaction type. If refunds and charges are tied to one invoice, it's designated as 'charge + refund'.

Should we include the other type(s) as well?

Copy link
Contributor Author

@fivetran-avinash fivetran-avinash Nov 26, 2024

Choose a reason for hiding this comment

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

Good call. Added!

Copy link
Contributor Author

@fivetran-avinash fivetran-avinash left a comment

Choose a reason for hiding this comment

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

@fivetran-jamie Ready for re-review! Let me know your thoughts on the refund/charge situation. I'm fairly certain a refund must have a charge tied to it, but I can also add in the logic if we feel it's best.

@fivetran-avinash
Copy link
Contributor Author

@fivetran-jamie Addressed your follow up comments, should be ready for re-review now!

Copy link
Contributor

@fivetran-jamie fivetran-jamie left a comment

Choose a reason for hiding this comment

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

LGTM! just one suggestion to make a changelog note clearer, consider this approved

CHANGELOG.md Outdated
- Since charges and refunds are both types of balance transactions, included an additional join between refunds and balance transactions to bring in refunds at the same level as charges.
- Updated balance transactions join on `connected_account_id` and `source_relation` to look at both charge and refund balance transactions.
- Fixed `fee_amount` logic to sum together charge and refund amounts.
- Updated conditional logic for invoice-only records to ensure `fee_amount` is not null by coalescing to zero for summing non-header rows.
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
- Updated conditional logic for invoice-only records to ensure `fee_amount` is not null by coalescing to zero for summing non-header rows.
- Coalesced `fee_amount` with zero for invoice-only (non-header) rows and updated downstream summing logic accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yeah that's much clearer. Thanks @fivetran-jamie !

Copy link
Contributor

@fivetran-joemarkiewicz fivetran-joemarkiewicz left a comment

Choose a reason for hiding this comment

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

@fivetran-avinash a few comments on this PR before release approval

when bt_refund.balance_transaction_id is not null and bt_charge.balance_transaction_id is not null then 'charge + refund'
when bt_charge.balance_transaction_id is not null then 'charge'
when bt_refund.balance_transaction_id is not null then 'payment intent + refund'
else null
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason we default to null here? Should we default to the base balance_transaction.type field?

Copy link
Contributor

Choose a reason for hiding this comment

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

Especially since I see there are other "types" of transaction_types listed in our data and I'm unsure if null is entirely accurate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, updated. I was hesitant to do this since we are technically only joining in on charge and refund, but I think it makes sense that we should bring in whatever transaction type is associated with a line item.

@@ -123,7 +129,7 @@ with invoice_line_item as (
cast(payment_method.payment_method_id as {{ dbt.type_string() }}) as payment_method_id,
cast(payment_method.type as {{ dbt.type_string() }}) as payment_method,
cast(charge.created_at as {{ dbt.type_timestamp() }}) as payment_at,
cast(balance_transaction.fee as {{ dbt.type_numeric() }}) as fee_amount,
cast(coalesce(bt_charge.fee, 0) as {{ dbt.type_numeric() }}) + cast(coalesce(bt_refund.fee, 0) as {{ dbt.type_numeric() }}) as fee_amount,
Copy link
Contributor

Choose a reason for hiding this comment

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

Just want to confirm here. Is there any case where the signs of a charge.fee and a refund.fee would be different (i.e. a charge fee is positive and a refund fee is negative)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Checking our internal data, a refund fee is always negative (or 0) in our internal data as it's returning fees that are not longer being incurred. Whereas a charge fee will always be positive.

I think the logic makes sense, since deducting refund fees will give us how much fees are actually being incurred on the line item. But open to changing this if we think there are reasons they should be accumulated differently (or creating a new column, and delineating between charge and refund fees).

Copy link
Contributor

Choose a reason for hiding this comment

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

(or creating a new column, and delineating between charge and refund fees).

Unfortunately with this model we can't take the approach to add or remove columns since this is required to be the same schema for all *__line_item_enhanced models in the other platforms (Zuora, Recharge, Recurly, Shopify). If we add a new column here then we will need to add the same column in the other platforms which may not work for their use cases.

Thanks for the explanation here. This sounds appropriate to keep as is.

Copy link
Contributor Author

@fivetran-avinash fivetran-avinash left a comment

Choose a reason for hiding this comment

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

@fivetran-joemarkiewicz Sorry I realized I never submitted this. This is ready for re-review.

Copy link
Contributor

@fivetran-joemarkiewicz fivetran-joemarkiewicz left a comment

Choose a reason for hiding this comment

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

Thanks for addressing all my review notes. This looks good for release on Monday!

@@ -123,7 +129,7 @@ with invoice_line_item as (
cast(payment_method.payment_method_id as {{ dbt.type_string() }}) as payment_method_id,
cast(payment_method.type as {{ dbt.type_string() }}) as payment_method,
cast(charge.created_at as {{ dbt.type_timestamp() }}) as payment_at,
cast(balance_transaction.fee as {{ dbt.type_numeric() }}) as fee_amount,
cast(coalesce(bt_charge.fee, 0) as {{ dbt.type_numeric() }}) + cast(coalesce(bt_refund.fee, 0) as {{ dbt.type_numeric() }}) as fee_amount,
Copy link
Contributor

Choose a reason for hiding this comment

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

(or creating a new column, and delineating between charge and refund fees).

Unfortunately with this model we can't take the approach to add or remove columns since this is required to be the same schema for all *__line_item_enhanced models in the other platforms (Zuora, Recharge, Recurly, Shopify). If we add a new column here then we will need to add the same column in the other platforms which may not work for their use cases.

Thanks for the explanation here. This sounds appropriate to keep as is.

@fivetran-avinash fivetran-avinash merged commit 17222c8 into main Dec 10, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants