# -*- coding: utf-8 -*- # ============================================================================= # Nazev: forward_offer_outlook_v1.0.py # Verze: 1.0 # Datum: 2026-06-16 # Popis: JNJ-native skript. Pres MAPI (Outlook, pywin32) najde v odeslane # poste PUVODNI uvodni nabidku ("Nabidka spoluprace na klinickem # hodnoceni pripravku icotrokinra...") odeslanou konkretnimu lekari # dne 31.05.2026 a vytvori jeji FORWARD (skutecny Outlook Forward, # tj. zachova original vcetne data, formatovani i hlavicky). # Forward predvyplni prijemce (lekar) + CC (Kocourkova, Bartosova), # volitelne prida kratky uvod a OTEVRE okno k rucni kontrole/odeslani. # Pouziti: Spustit v JNJ Pythonu, kde je nakonfigurovany Outlook s JNJ schrankou. # Vyzaduje pywin32: pip install pywin32 # python forward_offer_outlook_v1.0.py # Bezpecnost: ACTION = "display" => jen otevre Forward, NEODESILA. # "draft" => ulozi do Konceptu. "send" => odesle (uvazene zapnout). # ============================================================================= import sys import datetime import win32com.client # pywin32 # ----------------------------- KONFIGURACE ----------------------------------- # JNJ schranka (odesilatel puvodnich nabidek). Pouzije se jeji slozka Odeslane. SENDER_SMTP = "vbuzalka@its.jnj.com" # Komu forwardovat. Pro odladeni zatim JEN Hustak; ostatni odkomentuj az to klapne. TARGETS = [ "rastislav.hustak@fntt.sk", # "voska@nemocnice-horovice.cz", # "sercl@seznam.cz", # "petra.minarikova@uvn.cz", ] # CC na kazdy forward (nas lokalni tym). CC_RECIPIENTS = ["AKocourk@ITS.JNJ.com", "EBartoso@ITS.JNJ.com"] # Identifikace puvodniho e-mailu: # - subjekt zacina na (po ocisteni) tento text (odlisi nabidku od pripominek/RE) SUBJECT_STARTSWITH = "nabidka spoluprace na klinickem hodnoceni" # - datum odeslani originalu ORIG_DATE = datetime.date(2026, 5, 31) # Volitelny kratky uvod nad forwardovanym originalem. # ADD_INTRO = False => ciste preposlani bez jakehokoli textu navic. ADD_INTRO = True INTRO_HTML = ( "

Dobry den,

" "

dovoluji si Vam znovu preposlat nize uvedenou nabidku ze dne " "31. kvetna 2026. Velmi bych ocenil Vase vyjadreni — a to " "i v pripade, ze o ucast nemate zajem. Dekuji.

" "

S pozdravem
MUDr. Vladimir Buzalka

" "
" ) # Co s vytvorenym forwardem: "display" | "draft" | "send" ACTION = "display" # ----------------------------------------------------------------------------- OL_FOLDER_SENT = 5 # olFolderSentMail OL_TO, OL_CC = 1, 2 # olTo, olCC PR_SMTP = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E" def norm(s): """male pismena bez diakritiky pro porovnani subjektu""" import unicodedata s = s or "" s = unicodedata.normalize("NFKD", s) s = "".join(c for c in s if not unicodedata.combining(c)) return " ".join(s.lower().split()) def smtp_of(recipient): try: return (recipient.PropertyAccessor.GetProperty(PR_SMTP) or "").lower() except Exception: try: return (recipient.Address or "").lower() except Exception: return "" def get_sent_folder(ns): """Slozka Odeslane prislusneho uctu (dle SENDER_SMTP), fallback default.""" try: for acct in ns.Accounts: if (acct.SmtpAddress or "").lower() == SENDER_SMTP.lower(): return acct.DeliveryStore.GetDefaultFolder(OL_FOLDER_SENT) except Exception: pass return ns.GetDefaultFolder(OL_FOLDER_SENT) def find_original(items, target_email): """Najde puvodni nabidku: subjekt + datum 31.05.2026 + prijemce To.""" tgt = target_email.lower() matches = [] for it in items: try: if it.Class != 43: # olMail continue if norm(it.Subject)[: len(SUBJECT_STARTSWITH)] != SUBJECT_STARTSWITH: continue sent = it.SentOn if sent is None or sent.date() != ORIG_DATE: continue for r in it.Recipients: if r.Type == OL_TO and smtp_of(r) == tgt: matches.append(it) break except Exception: continue return matches def main(): outlook = win32com.client.Dispatch("Outlook.Application") ns = outlook.GetNamespace("MAPI") sent = get_sent_folder(ns) items = sent.Items items.Sort("[SentOn]", True) # nejnovejsi prvni print("Slozka Odeslane:", sent.FolderPath) print("Rezim ACTION :", ACTION) print("=" * 60) for email in TARGETS: found = find_original(items, email) if not found: print(f"[!] {email}: PUVODNI NABIDKA NENALEZENA (subjekt/datum/prijemce). Preskakuji.") continue if len(found) > 1: print(f"[!] {email}: nalezeno {len(found)} shod — nejednoznacne, preskakuji (over rucne).") continue orig = found[0] fwd = orig.Forward() # SKUTECNY Outlook Forward (zachova original + datum) # prijemce fwd.Recipients.Add(email).Type = OL_TO for cc in CC_RECIPIENTS: fwd.Recipients.Add(cc).Type = OL_CC fwd.Recipients.ResolveAll() # volitelny uvod nad forward blokem if ADD_INTRO: try: fwd.HTMLBody = INTRO_HTML + fwd.HTMLBody except Exception: pass if ACTION == "send": fwd.Send() print(f"[ODESLANO] {email} (subjekt: {fwd.Subject})") elif ACTION == "draft": fwd.Save() print(f"[KONCEPT ] {email} (subjekt: {fwd.Subject})") else: # display fwd.Display() print(f"[OTEVRENO] {email} (subjekt: {fwd.Subject}) — zkontroluj a posli rucne") print("=" * 60) print("Hotovo.") if __name__ == "__main__": try: main() except Exception as e: print("CHYBA:", e) sys.exit(1)