
    >jc                     n   d Z ddlZddlZddlZddlZddlZddlZddlmZ  ed      Z	e	dz  dz  Z
e	dz  dz  Ze	dz  dz  Ze	dz  d	z  Ze	d
z  Z ed      Z ej                   dej"                        Zej&                  j)                  d ee	             ddlZd ZdefdZdefdZd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d4dZ)d5d Z*d5d!Z+d6d"Z,d# Z-d7d$Z.d8d%Z/d& Z0d9d'Z1d:d(Z2d) Z3d;d*Z4d<d+Z5d=d,Z6d- Z7d. Z8d/ Z9e e!e"e#e$ee%e&e'e7e(e8e9d0Z:defd1Z;d2 Z<e=d3k(  r e<        yy)>zPersistent local queue daemon for MichelBridge.

Runs inside the interactive Windows desktop session. WinRM only drops JSON jobs into
C:\MCSJAgent\MichelBridge\queue\in and reads results from queue\out.
    N)PathzC:\MCSJAgent\MichelBridgequeueindoneoutbadzmichel_daemon.logzC:\MCSJAgent\proof\MichelBridgezR\b(test|demo|sample|automation|macro|bot|llm|michel|speed\s*test)\b|MICHEL_|_TEST_c                     t         j                  dd       t        j                  dd      5 }|j	                  t        j                  d      dz   | z   dz          d d d        y # 1 sw Y   y xY w)	NTparentsexist_okautf-8encoding%Y-%m-%dT%H:%M:%S%z 
)ROOTmkdirLOGopenwritetimestrftime)msgfs     *C:/MCSJAgent/MichelBridge/michel_daemon.pylogr      sU    JJtdJ+	#	(A	34s:S@4GH 
)	(	(s   .A&&A/pathc                    | j                   j                  dd       | j                  | j                  dz         }|j	                  t        j                  |dd      d       t        j                  t        |      t        |              y )	NTr
   z.tmpF),:)ensure_ascii
separatorsr   r   )
parentr   with_suffixsuffix
write_textjsondumpsosreplacestr)r   objtmps      r   atomic_write_jsonr0      sf    KKdT2


