mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-22 06:39:39 +02:00
feat(import): add currency and number format support for CSV imports (#1819)
* feat(import): add currency and number format support for CSV imports * feat(import): add currency and format for mint and trade * fix(imports): remove currency field in favor of currency csv col * fix(imports): remove validate column from import model * test(import): add some tests for imports * test(import): add some tests for generate_rows_from_csv * fix: change method name for import model * fix: change before validation --------- Co-authored-by: danestves <danestves@users.noreply.github.com>
This commit is contained in:
parent
9e5f1574bc
commit
077694bbde
9 changed files with 307 additions and 13 deletions
|
@ -54,4 +54,233 @@ module ImportInterfaceTest
|
|||
assert_equal "Failed to publish", import.error
|
||||
assert_equal "failed", import.status
|
||||
end
|
||||
|
||||
test "parses US/UK number format correctly" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
number_format: "1,234.56",
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
|
||||
csv_data = "date,amount,name\n01/01/2024,\"1,234.56\",Test"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "1234.56", row.amount
|
||||
end
|
||||
|
||||
test "parses European number format correctly" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
number_format: "1.234,56",
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
|
||||
csv_data = "date,amount,name\n01/01/2024,\"1.234,56\",Test"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "1234.56", row.amount
|
||||
end
|
||||
|
||||
test "parses French/Scandinavian number format correctly" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
number_format: "1 234,56",
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
|
||||
# Quote the amount field to ensure proper CSV parsing
|
||||
csv_data = "date,amount,name\n01/01/2024,\"1 234,56\",Test"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "1234.56", row.amount
|
||||
end
|
||||
|
||||
test "parses zero-decimal currency format correctly" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
number_format: "1,234",
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
|
||||
csv_data = "date,amount,name\n01/01/2024,1234,Test"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "1234", row.amount
|
||||
end
|
||||
|
||||
test "currency from CSV takes precedence over default" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
currency_col_label: "currency",
|
||||
number_format: "1,234.56",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
import.family.update!(currency: "USD")
|
||||
|
||||
csv_data = "date,amount,name,currency\n01/01/2024,123.45,Test,EUR"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "EUR", row.currency
|
||||
end
|
||||
|
||||
test "uses default currency when CSV currency column is empty" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
currency_col_label: "currency",
|
||||
number_format: "1,234.56",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
import.family.update!(currency: "USD")
|
||||
|
||||
csv_data = "date,amount,name,currency\n01/01/2024,123.45,Test,"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "USD", row.currency
|
||||
end
|
||||
|
||||
test "uses default currency when CSV has no currency column" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
number_format: "1,234.56",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
import.family.update!(currency: "USD")
|
||||
|
||||
csv_data = "date,amount,name\n01/01/2024,123.45,Test"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "USD", row.currency
|
||||
end
|
||||
|
||||
test "generates rows with all optional fields" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
account_col_label: "account",
|
||||
category_col_label: "category",
|
||||
tags_col_label: "tags",
|
||||
notes_col_label: "notes",
|
||||
currency_col_label: "currency",
|
||||
number_format: "1,234.56",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
|
||||
csv_data = "date,amount,name,account,category,tags,notes,currency\n" \
|
||||
"01/01/2024,1234.56,Salary,Bank Account,Income,\"monthly,salary\",Salary payment,EUR"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "01/01/2024", row.date
|
||||
assert_equal "1234.56", row.amount
|
||||
assert_equal "Salary", row.name
|
||||
assert_equal "Bank Account", row.account
|
||||
assert_equal "Income", row.category
|
||||
assert_equal "monthly,salary", row.tags
|
||||
assert_equal "Salary payment", row.notes
|
||||
assert_equal "EUR", row.currency
|
||||
end
|
||||
|
||||
test "generates rows with minimal required fields" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
number_format: "1,234.56",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
|
||||
csv_data = "date,amount\n01/01/2024,1234.56"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "01/01/2024", row.date
|
||||
assert_equal "1234.56", row.amount
|
||||
assert_equal "Imported item", row.name # Default name
|
||||
assert_equal import.family.currency, row.currency # Default currency
|
||||
end
|
||||
|
||||
test "handles empty values in optional fields" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
name_col_label: "name",
|
||||
category_col_label: "category",
|
||||
tags_col_label: "tags",
|
||||
number_format: "1,234.56",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
|
||||
csv_data = "date,amount,name,category,tags\n01/01/2024,1234.56,,,"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "01/01/2024", row.date
|
||||
assert_equal "1234.56", row.amount
|
||||
assert_equal "Imported item", row.name # Falls back to default
|
||||
assert_equal "", row.category
|
||||
assert_equal "", row.tags
|
||||
end
|
||||
|
||||
test "handles trade-specific fields" do
|
||||
import = imports(:transaction)
|
||||
import.update!(
|
||||
amount_col_label: "amount",
|
||||
date_col_label: "date",
|
||||
qty_col_label: "quantity",
|
||||
ticker_col_label: "symbol",
|
||||
price_col_label: "price",
|
||||
number_format: "1,234.56",
|
||||
date_format: "%m/%d/%Y"
|
||||
)
|
||||
|
||||
csv_data = "date,amount,quantity,symbol,price\n01/01/2024,1234.56,10,AAPL,123.456"
|
||||
import.update!(raw_file_str: csv_data)
|
||||
import.generate_rows_from_csv
|
||||
|
||||
row = import.rows.first
|
||||
assert_equal "10", row.qty
|
||||
assert_equal "AAPL", row.ticker
|
||||
assert_equal "123.456", row.price
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue