70 lines
2.9 KiB
Python
70 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from jarca_ledger_mcp import service
|
|
from jarca_ledger_mcp.seoulpay_xlsx import parse_seoulpay_xlsx
|
|
|
|
|
|
def _write_sample_seoulpay_xlsx(path: Path) -> None:
|
|
import openpyxl
|
|
|
|
wb = openpyxl.Workbook()
|
|
ws = wb.active
|
|
ws.title = "결제내역"
|
|
ws.append(["성명", "최진선"])
|
|
ws.append(["생년월일", "19791010"])
|
|
ws.append(["조회기간", "20260601~20260620"])
|
|
ws.append([])
|
|
ws.append([])
|
|
ws.append(["결제채널", "거래번호", "결제일", "가맹점", "사업자번호", "가맹점ID", "거래유형", "결제구분", "거래금액", "공급가액", "봉사료", "부가세", "과세여부"])
|
|
ws.append(["서울페이", "260618ZP00534273", "2026-06-18 18:27:46", "땡겨요", "2028102637", "AF2402815444", "온라인 결제 ", "결제", 42000, 38182, 0, 3818, "과세"])
|
|
ws.append(["서울페이", "ABP0123761927", "2026-06-10 15:14:05", "리엘바이올린음악교습소", "8259301583", "AF2402827183", "비대면 결제 ", "결제", 260000, 260000, 0, 0, "면세"])
|
|
wb.save(path)
|
|
|
|
|
|
def test_parse_seoulpay_xlsx_plain_file(tmp_path):
|
|
file_path = tmp_path / "서울페이.xlsx"
|
|
_write_sample_seoulpay_xlsx(file_path)
|
|
|
|
parsed = parse_seoulpay_xlsx(str(file_path))
|
|
|
|
assert parsed["metadata"]["holder_name"] == "최진선"
|
|
assert parsed["metadata"]["period"] == "20260601~20260620"
|
|
assert parsed["validation"]["ok"] is True
|
|
assert len(parsed["transactions"]) == 2
|
|
first = parsed["transactions"][0]
|
|
assert first.transaction_date == "2026-06-18"
|
|
assert first.merchant == "땡겨요"
|
|
assert first.amount == 42000
|
|
assert first.type == "expense"
|
|
|
|
|
|
def test_import_seoulpay_xlsx_creates_account_and_expenses(tmp_path):
|
|
db_path = str(tmp_path / "ledger.sqlite3")
|
|
file_path = tmp_path / "서울페이.xlsx"
|
|
_write_sample_seoulpay_xlsx(file_path)
|
|
|
|
preview = service.preview_seoulpay_xlsx_import(str(file_path), preview_limit=10, db_path=db_path)
|
|
assert preview["success"] is True
|
|
assert preview["row_count"] == 2
|
|
assert preview["duplicate_count"] == 0
|
|
assert preview["by_category"]["식비/배달"]["amount"] == 42000
|
|
assert preview["by_category"]["교육/학원"]["amount"] == 260000
|
|
|
|
imported = service.import_seoulpay_xlsx(str(file_path), db_path=db_path)
|
|
assert imported["success"] is True
|
|
assert imported["inserted_count"] == 2
|
|
assert imported["skipped_duplicate_count"] == 0
|
|
|
|
duplicate = service.import_seoulpay_xlsx(str(file_path), db_path=db_path)
|
|
assert duplicate["success"] is True
|
|
assert duplicate["inserted_count"] == 0
|
|
assert duplicate["skipped_duplicate_count"] == 2
|
|
|
|
cashflow = service.get_monthly_cashflow_report("2026-06", db_path)
|
|
assert cashflow["expenses"] == 302000
|
|
categories = service.get_category_spending_report(month="2026-06", db_path=db_path)
|
|
assert categories["total_expense"] == 302000
|
|
assert categories["items"][0]["category"] == "교육"
|