4;;/
0CNN4::c*MX_N`JJs3xT#    c                 P    | j                  d      }t        j                  |      S )Nr   r   )	read_textr)   loads)r   txts     r   read_jobr6   &   s     
..'.
*C::c?r1   c           	      <   g }dD ]3  }| j                  |      s|j                  |t        | |         f       5 t        | j                  d      xs g       D ]T  \  }}t	        |t
              sdD ]9  }|j                  |      s|j                  d| d| t        ||         f       ; V g }|D ]A  \  }}t        j                  |      }|s|j                  ||j                  d      |d       C |r#t        dt        j                  |d	
      z         y)z>Reject internal/test wording in all PO business-facing fields.)descriptioncommentheader_commentlines)r8   noter9   zlines[z].r   )fieldmatchtextz,blocked internal/test wording in PO fields: Fr#   N)getappendr-   	enumerate
isinstancedictBANNED_PO_REsearchgroup
ValueErrorr)   r*   )	jobfieldskeyiliner   namer?   ms	            r   safe_po_text_checkrQ   +   s   F;773<MM3CH./ < SWWW-344dD!988C=MMVA3b#6DI"GH : 5
 C
d%JJ
DIJ  G$**UXglJmmnn r1   c           	          t         j                  dd       t        t         d|  dt        j                  d       dz        S )NTr
   zdaemon--z%Y%m%d-%H%M%Sz.png)PROOFr   r-   r   r   )prefixs    r   
proof_namerV   ?   s;    	KKtK,u$--*H)INNOOr1   c                 J   t        | j                  dd            j                         st        | d      |j	                  d      r| j                  d      st        | d      | j                  d      | j                  dd      t        | j                  d            d	S )
zZBusiness/write commands must carry a planning envelope so the daemon never blindly clicks.intent z; requires intent: what MCSJ task is being performed and whypo_approved_training_writez? requires approved_training_write=true for demo/training writesexpected_screenPurchase Order Maintenance)rX   r\   r[   )r-   rA   striprI   
startswithbool)rJ   action_names     r   require_business_reasoningrb   D   s    swwx$%++-K=(cdeee$SWW5N-OK=(ghii''(#77#46RS#'0I(J#K r1   c                 h   t        |        | j                  d      xs g }dd| j                  d      | j                  dd      g d| j                  dd	      | j                  d
      t        |      | j                  d      xs- |r)t        |d   t              r|d   j                  d      d	S d d	S )Nr;   	po_createznplan-before-execute: validate intent, screen, content, account, then perform deterministic UI steps with proofrX   r\   r]   )z0activate MCSJ and verify current database/windowz:reject internal/test wording in header/comment/line fieldsz6create header with explicit vendor/description/commentzYopen line items and select account by OCR-visible exact account text, not scroll positionz5verify selected account crop before saving first linezDsave each line, close line window, OCR final header and banned wordsvendorSACCH005r8   account_coder   account)	actionreasoning_contractrX   r\   	preflightre   r8   
line_countrg   )rQ   rA   lenrD   rE   )rJ   r;   s     r   po_create_planrn   Q   s    sGGG"E O''(#77#46RS
 ''(J/ww}-%j/~uYcdijkdlnrYsE!HLL4K!   z~! r1   c                     dt        |       dS )NT)okplan)rn   rJ   s    r   cmd_plan_po_creaters   h   s    s 344r1   c                     dddt        j                  d      t        j                         t	        t
              t        j                         dS )NTmichel_daemon   r   )rp   daemonversionr   pidqueue_instate)r   r   r+   getpidr-   QUEUE_INbridgewindow_staterr   s    r   
cmd_healthr   l   s>    !34yy{M$$& r1   c                 V    dt        j                         t        j                         dS )NT)rp   activatefingerprint)r~   activate_mcsjr   rr   s    r   cmd_activater   x   s!    F$8$8$:6K]K]K_``r1   c                 P    dt        j                  | j                  d            dS )NTr   )rp   
screenshot)r~   r   rA   rr   s    r   cmd_screenshotr   |   s     f&7&7&HIIr1   c                     dt        j                  t        | d         t        | d         t        | d         t        | d         | j                  d      t        | j                  dd                  d	S )
NTxywhr   psm   )rp   ocr)r~   crop_ocrintrA   rr   s    r   cmd_ocr_cropr      s    vs3s8}c#c(mSQTUXQY]\_`cdg`h\iknkrkrsykz|  AD  AH  AH  IN  PQ  AR  }S   T  U  Ur1   c                 0    dt        j                         dS )NT)rp   r   )r~   r   rr   s    r   cmd_fingerprintr      s    v'9'9';<<r1   c           
          t        j                          t        t        | d         t        | d         t	        | j                  dd                   dt        | d         t        | d         gdS )zALow-level click for calibration only; not for business workflows.r   r   wait      ?T)rp   clicked)r~   r   clickr   floatrA   rr   s    r   	cmd_clickr      sZ    
	#c#h-SXcggfd.C(DECCM3s3x=#ABBr1   c           	      .   t        j                          t        | d         }t        | j	                  dd            }t        |      D ]E  }t        j                  |       t        j                  t        | j	                  dd                   G d||dS )NrL   countrv   delayg{Gz?T)rp   pressedr   )
r~   r   r-   r   rA   rangetapr   sleepr   )rJ   rL   r   _s       r   	cmd_pressr      st    

c%j/C#$E5\

3

5$/01  377r1   c                 l   t        j                          t        j                  t        d            }t	        t        | j                  dd            t        | j                  dd            t        | j                  dd                   t        j                  t        d            }t        j                  d	d
ddt        d      t        | j                  dd                  }t        j                  d       t        j                  d       t        j                  t        d            }d||||dS )zUOpen the PO line-item account picklist from current line screen, OCR it, then Escape.zaccount-probe-beforer   i  r   i  r   皙?zaccount-probe-opened   x   i  l  zaccount-probe-cropr      r   ESCr   zaccount-probe-after-escT)rp   beforeopenedr   after)r~   r   r   rV   r   r   rA   r   r   r   r   r   )rJ   r   r   r   r   s        r   cmd_account_picklist_prober      s    
z*@ABF	#cggc3
 #cggc3&7"8%PS@T:UVz*@ABF
//#sCj9M.NTWX[X_X_`eghXiTj
kC
JJuJJtj)BCDE&F3QVWWr1   c                 p   t        j                          t        j                  t        d            }t        j                  ddddt        d      t        | j                  dd            	      }|j                  d
d      }t        t        d t        j                  |      D                    }dd|||dS )zBCompact proof/OCR for the currently visible PO header/line screen.z
po-current(       i  zpo-header-cropr   r   r   r?   rY   c              3   >   K   | ]  }|j                  d         yw)r   N)rH   ).0rP   s     r   	<genexpr>z(cmd_po_verify_current.<locals>.<genexpr>   s     E)DAQWWQZ)Ds   Tpo_verify_current)rp   screenr   
header_ocrbanned_matches)r~   r   r   rV   r   r   rA   sortedsetrF   finditer)rJ   shotheaderr?   r   s        r   cmd_po_verify_currentr      s    
Z56D__Rc3
;K0LRUVYV]V]^cefVgRhiF::fb!D
E)>)>t)DEE
FC% r1   c                 Z    dd l }|j                  | |       t        j                  |       y )Nr   )	pyautoguir   r   r   )r   r   r   r   s       r   r   r      s    OOAqJJtr1   c                     dd l }dd l}|j                  |        |j                  dd       t	        j
                  |       y )Nr   ctrlv)r   	pyperclipcopyhotkeyr   r   )r?   r   r   r   s       r   
