"""Application constants and business rule definitions. Defines immutable constants used throughout the adjustment file preparation pipeline, including business validation rules and schema definitions for input and staging tables. Constants: - ValidationRules: Business logic constraints (UPC lengths, distribution types) - AdjustmentInputSchema: Input file schema with column mappings - AdjustmentStagingSchema: MySQL staging table schema Data Transformation Flow: File (external columns) → DuckDB (normalized) → MySQL staging (final schema) """ from typing import Final from src.enums import AdjustmentColumn, AdjustmentFileColumn, DuckDBTable from src.schemas import ColumnMapping class ValidationRules: """Business validation rules.""" ACCOUNT_EXPENSE_ADJUSTMENT_TYPE: Final[str] = 'account expense' ACTION_STATUS_COMPLETE: Final[str] = 'complete' DISTRIBUTION_TYPES: Final[frozenset[str]] = frozenset({'digital', 'physical'}) STATEMENT_PERIOD_STATUS: Final[str] = 'current' UPC_MIN_LENGTH: Final[int] = 12 UPC_MAX_LENGTH: Final[int] = 13 class AdjustmentInputSchema: """Input file schema mapping external columns to internal database columns.""" TABLE = DuckDBTable.ADJUSTMENT_FILE COLUMNS: Final[tuple[ColumnMapping, ...]] = ( ColumnMapping( column_name=AdjustmentColumn.ACCOUNT_ID, display_name=AdjustmentFileColumn.ACCOUNT_ID, required=True, ), ColumnMapping( column_name=AdjustmentColumn.ACCOUNT_NAME, display_name=AdjustmentFileColumn.ACCOUNT_NAME, required=False, ), ColumnMapping( column_name=AdjustmentColumn.ACTIVITY_MONTH, display_name=AdjustmentFileColumn.ACTIVITY_MONTH, required=True, ), ColumnMapping( column_name=AdjustmentColumn.ACTIVITY_YEAR, display_name=AdjustmentFileColumn.ACTIVITY_YEAR, required=True, ), ColumnMapping( column_name=AdjustmentColumn.ADJUSTMENT_TYPE, display_name=AdjustmentFileColumn.ADJUSTMENT_TYPE, required=True, ), ColumnMapping( column_name=AdjustmentColumn.AMOUNT, display_name=AdjustmentFileColumn.AMOUNT, required=True, ), ColumnMapping( column_name=AdjustmentColumn.APPLY_TO_FLOWTHROUGH, display_name=AdjustmentFileColumn.APPLY_TO_FLOWTHROUGH, required=False, ), ColumnMapping( column_name=AdjustmentColumn.CLIENT_FACING_COMMENT, display_name=AdjustmentFileColumn.CLIENT_FACING_COMMENT, required=True, ), ColumnMapping( column_name=AdjustmentColumn.CONTRACT_ID, display_name=AdjustmentFileColumn.CONTRACT_ID, required=True, ), ColumnMapping( column_name=AdjustmentColumn.CONTRACT_NAME, display_name=AdjustmentFileColumn.CONTRACT_NAME, required=False, ), ColumnMapping( column_name=AdjustmentColumn.CURRENCY, display_name=AdjustmentFileColumn.CURRENCY, required=True, ), ColumnMapping( column_name=AdjustmentColumn.DISTRIBUTION_TYPE, display_name=AdjustmentFileColumn.DISTRIBUTION_TYPE, required=False, ), ColumnMapping( column_name=AdjustmentColumn.INTERNAL_NOTE, display_name=AdjustmentFileColumn.INTERNAL_NOTE, required=False, ), ColumnMapping( column_name=AdjustmentColumn.STATEMENT_MONTH, display_name=AdjustmentFileColumn.STATEMENT_MONTH, required=True, ), ColumnMapping( column_name=AdjustmentColumn.STATEMENT_YEAR, display_name=AdjustmentFileColumn.STATEMENT_YEAR, required=True, ), ColumnMapping( column_name=AdjustmentColumn.UPC, display_name=AdjustmentFileColumn.UPC, required=False, ), ) class AdjustmentStagingSchema: """MySQL staging table schema for validated adjustment data.""" TABLE: Final[str] = 'worksheet_flowthrough' COLUMNS: Final[list[str]] = [ 'worksheet_flowthrough_batch_id', 'batch_row_index', 'account_id', 'activity_statement_period_id', # 'apply_to_statement_period_id', # TODO: Add back # 'reference_adjustment_type_id', # TODO: Add back 'contract_id', # 'currency_code', # TODO: Add back 'amount', 'amount_raw', # 'upc', # TODO: Add back # 'distribution_type', # TODO: Add back 'note', 'internal_note', # 'apply_to_flowthrough_payment', # TODO: Add back 'errors', 'source_data', ]