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

Feature: Multicurrency support (plus some bug fixes for double entry models) #134

Merged
merged 19 commits into from
Jul 22, 2024
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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,6 @@ body:
description: Our team will assess this issue and let you know if we will add it to a future sprint. However, if you would like to expedite the solution, we encourage you to contribute to the package via a PR. Our team will then work with you to approve and merge your contributions as soon as possible.
options:
- label: Yes.
- label: Yes, but I will need assistance and will schedule time during our [office hours](https://calendly.com/fivetran-solutions-team/fivetran-solutions-team-office-hours) for guidance
- label: Yes, but I will probably need assistance.
- label: No.
required: false
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/feature-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ body:
label: Are you interested in contributing this feature?
description: Our team will assess this feature and let you know if we will add it to a future sprint. However, if you would like to expedite the feature, we encourage you to contribute to the package via a PR. Our team will then work with you to approve and merge your contributions as soon as possible.
options:
- label: Yes.
- label: Yes, but I will need assistance and will schedule time during your [office hours](https://calendly.com/fivetran-solutions-team/fivetran-solutions-team-office-hours) for guidance.
- label: Yes.
- label: Yes, but I will probably need assistance.
- label: No.
required: false
- type: textarea
Expand Down
40 changes: 35 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
# dbt_quickbooks v0.X.X RELEASE TO BE ANNOUNCED
# dbt_quickbooks v0.14.0
New major feature alert! Multicurrency is here!

This pull request includes the following updates:
## Bug Fix
## 🚨 Breaking Changes 🚨
fivetran-joemarkiewicz marked this conversation as resolved.
Show resolved Hide resolved
### Feature Updates: Multicurrency Support
- We have introduced multicurrency support to the following models by providing these new fields that convert transaction amounts by their exchange rates. ([PR #134](https://github.com/fivetran/dbt_quickbooks/pull/134))
- **IMPORTANT**: We do not yet have proper `converted_amount` values for credit card payments and transfers. Currently it is being brought in as the equivalent of `amount`, so you might see slight discrepancies if need these values converted as well. [Please open an issue with us](https://github.com/fivetran/dbt_quickbooks/issues/new/choose) to help work with us to support this feature.
- We have kept the existing cash value fields that provides amounts and balances to ensure full coverage to customers regardless of their currency setup. ([PR #134](https://github.com/fivetran/dbt_quickbooks/pull/134))
- The new multicurrency fields that fulfill the same function as the respective existing fields is below:

<!--section="new_multicurrency_fields_map"-->

| **Model** | **New Multicurrency Fields** | **Respective Single Currency Fields** |
| ------------------------ | ------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| [quickbooks__general_ledger](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__general_ledger) | `adjusted_converted_amount`, `running_converted_balance` | `adjusted_amount`, `running_balance` |
|[quickbooks__general_ledger_by_period](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__general_ledger_by_period) | `period_net_converted_change`, `period_beginning_converted_balance`, `period_ending_converted_balance` | `period_net_change`, `period_beginning_balance`, `period_ending_balance` |
| [quickbooks__profit_and_loss](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__profit_and_loss) | `converted_amount` | `amount` |
| [quickbooks__balance_sheet](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__balance_sheet) | `converted_amount` | `amount` |
| [quickbooks__cash_flow_statement](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__cash_flow_statement) | `cash_converted_ending_period`, `cash_converted_beginning_period`, `cash_converted_net_period` | `cash_ending_period`, `cash_beginning_period`, `cash_net_period` |
| [quickbooks__ap_ar_enhanced](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__ap_ar_enhanced) | `total_converted_amount`, `estimate_total_converted_amount`, `total_current_converted_payment` | `total_amount`, `estimate_total_amount`, `total_current_payment` |
| [quickbooks__expenses_sales_enhanced](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__expenses_sales_enhanced) | `total_converted_amount`, `converted_amount` | `total_amount`, `amount` |
<!--section-end-->

- Introduced `*_converted_*` type fields in our intermediate models to convert amounts where exchange rates exist for those transactions. If there is no exchange rate, these `*_converted_*` fields will default back to the already existing fields created for single currency, and all downstream calculations should match the single currency amount, balance and cash values. ([PR #134](https://github.com/fivetran/dbt_quickbooks/pull/134))
- For double-entry models that applied a cross-join to either AP/AR accounts, we are now mapping those accounts based on the `currency_id` value in the `accounts` source table for those transactions. ([PR #134](https://github.com/fivetran/dbt_quickbooks/pull/134))
- In the `analysis` folder, added the `converted_balance` to the `quickbooks__balance_sheet` and `ending_converted_balance` to the `quickbooks__income_statement` models. ([PR #134](https://github.com/fivetran/dbt_quickbooks/pull/134))

## Bug Fixes
- Adjusted logic for discount sales receipt lines in `int_quickbooks__sales_receipt_double_entry` model to bring in these values properly as negative adjusted amounts in the `quickbooks__general_ledger`.
[PR #130](https://github.com/fivetran/dbt_quickbooks/pull/130)
([PR #130](https://github.com/fivetran/dbt_quickbooks/pull/130))
- Applied filter in `int_quickbooks__invoice_double_entry` to filter out 'Accounts Receivable' accounts that are inactive. ([PR #134](https://github.com/fivetran/dbt_quickbooks/pull/134))

## Under the Hood
- Added consistency tests within integration tests for the `quickbooks__general_ledger` model.
- Added consistency and integrity tests within integration tests for all end models. ([PR #130](https://github.com/fivetran/dbt_quickbooks/pull/130)) & ([PR 134](https://github.com/fivetran/dbt_quickbooks/pull/134))
- Appended `using_credit_card_payment_txn` check in `get_enabled_unioned_models` macro to `false` to match consistency of how the variable is defined throughout our Quickbooks models by default.

## Documentation Update
- Updated README to [reflect the new multicurrency support](https://github.com/fivetran/dbt_quickbooks?tab=readme-ov-file#multicurrency-vs-single-currency-configuration). ([PR #134](https://github.com/fivetran/dbt_quickbooks/pull/134))
- Added yml documentation with the new multicurrency fields and descriptions. ([PR #134](https://github.com/fivetran/dbt_quickbooks/pull/134))

## Contributors
- [@mikerenderco](https://github.com/mikerenderco) ([PR #131](https://github.com/fivetran/dbt_quickbooks/pull/131))
Expand Down
19 changes: 19 additions & 0 deletions DECISIONLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,22 @@ The corresponding entry that would result from the `int_quickbooks__invoice_doub
- Cash basis, which records revenue and expenses when cash related to transactions actually is received or dispensed.
- For our initial build of `quickbooks__profit_and_loss`, `quickbooks__general_ledger_by_period`, and `quickbooks__balance_sheet`, we used the accrual accounting method rather than cash, as it is approved by GAAP (generally accepted accounting principles). Accrual accounting requires companies match revenues with expenses incurred to generate them.
- If you'd like models that rely on the cash basis accounting, [please comment on this feature and we can prioritize it for future development](https://github.com/fivetran/dbt_quickbooks/issues/111).

## Multicurrency vs. Single Currency Configuration
We introduced multicurrency support in our v0.14.0 release. We introduced new fields to allow you the ability to pick and choose which amount, balance, and cash fields provide the most value to your end models.

These fields will be in the `*_converted_*` format of the original single currency amount/balance/cash fields. If you are single currency customer, you should still leverage the original version of the fields

There are still some limitations [for multicurrency support](https://github.com/fivetran/dbt_quickbooks/blob/main/README.md#multicurrency-support-and-existing-limitations), particularly with regards to calculating credit card payment and transfer currency converted amounts. [Please open an issue with us if this is critical to resolve](https://github.com/fivetran/dbt_quickbooks/issues/new/choose), especially if you think you can help contribute based on your knowledge of the Quickbooks data models.

Please leverage the below fields in your end models for your financial statements depending on what your currency configuration looks like.

| **Model** | **Multicurrency Fields** | **Single Currency Fields** |
| ------------------------ | ------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| [quickbooks__general_ledger](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__general_ledger) | `adjusted_converted_amount`, `running_converted_balance` | `adjusted_amount`, `running_balance` |
|[quickbooks__general_ledger_by_period](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__general_ledger_by_period) | `period_net_converted_change`, `period_beginning_converted_balance`, `period_ending_converted_balance` | `period_net_change`, `period_beginning_balance`, `period_ending_balance` |
| [quickbooks__profit_and_loss](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__profit_and_loss) | `converted_amount` | `amount` |
| [quickbooks__balance_sheet](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__balance_sheet) | `converted_amount` | `amount` |
| [quickbooks__cash_flow_statement](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__cash_flow_statement) | `cash_converted_ending_period`, `cash_converted_beginning_period`, `cash_converted_net_period` | `cash_ending_period`, `cash_beginning_period`, `cash_net_period` |
| [quickbooks__ap_ar_enhanced](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__ap_ar_enhanced) | `total_converted_amount`, `estimate_total_converted_amount`, `total_current_converted_payment` | `total_amount`, `estimate_total_amount`, `total_current_payment` |
| [quickbooks__expenses_sales_enhanced](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__expenses_sales_enhanced) | `total_converted_amount`, `converted_amount` | `total_amount`, `amount` |
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ The following table provides a detailed list of all models materialized within t
| [quickbooks__expenses_sales_enhanced](https://fivetran.github.io/dbt_quickbooks/#!/model/model.quickbooks.quickbooks__expenses_sales_enhanced) | Table providing enhanced customer, vendor, and account details for each expense and sale transaction. |
<!--section-end-->

## Currency Package Compatibility
## Multicurrency Support (And Existing Limitations)

> Please be aware that the [dbt_quickbooks](https://github.com/fivetran/dbt_quickbooks) and [dbt_quickbooks_source](https://github.com/fivetran/dbt_quickbooks_source) packages were developed with single currency company data. As such, the package models will not reflect accurate totals if your QuickBooks account has Multi-Currency enabled.
> [dbt_quickbooks](https://github.com/fivetran/dbt_quickbooks) and [dbt_quickbooks_source](https://github.com/fivetran/dbt_quickbooks_source) now supports multicurrency by bringing in values by specifying `*_converted_*` values for cash amounts. More details are [available in the DECISIONLOG](https://github.com/fivetran/dbt_quickbooks/blob/main/DECISIONLOG.md#multicurrency-vs-single-currency-configuration).

There are specific limitations if you need converted amounts for credit card payments and transfers, as we do not currently have the ability to validate a best approach to convert the original amounts into their proper home currency. [Please open an issue with us](https://github.com/fivetran/dbt_quickbooks/issues/new/choose) if this is critical and/or you believe you can help contribute to scoping out adding that functionality in.

# 🎯 How do I use the dbt package?
## Step 1: Prerequisites
Expand All @@ -71,7 +73,7 @@ Include the following QuickBooks package version in your `packages.yml` file.
```yaml
packages:
- package: fivetran/quickbooks
version: [">=0.13.0", "<0.14.0"] # we recommend using ranges to capture non-breaking changes automatically
version: [">=0.14.0", "<0.15.0"] # we recommend using ranges to capture non-breaking changes automatically
```

Do NOT include the `quickbooks_source` package in this file. The transformation package itself has a dependency on it and will install the source package as well.
Expand Down Expand Up @@ -252,4 +254,3 @@ This dbt package takes an opinionated stance on how to define the ordering and c
# 🏪 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.
- If you would like to provide feedback to the dbt package team at Fivetran or would like to request a new dbt package, fill out our [Feedback Form](https://www.surveymonkey.com/r/DQ7K7WW).
- Have questions or want to be part of the community discourse? Create a post in the [Fivetran community](https://community.fivetran.com/t5/user-group-for-dbt/gh-p/dbt-user-group) and our team along with the community can join in on the discussion!
28 changes: 19 additions & 9 deletions analysis/quickbooks__balance_sheet.sql
Original file line number Diff line number Diff line change
Expand Up @@ -43,51 +43,61 @@ equity_date as (
liability as (
select
ld.account_id,
l.period_ending_balance
l.period_ending_balance,
l.period_ending_converted_balance
from liability_date ld

left join (select account_id, source_relation, period_first_day, period_ending_balance from general_ledger_by_period where account_class = 'Liability') l
left join (select account_id, source_relation, period_first_day, period_ending_balance, period_ending_converted_balance from general_ledger_by_period where account_class = 'Liability') l
on l.account_id = ld.account_id
and l.period_first_day = ld.period_first_day
and l.source_relation = ld.source_relation
),

asset as (
select ad.account_id, a.period_ending_balance
select
ad.account_id,
a.period_ending_balance,
a.period_ending_converted_balance
from asset_date ad
left join (select account_id, source_relation, period_first_day, period_ending_balance from general_ledger_by_period where account_class = 'Asset') a
left join (select account_id, source_relation, period_first_day, period_ending_balance, period_ending_converted_balance from general_ledger_by_period where account_class = 'Asset') a
on a.account_id = ad.account_id
and a.period_first_day = ad.period_first_day
and a.source_relation = ad.source_relation
),

equity as (
select ed.account_id, e.period_ending_balance
select
ed.account_id,
e.period_ending_balance,
e.period_ending_converted_balance
from equity_date ed
left join (select account_id, source_relation, period_first_day, period_ending_balance from general_ledger_by_period where account_class = 'Equity') e
left join (select account_id, source_relation, period_first_day, period_ending_balance, period_ending_converted_balance from general_ledger_by_period where account_class = 'Equity') e
on e.account_id = ed.account_id
and e.period_first_day = ed.period_first_day
and e.source_relation = ed.source_relation
)

select
'liability' as balance_sheet_type,
sum(period_ending_balance) as balance
sum(period_ending_balance) as balance,
sum(period_ending_converted_balance) as converted_balance
from liability
group by 1

union all

select
'asset' as balance_sheet_type,
sum(period_ending_balance) as balance
sum(period_ending_balance) as balance,
sum(period_ending_converted_balance) as converted_balance
from asset
group by 1

union all

select
'equity' as balance_sheet_type,
sum(period_ending_balance) as balance
sum(period_ending_balance) as balance,
sum(period_ending_converted_balance) as converted_balance
from equity
group by 1
14 changes: 9 additions & 5 deletions analysis/quickbooks__income_statement.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ with general_ledger_by_period as (
revenue as (
select
account_id,
sum(period_net_change) as ending_balance
sum(period_net_change) as ending_balance,
sum(period_net_converted_change) as ending_converted_balance
from general_ledger_by_period

where account_class = 'Revenue'
Expand All @@ -18,7 +19,8 @@ revenue as (
expense as (
select
account_id,
sum(period_net_change) as ending_balance
sum(period_net_change) as ending_balance,
sum(period_net_converted_change) as ending_converted_balance
from general_ledger_by_period

where account_class = 'Expense'
Expand All @@ -30,14 +32,16 @@ expense as (
revenue_total as (
select
'revenue' as income_statement_type,
sum(ending_balance)
sum(ending_balance) as ending_balance,
sum(ending_converted_balance) as ending_converted_balance
from revenue
),

expense_total as (
select
'expene' as income_statement_type,
sum(ending_balance)
'expense' as income_statement_type,
sum(ending_balance) as ending_balance,
sum(ending_converted_balance) as ending_converted_balance
from expense
)

Expand Down
2 changes: 1 addition & 1 deletion dbt_project.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
config-version: 2
name: 'quickbooks'

version: '0.13.1'
version: '0.14.0'

require-dbt-version: [">=1.3.0", "<2.0.0"]

Expand Down
2 changes: 1 addition & 1 deletion docs/catalog.json

Large diffs are not rendered by default.

37 changes: 32 additions & 5 deletions docs/index.html

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.

10 changes: 5 additions & 5 deletions integration_tests/ci/sample.profiles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ integration_tests:
pass: "{{ env_var('CI_REDSHIFT_DBT_PASS') }}"
dbname: "{{ env_var('CI_REDSHIFT_DBT_DBNAME') }}"
port: 5439
schema: quickbooks_integration_tests_07
schema: quickbooks_integration_tests_12
threads: 8
bigquery:
type: bigquery
method: service-account-json
project: 'dbt-package-testing'
schema: quickbooks_integration_tests_07
schema: quickbooks_integration_tests_12
threads: 8
keyfile_json: "{{ env_var('GCLOUD_SERVICE_KEY') | as_native }}"
snowflake:
Expand All @@ -33,7 +33,7 @@ integration_tests:
role: "{{ env_var('CI_SNOWFLAKE_DBT_ROLE') }}"
database: "{{ env_var('CI_SNOWFLAKE_DBT_DATABASE') }}"
warehouse: "{{ env_var('CI_SNOWFLAKE_DBT_WAREHOUSE') }}"
schema: quickbooks_integration_tests_07
schema: quickbooks_integration_tests_12
threads: 8
postgres:
type: postgres
Expand All @@ -42,13 +42,13 @@ integration_tests:
pass: "{{ env_var('CI_POSTGRES_DBT_PASS') }}"
dbname: "{{ env_var('CI_POSTGRES_DBT_DBNAME') }}"
port: 5432
schema: quickbooks_integration_tests_07
schema: quickbooks_integration_tests_12
threads: 8
databricks:
catalog: "{{ env_var('CI_DATABRICKS_DBT_CATALOG') }}"
host: "{{ env_var('CI_DATABRICKS_DBT_HOST') }}"
http_path: "{{ env_var('CI_DATABRICKS_DBT_HTTP_PATH') }}"
schema: quickbooks_integration_tests_07
schema: quickbooks_integration_tests_12
threads: 8
token: "{{ env_var('CI_DATABRICKS_DBT_TOKEN') }}"
type: databricks
Loading