paste_textr      s-    NN4VS!JJtr1   c                 r    dd l }|j                  dd       t        j                  d       t	        | |       y )Nr   r   r   皙?)r   r   r   r   r   )r?   r   r   s      r   select_all_paster      s+    VS!JJttTr1   c                 8    t        ddd       t        dd|        y )N      ?i  r   )r   )r   s    r   save_yesr      s    	#sD	#sDr1   c                 T    t        j                  dd| xs dj                               S )Nz	[^A-Z0-9]rY   )resubupper)ss    r   normalize_account_textr      s     66,QW"OO$566r1   c                 n   ddl m}m}m} dd l}t
        j                  j                  t        j                        rt        j                  |j                  _
        |j                  |       }|\  }}	}
}|j                  ||	||
z   |	|z   f      }|j                  |      j                  |j                        }t!        d      }|j#                  |       |j%                  |d| |j&                  j(                        }g }t+        |j-                  dg             D ]  \  }}|xs dj/                         }|s|j1                  |t3        |      t5        |d   |         |z   t5        |d	   |         |	z   t5        |d
   |         t5        |d   |         |j-                  dd g      |   d        ||fS )Nr   )ImageImageOpsImageFilterzocr-cropz--psm )configoutput_typer?   rY   lefttopwidthheightconf)r?   normr   r   r   r   r   )PILr   r   r   pytesseractr+   r   existsr~   	TESSERACTtesseract_cmdr   crop	grayscalefilterSHARPENrV   saveimage_to_dataOutputDICTrC   rA   r^   rB   r   r   )
