#!/usr/bin/env python3 import json import os import shutil import datetime import re from pathlib import Path from dateutil.relativedelta import relativedelta from update_excel_xlsxwriter import update_excel_variables def create_excel_from_template(): """ Create a copy of the Excel template and save it to the output folder, then inject variables from config.json into the Variables sheet. This version uses openpyxl exclusively for modifying existing Excel files to preserve all formatting, formulas, and Excel features. """ # Define paths script_dir = os.path.dirname(os.path.abspath(__file__)) config_path = os.path.join(script_dir, 'config.json') # Look for any Excel template in the template directory template_dir = os.path.join(script_dir, 'template') template_files = [f for f in os.listdir(template_dir) if f.endswith('.xlsx')] if not template_files: print("Error: No Excel template found in the template directory") return False template_path = os.path.join(template_dir, template_files[0]) output_dir = os.path.join(script_dir, 'output') # Ensure output directory exists os.makedirs(output_dir, exist_ok=True) # Read config.json to get store_name, starting_date, and duration try: with open(config_path, 'r') as f: config = json.load(f) user_data = config.get('user_data', {}) store_name = user_data.get('store_name', '') starting_date = user_data.get('starting_date', '') duration = user_data.get('duration', 36) # If store_name is empty, use a default value if not store_name: store_name = "Your Store" # Calculate years array based on starting_date and duration years = calculate_years(starting_date, duration) print(f"Years in the period: {years}") except Exception as e: print(f"Error reading config file: {e}") return False # Use first and last years from the array in the filename year_range = "" if years and len(years) > 0: if len(years) == 1: year_range = f"{years[0]}" else: year_range = f"{years[0]}-{years[-1]}" else: # Fallback to current year if years array is empty current_year = datetime.datetime.now().year year_range = f"{current_year}" # Create output filename with store_name and year range output_filename = f"Footprints AI for {store_name} - Retail Media Business Case Calculations {year_range}.xlsx" output_path = os.path.join(output_dir, output_filename) # Copy the template to the output directory with the new name try: shutil.copy2(template_path, output_path) print(f"Excel file created successfully: {output_path}") # Update the Excel file with variables from config.json print("Updating Excel file with variables from config.json...") update_result = update_excel_variables(output_path) if update_result: print("Excel file updated successfully with variables from config.json") else: print("Warning: Failed to update Excel file with variables from config.json") return True except Exception as e: print(f"Error creating Excel file: {e}") return False def calculate_years(starting_date, duration): """ Calculate an array of years that appear in the period from starting_date for duration months. Args: starting_date (str): Date in format dd/mm/yyyy or dd.mm.yyyy duration (int): Number of months, including the starting month Returns: list: Array of years in the period [year1, year2, ...] """ # Default result if we can't parse the date default_years = [datetime.datetime.now().year] # If starting_date is empty, return current year if not starting_date: return default_years try: # Try to parse the date, supporting both dd/mm/yyyy and dd.mm.yyyy formats if '/' in starting_date: day, month, year = map(int, starting_date.split('/')) elif '.' in starting_date: day, month, year = map(int, starting_date.split('.')) elif '-' in starting_date: # Handle ISO format (yyyy-mm-dd) date_parts = starting_date.split('-') if len(date_parts) == 3: year, month, day = map(int, date_parts) else: # Default to current date if format is not recognized return default_years else: # If format is not recognized, return default return default_years # Create datetime object for starting date start_date = datetime.datetime(year, month, day) # Calculate end date (starting date + duration months - 1 day) end_date = start_date + relativedelta(months=duration-1) # Create a set of years (to avoid duplicates) years_set = set() # Add starting year years_set.add(start_date.year) # Add ending year years_set.add(end_date.year) # If there are years in between, add those too for y in range(start_date.year + 1, end_date.year): years_set.add(y) # Convert set to sorted list return sorted(list(years_set)) except Exception as e: print(f"Error calculating years: {e}") return default_years if __name__ == "__main__": create_excel_from_template()