from __future__ import annotations import csv import hashlib from datetime import datetime from typing import Iterable from .base import CSVParserBase, ExpenseRow class IdemitsuParser(CSVParserBase): source = 'idemitsu' def detect(self, header_line: str) -> bool: return '出光' in header_line or 'apollostation' in header_line def parse(self, lines: Iterable[str]) -> list[ExpenseRow]: rows: list[ExpenseRow] = [] reader = csv.reader(lines) last_row_index: int | None = None for columns in reader: if not columns: continue head = columns[0].strip() if head in ('カード名称', 'お支払日', '今回ご請求額'): continue if head == '利用日': continue if not head: if last_row_index is not None: extra_desc = columns[1].strip() if len(columns) > 1 else '' extra_note = columns[6].strip() if len(columns) > 6 else '' if extra_desc: rows[last_row_index].description += f' {extra_desc}' if extra_note: if rows[last_row_index].note: rows[last_row_index].note += f' {extra_note}' else: rows[last_row_index].note = extra_note continue if len(columns) < 6: continue try: use_date = datetime.strptime(head, '%Y/%m/%d').date() except ValueError: continue description = columns[1].strip() amount_text = columns[5].replace(',', '').strip() note = columns[6].strip() if len(columns) > 6 else '' try: amount = int(amount_text) except ValueError: continue raw = f"{use_date.isoformat()}|{description}|{amount}|{note}|{self.source}" source_hash = hashlib.sha256(raw.encode('utf-8')).hexdigest() rows.append( ExpenseRow( use_date=use_date, description=description, amount=amount, note=note, source=self.source, source_hash=source_hash, ) ) last_row_index = len(rows) - 1 return rows