image_pathcrop_boxr   r   r   r   r   imr   r   r   r   r   gray	crop_pathdatatokensrM   words                      r   _ocr_tokens_for_boxr      s   00	ww~~f&&'060@0@-	J	BJAq!Q77Aq!a%Q'(Dd#**;+>+>?D:&IIIi$$TF3%.kN`N`NeNe$fDFTXXfb124
!!#*40VQ(1,tE{1~&*gq)*$x.+,HHVdV,Q/
 		 3 fr1   c                    g }t        | d       D ]  }|d   |d   dz  z   }|rt        |d   d   |z
        |kD  r|j                  ||gd       @|d   d	   j                  |       t        t	        d
 |d   d	   D              t        |d   d	         z        |d   d<    |D ]=  }dj                  d t        |d	   d       D              |d<   t        |d         |d<   ? |S )Nc                 (    | d   | d   dz  z   | d   fS )Nr   r      r    ts    r   <lambda>z&_group_tokens_by_row.<locals>.<lambda>   s    QuX(q8H-H!F),Tr1   rL   r   r   r   cy)r  r   r   c              3   8   K   | ]  }|d    |d   dz  z     yw)r   r   r   Nr   r   r  s     r   r   z'_group_tokens_by_row.<locals>.<genexpr>   s%     $]J\QQuX(q0@%@J\s   r   c              3   &   K   | ]	  }|d      ywr?   Nr   r  s     r   r   z'_group_tokens_by_row.<locals>.<genexpr>   s     a2`Qqy2`   c                     | d   S )Nr   r   r   s    r   r  z&_group_tokens_by_row.<locals>.<lambda>   s    VWX^V_r1   r?   r   )r   absrB   r   sumrm   joinr   )r   	tolerancerowstokr  rows         r   _group_tokens_by_rowr     s    Df"TUZ#h-1,,s48D>B./);KKrcU34HX%%c* $]$r(S[J\$]!]`cdhikdlmudv`w!wxDHTN V hha&XL_2`aaF,S[9F  Kr1   c                    |sy|| v ryt        |      dk\  r|d d | v ryt        j                  d|       }|sy|j                  d      d t        |       }t        |      t        |      k7  ryt	        d t        ||      D              }|dk  S )	NFT   r  zA\d{7,8}r   c              3   2   K   | ]  \  }}||k7  sd   yw)rv   Nr   )r   r   bs      r   r   z+_account_code_like_match.<locals>.<genexpr>  s     B7TQ16q7s   rv   )rm   r   rG   rH   r  zip)row_normtarget_normrP   row_codedists        r   _account_code_like_matchr     s    h
;1Sb!1X!=
		+x(Awwqz+3{+,H
8}K((BS;7BBD19r1   c                 2    t        | |      }|s|S |xr || v S N)r  )r  r  
label_normcode_oks       r   _account_row_matchesr"    s&    &x=G-zX--r1   c           	         t        j                  t        d            }t        |d   |d      \  }}t	        |      }t        |       t        |xs d      g }|D ]7  }t        |d         s|j                  |d   |d   |d   d	|d   gd
       9 |sd|dd ||dS fd}	t        ||	      d   }
d|
d   |
|||dS )a  Return screen click point for an OCR-visible account row in the open picklist.

    Hard rule: choose the row whose OCR text matches the requested account/label. Do not
    scroll-position-click. This prevents selecting A-1110-0000 when A-1110-0400 was intended.
    zaccount-picklist-screenr   r   r   rY   r   r  r?   i  )r  r?   r   r   FN   )foundtargetlabelr  
proof_cropr   c                 z    d}j                  d      rd| d   v r|dz  }r| d   v r|dz  }| d   v r|dz  }|S )Nr   04000000r   d   
      )endswith)cpenaltyr   r&  s     r   scorez)ocr_find_account_in_region.<locals>.score.  sY    ??6"v6':sNG*&	1rMGQvYrMGr1   r  r   Tr   )r%  r   r&  r'  matched
