# /// script # requires-python = ">=3.12" # dependencies = ["typer", "rich", "xlwings"] # /// from contextlib import contextmanager from pathlib import Path from typing import Annotated import xlwings as xw import typer from rich.console import Console console = Console() def get_totals(book: xw.Book): for sheet in book.sheets: if sheet.name.endswith("Rate"): continue try: total = float(sheet.range("S3").expand("down").value[-1]) except Exception as e: console.print(f"[red]Error reading total from sheet {sheet.name}: {e}[/red]") console.print_exception(show_locals=False) else: yield sheet.name, total def get_grand_total(book: xw.Book): totals = dict(get_totals(book)) grand_total = sum(totals.values()) return grand_total @contextmanager def switch_values(book: xw.Book): og_vals = book.sheets['GSA Rate'].range("B2").expand("down").value try: book.sheets['GSA Rate'].range("B2").expand("down").value = 0.70 yield finally: book.sheets['GSA Rate'].range("B2").expand("down").options(transpose=True).value = og_vals def get_diff(book: xw.Book): book.sheets['GSA Rate'].range("B2:B10").value = 0.67 initial = get_grand_total(book) with switch_values(book): fixed = get_grand_total(book) diff = round(fixed - initial, 2) return diff def get_all_diffs(base: Path): reports = [f for f in base.glob('*Mileage*.xlsx') if f.is_file() and not f.stem.startswith('~$')] console.print(f"Found {len(reports)} report(s).") for r in reports: with console.status(f'Processing [bold blue]{r.name}[/bold blue]'): console.print('Opening workbook...') book = xw.Book(r) try: console.print('Calculating totals...') diff = get_diff(book) yield r.name, diff console.print(f"[cyan]Report:[/] {r.name}") console.print(f" Difference after rate change: [bold green]${diff:.2f}[/]") except Exception as e: console.print(f"[red]Error processing {r.name}: {e}[/red]") finally: book.close() def main( directory: Annotated[ Path, typer.Argument( exists=True, file_okay=False, dir_okay=True, readable=True, writable=True, resolve_path=True ) ] = None) -> None: console.print(f"Processing files in directory: {directory}") results = dict(get_all_diffs(directory)) with Path('results.csv').open('w', encoding='utf-8') as f: f.write("Report,Difference\n") for report, diff in results.items(): f.write(f'{report},{diff}\n') if __name__ == "__main__": typer.run(main)