From 855cef678f062c72a82fcb37585b28f09a206635 Mon Sep 17 00:00:00 2001 From: "vladimir.buzalka" Date: Wed, 8 Apr 2026 14:59:00 +0200 Subject: [PATCH] z230 --- format_accountability.py | 118 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 format_accountability.py diff --git a/format_accountability.py b/format_accountability.py new file mode 100644 index 0000000..a7ef956 --- /dev/null +++ b/format_accountability.py @@ -0,0 +1,118 @@ +import pandas as pd +from openpyxl import load_workbook +from openpyxl.styles import Font, PatternFill, Alignment, Border, Side +from openpyxl.utils import get_column_letter + +INPUT_FILE = "accountability_combined.xlsx" +OUTPUT_FILE = "accountability_formatted.xlsx" +SHEET_NAME = "CountryMedicationOverview" + +COLUMN_RENAMES = { + "Site": "Site", + "Medication ID": "Med ID", + "Packaged Lot number": "Lot No.", + "Original Expiration Date when Packaged Lot was Added": "Orig Exp Date", + "Expiration date": "Exp Date", + "Received Date": "Rcv Date", + "Shipment Receipt User": "Rcpt User", + "Subject Identifier": "Subject ID", + "Quantity Assigned": "Qty Asgn", + "IRT Transaction": "IRT Tx", + "Date Assigned": "Date Asgn", + "Assignment User": "Asgn User", + "Dispensation Status": "Disp Status", + "Dispensing Date": "Disp Date", + "Quantity Dispensed": "Qty Disp", + "Dispensing User": "Disp User", + "Quantity Returned": "Qty Ret", + "Date Returned": "Date Ret", + "Return User": "Ret User", + "DestroyedOn": "Destroyed", + "Basket number": "Basket No.", +} + +DATE_COLUMNS = { + "Orig Exp Date", "Exp Date", "Rcv Date", + "Date Asgn", "Disp Date", "Date Ret", "Destroyed", +} + +COLUMN_WIDTHS = { + "Site": 14, + "Med ID": 10, + "Lot No.": 12, + "Orig Exp Date": 16, + "Exp Date": 14, + "Rcv Date": 14, + "Rcpt User": 22, + "Subject ID": 14, + "Qty Asgn": 9, + "IRT Tx": 8, + "Date Asgn": 14, + "Asgn User": 20, + "Disp Status": 16, + "Disp Date": 14, + "Qty Disp": 9, + "Disp User": 20, + "Qty Ret": 10, + "Date Ret": 14, + "Ret User": 18, + "Destroyed": 14, + "Basket No.": 12, +} + +# ── 1. Load with pandas and convert date columns ───────────────────────────── +df = pd.read_excel(INPUT_FILE) +df.rename(columns=COLUMN_RENAMES, inplace=True) + +for col in DATE_COLUMNS: + if col in df.columns: + df[col] = pd.to_datetime(df[col], dayfirst=True, errors="coerce") + +df.sort_values(["Site", "Rcv Date", "Med ID"], inplace=True, ignore_index=True) +df.to_excel(OUTPUT_FILE, index=False, sheet_name=SHEET_NAME) + +# ── 2. Format with openpyxl ─────────────────────────────────────────────────── +wb = load_workbook(OUTPUT_FILE) +ws = wb[SHEET_NAME] + +header_fill = PatternFill("solid", start_color="1F4E79") +header_font = Font(bold=True, color="FFFFFF", name="Arial", size=10) +new_col_fill = PatternFill("solid", start_color="E2EFDA") +row_font = Font(name="Arial", size=10) + +thin = Side(style="thin", color="000000") +border = Border(left=thin, right=thin, top=thin, bottom=thin) + +headers = [cell.value for cell in ws[1]] +new_cols = {"Destroyed", "Basket No."} + +# Header row +for cell in ws[1]: + cell.fill = header_fill + cell.font = header_font + cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=False) + cell.border = border + +# Data rows +max_row = ws.max_row +for row in ws.iter_rows(min_row=2, max_row=max_row): + for cell in row: + col_name = headers[cell.column - 1] if cell.column <= len(headers) else None + cell.font = row_font + cell.border = border + cell.alignment = Alignment(horizontal="center") + if col_name in DATE_COLUMNS: + cell.number_format = "DD-MMM-YYYY" + if col_name in new_cols: + cell.fill = new_col_fill + +# Column widths +for cell in ws[1]: + width = COLUMN_WIDTHS.get(cell.value, 14) + ws.column_dimensions[get_column_letter(cell.column)].width = width + +ws.auto_filter.ref = ws.dimensions +ws.freeze_panes = "A2" + +wb.save(OUTPUT_FILE) +print(f"Saved: {OUTPUT_FILE} ({max_row - 1} rows, sheet '{SHEET_NAME}')")