candidatesr(  r   )	r~   r   rV   r   r  r   r"  rB   r   )rg   account_labelr   r   r   r   r  r4  r  r2  bestr   r&  s              @@r   ocr_find_account_in_regionr7    s    Z(ABCD+DL(JIv'D#L1F'(;<JJFVZ@SYFSQW[dgilmqircstu  &:tTWUWyhq  ~B  C  	C *%(+DDMVjei  zD  T]  im  n  nr1   c                      t        j                  t        d            } t        | d   dd      \  }}dj	                  d |D              }t        |      }| |||d|v xs
 d	|v xr d
|v dS )Nzaccount-message-checkr   )0  r9  i     r   r   r   c              3   &   K   | ]	  }|d      ywr	  r   r  s     r   r   z1detect_control_account_message.<locals>.<genexpr>>  s     .v!AfIvr
  ACCOUNTENTEREDISACONTROLACCOUNTCONTROLACCOUNTMESSAGE)r   r   r?   r   is_control_message)r~   r   rV   r   r  r   )r   r   r   r?   r   s        r   detect_control_account_messager@  ;  s    Z(?@AD+DL:NTUVIv88.v..D!$'DItT  bC  GK  bK  b  P`  dh  Ph  P~  mv  z~  m~  @  @r1   c                 Z   dd l }g }dD ]  }|r&|j                  |       t        j                  d       t	        |dz         D ]  }t        | |      }|j                  |       |j                  d      r||dd  D cg c]_  }|j                  d      |j                  d      |j                  d	      |j                  d
      t        |j                  dg             da c}|d<   ||d<   |c c S |j                  d       t        j                  d         |r|d   S dddS c c}w )Nr   )homeNgffffff?rv   r5  r%  r&  r'  r3  r  )r%  r&  r'  r3  
rows_countattempt_summaries
page_indexpagedownr  Fzno attempts)r%  error)	r   pressr   r   r   r7  rB   rA   rm   )	rg   r5  	max_pagesr   attemptsrL   pager%  r   s	            r   !_find_account_visible_with_scrollrN  C  sE   HOOC JJt)a-(D.|=YEOOE"yy! &bc].*  eeGnhRSRWRWX_R`mnmrmrs|m}  NQ  RS  RW  RW  X^  `b  Rc  Nd  e*.)* '+l#OOJ'JJt )	   $8B<Q5=)QQ.s   <A$D(c                    t        t        |d         t        |d         d       t        | |      }|j                  d      st	        j
                  d       t        j                  d       t        dt        |d         d	z
        }t        |d         }t        ||d
       t        t        |       d       t        t        |d         t        |d         d       t        | |      }|j                  d      s;t	        j
                  d       t        dt        j                  |d      dd z         t        |d   d   |d   d   d       t        t        |d         t        |d         d       t               }|j                  d      r)t        dt        j                  ||dd      dd z         t	        j                  g |t!        d      ddi}	t#        |	j                  dd            }
t#        |       }t#        |xs d      }||
v xs% t%        |      dk\  xr |dd |
v xs t'        |
|      }|s#t        d|  d|	j                  d      d|       ||	|d S )!zlOpen account picklist, find requested account row by OCR, click it, OK, and verify no control-account modal.r   rv   ffffff?rC  r%  r   皙?i  F   {Gz?333333?zdrequested account not OCR-visible in picklist after filter pass; refusing scroll-position fallback: Fr@   Ni@  r   r   r?  zFaccount selection produced control-account message; refusing to save: )	selectionmessagezaccount-selected-cropr   r   r?   rY   r  r  z9account verification failed after pick: expected account z, OCR=z, selection=)rU  selected_ocrmessage_check)r   r   rN  rA   r~   r   r   r   maxr   r-   rI   r)   r*   r@  r   rV   r   rm   r  )rg   r5  ellipsisrp   selected_cropr%  field_xfield_yr   selectedselected_normr  r   code_verifieds                 r   select_account_verifiedra  Z  s   	#hqk
C,c2-l-XE99W 	

5

