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

Bugfix/invoice discount consideration #85

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
# dbt_quickbooks v0.9.0
## Bug Fixes
- Added logic to the `int_quickbooks__invoice_double_entry` model to account for invoice discounts as they should be treated as contra revenue accounts that behavior differently from normal sale item detail invoice line items. ([#85](https://github.com/fivetran/dbt_quickbooks/pull/85))

## Additional Features
- Added `department_id` to the `quickbooks__general_ledger` and the upstream tables required for that change. ([#63](https://github.com/fivetran/dbt_quickbooks/pull/63))
- Please note that this field was not added to the downstream `quickbooks__general_ledger_by_period`, `quickbooks__balance_sheet`, `quickbooks__profit_and_loss`, or `quickbooks__cash_flow_statement` models as this would require the grain of these models to be adjusted for the `department_id`. This would likely cause more confusion in the initial output. As such, the field was omitted in the aggregate models to ensure consistency of these models. If you wish this to be included, please open a [Feature Request](https://github.com/fivetran/dbt_quickbooks/issues/new?assignees=&labels=enhancement&template=feature-request.yml&title=%5BFeature%5D+%3Ctitle%3E) to let us know!

## Documentation
- Included documentation [within the DECISIONLOG](https://github.com/fivetran/dbt_quickbooks/blob/main/DECISIONLOG.md) centered around the behavior of how invoice discounts are handled within the `int_quickbooks__invoice_double_entry` model. ([#85](https://github.com/fivetran/dbt_quickbooks/pull/85))

## Under the Hood
- Leveraged the new `detail_type` field to ensure better accuracy when identifying invoice lines that should be accounted for in the general ledger calculations. ([#85](https://github.com/fivetran/dbt_quickbooks/pull/85))
## Contributors
- [@MarcelloMolinaro](https://github.com/MarcelloMolinaro) ([#63](https://github.com/fivetran/dbt_quickbooks/pull/63))

## Complimentary Release Notes
- See the source package [CHANGELOG](https://github.com/fivetran/dbt_quickbooks_source/blob/main/CHANGELOG.md#dbt_quickbooks_source-v080) for updates made to the staging layer in `dbt_quickbooks_source v0.8.0`.

## Contributors
- [@SellJamHere](https://github.com/SellJamHere) ([#60](https://github.com/fivetran/dbt_quickbooks/pull/60))

# dbt_quickbooks v0.8.1

## 🐛 Bug Fixes 🔨
Expand Down
23 changes: 23 additions & 0 deletions DECISIONLOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
# Decision Log
## Invoice Discounts Logic
The `int_quickbooks__invoice_double_entry` model has some unique logic to account for invoice discounts at the invoice line item level. These `DiscountLineDetail` invoice line detail types are handled differently from the normal `SalesItemLineDetail` lines. In the QuickBooks data for invoice lines these entries will not show up as a negative amount, but will instead be shown as a positive value that is to be discounted from the subtotal. As such, we do not want to add these discount lines to the total invoice cost. However, we still want to recognize them in the downstream general ledger models as they are contra revenue accounts that reduce the revenue accounts. Therefore, we need to take a different approach to debit and credit these discounts accordingly.

In particular, to handle these discounts we apply a debit to the `discount_account_id` (provided in the invoice line record) and a credit to the Accounts Receivable account. This is inherently different from the other behaviors of the invoice double entry model and it is handled accordingly with appropriate case when statements within the final cte.

As an example, if we have the following invoice with the relevant line items:
| **invoice_id** | **index** | **amount** | **detail_type** | **account_id** | **discount_account_id** |
| ------------------ | ----------------- | ----------------- | ----------------- | ----------------- | ----------------- |
| 1111 | 0 | 80000 | SalesItemLineDetail | 55 | |
| 1111 | 1 | 32000 | SalesItemLineDetail | 55 | |
| 1111 | 2 | 112000 | SubTotalLineDetail | | |
| 1111 | 3 | 14000 | DiscountLineDetail | | 44 |

The corresponding entry that would result from the `int_quickbooks__invoice_double_entry` model would look like the following:

| **account_id** | **account_name** | **debit** | **credit** |
| ------------------ | ----------------- | ----------------- | ----------------- |
| 1 | accounts receivable | 32000 | |
| 1 | accounts receivable | 80000 | |
| 44 | discount account | 14000 | |
| 1 | accounts receivable | | 14000 |
| 55 | cash account | | 80000 |
| 55 | other cash account | | 32000 |

## QuickBooks Cash Flow Type Logic
- In the `int_quickbooks__cash_flow_classifications` model, our default behavior is to classify the `cash_flow_type` based on the `account_type`, `account_class` or `account_name` fields of the balance sheet line. This logic was based on best available financial practices, with the cash flow being calculated using the indirect method rather than the direct method. Cash flow types usually fall into one of four buckets:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ A small team of analytics engineers at Fivetran develops these dbt packages. How
We highly encourage and welcome contributions to this package. Check out [this dbt Discourse article](https://discourse.getdbt.com/t/contributing-to-a-dbt-package/657) to learn how to contribute to a dbt package!

## Opinionated Modelling Decisions
This dbt package takes an opinionated stance on how to define the ordering and cash flow types in our model based on best financial practices. Customers do have the option to customize these orderings and cash flow types with a seed file. [Instructions are available in the Additional Configuration section](https://github.com/fivetran/dbt_quickbooks/#optional-step-5-additional-configurations). If you would like a deeper explanation of the logic used by default in the dbt package, [you may reference the DECISIONLOG](https://github.com/fivetran/dbt_quickbooks/blob/main/DECISIONLOG.md).
This dbt package takes an opinionated stance on how to define the ordering and cash flow types in our model based on best financial practices. Customers do have the option to customize these orderings and cash flow types with a seed file. [Instructions are available in the Additional Configuration section](https://github.com/fivetran/dbt_quickbooks/#optional-step-5-additional-configurations). If you would like a deeper explanation of the logic used by default or for more insight into certain modeling practices within this dbt package, [you may reference the DECISIONLOG](https://github.com/fivetran/dbt_quickbooks/blob/main/DECISIONLOG.md).
fivetran-avinash marked this conversation as resolved.
Show resolved Hide resolved

# 🏪 Are there any resources available?
- If you have questions or want to reach out for help, please refer to the [GitHub Issue](https://github.com/fivetran/dbt_quickbooks/issues/new/choose) section to find the right avenue of support for you.
Expand Down
2 changes: 1 addition & 1 deletion docs/catalog.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/manifest.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/run_results.json

Large diffs are not rendered by default.

20 changes: 11 additions & 9 deletions integration_tests/seeds/invoice_line_data.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
index,invoice_id,_fivetran_synced,amount,bundle_id,bundle_quantity,description,description_service_date,description_tax_code_id,discount_account_id,discount_class_id,discount_discount_percent,discount_percent_based,discount_tax_code_id,sales_item_account_id,sales_item_class_id,sales_item_discount_amount,sales_item_discount_rate,sales_item_item_id,sales_item_quantity,sales_item_service_date,sales_item_tax_code_id,sales_item_unit_price,sub_total_item_id,item_id,quantity,tax_code_id,account_id
0,35647,2021-01-18 6:16:26,27381.64,211,0.6993497,,,,,,,,,,,,,,,,,,,,,,
5,35647,2021-01-18 6:16:26,24850,,,,,,,,,,,,,,,,,,,,,,,,
2,35647,2021-01-18 6:16:26,0,,,0f9d69329f489637a6ae046f4091e365,,,,,,,,,,,,18,,,NON,,,,,,
4,35647,2021-01-18 6:16:26,0,,,553bf7b55f32b6f7074ae45d987530ce,,,,,,,,,,,,18,,,NON,,,,,,
3,35647,2021-01-18 6:16:26,-4280.01,,,2ae778d8d42424d33b656517b2c892bf,,,,,,,,224,,,,34,0.7,,NON,-6120,,,,,
1,35647,2021-01-18 6:16:26,1748.37,,,,,,,,,,,211,,,,227,0.7,,NON,2500,,,,,
0,40092,2021-01-19 2:18:38,21437.5,212,0.5,,,,,,,,,,,,,,,,,,,,,,
10,40092,2021-01-19 2:18:38,17181.75,,,,,,,,,,,,,,,,,,,,,,,,
index,invoice_id,_fivetran_synced,amount,bundle_id,bundle_quantity,description,description_service_date,description_tax_code_id,discount_account_id,discount_class_id,discount_discount_percent,discount_percent_based,discount_tax_code_id,sales_item_account_id,sales_item_class_id,sales_item_discount_amount,sales_item_discount_rate,sales_item_item_id,sales_item_quantity,sales_item_service_date,sales_item_tax_code_id,sales_item_unit_price,sub_total_item_id,item_id,quantity,tax_code_id,account_id,detail_type
0,35647,2021-01-18 6:16:26,27381.64,211,0.6993497,,,,,,,,,,,,,,,,,,,,,,,SalesItemLineDetail
5,35647,2021-01-18 6:16:26,24850,,,,,,226,,,,,,,,,,,,,,,,,,,DiscountLineDetail
2,35647,2021-01-18 6:16:26,0,,,0f9d69329f489637a6ae046f4091e365,,,,,,,,,,,,18,,,NON,,,,,,,SalesItemLineDetail
4,35647,2021-01-18 6:16:26,0,,,553bf7b55f32b6f7074ae45d987530ce,,,,,,,,,,,,18,,,NON,,,,,,,
3,35647,2021-01-18 6:16:26,-4280.01,,,2ae778d8d42424d33b656517b2c892bf,,,,,,,,224,,,,34,0.7,,NON,-6120,,,,,,
1,35647,2021-01-18 6:16:26,1748.37,,,,,,,,,,,,,,,,,,NON,2500,,,,,,DescriptionOnly
0,40092,2021-01-19 2:18:38,21437.5,212,0.5,,,,,,,,,,,,,,,,,,,,,,,SalesItemLineDetail
10,40092,2021-01-19 2:18:38,17181.75,,,,,,,,,,,,,,,,,,,,,,,,,SubTotalLineDetail
4,40092,2021-01-19 2:18:38,0,,,7f3c88bf068c8edd47367bd68c01cd8f,,,,,,,,,,,,,,,NON,,,,,,,SubTotalLineDetail
7,40092,2021-01-19 2:18:38,0,,,703d01ddc458e55f5b43da8c88aaa581,,,,,,,,,,,,,,,NON,,,,,,,SubTotalLineDetail
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,19 @@ invoice_join as (
end as amount,

{% if var('using_invoice_bundle', True) %}
coalesce(invoice_lines.account_id, items.parent_income_account_id, items.income_account_id, bundle_income_accounts.account_id) as account_id,
case when invoice_lines.detail_type is not null then invoice_lines.detail_type
when coalesce(invoice_lines.account_id, items.parent_income_account_id, items.income_account_id, bundle_income_accounts.account_id) is not null then 'SalesItemLineDetail'
when invoice_lines.discount_account_id is not null then 'DiscountLineDetail'
when coalesce(invoice_lines.account_id, items.parent_income_account_id, items.income_account_id, bundle_income_accounts.account_id, invoice_lines.discount_account_id) is null then 'DescriptionOnly'
end as invoice_line_transaction_type,
coalesce(invoice_lines.account_id, items.parent_income_account_id, items.income_account_id, bundle_income_accounts.account_id, invoice_lines.discount_account_id) as account_id,
{% else %}
coalesce(invoice_lines.account_id, items.income_account_id) as account_id,
case when invoice_lines.detail_type is not null then invoice_lines.detail_type
Copy link
Contributor

Choose a reason for hiding this comment

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

Quick clarifying question: The when clause was changed because detail_type will have the SubTotalLineDetail? What does DescriptionOnly refer to, an invoice line item ro wwhere there's an amount but no id associated with it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exactly!

when coalesce(invoice_lines.account_id, items.parent_income_account_id, items.income_account_id) is not null then 'SalesItemLineDetail'
when invoice_lines.discount_account_id is not null then 'DiscountLineDetail'
when coalesce(invoice_lines.account_id, items.parent_income_account_id, items.income_account_id, invoice_lines.discount_account_id) is null then 'DescriptionOnly'
end as invoice_line_transaction_type,
coalesce(invoice_lines.account_id, items.income_account_id, invoice_lines.discount_account_id) as account_id,
{% endif %}

coalesce(invoice_lines.sales_item_class_id, invoice_lines.discount_class_id, invoices.class_id) as class_id,
Expand All @@ -128,20 +138,21 @@ invoice_join as (
left join bundle_income_accounts
on bundle_income_accounts.bundle_id = invoice_lines.bundle_id
and bundle_income_accounts.source_relation = invoice_lines.source_relation
{% endif %}
),

where coalesce(invoice_lines.account_id, invoice_lines.sales_item_account_id, invoice_lines.sales_item_item_id, invoice_lines.item_id, bundle_income_accounts.account_id) is not null

{% else %}
where coalesce(invoice_lines.account_id, invoice_lines.sales_item_account_id, invoice_lines.sales_item_item_id, invoice_lines.item_id) is not null
invoice_filter as (

{% endif %}
select *
fivetran-avinash marked this conversation as resolved.
Show resolved Hide resolved
from invoice_join
where invoice_line_transaction_type not in ('SubTotalLineDetail','DescriptionOnly')
),

final as (

select
transaction_id,
invoice_join.source_relation,
invoice_filter.source_relation,
index,
transaction_date,
customer_id,
Expand All @@ -150,15 +161,19 @@ final as (
account_id,
class_id,
department_id,
'credit' as transaction_type,
'invoice' as transaction_source
from invoice_join
case when invoice_line_transaction_type = 'DiscountLineDetail' then 'debit'
fivetran-avinash marked this conversation as resolved.
Show resolved Hide resolved
else 'credit'
end as transaction_type,
case when invoice_line_transaction_type = 'DiscountLineDetail' then 'invoice discount'
else 'invoice'
end as transaction_source
from invoice_filter

union all

select
transaction_id,
invoice_join.source_relation,
invoice_filter.source_relation,
index,
transaction_date,
customer_id,
Expand All @@ -167,9 +182,13 @@ final as (
ar_accounts.account_id,
class_id,
department_id,
'debit' as transaction_type,
'invoice' as transaction_source
from invoice_join
case when invoice_line_transaction_type = 'DiscountLineDetail' then 'credit'
else 'debit'
end as transaction_type,
case when invoice_line_transaction_type = 'DiscountLineDetail' then 'invoice discount'
else 'invoice'
end as transaction_source
from invoice_filter

cross join ar_accounts
)
Expand Down
1 change: 1 addition & 0 deletions packages.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
packages:
# - package: fivetran/quickbooks_source
Copy link
Contributor

Choose a reason for hiding this comment

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

standard revert packages message

# version: [">=0.8.0", "<0.9.0"]

- git: https://github.com/fivetran/dbt_quickbooks_source.git
revision: release/v0.8.0
warn-unpinned: false