#!/usr/bin/env python3 """ Generate adjustment files from trimmed input files. Processes trimmed inputs and generates adjustment outputs that can be compared with the original adjustment files. """ import csv from pathlib import Path TRIMMED_DIR = Path(__file__).parent / "trimmed_input" OUTPUT_DIR = Path(__file__).parent / "output" OUTPUT_DIR.mkdir(exist_ok=True) def calculate_adjustment_amount(balance, percentage, amount_from_input): """ Calculate the adjustment amount. Returns the numeric amount from input if present, otherwise calculates balance * percentage. Preserves special values (FALSE, #N/A) as-is. """ if amount_from_input == 'FALSE': return 'FALSE' if amount_from_input == '#N/A': return '#N/A' if amount_from_input and amount_from_input.strip(): try: return float(amount_from_input.replace(',', '')) except (ValueError, AttributeError): pass # Fall back to balance * percentage try: balance_val = float(balance.replace(',', '') if balance else '0') percentage_val = float(percentage.replace('%', '').strip() if percentage else '0') / 100.0 return balance_val * percentage_val except (ValueError, AttributeError): return 0.0 def generate_adjustments(input_file, output_prefix, is_overrides=False): """ Generate adjustment file from trimmed input. Args: input_file: Name of the trimmed input CSV file output_prefix: Prefix for the generated adjustment file is_overrides: True if processing overrides file (different column structure) """ input_path = TRIMMED_DIR / input_file output_path = OUTPUT_DIR / f"generated_{output_prefix}_adjustments.csv" print(f"\nProcessing {input_file}...") with open(input_path, 'r', encoding='utf-8') as infile: rows = list(csv.reader(infile)) if not rows: print(f" WARNING: Empty file!") return header = rows[0] adj_columns = [ "Account Name", "Account ID *", "Contract Name", "Contract ID *", "UPC", "Amount *", "Currency *", "Activity Month *", "Activity Year *", "Statement Month *", "Statement Year *", "Adjustment Type *", "Client Facing Comments *", "Distribution Type", "Internal Note", "Apply to Flowthrough Payment" ] adjustment_rows = [adj_columns] for i, row in enumerate(rows[1:], start=2): min_cols = 27 if is_overrides else 31 if len(row) < min_cols: print(f" WARNING: Row {i} has insufficient columns ({len(row)}), skipping") adjustment_rows.append([''] * len(adj_columns)) continue account_name = row[1] if len(row) > 1 else '' account_id = row[2] if len(row) > 2 else '' contract_name = row[3] if len(row) > 3 else '' contract_id = row[4] if len(row) > 4 else '' action = row[5] if len(row) > 5 else '' # Column indices differ between overrides and transfers/cross_recoupment if is_overrides: balance = row[16] if len(row) > 16 else '0' percentage = row[15] if len(row) > 15 else '0' currency = row[12] if len(row) > 12 else '' amount_from_input = row[23] if len(row) > 23 else '' currency_from_amount = row[24] if len(row) > 24 else '' comment = row[27] if len(row) > 27 else '' else: balance = row[16] if len(row) > 16 else '0' percentage = row[15] if len(row) > 15 else '0' currency = row[12] if len(row) > 12 else '' amount_from_input = row[26] if len(row) > 26 else '' currency_from_amount = row[27] if len(row) > 27 else '' comment = row[30] if len(row) > 30 else '' amount = calculate_adjustment_amount(balance, percentage, amount_from_input) # Prefer currency from the amount column over the general currency column final_currency = currency_from_amount if currency_from_amount else currency if isinstance(amount, str): amount_str = amount elif amount is not None: amount_str = f"{amount:.2f}" else: amount_str = 'FALSE' adj_row = [ account_name, account_id, contract_name, contract_id, '', amount_str, final_currency if final_currency else '#N/A', '1', '2026', '1', '2026', action, comment, '', '', '' ] adjustment_rows.append(adj_row) with open(output_path, 'w', encoding='utf-8', newline='') as outfile: csv.writer(outfile).writerows(adjustment_rows) print(f" Generated adjustments saved to: {output_path}") print(f" Rows: {len(adjustment_rows)} (including header)") def main(): print("=" * 70) print("GENERATING ADJUSTMENT FILES FROM TRIMMED INPUTS") print("=" * 70) generate_adjustments("input_cross_recoupment.csv", "cross_recoupment", is_overrides=False) generate_adjustments("input_transfers.csv", "transfers", is_overrides=False) generate_adjustments("input_overrides.csv", "overrides", is_overrides=True) print("\n" + "=" * 70) print("GENERATION COMPLETE!") print("=" * 70) print(f"\nGenerated adjustments saved in: {OUTPUT_DIR}") if __name__ == "__main__": main()