3c3x{+b01hqk"gw%\*D1c(1+HQK 0#61,m\yy!JJu  D  GK  GQ  GQ  RW  fk  Gl  mr  nr  Gs  s  t  t	%.
U7^A.5	#be*c"Q%j$'
(
*C
ww#$adhdndn  ~C  PS  pT  ch  ei  jo  ko  ep  p  q  	qZZz:Q/RZXYZH*8<<+CDM(6K'(;<J=0  jS5E5J5p{[^\^O_cpOp  j  vN  O\  ^i  vjMTUaTbbhiqiuiuv|i}  iA  AM  NS  MT  U  V  	V3OOr1   c                 v   t        ddd       | dk(  rKt        ddd       t        dd	d
       t        |d       t        |      }t        ddd
       t        |d       nPt        ddd       t        ddd       t        dd	d
       t        |d       t        ddd
       t        |d       ddi}t        d       |S )N<   r   皙?rv   i"  iy  ?   i  皙?rT     i  i  i:  rS        ?rU  &duplicated_from_previous_verified_line      ?)r   r   ra  r   )seqdescpricerg   account_results        r   fill_po_linerp  |  s    	"c4
axc3c3.tT:0>c3.ud;c3c3c3.tT:c3.ud;%'OPSMr1   c                    t        j                          t        t        | j	                  d      xs d      t        | j	                  d      xs d      t        | j	                  d      xs d      t        | j	                  d      xs d      t        | j	                  d	      xs d
            }t        j                  t        d            }d||dS )zQDry-run account OCR selection from current unsaved PO line screen. Does not save.rh   A-1010-0400r5  CONTRACTUAL EXPENSErZ  i  iK  rp   i  in  r[    r9  r9  r   r5  rZ  rp   r[  zaccount-select-dryrun-afterT)rp   rU  r   )r~   r   ra  r-   rA   tupler   rV   )rJ   resultr   s      r   cmd_po_account_select_dryrunr{    s    
$CGGI/-0#''/2K6KLswwz*8j9,*-CGGO4L8LMF Z(EFGDV4@@r1   c           	      F   t        | d      }t        |        | j                  d      xs g }t        |      dk7  rt	        d      |d   }t        | d         }t        |d         }t        |j                  dd            }t        | j                  d	d
            }t        j                         }i }	t        j                          t        j                  t        d            |	d<   t        j                  ddddt        d      d      }
t        |
j                  dd            }d|v sd|vrt	        d|
j                  d            |
|	d<   t        ddd       t        j                  t        d            |	d<   t        dd d!       t        j                  d"       t        j                   d#       t        j                  d"       t        j                   d$       t        j                  t        d%            |	d&<   t        d'd(d)       t#        |d*       t        d+d,d)       t#        |d*       t        d-d(d#       t        j                  t        d.            |	d/<   t        d0d1d2       t        d3d d4       t        d5d6d$       t        j                  t        d7            |	d8<   t        d9d d:       t        j                  t        d;            |	d<<   t        d=d>d?       t        d@dAd2       t        dBdCd)       t#        |d*       t%        t        |j                  dD      xs | j                  dE      xs dF      t        |j                  dG      xs dH      dIdJdKL      }||	dM<   t        dNdOd)       t'        |d*       t        j                  t        dP            |	dQ<   t        dRd>d4       t        dSdTd!       t        dUdVd:       t        j                  t        dW            |	dX<   t)        dYdi      }dZ|t+        t        j                         |z
  d[      ||||	|d\S )]a@  Create a simple one-line PO from a visible centered Purchase Order Maintenance header.

    Verified start map: 1600x1200, internal Purchase Order Maintenance centered or already
    maximized, header saved/not in edit mode. Account selection is OCR row-verified before
    OK and aborts on control-account message.
    po_create_speed_centeredr;   rv   z2po_create_speed_centered requires exactly one liner   r8   rn  z1.00re   10T07005zspeed-beforer   ih  ;  r   P   zspeed-start-titler   r   r?   rY   LINEITEMMAINTENANCEPURCHASEORDERMAINTENANCEzbunsafe start screen for po_create_speed_centered; expected Purchase Order Maintenance header, OCR=start_titlei  iQ  g?zspeed-header-maxheader_maximized8   r,  r   ENTERrd  rk  zspeed-add-modeadd_modei     rS  rT        iB  zspeed-vendor-picklistvendor_picklisti  i#  ri     r   i  i  zspeed-header-savedheader_savedi  re  zspeed-line-open	line_openi  in  rP  i  iq  i?  i1  rh   rg   rr  r5  rs  rt  ru  rv  rx  account_selectedi  i
  zspeed-line-filledline_filledi  i  i  ij  i  zspeed-final-line
