160 lines
6.3 KiB
Python
160 lines
6.3 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
|
|
import scripts.retry_failed_wehago_accounts_direct as direct
|
|
import scripts.wehago_data_download_2022_work as wehago
|
|
import scripts.wehago_ledger_api_download as api_download
|
|
from runtime_config import DB_PATH
|
|
from scripts.redownload_and_fix_hanmac_ledger_account import import_account_file
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
REPORT_DIR = ROOT / "reports" / "wehago_account_fixes"
|
|
YEARS = (2018, 2019, 2020, 2021)
|
|
GISU_BY_YEAR = {2018: 23, 2019: 24, 2020: 25, 2021: 26}
|
|
ACCOUNTS = (
|
|
wehago.Account("114", "단기대여금"),
|
|
wehago.Account("137", "주.종단기채권"),
|
|
wehago.Account("179", "장기대여금"),
|
|
wehago.Account("260", "단기차입금"),
|
|
wehago.Account("290", "주.종단기차입금"),
|
|
wehago.Account("901", "이자수익"),
|
|
wehago.Account("931", "이자비용"),
|
|
wehago.Account("116", "미수수익"),
|
|
wehago.Account("136", "선납세금"),
|
|
)
|
|
|
|
|
|
def parse_codes(raw: str) -> tuple[str, ...]:
|
|
return tuple(part.strip() for part in raw.split(",") if part.strip())
|
|
|
|
|
|
def fetch_cookies(debugger_address: str, run_dir: Path) -> dict[str, str]:
|
|
wehago.CHROME_DEBUGGER_ADDRESS = debugger_address
|
|
wehago.DOWNLOAD_DIR = run_dir
|
|
driver = wehago.build_driver(run_dir)
|
|
try:
|
|
return direct.cookie_map(driver)
|
|
finally:
|
|
driver.quit()
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(
|
|
description="한맥기술 2018~2021년 계열사 대여/차입 검토 계정별원장을 WEHAGO API로 내려받아 DB에 적재합니다."
|
|
)
|
|
parser.add_argument("--years", default=",".join(str(year) for year in YEARS))
|
|
parser.add_argument("--accounts", default=",".join(account.code for account in ACCOUNTS))
|
|
parser.add_argument("--db", type=Path, default=DB_PATH)
|
|
parser.add_argument("--debugger-address", default="127.0.0.1:9225")
|
|
parser.add_argument("--output-dir", type=Path)
|
|
parser.add_argument("--skip-import", action="store_true")
|
|
args = parser.parse_args()
|
|
|
|
selected_years = tuple(int(year) for year in parse_codes(args.years))
|
|
selected_codes = set(parse_codes(args.accounts))
|
|
accounts = tuple(account for account in ACCOUNTS if account.code in selected_codes)
|
|
unknown_years = sorted(set(selected_years) - set(GISU_BY_YEAR))
|
|
if unknown_years:
|
|
raise ValueError(f"지원하지 않는 연도입니다: {unknown_years}")
|
|
if not accounts:
|
|
raise ValueError("다운로드할 계정이 없습니다.")
|
|
|
|
run_dir = args.output_dir or (REPORT_DIR / f"legacy_related_accounts_{datetime.now():%Y%m%d_%H%M%S}")
|
|
run_dir.mkdir(parents=True, exist_ok=True)
|
|
direct.DIRECT_GISU_BY_YEAR.update(GISU_BY_YEAR)
|
|
cookies = fetch_cookies(args.debugger_address, run_dir)
|
|
|
|
summary: dict[str, Any] = {
|
|
"run_dir": str(run_dir),
|
|
"years": list(selected_years),
|
|
"accounts": [{"account_code": account.code, "account_name": account.name} for account in accounts],
|
|
"downloaded": [],
|
|
"failures": [],
|
|
}
|
|
|
|
for year in selected_years:
|
|
year_dir = run_dir / str(year)
|
|
year_dir.mkdir(parents=True, exist_ok=True)
|
|
progress_accounts: list[dict[str, Any]] = []
|
|
progress_failures: list[dict[str, str]] = []
|
|
for account in accounts:
|
|
item = {"year": year, "account_code": account.code, "account_name": account.name}
|
|
try:
|
|
rows = direct.fetch_ledger_rows(year, account, cookies)
|
|
api_download.validate_api_rows(account, rows)
|
|
target = year_dir / account.safe_filename
|
|
api_download.write_api_rows(target, account, rows)
|
|
item.update({"path": str(target), "api_response_rows": len(rows)})
|
|
progress_accounts.append(
|
|
{
|
|
"account_code": account.code,
|
|
"account_name": account.name,
|
|
"api_request_code": f"{account.code}00",
|
|
"api_response_rows": len(rows),
|
|
"path": str(target),
|
|
}
|
|
)
|
|
if not args.skip_import:
|
|
result = import_account_file(
|
|
args.db,
|
|
target,
|
|
year,
|
|
account,
|
|
year_dir,
|
|
skip_rebuild=True,
|
|
no_backup=True,
|
|
skip_cache_clear=True,
|
|
)
|
|
item.update(
|
|
{
|
|
"deleted_rows": result["deleted_rows"],
|
|
"inserted_rows": result["inserted_rows"],
|
|
}
|
|
)
|
|
summary["downloaded"].append(item)
|
|
print(
|
|
f"OK {year} {account.code} {account.name}: rows={item.get('api_response_rows')} "
|
|
f"inserted={item.get('inserted_rows', '-')}",
|
|
flush=True,
|
|
)
|
|
except Exception as exc:
|
|
failure = {
|
|
"year": str(year),
|
|
"account_code": account.code,
|
|
"account_name": account.name,
|
|
"reason": f"{type(exc).__name__}: {exc}",
|
|
}
|
|
summary["failures"].append(failure)
|
|
progress_failures.append(failure)
|
|
print(f"FAIL {year} {account.code} {account.name}: {failure['reason']}", flush=True)
|
|
api_download.write_progress(
|
|
year_dir,
|
|
{
|
|
"status": "completed_with_failures" if progress_failures else "completed",
|
|
"completed": len(progress_accounts),
|
|
"total": len(accounts),
|
|
"accounts": progress_accounts,
|
|
"failures": progress_failures,
|
|
},
|
|
)
|
|
(run_dir / "legacy_related_accounts_result.json").write_text(
|
|
json.dumps(summary, ensure_ascii=False, indent=2),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
print(json.dumps(summary, ensure_ascii=False, indent=2))
|
|
return 1 if summary["failures"] else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|