153 lines
5.4 KiB
Python
153 lines
5.4 KiB
Python
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
from datetime import date, datetime
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from openpyxl import load_workbook
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
DB_PATH = ROOT / "data.db"
|
|
SOURCE_XLSX = ROOT / "reports" / "wehago_account_fixes" / "2025_137_20260617_092619" / "137_주.종단기채권.xlsx"
|
|
YEAR = 2025
|
|
ACCOUNT_CODE = "137"
|
|
ACCOUNT_NAME = "주.종단기채권"
|
|
|
|
|
|
def clean(value: Any) -> str:
|
|
return "" if value is None else str(value).strip()
|
|
|
|
|
|
def parse_amount(value: Any) -> float:
|
|
if value is None or value == "":
|
|
return 0.0
|
|
if isinstance(value, (int, float)):
|
|
return float(value)
|
|
text = clean(value).replace(",", "")
|
|
try:
|
|
return float(text)
|
|
except ValueError:
|
|
return 0.0
|
|
|
|
|
|
def parse_ledger_date(value: Any) -> str | None:
|
|
if value is None or clean(value) == "":
|
|
return None
|
|
if isinstance(value, datetime):
|
|
return value.date().isoformat()
|
|
if isinstance(value, date):
|
|
return value.isoformat()
|
|
text = clean(value).replace(".", "-").replace("/", "-")
|
|
parts = [part for part in text.split("-") if part]
|
|
if len(parts) == 2:
|
|
month, day = parts
|
|
return f"{YEAR}-{int(month):02d}-{int(day):02d}"
|
|
if len(parts) == 3:
|
|
year, month, day = parts
|
|
return f"{int(year):04d}-{int(month):02d}-{int(day):02d}"
|
|
return text
|
|
|
|
|
|
def compare_voucher_no(ledger_date: str | None, voucher_no: str) -> str:
|
|
if not ledger_date or not voucher_no:
|
|
return ""
|
|
return f"{ledger_date.replace('-', '')}-{voucher_no}"
|
|
|
|
|
|
def normalize_text(value: Any) -> str:
|
|
return " ".join(clean(value).split())
|
|
|
|
|
|
def main() -> int:
|
|
wb = load_workbook(SOURCE_XLSX, read_only=True, data_only=True)
|
|
try:
|
|
ws = wb.worksheets[0]
|
|
source_rows = list(ws.iter_rows(min_row=2, values_only=True))
|
|
finally:
|
|
wb.close()
|
|
|
|
conn = sqlite3.connect(DB_PATH, timeout=300)
|
|
try:
|
|
conn.execute("PRAGMA busy_timeout = 300000")
|
|
source_id_row = conn.execute(
|
|
"""
|
|
SELECT source_file_id
|
|
FROM wehago_ledger_rows
|
|
WHERE fiscal_year = ? AND account_code = ?
|
|
GROUP BY source_file_id
|
|
ORDER BY COUNT(*) DESC
|
|
LIMIT 1
|
|
""",
|
|
(YEAR, ACCOUNT_CODE),
|
|
).fetchone()
|
|
source_file_id = int(source_id_row[0]) if source_id_row else 0
|
|
if not source_file_id:
|
|
source_file_id = int(
|
|
conn.execute(
|
|
"SELECT source_file_id FROM wehago_ledger_rows WHERE fiscal_year = ? LIMIT 1",
|
|
(YEAR,),
|
|
).fetchone()[0]
|
|
)
|
|
|
|
with conn:
|
|
deleted = conn.execute(
|
|
"DELETE FROM wehago_ledger_rows WHERE fiscal_year = ? AND account_code = ?",
|
|
(YEAR, ACCOUNT_CODE),
|
|
).rowcount
|
|
inserted = 0
|
|
for row_number, values in enumerate(source_rows, start=2):
|
|
if not any(clean(item) for item in values):
|
|
continue
|
|
ledger_date = parse_ledger_date(values[0] if len(values) > 0 else None)
|
|
description = clean(values[1] if len(values) > 1 else "")
|
|
vendor_name = clean(values[2] if len(values) > 2 else "")
|
|
debit = parse_amount(values[3] if len(values) > 3 else 0)
|
|
credit = parse_amount(values[4] if len(values) > 4 else 0)
|
|
balance = parse_amount(values[5] if len(values) > 5 else 0)
|
|
voucher_no = clean(values[6] if len(values) > 6 else "")
|
|
account_code = clean(values[7] if len(values) > 7 else ACCOUNT_CODE) or ACCOUNT_CODE
|
|
account_name = clean(values[8] if len(values) > 8 else ACCOUNT_NAME) or ACCOUNT_NAME
|
|
conn.execute(
|
|
"""
|
|
INSERT INTO wehago_ledger_rows (
|
|
source_file_id, sheet_name, row_number, ledger_date, description,
|
|
vendor_name, debit, credit, balance, voucher_no, account_code,
|
|
account_name, compare_voucher_no, compare_amount, compare_side,
|
|
compare_vendor, compare_desc, fiscal_year
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
""",
|
|
(
|
|
source_file_id,
|
|
ws.title,
|
|
row_number,
|
|
ledger_date,
|
|
description,
|
|
vendor_name,
|
|
debit,
|
|
credit,
|
|
balance,
|
|
voucher_no,
|
|
account_code,
|
|
account_name,
|
|
compare_voucher_no(ledger_date, voucher_no),
|
|
debit if debit else credit,
|
|
"debit" if debit else ("credit" if credit else ""),
|
|
normalize_text(vendor_name),
|
|
normalize_text(description),
|
|
YEAR,
|
|
),
|
|
)
|
|
inserted += 1
|
|
print(f"source={SOURCE_XLSX}")
|
|
print(f"source_file_id={source_file_id}")
|
|
print(f"deleted={deleted}")
|
|
print(f"inserted={inserted}")
|
|
finally:
|
|
conn.close()
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|