final_liner   Tr   )rp   	reasoningelapsed_secondsr8   rN   re   proofverify)rb   rQ   rA   rm   rI   r-   r   perf_counterr~   r   r   rV   r   r   r   r   r   r   ra  r   r   round)rJ   r  r;   rN   rm  	line_descrn  re   startr  r  
start_normro  r  s                 r   cmd_po_create_speed_centeredr    s    +30JKIsGGG"E
5zQMNN8Ds=!"DD'(I&)*E:./FEE
''
>(BCE(O//#sCZ@S5TZ[\K'(CDJ
*.HPZ.Z}  J  N  N  OU  V  ~Y  Z  [  	[&E-	$T & 1 1*=O2P QE
	"c3
JJwD)
JJwC))*5E*FGE*	#sD:fd3	#sD:dD1	#sD%00<S1TUE
	#sD	#sD	#sC"--j9M.NOE.	#sC**:6G+HIE+	#sC	#sD	#sD:i6,DHHYK377>#:KmL$((?3L7LM*N !/E
	#sD+E48!,,Z8K-LME-	#sD	#sC	#sC ++J7I,JKE,"E1:.FY5IZIZI\_dIdfgChy}  HL  X^  in  z@  A  Ar1   c                 j   t        | d      }t        |       }| j                  dd      }| d   }| j                  d      xs | j                  d      xs d}| j                  d      xs g }|st        d	      t	        |      d
kD  rt        d      ddl}d|_        d|_        t        j                         }t        j                          dt        j                  t        d            i}	t        ddd       t        ddd       t        ddd       t        ddd       t        |d       t        ddd       t        |d       |rt        d dd       t        |d       t!        d!       t        j                  t        d"            |	d#<   t        d$d%d&       g }
| j                  d'      xs d(}t#        |d)      D ]e  \  }}t%        |j                  d*      xs |      }|
j'                  t)        |t%        |d         t%        |j                  d+d,            |             g t        j                  t        d-            |	d.<   t        d/d%d0       t        j                  t        d1            |	d2<   t+        d3d4i      }d5||t-        t        j                         |z
  d6      ||t	        |      |
|	|d7
S )8zCreate a PO using the currently mapped PO Maintenance path.

    Requires current visible screen to be Purchase Order Maintenance. This is a demo/training
    command and uses calibrated 1600x1200 coordinates plus OCR-verified account selection.
    rd   re   rf   r8   r9   r:   rY   r;   z$po_create requires at least one liner-  z2po_create line limit is 10 for this mapped commandr   NFr   r   zpo-create-beforerc     r   i
  iJ  r9  iP  g?iX  r  rg  r      i  i  g      ?zpo-create-header-savedr  i  r   re  rg   F-1910-0400rv   rh   rn  z0.01zpo-create-lines-savedlines_savedr   r   zpo-create-final-headerfinal_headerr   r   Tr   )
