From db5e7fbaec024bd1b030cb259a296f30562c7732 Mon Sep 17 00:00:00 2001 From: mhbw Date: Mon, 11 Nov 2024 17:36:20 -0500 Subject: [PATCH 1/2] Create generate_invoices.py --- docs/mail-merge/generate_invoices.py | 96 ++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 docs/mail-merge/generate_invoices.py diff --git a/docs/mail-merge/generate_invoices.py b/docs/mail-merge/generate_invoices.py new file mode 100644 index 000000000..fdada2c3a --- /dev/null +++ b/docs/mail-merge/generate_invoices.py @@ -0,0 +1,96 @@ +import os +import pandas as pd +from google.oauth2 import service_account +from googleapiclient.discovery import build + +# Set up Google Sheets and Google Docs API credentials +SERVICE_ACCOUNT_FILE = process.env.gcp_client_secret.json +SCOPES = [ + 'https://www.googleapis.com/auth/spreadsheets.readonly', + 'https://www.googleapis.com/auth/documents', + 'https://www.googleapis.com/auth/drive.file' +] +creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES) + +# Configuration +SHEET_ID = 'your_google_sheet_id' +PACKAGE_META_TAB = 'Package_Meta' +PACKAGE_CONTENTS_TAB = 'Package_Contents' +TEMPLATE_DOC_ID = 'your_template_doc_id' +OUTPUT_FOLDER_ID = 'your_drive_folder_id' + +def fetch_google_sheet_data(sheet_id, range_name): + """Fetch data from Google Sheets.""" + service = build('sheets', 'v4', credentials=creds) + sheet = service.spreadsheets() + result = sheet.values().get(spreadsheetId=sheet_id, range=range_name).execute() + values = result.get('values', []) + return pd.DataFrame(values[1:], columns=values[0]) if values else pd.DataFrame() + +def get_package_data(): + """Fetch data from both tabs and merge them based on Package_Number.""" + # Fetch data from Google Sheets tabs + package_meta = fetch_google_sheet_data(SHEET_ID, PACKAGE_META_TAB) + package_contents = fetch_google_sheet_data(SHEET_ID, PACKAGE_CONTENTS_TAB) + + # Convert Package_Number to string for consistent merging + package_meta['Package_Number'] = package_meta['Package_Number'].astype(str) + package_contents['Package_Number'] = package_contents['Package_Number'].astype(str) + + # Merge data based on Package_Number + merged_data = pd.merge(package_meta, package_contents, on='Package_Number', how='left') + return merged_data + +def copy_template(template_id, output_name, folder_id): + """Create a copy of the Google Docs template for each invoice.""" + drive_service = build('drive', 'v3', credentials=creds) + copied_file = drive_service.files().copy( + fileId=template_id, + body={'name': output_name, 'parents': [folder_id]} + ).execute() + return copied_file['id'] + +def replace_placeholders(document_id, replacements): + """Replace placeholders in a Google Docs document.""" + docs_service = build('docs', 'v1', credentials=creds) + requests = [ + {'replaceAllText': { + 'containsText': {'text': '{{' + key + '}}', 'matchCase': True}, + 'replaceText': value + }} for key, value in replacements.items() + ] + docs_service.documents().batchUpdate(documentId=document_id, body={'requests': requests}).execute() + +def generate_invoices(): + """Main function to generate invoices based on merged data.""" + merged_data = get_package_data() + + # Group by Package_Number to create individual invoices + for package_number, group in merged_data.groupby('Package_Number'): + package_info = group.iloc[0] # Get customer info for this package + + # Format items list with details from Package_Contents + items = "\n".join([ + f"Card: {row['Card']}, Set: {row['Set']}, Cond.: {row['Cond.']}, Finish: {row['Finish']}, " + f"Lang.: {row['Lang.']}, Amount: {row['Amount']}, Status: {row['Status']}, Date: {row['Date']}" + for _, row in group.iterrows() + ]) + + # Prepare replacements dictionary + replacements = { + 'Customer_Name': package_info['Customer_Name'], + 'Customer_Email': package_info['Customer_Email'], + 'Package_Number': package_number, + 'Order_Date': package_info['Order_Date'], + 'Shipping_Address': package_info['Shipping_Address'], + 'Items': items, + 'Total_Amount': str(group['Amount'].astype(float).sum()) + } + + # Copy the template and replace placeholders + document_id = copy_template(TEMPLATE_DOC_ID, f"Invoice_{package_number}", OUTPUT_FOLDER_ID) + replace_placeholders(document_id, replacements) + print(f"Invoice generated for Package {package_number}.") + +if __name__ == '__main__': + generate_invoices() From c38e0d34439c2b83a33946a9463cd574652202b6 Mon Sep 17 00:00:00 2001 From: mhbw Date: Mon, 11 Nov 2024 17:40:52 -0500 Subject: [PATCH 2/2] Update generate_invoices.py added paths --- docs/mail-merge/generate_invoices.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/mail-merge/generate_invoices.py b/docs/mail-merge/generate_invoices.py index fdada2c3a..d962fae2d 100644 --- a/docs/mail-merge/generate_invoices.py +++ b/docs/mail-merge/generate_invoices.py @@ -4,7 +4,7 @@ from googleapiclient.discovery import build # Set up Google Sheets and Google Docs API credentials -SERVICE_ACCOUNT_FILE = process.env.gcp_client_secret.json +SERVICE_ACCOUNT_FILE = process.env.GCP_CLIENT_SECRET SCOPES = [ 'https://www.googleapis.com/auth/spreadsheets.readonly', 'https://www.googleapis.com/auth/documents', @@ -13,11 +13,11 @@ creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES) # Configuration -SHEET_ID = 'your_google_sheet_id' +SHEET_ID = '1lZtro8sLdpx8IozYQUbe-dJFhkacxw8W3RvZf45furo' PACKAGE_META_TAB = 'Package_Meta' PACKAGE_CONTENTS_TAB = 'Package_Contents' -TEMPLATE_DOC_ID = 'your_template_doc_id' -OUTPUT_FOLDER_ID = 'your_drive_folder_id' +TEMPLATE_DOC_ID = '19VGSJoRY2n1BmyQcqUBuI0aVEJd_1Uh2wHMDB-0FXi8' +OUTPUT_FOLDER_ID = '1VWF48TKNHBtAfIt1SF9ks1uzmXj02IQj' def fetch_google_sheet_data(sheet_id, range_name): """Fetch data from Google Sheets."""