z230
This commit is contained in:
@@ -5,14 +5,25 @@ from openpyxl import load_workbook
|
|||||||
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
||||||
from openpyxl.utils import get_column_letter
|
from openpyxl.utils import get_column_letter
|
||||||
|
|
||||||
# STUDY = "42847922MDD3003"
|
STUDY = "42847922MDD3003"
|
||||||
STUDY = "77242113UCO3001"
|
#STUDY = "77242113UCO3001"
|
||||||
|
|
||||||
INVENTORY_DIR = Path(f"xls_reports_{STUDY}")
|
INVENTORY_DIR = Path(f"xls_reports_{STUDY}")
|
||||||
DESTRUCTION_DIR = Path(f"xls_ip_destruction_{STUDY}")
|
DESTRUCTION_DIR = Path(f"xls_ip_destruction_{STUDY}")
|
||||||
|
SHIPMENTS_FILE = Path(f"xls_shipments_{STUDY}/shipments_report_{STUDY}.xlsx")
|
||||||
|
DETAILS_DIR = Path(f"xls_shipment_details_{STUDY}")
|
||||||
OUTPUT_DIR = Path("output")
|
OUTPUT_DIR = Path("output")
|
||||||
OUTPUT_FILE = OUTPUT_DIR / f"{date.today().strftime('%Y-%m-%d')} {STUDY} CZ IWRS overview.xlsx"
|
OUTPUT_FILE = OUTPUT_DIR / f"{date.today().strftime('%Y-%m-%d')} {STUDY} CZ IWRS overview.xlsx"
|
||||||
|
|
||||||
|
SHIPMENT_DROP_COLS = {
|
||||||
|
"Location", "Shipped Date", "Delivered Date [UTC]",
|
||||||
|
"Delivery Recipient", "Delivery Details", "Cancelled Date",
|
||||||
|
"Tracking #", "Total Medication IDs",
|
||||||
|
"Shipping Category", "Study", "Destination Location", "Destination Site",
|
||||||
|
"Medication type", "Container ID", "Quantity of Medication IDs",
|
||||||
|
"Packaged Lot description",
|
||||||
|
}
|
||||||
|
|
||||||
# ── Shared constants ──────────────────────────────────────────────────────────
|
# ── Shared constants ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
COLUMN_RENAMES = {
|
COLUMN_RENAMES = {
|
||||||
@@ -144,6 +155,85 @@ def format_sheet(ws, header_color, highlight_col=None, highlight_color=None):
|
|||||||
ws.freeze_panes = "A2"
|
ws.freeze_panes = "A2"
|
||||||
|
|
||||||
|
|
||||||
|
# ── Shipment helpers ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def build_shipments():
|
||||||
|
sh = pd.read_excel(SHIPMENTS_FILE, sheet_name=0, header=5)
|
||||||
|
sh.columns = sh.columns.str.strip()
|
||||||
|
sh = sh.dropna(how="all")
|
||||||
|
sh["Shipment ID"] = sh["Shipment ID"].astype(str).str.strip()
|
||||||
|
sh = sh.drop(columns=[c for c in SHIPMENT_DROP_COLS if c in sh.columns])
|
||||||
|
shipment_cols = list(sh.columns)
|
||||||
|
|
||||||
|
all_rows = []
|
||||||
|
for _, s_row in sh.iterrows():
|
||||||
|
sid = s_row["Shipment ID"]
|
||||||
|
path = DETAILS_DIR / f"shipment_details_{sid}.xlsx"
|
||||||
|
if not path.exists():
|
||||||
|
continue
|
||||||
|
det = pd.read_excel(path, sheet_name=0, header=5)
|
||||||
|
det.columns = det.columns.str.strip()
|
||||||
|
det = det.dropna(how="all")
|
||||||
|
det["Shipment"] = det["Shipment"].astype(str).str.strip()
|
||||||
|
extra_cols = [c for c in det.columns if c not in shipment_cols and c != "Shipment" and c not in SHIPMENT_DROP_COLS]
|
||||||
|
for _, d_row in det.iterrows():
|
||||||
|
all_rows.append({**s_row.to_dict(), **{c: d_row[c] for c in extra_cols}})
|
||||||
|
|
||||||
|
result = pd.DataFrame(all_rows)
|
||||||
|
all_cols = shipment_cols + [c for c in extra_cols if c in result.columns]
|
||||||
|
result = result[all_cols]
|
||||||
|
|
||||||
|
for col in ["Request Date", "Received Date", "Expiration Date"]:
|
||||||
|
if col in result.columns:
|
||||||
|
result[col] = pd.to_datetime(result[col], errors="coerce")
|
||||||
|
|
||||||
|
print(f" Shipments: {result['Shipment ID'].nunique()} shipments, {len(result)} kitu")
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def build_site_summary(result):
|
||||||
|
STATUS_COLS = ["Available", "Assigned", "Dispensed", "Returned by Subject"]
|
||||||
|
pivot = result.groupby("Ship To:")["Status"].value_counts().unstack(fill_value=0)
|
||||||
|
for s in STATUS_COLS:
|
||||||
|
if s not in pivot.columns:
|
||||||
|
pivot[s] = 0
|
||||||
|
pivot = pivot[STATUS_COLS].reset_index().rename(columns={
|
||||||
|
"Ship To:": "Site", "Returned by Subject": "Returned"
|
||||||
|
})
|
||||||
|
pivot = pivot.sort_values("Site").reset_index(drop=True)
|
||||||
|
pivot["Total"] = pivot[["Available", "Assigned", "Dispensed", "Returned"]].sum(axis=1)
|
||||||
|
print(f" Site Summary: {len(pivot)} center")
|
||||||
|
return pivot
|
||||||
|
|
||||||
|
|
||||||
|
def format_shipment_sheet(ws, header_color_ship, header_color_detail, n_ship_cols):
|
||||||
|
thin = Side(style="thin", color="000000")
|
||||||
|
border = Border(left=thin, right=thin, top=thin, bottom=thin)
|
||||||
|
hfont = Font(bold=True, color="FFFFFF", name="Arial", size=10)
|
||||||
|
dfont = Font(name="Arial", size=10)
|
||||||
|
fill_ship = PatternFill("solid", start_color=header_color_ship)
|
||||||
|
fill_detail = PatternFill("solid", start_color=header_color_detail)
|
||||||
|
|
||||||
|
for cell in ws[1]:
|
||||||
|
cell.fill = fill_ship if cell.column <= n_ship_cols else fill_detail
|
||||||
|
cell.font = hfont
|
||||||
|
cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||||
|
cell.border = border
|
||||||
|
ws.column_dimensions[get_column_letter(cell.column)].width = min(len(str(cell.value or "")) + 4, 35)
|
||||||
|
ws.row_dimensions[1].height = 30
|
||||||
|
|
||||||
|
for row in ws.iter_rows(min_row=2, max_row=ws.max_row):
|
||||||
|
for cell in row:
|
||||||
|
cell.font = dfont
|
||||||
|
cell.border = border
|
||||||
|
cell.alignment = Alignment(horizontal="center", vertical="center")
|
||||||
|
if cell.value.__class__.__name__ in ("datetime", "date", "Timestamp"):
|
||||||
|
cell.number_format = "DD-MMM-YYYY"
|
||||||
|
|
||||||
|
ws.auto_filter.ref = ws.dimensions
|
||||||
|
ws.freeze_panes = "A2"
|
||||||
|
|
||||||
|
|
||||||
# ── Build DataFrames ──────────────────────────────────────────────────────────
|
# ── Build DataFrames ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
def build_main(lookup):
|
def build_main(lookup):
|
||||||
@@ -234,6 +324,10 @@ def main():
|
|||||||
not_returned_df = build_not_returned(df)
|
not_returned_df = build_not_returned(df)
|
||||||
destruction_df = build_kits_for_destruction(df)
|
destruction_df = build_kits_for_destruction(df)
|
||||||
|
|
||||||
|
shipments_df = build_shipments()
|
||||||
|
site_summary_df = build_site_summary(shipments_df)
|
||||||
|
n_ship_cols = shipments_df.columns.tolist().index("Investigator") # first detail col index (0-based)
|
||||||
|
|
||||||
# Write all sheets
|
# Write all sheets
|
||||||
with pd.ExcelWriter(OUTPUT_FILE, engine="openpyxl") as writer:
|
with pd.ExcelWriter(OUTPUT_FILE, engine="openpyxl") as writer:
|
||||||
df.to_excel( writer, index=False, sheet_name="CountryMedicationOverview")
|
df.to_excel( writer, index=False, sheet_name="CountryMedicationOverview")
|
||||||
@@ -241,6 +335,8 @@ def main():
|
|||||||
assigned_df.to_excel( writer, index=False, sheet_name="Assigned not dispensed")
|
assigned_df.to_excel( writer, index=False, sheet_name="Assigned not dispensed")
|
||||||
not_returned_df.to_excel( writer, index=False, sheet_name="Not returned")
|
not_returned_df.to_excel( writer, index=False, sheet_name="Not returned")
|
||||||
destruction_df.to_excel( writer, index=False, sheet_name="Kits for destruction")
|
destruction_df.to_excel( writer, index=False, sheet_name="Kits for destruction")
|
||||||
|
shipments_df.to_excel( writer, index=False, sheet_name="Shipments")
|
||||||
|
site_summary_df.to_excel( writer, index=False, sheet_name="Site Summary")
|
||||||
|
|
||||||
# Format all sheets
|
# Format all sheets
|
||||||
wb = load_workbook(OUTPUT_FILE)
|
wb = load_workbook(OUTPUT_FILE)
|
||||||
@@ -261,9 +357,12 @@ def main():
|
|||||||
format_sheet(wb["Assigned not dispensed"], header_color="833C00", highlight_col="Subject ID", highlight_color="FFF2CC")
|
format_sheet(wb["Assigned not dispensed"], header_color="833C00", highlight_col="Subject ID", highlight_color="FFF2CC")
|
||||||
format_sheet(wb["Not returned"], header_color="375623", highlight_col="Max Visit Date", highlight_color="E2EFDA")
|
format_sheet(wb["Not returned"], header_color="375623", highlight_col="Max Visit Date", highlight_color="E2EFDA")
|
||||||
format_sheet(wb["Kits for destruction"], header_color="595959")
|
format_sheet(wb["Kits for destruction"], header_color="595959")
|
||||||
|
format_shipment_sheet(wb["Shipments"], "1F4E79", "375623", n_ship_cols)
|
||||||
|
format_sheet(wb["Site Summary"], header_color="1F4E79")
|
||||||
|
|
||||||
wb.save(OUTPUT_FILE)
|
wb.save(OUTPUT_FILE)
|
||||||
print(f"\nSaved: {OUTPUT_FILE} ({len(df)} rows on main sheet, {wb.sheetnames})")
|
print(f"\nSaved: {OUTPUT_FILE} ({len(df)} rows on main sheet, {wb.sheetnames})")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
import pandas as pd
|
||||||
|
import openpyxl
|
||||||
|
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
||||||
|
from openpyxl.utils import get_column_letter
|
||||||
|
from datetime import date
|
||||||
|
import os
|
||||||
|
|
||||||
|
STUDY = "77242113UCO3001"
|
||||||
|
SHIPMENTS_FILE = f"xls_shipments_{STUDY}/shipments_report_{STUDY}.xlsx"
|
||||||
|
DETAILS_DIR = f"xls_shipment_details_{STUDY}"
|
||||||
|
OUTPUT_DIR = "output"
|
||||||
|
TEST_SHIPMENT = None # None = vsechny shipments
|
||||||
|
|
||||||
|
DROP_COLS = {
|
||||||
|
"Location", "Shipped Date", "Delivered Date [UTC]",
|
||||||
|
"Delivery Recipient", "Delivery Details", "Cancelled Date",
|
||||||
|
"Tracking #", "Total Medication IDs",
|
||||||
|
"Shipping Category", "Study", "Destination Location", "Destination Site",
|
||||||
|
"Medication type", "Container ID", "Quantity of Medication IDs",
|
||||||
|
"Packaged Lot description",
|
||||||
|
}
|
||||||
|
|
||||||
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
def read_shipments():
|
||||||
|
df = pd.read_excel(SHIPMENTS_FILE, sheet_name=0, header=5)
|
||||||
|
df.columns = df.columns.str.strip()
|
||||||
|
df = df.dropna(how="all")
|
||||||
|
df["Shipment ID"] = df["Shipment ID"].astype(str).str.strip()
|
||||||
|
df = df.drop(columns=[c for c in DROP_COLS if c in df.columns])
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
def read_details(shipment_id):
|
||||||
|
path = os.path.join(DETAILS_DIR, f"shipment_details_{shipment_id}.xlsx")
|
||||||
|
if not os.path.exists(path):
|
||||||
|
return None
|
||||||
|
df = pd.read_excel(path, sheet_name=0, header=5)
|
||||||
|
df.columns = df.columns.str.strip()
|
||||||
|
df = df.dropna(how="all")
|
||||||
|
df["Shipment"] = df["Shipment"].astype(str).str.strip()
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
def build_report():
|
||||||
|
shipments = read_shipments()
|
||||||
|
if TEST_SHIPMENT:
|
||||||
|
shipments = shipments[shipments["Shipment ID"] == TEST_SHIPMENT]
|
||||||
|
|
||||||
|
shipment_cols = list(shipments.columns)
|
||||||
|
all_rows = []
|
||||||
|
|
||||||
|
for _, s_row in shipments.iterrows():
|
||||||
|
sid = s_row["Shipment ID"]
|
||||||
|
details = read_details(sid)
|
||||||
|
if details is None:
|
||||||
|
continue
|
||||||
|
extra_cols = [c for c in details.columns if c not in shipment_cols and c != "Shipment" and c not in DROP_COLS]
|
||||||
|
for _, d_row in details.iterrows():
|
||||||
|
row = {**s_row.to_dict(), **{c: d_row[c] for c in extra_cols}}
|
||||||
|
all_rows.append(row)
|
||||||
|
print(f" [{sid}] {len(details)} kitu")
|
||||||
|
|
||||||
|
result = pd.DataFrame(all_rows)
|
||||||
|
all_cols = shipment_cols + [c for c in extra_cols if c in result.columns]
|
||||||
|
result = result[all_cols]
|
||||||
|
|
||||||
|
wb = openpyxl.Workbook()
|
||||||
|
ws = wb.active
|
||||||
|
ws.title = "Shipments"
|
||||||
|
|
||||||
|
HEADER_FILL_SHIP = PatternFill("solid", fgColor="1F4E79")
|
||||||
|
HEADER_FILL_DETAIL = PatternFill("solid", fgColor="375623")
|
||||||
|
HEADER_FONT = Font(name="Arial", bold=True, color="FFFFFF", size=10)
|
||||||
|
DATA_FONT = Font(name="Arial", size=10)
|
||||||
|
BORDER = Border(
|
||||||
|
left=Side(style="thin", color="BFBFBF"),
|
||||||
|
right=Side(style="thin", color="BFBFBF"),
|
||||||
|
bottom=Side(style="thin", color="BFBFBF"),
|
||||||
|
)
|
||||||
|
|
||||||
|
n_ship = len(shipment_cols)
|
||||||
|
for ci, col in enumerate(all_cols, 1):
|
||||||
|
cell = ws.cell(row=1, column=ci, value=col)
|
||||||
|
cell.font = HEADER_FONT
|
||||||
|
cell.fill = HEADER_FILL_SHIP if ci <= n_ship else HEADER_FILL_DETAIL
|
||||||
|
cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||||
|
cell.border = BORDER
|
||||||
|
ws.row_dimensions[1].height = 30
|
||||||
|
|
||||||
|
for ri, (_, row) in enumerate(result.iterrows(), 2):
|
||||||
|
for ci, col in enumerate(all_cols, 1):
|
||||||
|
val = row[col]
|
||||||
|
if pd.isna(val):
|
||||||
|
val = None
|
||||||
|
elif hasattr(val, "date"):
|
||||||
|
val = val.date()
|
||||||
|
cell = ws.cell(row=ri, column=ci, value=val)
|
||||||
|
cell.font = DATA_FONT
|
||||||
|
cell.border = BORDER
|
||||||
|
cell.alignment = Alignment(horizontal="center", vertical="center")
|
||||||
|
if isinstance(val, date):
|
||||||
|
cell.number_format = "DD-MMM-YYYY"
|
||||||
|
|
||||||
|
ws.auto_filter.ref = ws.dimensions
|
||||||
|
ws.freeze_panes = "A2"
|
||||||
|
|
||||||
|
for ci, col in enumerate(all_cols, 1):
|
||||||
|
vals = [col] + [str(result.iloc[r][col]) for r in range(len(result)) if pd.notna(result.iloc[r][col])]
|
||||||
|
ws.column_dimensions[get_column_letter(ci)].width = min(max((len(v) for v in vals), default=10) + 2, 35)
|
||||||
|
|
||||||
|
# --- Sheet 2: Site Summary ---
|
||||||
|
STATUS_COLS = ["Available", "Assigned", "Dispensed", "Returned by Subject"]
|
||||||
|
pivot = result.groupby("Ship To:")["Status"].value_counts().unstack(fill_value=0)
|
||||||
|
for s in STATUS_COLS:
|
||||||
|
if s not in pivot.columns:
|
||||||
|
pivot[s] = 0
|
||||||
|
pivot = pivot[STATUS_COLS].reset_index().rename(columns={"Ship To:": "Site", "Returned by Subject": "Returned"})
|
||||||
|
pivot = pivot.sort_values("Site").reset_index(drop=True)
|
||||||
|
pivot["Total"] = pivot[["Available", "Assigned", "Dispensed", "Returned"]].sum(axis=1)
|
||||||
|
|
||||||
|
ws2 = wb.create_sheet("Site Summary")
|
||||||
|
summary_cols = ["Site", "Available", "Assigned", "Dispensed", "Returned", "Total"]
|
||||||
|
HEADER_FILL_SUMM = PatternFill("solid", fgColor="1F4E79")
|
||||||
|
|
||||||
|
for ci, col in enumerate(summary_cols, 1):
|
||||||
|
cell = ws2.cell(row=1, column=ci, value=col)
|
||||||
|
cell.font = HEADER_FONT
|
||||||
|
cell.fill = HEADER_FILL_SUMM
|
||||||
|
cell.alignment = Alignment(horizontal="center", vertical="center")
|
||||||
|
cell.border = BORDER
|
||||||
|
ws2.row_dimensions[1].height = 25
|
||||||
|
|
||||||
|
for ri, (_, row) in enumerate(pivot.iterrows(), 2):
|
||||||
|
for ci, col in enumerate(summary_cols, 1):
|
||||||
|
cell = ws2.cell(row=ri, column=ci, value=row[col])
|
||||||
|
cell.font = DATA_FONT
|
||||||
|
cell.border = BORDER
|
||||||
|
cell.alignment = Alignment(horizontal="center", vertical="center")
|
||||||
|
|
||||||
|
for ci, col in enumerate(summary_cols, 1):
|
||||||
|
vals = [col] + [str(pivot.iloc[r][col]) for r in range(len(pivot))]
|
||||||
|
ws2.column_dimensions[get_column_letter(ci)].width = min(max(len(v) for v in vals) + 4, 35)
|
||||||
|
|
||||||
|
ws2.freeze_panes = "A2"
|
||||||
|
|
||||||
|
suffix = f"_{TEST_SHIPMENT}" if TEST_SHIPMENT else ""
|
||||||
|
pattern = f"{STUDY} CZ Shipments{suffix}.xlsx"
|
||||||
|
for old in os.listdir(OUTPUT_DIR):
|
||||||
|
if old.endswith(pattern):
|
||||||
|
try:
|
||||||
|
os.remove(os.path.join(OUTPUT_DIR, old))
|
||||||
|
print(f"Smazan -> {old}")
|
||||||
|
except OSError:
|
||||||
|
print(f"Preskakuji smazani (soubor otevren?) -> {old}")
|
||||||
|
|
||||||
|
outfile = os.path.join(OUTPUT_DIR, f"{date.today()} {STUDY} CZ Shipments{suffix}.xlsx")
|
||||||
|
wb.save(outfile)
|
||||||
|
print(f"\nUlozeno -> {outfile}")
|
||||||
|
|
||||||
|
|
||||||
|
build_report()
|
||||||
@@ -13,78 +13,64 @@ STUDY = "77242113UCO3001"
|
|||||||
OUTPUT_DIR = f"xls_ip_destruction_{STUDY}"
|
OUTPUT_DIR = f"xls_ip_destruction_{STUDY}"
|
||||||
# ────────────────────────────────────────────────────────────────────────────
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
def run(page, study):
|
||||||
|
output_dir = f"xls_ip_destruction_{study}"
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
page.goto(f"{BASE_URL}/report/ip_destruction_form")
|
||||||
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
|
page.locator('input[placeholder="search"], input[type="text"]').first.click()
|
||||||
|
page.wait_for_timeout(1000)
|
||||||
|
baskets = [b.strip() for b in page.locator('mat-option').all_inner_texts()
|
||||||
|
if b.strip() and b.strip() != "No results found"]
|
||||||
|
print(f" Nalezeno {len(baskets)} kosiku: {baskets}")
|
||||||
|
page.keyboard.press("Escape")
|
||||||
|
page.wait_for_timeout(500)
|
||||||
|
|
||||||
|
if not baskets:
|
||||||
|
print(" Zadne destruction kosite — preskakuji.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for basket in baskets:
|
||||||
|
filename = os.path.join(output_dir, f"ip_destruction_basket_{basket}.xlsx")
|
||||||
|
if os.path.exists(filename):
|
||||||
|
print(f" [{basket}] Preskakuji — existuje.")
|
||||||
|
continue
|
||||||
|
print(f" [{basket}] Stahuji...")
|
||||||
|
input_field = page.locator('input[placeholder="search"], input[type="text"]').first
|
||||||
|
input_field.click()
|
||||||
|
input_field.fill(basket)
|
||||||
|
page.wait_for_timeout(500)
|
||||||
|
page.locator('mat-option').first.dispatch_event('click')
|
||||||
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
|
with page.expect_download(timeout=120000) as dl:
|
||||||
|
page.get_by_role("button", name="Download XLS").click()
|
||||||
|
dl.value.save_as(filename)
|
||||||
|
print(f" [{basket}] OK")
|
||||||
|
|
||||||
|
page.get_by_role("button", name="Clear").click()
|
||||||
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
|
print(" Destruction hotovo.")
|
||||||
|
|
||||||
|
|
||||||
def download_ip_destruction():
|
if __name__ == "__main__":
|
||||||
|
from playwright.sync_api import sync_playwright
|
||||||
with sync_playwright() as p:
|
with sync_playwright() as p:
|
||||||
browser = p.chromium.launch(headless=False)
|
browser = p.chromium.launch(headless=False)
|
||||||
context = browser.new_context(accept_downloads=True)
|
context = browser.new_context(accept_downloads=True)
|
||||||
page = context.new_page()
|
page = context.new_page()
|
||||||
|
|
||||||
# Přihlášení
|
|
||||||
page.goto(BASE_URL)
|
page.goto(BASE_URL)
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
page.get_by_label("Email *").fill(EMAIL)
|
page.get_by_label("Email *").fill(EMAIL)
|
||||||
page.get_by_label("Password *").fill(PASSWORD)
|
page.get_by_label("Password *").fill(PASSWORD)
|
||||||
page.locator('#login__submit').click()
|
page.locator('#login__submit').click()
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
|
|
||||||
# Výběr studie
|
|
||||||
page.get_by_label("Study *").click()
|
page.get_by_label("Study *").click()
|
||||||
page.get_by_role("option", name=STUDY).click()
|
page.get_by_role("option", name=STUDY).click()
|
||||||
page.get_by_role("button", name="SELECT").click()
|
page.get_by_role("button", name="SELECT").click()
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
|
run(page, STUDY)
|
||||||
# Naviguj na report
|
|
||||||
page.goto(f"{BASE_URL}/report/ip_destruction_form")
|
|
||||||
page.wait_for_load_state("networkidle", timeout=15000)
|
|
||||||
|
|
||||||
# Přečti dostupné košíky
|
|
||||||
page.locator('input[placeholder="search"], input[type="text"]').first.click()
|
|
||||||
page.wait_for_timeout(1000)
|
|
||||||
baskets = [b.strip() for b in page.locator('mat-option').all_inner_texts()
|
|
||||||
if b.strip() != "No results found"]
|
|
||||||
print(f"Nalezeno {len(baskets)} košíků: {baskets}")
|
|
||||||
page.keyboard.press("Escape")
|
|
||||||
page.wait_for_timeout(500)
|
|
||||||
|
|
||||||
if not baskets:
|
|
||||||
print("Žádné destruction košíky nenalezeny — přeskakuji.")
|
|
||||||
browser.close()
|
browser.close()
|
||||||
return
|
|
||||||
|
|
||||||
for basket in baskets:
|
|
||||||
filename = os.path.join(OUTPUT_DIR, f"ip_destruction_basket_{basket}.xlsx")
|
|
||||||
if os.path.exists(filename):
|
|
||||||
print(f"[{basket}] Přeskakuji — soubor již existuje.")
|
|
||||||
continue
|
|
||||||
print(f"[{basket}] Stahuji...")
|
|
||||||
|
|
||||||
# Otevři dropdown a vyber košík přes dispatch_event
|
|
||||||
input_field = page.locator('input[placeholder="search"], input[type="text"]').first
|
|
||||||
input_field.click()
|
|
||||||
input_field.fill(basket)
|
|
||||||
page.wait_for_timeout(500)
|
|
||||||
page.locator('mat-option').first.dispatch_event('click')
|
|
||||||
|
|
||||||
# Počkej na načtení dat
|
|
||||||
page.wait_for_load_state("networkidle", timeout=30000)
|
|
||||||
|
|
||||||
# Stáhni XLS
|
|
||||||
with page.expect_download(timeout=30000) as dl:
|
|
||||||
page.get_by_role("button", name="Download XLS").click()
|
|
||||||
|
|
||||||
download = dl.value
|
|
||||||
download.save_as(filename)
|
|
||||||
print(f"[{basket}] Uloženo → {filename}")
|
|
||||||
|
|
||||||
# Reset pro další košík
|
|
||||||
page.get_by_role("button", name="Clear").click()
|
|
||||||
page.wait_for_load_state("networkidle", timeout=15000)
|
|
||||||
|
|
||||||
browser.close()
|
|
||||||
print("\nHotovo!")
|
|
||||||
|
|
||||||
|
|
||||||
download_ip_destruction()
|
|
||||||
|
|||||||
+26
-38
@@ -38,58 +38,46 @@ SITES = {
|
|||||||
OUTPUT_DIR = f"xls_reports_{STUDY}"
|
OUTPUT_DIR = f"xls_reports_{STUDY}"
|
||||||
# ────────────────────────────────────────────────────────────────────────────
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
def run(page, study):
|
||||||
|
output_dir = f"xls_reports_{study}"
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
page.goto(f"{BASE_URL}/report/onsite_inventory_detail")
|
||||||
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
|
for site_id in SITES[study]:
|
||||||
|
print(f" [{site_id}] Stahuji...")
|
||||||
|
page.locator('input[placeholder="search"], input[type="text"]').first.click()
|
||||||
|
page.get_by_role("option", name=site_id).click()
|
||||||
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
|
with page.expect_download(timeout=120000) as dl:
|
||||||
|
page.get_by_role("button", name="Download XLS").click()
|
||||||
|
|
||||||
|
dl.value.save_as(os.path.join(output_dir, f"onsite_inventory_detail_{site_id}.xlsx"))
|
||||||
|
print(f" [{site_id}] OK")
|
||||||
|
|
||||||
|
page.get_by_role("button", name="Clear").click()
|
||||||
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
|
print(" Inventory hotovo.")
|
||||||
|
|
||||||
|
|
||||||
def download_reports():
|
if __name__ == "__main__":
|
||||||
|
from playwright.sync_api import sync_playwright
|
||||||
with sync_playwright() as p:
|
with sync_playwright() as p:
|
||||||
browser = p.chromium.launch(headless=False)
|
browser = p.chromium.launch(headless=False)
|
||||||
context = browser.new_context(accept_downloads=True)
|
context = browser.new_context(accept_downloads=True)
|
||||||
page = context.new_page()
|
page = context.new_page()
|
||||||
|
|
||||||
# Přihlášení
|
|
||||||
page.goto(BASE_URL)
|
page.goto(BASE_URL)
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
page.get_by_label("Email *").fill(EMAIL)
|
page.get_by_label("Email *").fill(EMAIL)
|
||||||
page.get_by_label("Password *").fill(PASSWORD)
|
page.get_by_label("Password *").fill(PASSWORD)
|
||||||
page.locator('#login__submit').click()
|
page.locator('#login__submit').click()
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
|
|
||||||
# Výběr studie
|
|
||||||
page.get_by_label("Study *").click()
|
page.get_by_label("Study *").click()
|
||||||
page.get_by_role("option", name=STUDY).click()
|
page.get_by_role("option", name=STUDY).click()
|
||||||
page.get_by_role("button", name="SELECT").click()
|
page.get_by_role("button", name="SELECT").click()
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
|
run(page, STUDY)
|
||||||
# Naviguj na report stránku
|
|
||||||
page.goto(f"{BASE_URL}/report/onsite_inventory_detail")
|
|
||||||
page.wait_for_load_state("networkidle", timeout=15000)
|
|
||||||
|
|
||||||
for site_id in SITES[STUDY]:
|
|
||||||
print(f"[{site_id}] Stahuji...")
|
|
||||||
|
|
||||||
# Otevři dropdown a vyber site
|
|
||||||
page.locator('input[placeholder="search"], input[type="text"]').first.click()
|
|
||||||
page.get_by_role("option", name=site_id).click()
|
|
||||||
|
|
||||||
# Počkej na dokončení načítání dat (síť se uklidní)
|
|
||||||
page.wait_for_load_state("networkidle", timeout=30000)
|
|
||||||
|
|
||||||
# Stáhni XLS
|
|
||||||
with page.expect_download(timeout=30000) as dl:
|
|
||||||
page.get_by_role("button", name="Download XLS").click()
|
|
||||||
|
|
||||||
download = dl.value
|
|
||||||
filename = os.path.join(OUTPUT_DIR, f"onsite_inventory_detail_{site_id}.xlsx")
|
|
||||||
download.save_as(filename)
|
|
||||||
print(f"[{site_id}] Ulozeno: {filename}")
|
|
||||||
|
|
||||||
# Zruš výběr site pro další iteraci
|
|
||||||
page.get_by_role("button", name="Clear").click()
|
|
||||||
page.wait_for_load_state("networkidle", timeout=15000)
|
|
||||||
|
|
||||||
browser.close()
|
browser.close()
|
||||||
print("\nHotovo! Všechny reporty staženy.")
|
|
||||||
|
|
||||||
|
|
||||||
download_reports()
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from playwright.sync_api import sync_playwright
|
from playwright.sync_api import sync_playwright
|
||||||
import os
|
import os
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
# ── CONFIG ──────────────────────────────────────────────────────────────────
|
# ── CONFIG ──────────────────────────────────────────────────────────────────
|
||||||
BASE_URL = "https://janssen.4gclinical.com"
|
BASE_URL = "https://janssen.4gclinical.com"
|
||||||
@@ -7,58 +8,52 @@ BASE_URL = "https://janssen.4gclinical.com"
|
|||||||
EMAIL = "vbuzalka@its.jnj.com"
|
EMAIL = "vbuzalka@its.jnj.com"
|
||||||
PASSWORD = "Vlado123++-+"
|
PASSWORD = "Vlado123++-+"
|
||||||
|
|
||||||
# STUDY = "42847922MDD3003"
|
STUDY = "42847922MDD3003"
|
||||||
STUDY = "77242113UCO3001"
|
#STUDY = "77242113UCO3001"
|
||||||
|
|
||||||
OUTPUT_DIR = f"xls_shipment_details_{STUDY}"
|
OUTPUT_DIR = f"xls_shipment_details_{STUDY}"
|
||||||
# ────────────────────────────────────────────────────────────────────────────
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
def get_cz_shipment_ids(study):
|
||||||
|
path = f"xls_shipments_{study}/shipments_report_{study}.xlsx"
|
||||||
|
if not os.path.exists(path):
|
||||||
|
return None
|
||||||
|
df = pd.read_excel(path, header=5)
|
||||||
|
df.columns = df.columns.str.strip()
|
||||||
|
df = df.dropna(how="all")
|
||||||
|
df["Shipment ID"] = df["Shipment ID"].astype(str).str.strip()
|
||||||
|
cz = df[df["Location"].str.contains("Czech", na=False, case=False)]
|
||||||
|
return cz["Shipment ID"].tolist()
|
||||||
|
|
||||||
|
|
||||||
def download_shipment_details():
|
def run(page, study):
|
||||||
with sync_playwright() as p:
|
output_dir = f"xls_shipment_details_{study}"
|
||||||
browser = p.chromium.launch(headless=False)
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
context = browser.new_context(accept_downloads=True)
|
|
||||||
page = context.new_page()
|
|
||||||
|
|
||||||
# Prihlaseni
|
|
||||||
page.goto(BASE_URL)
|
|
||||||
page.wait_for_load_state("networkidle")
|
|
||||||
page.get_by_label("Email *").fill(EMAIL)
|
|
||||||
page.get_by_label("Password *").fill(PASSWORD)
|
|
||||||
page.locator('#login__submit').click()
|
|
||||||
page.wait_for_load_state("networkidle")
|
|
||||||
|
|
||||||
# Vyber studie
|
|
||||||
page.get_by_label("Study *").click()
|
|
||||||
page.get_by_role("option", name=STUDY).click()
|
|
||||||
page.get_by_role("button", name="SELECT").click()
|
|
||||||
page.wait_for_load_state("networkidle")
|
|
||||||
|
|
||||||
# Naviguj na Shipment Details Report
|
|
||||||
page.goto(f"{BASE_URL}/report/shipment_details_report")
|
page.goto(f"{BASE_URL}/report/shipment_details_report")
|
||||||
page.wait_for_load_state("networkidle", timeout=15000)
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
# Precti dostupne shipments z dropdownu
|
cz_ids = get_cz_shipment_ids(study)
|
||||||
|
if cz_ids is not None:
|
||||||
|
shipments = cz_ids
|
||||||
|
print(f" Filtrovano ze shipments reportu: {len(shipments)} CZ shipmentu")
|
||||||
|
else:
|
||||||
page.locator('input[placeholder="search"], input[type="text"]').first.click()
|
page.locator('input[placeholder="search"], input[type="text"]').first.click()
|
||||||
page.wait_for_timeout(1000)
|
page.wait_for_timeout(1000)
|
||||||
shipments = [s.strip() for s in page.locator('mat-option').all_inner_texts()
|
shipments = [s.strip() for s in page.locator('mat-option').all_inner_texts()
|
||||||
if s.strip() and s.strip() != "No results found"]
|
if s.strip() and s.strip() != "No results found"]
|
||||||
print(f"Nalezeno {len(shipments)} shipmentu: {shipments}")
|
print(f" Nalezeno {len(shipments)} shipmentu z dropdownu")
|
||||||
page.keyboard.press("Escape")
|
page.keyboard.press("Escape")
|
||||||
page.wait_for_timeout(500)
|
page.wait_for_timeout(500)
|
||||||
|
|
||||||
if not shipments:
|
if not shipments:
|
||||||
print("Zadne shipments nenalezeny — konec.")
|
print(" Zadne shipments — preskakuji.")
|
||||||
browser.close()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
for shipment in shipments:
|
for shipment in shipments:
|
||||||
safe_name = shipment.replace("/", "-").replace("\\", "-").replace(" ", "_")
|
filename = os.path.join(output_dir, f"shipment_details_{shipment}.xlsx")
|
||||||
filename = os.path.join(OUTPUT_DIR, f"shipment_details_{safe_name}.xlsx")
|
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
print(f"[{shipment}] Preskakuji — soubor jiz existuje.")
|
print(f" [{shipment}] Preskakuji — existuje.")
|
||||||
continue
|
continue
|
||||||
print(f" [{shipment}] Stahuji...")
|
print(f" [{shipment}] Stahuji...")
|
||||||
|
|
||||||
@@ -67,20 +62,34 @@ def download_shipment_details():
|
|||||||
input_field.fill(shipment)
|
input_field.fill(shipment)
|
||||||
page.wait_for_timeout(500)
|
page.wait_for_timeout(500)
|
||||||
page.locator('mat-option').first.dispatch_event('click')
|
page.locator('mat-option').first.dispatch_event('click')
|
||||||
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
page.wait_for_load_state("networkidle", timeout=30000)
|
with page.expect_download(timeout=120000) as dl:
|
||||||
|
|
||||||
with page.expect_download(timeout=30000) as dl:
|
|
||||||
page.get_by_role("button", name="Download XLS").click()
|
page.get_by_role("button", name="Download XLS").click()
|
||||||
|
|
||||||
dl.value.save_as(filename)
|
dl.value.save_as(filename)
|
||||||
print(f"[{shipment}] Ulozeno -> {filename}")
|
print(f" [{shipment}] OK")
|
||||||
|
|
||||||
page.get_by_role("button", name="Clear").click()
|
page.get_by_role("button", name="Clear").click()
|
||||||
page.wait_for_load_state("networkidle", timeout=15000)
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
|
print(" Shipment details hotovo.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from playwright.sync_api import sync_playwright
|
||||||
|
with sync_playwright() as p:
|
||||||
|
browser = p.chromium.launch(headless=False)
|
||||||
|
context = browser.new_context(accept_downloads=True)
|
||||||
|
page = context.new_page()
|
||||||
|
page.goto(BASE_URL)
|
||||||
|
page.wait_for_load_state("networkidle")
|
||||||
|
page.get_by_label("Email *").fill(EMAIL)
|
||||||
|
page.get_by_label("Password *").fill(PASSWORD)
|
||||||
|
page.locator('#login__submit').click()
|
||||||
|
page.wait_for_load_state("networkidle")
|
||||||
|
page.get_by_label("Study *").click()
|
||||||
|
page.get_by_role("option", name=STUDY).click()
|
||||||
|
page.get_by_role("button", name="SELECT").click()
|
||||||
|
page.wait_for_load_state("networkidle")
|
||||||
|
run(page, STUDY)
|
||||||
browser.close()
|
browser.close()
|
||||||
print("\nHotovo!")
|
|
||||||
|
|
||||||
|
|
||||||
download_shipment_details()
|
|
||||||
|
|||||||
@@ -13,43 +13,35 @@ STUDY = "77242113UCO3001"
|
|||||||
OUTPUT_DIR = f"xls_shipments_{STUDY}"
|
OUTPUT_DIR = f"xls_shipments_{STUDY}"
|
||||||
# ────────────────────────────────────────────────────────────────────────────
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
def run(page, study):
|
||||||
|
output_dir = f"xls_shipments_{study}"
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
page.goto(f"{BASE_URL}/report/shipments_report")
|
||||||
|
page.wait_for_load_state("networkidle", timeout=120000)
|
||||||
|
|
||||||
|
filename = os.path.join(output_dir, f"shipments_report_{study}.xlsx")
|
||||||
|
with page.expect_download(timeout=120000) as dl:
|
||||||
|
page.get_by_role("button", name="Download XLS").click()
|
||||||
|
dl.value.save_as(filename)
|
||||||
|
print(f" Shipments report OK -> {filename}")
|
||||||
|
|
||||||
|
|
||||||
def download_shipments():
|
if __name__ == "__main__":
|
||||||
|
from playwright.sync_api import sync_playwright
|
||||||
with sync_playwright() as p:
|
with sync_playwright() as p:
|
||||||
browser = p.chromium.launch(headless=False)
|
browser = p.chromium.launch(headless=False)
|
||||||
context = browser.new_context(accept_downloads=True)
|
context = browser.new_context(accept_downloads=True)
|
||||||
page = context.new_page()
|
page = context.new_page()
|
||||||
|
|
||||||
# Prihlaseni
|
|
||||||
page.goto(BASE_URL)
|
page.goto(BASE_URL)
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
page.get_by_label("Email *").fill(EMAIL)
|
page.get_by_label("Email *").fill(EMAIL)
|
||||||
page.get_by_label("Password *").fill(PASSWORD)
|
page.get_by_label("Password *").fill(PASSWORD)
|
||||||
page.locator('#login__submit').click()
|
page.locator('#login__submit').click()
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
|
|
||||||
# Vyber studie
|
|
||||||
page.get_by_label("Study *").click()
|
page.get_by_label("Study *").click()
|
||||||
page.get_by_role("option", name=STUDY).click()
|
page.get_by_role("option", name=STUDY).click()
|
||||||
page.get_by_role("button", name="SELECT").click()
|
page.get_by_role("button", name="SELECT").click()
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
|
run(page, STUDY)
|
||||||
# Naviguj na Shipments Report
|
|
||||||
page.goto(f"{BASE_URL}/report/shipments_report")
|
|
||||||
page.wait_for_load_state("networkidle", timeout=15000)
|
|
||||||
|
|
||||||
# Stahni report
|
|
||||||
filename = os.path.join(OUTPUT_DIR, f"shipments_report_{STUDY}.xlsx")
|
|
||||||
with page.expect_download(timeout=30000) as dl:
|
|
||||||
page.get_by_role("button", name="Download XLS").click()
|
|
||||||
|
|
||||||
dl.value.save_as(filename)
|
|
||||||
print(f"Ulozeno -> {filename}")
|
|
||||||
|
|
||||||
browser.close()
|
browser.close()
|
||||||
print("Hotovo!")
|
|
||||||
|
|
||||||
|
|
||||||
download_shipments()
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+85
@@ -0,0 +1,85 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from playwright.sync_api import sync_playwright
|
||||||
|
|
||||||
|
import download_reports
|
||||||
|
import download_ip_destruction
|
||||||
|
import download_shipments_report
|
||||||
|
import download_shipment_details
|
||||||
|
import create_accountability_report
|
||||||
|
|
||||||
|
BASE_URL = "https://janssen.4gclinical.com"
|
||||||
|
EMAIL = "vbuzalka@its.jnj.com"
|
||||||
|
PASSWORD = "Vlado123++-+"
|
||||||
|
|
||||||
|
STUDIES = {
|
||||||
|
"1": "77242113UCO3001",
|
||||||
|
"2": "42847922MDD3003",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def pick_study():
|
||||||
|
print("Vyber studii:")
|
||||||
|
for k, v in STUDIES.items():
|
||||||
|
print(f" {k}) {v}")
|
||||||
|
while True:
|
||||||
|
choice = input("Volba (1/2): ").strip()
|
||||||
|
if choice in STUDIES:
|
||||||
|
return STUDIES[choice]
|
||||||
|
print(" Neplatna volba, zkus znovu.")
|
||||||
|
|
||||||
|
|
||||||
|
def login_and_select_study(page, study):
|
||||||
|
print(f"\n[1/5] Prihlaseni a vyber studie {study}...")
|
||||||
|
page.goto(BASE_URL)
|
||||||
|
page.wait_for_load_state("networkidle")
|
||||||
|
page.get_by_label("Email *").fill(EMAIL)
|
||||||
|
page.get_by_label("Password *").fill(PASSWORD)
|
||||||
|
page.locator('#login__submit').click()
|
||||||
|
page.wait_for_load_state("networkidle")
|
||||||
|
page.get_by_label("Study *").click()
|
||||||
|
page.get_by_role("option", name=study).click()
|
||||||
|
page.get_by_role("button", name="SELECT").click()
|
||||||
|
page.wait_for_load_state("networkidle")
|
||||||
|
print(" OK")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
study = pick_study()
|
||||||
|
|
||||||
|
with sync_playwright() as p:
|
||||||
|
browser = p.chromium.launch(headless=False)
|
||||||
|
context = browser.new_context(accept_downloads=True)
|
||||||
|
page = context.new_page()
|
||||||
|
|
||||||
|
login_and_select_study(page, study)
|
||||||
|
|
||||||
|
print(f"\n[2/5] Stahuji inventory reporty...")
|
||||||
|
download_reports.run(page, study)
|
||||||
|
|
||||||
|
print(f"\n[3/5] Stahuji IP destruction reporty...")
|
||||||
|
download_ip_destruction.run(page, study)
|
||||||
|
|
||||||
|
print(f"\n[4/5] Stahuji shipments report...")
|
||||||
|
download_shipments_report.run(page, study)
|
||||||
|
|
||||||
|
print(f"\n[5/5] Stahuji shipment details...")
|
||||||
|
download_shipment_details.run(page, study)
|
||||||
|
|
||||||
|
browser.close()
|
||||||
|
|
||||||
|
print(f"\n[6/6] Generuji accountability report...")
|
||||||
|
create_accountability_report.STUDY = study
|
||||||
|
create_accountability_report.INVENTORY_DIR = __import__("pathlib").Path(f"xls_reports_{study}")
|
||||||
|
create_accountability_report.DESTRUCTION_DIR= __import__("pathlib").Path(f"xls_ip_destruction_{study}")
|
||||||
|
create_accountability_report.SHIPMENTS_FILE = __import__("pathlib").Path(f"xls_shipments_{study}/shipments_report_{study}.xlsx")
|
||||||
|
create_accountability_report.DETAILS_DIR = __import__("pathlib").Path(f"xls_shipment_details_{study}")
|
||||||
|
create_accountability_report.OUTPUT_FILE = create_accountability_report.OUTPUT_DIR / f"{__import__('datetime').date.today().strftime('%Y-%m-%d')} {study} CZ IWRS overview.xlsx"
|
||||||
|
create_accountability_report.main()
|
||||||
|
|
||||||
|
print("\nVse hotovo!")
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user