rp   r  rq   r  r8   r9   line_count_requestedaccount_resultsr  r  )rb   rn   rA   rI   rm   r   FAILSAFEPAUSEr   r  r~   r   r   rV   r   r   r   rC   r-   rB   rp  r   r  )rJ   r  rq   re   rm  r9   r;   r   r  r  r  rg   idxrN   line_accountr  s                   r   cmd_po_creater    s    +3<I#DWWXz*F}Dggi CCGG,<$=CGGGG"E?@@
5zBMNNIIOE
v((4F)GHIE	"c4	#sD	#sC	#sC*VT2	#sC*T40c3j$7TN"--j9Q.RSE.	#sCO77>*;mLua(	T488I.>,?|CT-5H1I3txxX_agOhKikwxy ) ",,Z8O-PQE-	#sC"--j9Q.RSE."E1:.FYQVW[WhWhWjmrWrtuQv  HL  Y`  z}  ~C  zD  Yh  sx  DJ  K  Kr1   )healthr   r   ocr_cropr   plan_po_creater   rJ  account_picklist_probepo_account_select_dryrunr   r}  rd   c           	      t   | j                   }t        j                         }	 t        |       }|j	                  d      }|t
        vrt        d|       t        |   |      }|j                  dd       |j	                  d      xs ||d<   ||d<   t        t        j                         |z
  d      |d<   t        t        | d	z  |       | j                  t        | j                  z         t        d
| d| d|d    d       y # t        $ r}d|t!        |      t#        j$                  d      t        t        j                         |z
  d      d}t        t        | d	z  |       	 | j                  t&        | j                  z         n# t        $ r Y nw xY wt        d| d|        Y d }~y d }~ww xY w)Nri   zunknown action: rp   Tidjob_id   elapsed_seconds_totalz.jsonzDONE r   r   Fr.  )limit)rp   r  rI  	tracebackr  zERROR )stemr   r  r6   rA   COMMANDSrI   
setdefaultr  r0   	QUEUE_OUTr,   
QUEUE_DONErO   r   	Exceptionr-   r  
format_exc	QUEUE_BAD)r   r  startedrJ   ri   rz  eerrs           r   handle_filer    s   YYF!G#tn"!/x899&!#&$%774=2Fx!x*/0A0A0Cg0Mq*Q&')&66?Z$))+,eF81VHAf-D&E%FaHI #V"--B7%*4+<+<+>+H!%L
 	)&66<	LLTYY./ 		fVHAaS!""#s=   C#D 	F7AF2*"FF2	FF2FF22F7c            
         t         t        t        t        t        fD ]  } | j                  dd        t        dt        t        j                               z          t        t        dz  dt        j                         t        j                  d      t        t               t        t              d       	 t        t         j                  d      d 	      }|st        j                   d
       :|D ]  }t#        |        L)NTr
   zSTART daemon pid=zmichel_daemon.status.jsonr   )rp   ry   r  rz   	queue_outz*.jsonc                 6    | j                         j                  S r  )statst_mtime)ps    r   r  zmain.<locals>.<lambda>B  s    QVVX=N=Nr1   r  rQ  )r}   r  r  r  rT   r   r   r-   r+   r|   r0   r   r   r   r   globr   r  )djobsr   s      r   mainr  ;  s    
Iy%@	t, Ac"))+../d88biikfjfsfs  uJ  gK  Y\  ]e  Yf  ux  yB  uC  ;D  E
hmmH-3NOJJsOD  r1   __main__)r   )rQ  )rk  )r   )	   )rY   )N)rw  r   i  i  )Nr  )Nrt  ru  rv  )r  )>__doc__r)   r+   r   sysr   r  pathlibr   r   r}   r  r  r  r   rT   compileIrF   r   insertr-   michel_bridger~   r   r0   r6   rQ   rV   rb   rn   rs   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r"  r7  r@  rN  ra  rp  r{  r  r  r  r  r  __name__r   r1   r   <module>r     s  
 * ) ) ()'>D G^f$
7NU"	7NU"	
  /0rzzoqsququv 3t9  I$D $4 
o(P

.5	aJU=C8
X"
7:&.n@@R.PD"A@AF)KZ  "(8 <. <"#d #@ zF r1   