
    eQj-                        d Z ddlm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
 dddddd	d	d
ddd
ddddddddddd
dddddddd
ddd
dZdNdZdNdZd Zd Zd Zd Zd Zd Zd  Zd! Zd" Zd# Zd$ ZdOd&Zd' Zd( ZdPd)Zd*d+d,d-d.d/d0ddd1d2d3d4d5d6d7d/d8dd+d1d2d9d+d:d;d<d/d=ddd1d2d>d?d,d@d.d/dAddBd1d2dCd+d5d-d<d/d0ddd1d2gZdD ZdEdFdGdHZdI Z dJ Z!dPdKZ"dL Z#e$dMk    r e#             dS dS )Quj  
cut_sheet_calculator.py — McCoy Doors cut sheet BOM calculator.

Encodes Mike's per-series manufacturing formulas from
McCoy Doors More Invoice +Cut Sheet.xlsm.

Usage:
    python cut_sheet_calculator.py                 # Run built-in test cases
    python cut_sheet_calculator.py fill <template>  # Populate a copy of the workbook

Input (one line item):
    panels, series, door_size, color, mirror_type, hs_type, mutin_yn, mutin_count

Output (cut sheet fields):
    mirror_size, num_lites, rail_count, rail_size,
    vertical_count, vertical_size, head_length, sill_length,
    ss_track_length, mutin_bar_width
    )FractionN)PathMonumentg       @g      ?1632g      @T)
nameframe_deductionintermediate_stileheight_deductionrail_fraction_formatmirror_width_formatmirror_height_formatmirror_height_deductionrail_size_formulavertical_size_formulaCapitolg      g      ?g      @cut to size?FPatriotg      @)         c                 f   | t          j        |           rdS t          t          j        t	          |                               }t	          |           |z
  }| dk     rdnd}t	          |          dk     r| | S |rlt          ||z            }|dk    r| | S ||k    r|dz  }| | S t          j        ||          }|dk    r||z  }||z  }| | d| d| S | | d| d| S t          |                              |          }	|	j	        dk    r| | S | | d|	j	         d|	j
         S )	z
    Format a float as a fractional-inch string, matching Excel's TEXT(value, "# ?/D").

    If force_denominator=True, always round to that denominator.
    If False, use Fraction.limit_denominator() which reduces.
    N r   -gMbP?    /)mathisnanintfloorabsroundgcdr   limit_denominator	numeratordenominator)
valuer)   force_denominatorwhole	frac_partsignnumergdenom_reducedfracs
             H/home/chiefos/vaults/MCCOY_HQ/01_CONTEXT/scripts/cut_sheet_calculator.pyformat_fractionr4   L   s    }
5))}r
3u::&&''EE

U"I!))33D
9~~ Di+-..A::#E###KQJE#E###HUK((q55aKE'1,M;E;;E;;M;;;55555555	""44[AA>Q#E###CCCCC1ACCC    c                 6    t          | ||          }|r| dS |S )u>   Format as fractional inches with inch symbol: e.g. '29 1/2″'   ″)r4   )r*   r)   r+   ss       r3   format_inchesr9   r   s-    {,=>>A yyyHr5   c                    |                      dd                               dd                                          }d }d|                                v r\|                                                    d          }t	          |          dk    r" ||d                    ||d                   fS t          d	|  d
          )u   
    Parse a door size string like '60x80', '58 1/2x79 3/4', '69-1/2x78-7/8',
    '72″x96″', '94 3/4x79 3/4'. Returns (width_inches, height_inches) as floats.
    r7   r   "c                    |                                  } d}d| v rd| v r|                     d          }t          |          dk    rv|t          |d                   z  }|d                             d          }t          |          dk    r.|t          |d                   t          |d                   z  z  }|S d| v rd| v r|                     d          }|t          |d                   z  }|d                             d          }t          |          dk    r.|t          |d                   t          |d                   z  z  }|S d| v rS|                     d          }t          |          dk    r+t          |d                   t          |d                   z  S 	 t          |           S # t          $ r Y dS w xY w)z?Parse a single dimension like '58', '58 1/2', '58-1/2', '58.5'.g        r   r      r   r   r   )stripsplitlenfloat
ValueError)dimtotalpartsr2   s       r3   	parse_dimz"parse_door_size.<locals>.parse_dim   s   iikk #::#**IIcNNE5zzQuQx(Qx~~c**t99>>U47^^eDGnn<<E #::#**IIcNNEU58__$E8>>#&&D4yyA~~tAw%Q..88L #::IIcNNE5zzQU1XuQx88	:: 	 	 	33	s   (F7 7
GGxr=   r   r   zCannot parse door size: '')replacer>   lowerr?   r@   rB   )size_strr8   rF   rE   s       r3   parse_door_sizerL   |   s     	##++C44::<<A" " "H aggii		$$u::??9U1X&&		%((;(;;;
<<<<
=
==r5   c                 V    t           |         }| |d         |dz
  |d         z  z   z
  |z  S )z
    Calculate the width of one panel (mirror opening width) in inches.
    Used internally by mirror_size, rail_size, and mutin_bar_width.
    r	   r=   r
   )SERIES)
door_widthseriespanelscfgs       r3   _panel_widthrS      s8    
 .C#/0FQJ#FZB[3[[\`fffr5   c                    t           |         }t          | ||          }|r|dk    r||d         z
  |dz  z
  |dz   z  }n||d         z
  }t          ||d         dk    rt          |d                   nd|d         dk              }	t          ||d	         dk    rt          |d	                   nd
|d	         dk              }
|	 d|
 S )u   
    Calculate mirror size string: 'W x H' in fractional inches.
    Returns a formatted string like '29 16/32″ x 36 1/2″'.
    r   r   g      ?r   r   r       r)   r+   r   r   z x rN   rS   r9   r"   )rO   door_heightrP   rQ   mutin_ynmutin_countrR   whw_fmth_fmts              r3   mirror_sizer_      sB   
 .CZ00A  9K!OO3899K$<NNS^abSbc#788!CPeLfjmLmLmS1F-G)H)H)Hsu  KN  Od  Ke  il  Kl  n  n  nE!SQgMhloMoMoS1G-H)I)I)Iuw  MP  Qg  Mh  lo  Mo  q  q  qEr5   c                 &    |r|dk    r|dz   | z  S | S )z!Number of lites (glass openings).r   r    )rQ   rY   rZ   s      r3   	num_litesrb      s&     *K!OOa6))Mr5   c                     | dz  S )zNumber of rails = panels * 2.r=   ra   rQ   s    r3   
rail_countre          A:r5   c                     t           |         }|d         sdS t          | ||          }|dz
  }t          |t          |d                   d          S )u/   Rail size string — computed or 'cut to size'.r   r         ?r   TrV   rW   )rO   rX   rP   rQ   rR   r[   rails          r3   	rail_sizerj      sd    
.C"# }Z00At8D3s3I/J+K+K+/1 1 1 1r5   c                     | dz  S )z!Number of verticals = panels * 2.r=   ra   rd   s    r3   vertical_countrl      rf   r5   c                     t           |         }|d         sdS | |d         z
  }t          |t          |d                   d          S )u3   Vertical size string — computed or 'cut to size'.r   r   r   r   TrV   )rN   r9   r"   )rX   rP   rR   verts       r3   vertical_sizero      sZ    
.C&' }/00D3s3I/J+K+K+/1 1 1 1r5   c                 &    t          | |d          S )z+Head (top track) length based on cut style.Fwith_tt_track_lengthrO   hs_types     r3   head_lengthrw          We<<<<r5   c                 &    t          | |d          S )u4   Sill (bottom track) length — same formula as head.Frq   rs   ru   s     r3   sill_lengthrz      rx   r5   c                     t          | |dd          }d|v rt          j        |           dz   }n| }d|v rdnd}t          |d	
          }| d| S )u   
    Stainless steel track length — includes track count indicator.
    "(2)" for standard, "(3)" for top track (TT) configurations.
    Tr   )rr   include_suffixExtra Lengthr=   TTz(3)z(2)r   r)   u   ″ )rt   r    ceilr4   )rO   rv   fmt_valbasecount	formatteds         r3   ss_track_lengthr     sw    
 JbQQQG  y$$q(W__EE%E"555I$$U$$$r5   r7   c                 z    d|v rt          j        |           dz   }n| }t          |d          }|r	d|v r| dS |S )z*Internal: computes head/sill track length.r}   r=   r   r   r~   z TT)r    r   r9   )rO   rv   rr   r|   r   r   s         r3   rt   rt     s_      y$$q(d333I !47??    r5   c                     t           |         }|d         sdS t          | ||          }|dz
  }t          |t          |d                   d          S )u6   Width of mutin bars — same calculation as rail size.r   r   rh   r   TrV   rW   )rO   rP   rQ   rR   r[   bars         r3   mutin_bar_widthr   "  sd    
.C"# }Z00A
d(C#c2H.I*J*J+/1 1 1 1r5   c           
         t          | d                   \  }}t          | d                   }t          | d                   }t          |                     d          t                    r| d                                         dv }n#t          |                     dd                    }t          |                     dd                    }|                     d	d
          }|t          vr9t          d| dt          t          
                                                     i dt          ||||||          dt          |||          dt          |          dt          ||||          dt          |          dt!          ||          dt#          ||          dt%          ||          dt'          ||          dt)          |||          d|d|d|d|d|d|d|S )u  
    Compute all cut sheet fields for one line item.

    Input dict:
        panels (int): number of panels (1-7)
        series (int): 1000, 2000, 3000, or 4000
        door_size (str): e.g. '60x80', '72×96'
        color (str): finish color
        mirror_type (str): mirror type
        hs_type (str): Cut To Size, Cut To Size TT, Extra Length, Extra Length TT
        mutin_yn (bool/str): True/'Yes' if mutin bars
        mutin_count (int): number of mutin bars

    Returns dict with all cut sheet fields.
    	door_sizerP   rQ   rY   )yesytrueFrZ   r   rv   Cut To SizezSeries z# formulas not yet captured. Known: r_   rb   re   rj   rl   ro   rw   rz   r   r   _door_width_door_height_panels_series_hs_type	_mutin_yn_mutin_count)rL   r"   
isinstancegetstrrJ   boolrN   rB   listkeysr_   rb   re   rj   rl   ro   rw   rz   r   r   )	item_datarO   rX   rP   rQ   rY   rZ   rv   s           r3   compute_cut_sheetr   /  sH     .i.DEEJ8$%%F8$%%F )--
++S11 :Z(..004HH	j%8899immM15566KmmI}55GVc6ccdSYS^S^S`S`NaNaccddd{:{FFHVabbYvx== 	j(( 	Yz;GG	
 	.00 	{F;; 	{:w77 	{:w77 	?:w?? 	?:vvFF 	z 	 	6 	6  	G!" 	X#$ 	% r5   c           	         	 ddl }n3# t          $ r& t          d           t          j        d           Y nw xY w|                    | d          }|d         }|                    dd	          |d
<   |                    dd	          |d<   |                    dd	          |d<   |                    dd	          |d<   ddlm}m	}  |ddd          } |dd          }	d|d<   ||d         _
        |	|d         _        d|d<   ||d         _
        |	|d         _        |                    dd	          |d<   |                    dd	          |d<   |                    d d	          |d!<   |                    d"d	          |d#<   |                    d$d	          |d%<   |                    d&d	          }
|
r|
|d'<   |                    d(g           }t          |          D ] \  }}d)|z   }|d*k    r n|                    |d+|                    d,d          -           |                    |d.|                    d/d	          -           |                    |d0|                    d1d	          -           |                    |d2|                    d3d	          -           |                    |d4|                    d5d	          -           |                    |d6|                    d7d	          -           |                    |d8|                    d9d:          -           |                    d;d<          d=v rd>nd<}|                    |d?|-           |                    |d@|                    dAd          -           |                    |dB|                    dCd          -           dD|dz    }||j        vrt          |          }||         }|                    d/d          |d<   |                    d1d	          |d<   |                    d3d	          |dE<   |                    d5d	          |dF<   |                    d7d	          |dG<   |dH         |dI<   |dJ         |dK<   |dL         |dM<   |dN         |dO<   |dP         |dQ<   |dR         |dS<   |                    d9d:          |dT<   |dU         |dV<   |dW         |dX<   |dY         |dZ<   ||d[<   |                    dAd          |d\<   |d]         |d^<   "|d_         }|                    dd	          |d`<   |                    dd	          |da<   |                    dd	          |db<   |                    dd	          |dc<   |                    dd	          |d<   |                    dd	          |dE<   |                    ddd	          |dF<   t          |          D ]7\  }}de|z   }|dfk    r n%|                    |d|dz   -           |                    |d+|                    d/d	          -           |                    |d.|                    d1d	          -           |                    |d0|                    d3d	          -           |                    |d2|                    d5d	          -           |                    |d4|                    d7d	          -           |                    |d6|                    dCd          -           9ddglm} ddhlm} di |j        D             }|D ]}||         }dj|v rdk|j        _        ndl|j        _        d|j        _        d|j        _        d|j        _        |j        #|j        j                                        |_        |j        j         |            |j        _        d|j        j        _         |dmdmdmdmdndno          |_        dj|v rdp|_         |dk    rdq|_         |d_k    rdr|_         |GtB          j"        #                    tB          j"        $                    |                     d         }| ds}|%                    |           t          dt|            |S )ua  
    Open Mike's workbook template, populate cells for each line item,
    and save as a completed .xlsx.

    order_data: dict with keys:
        - customer_name, customer_address, contact_name, customer_email,
          customer_phone, date, delivery_date, order_num, po_number
        - items: list of item dicts (each with panels, series, door_size, color,
                 mirror_type, hs_type, mutin_yn, mutin_count, price, quantity)
    r   NzEopenpyxl required for template filling. Install: pip install openpyxlr   F)keep_vbazControl Sheet	order_numr   K2dateK3delivery_dateK4	po_numberK5)Font	AlignmentzAptos Narrow   Tr   sizeboldcenter)
horizontalverticalu   ☑B7u   ☐B8customer_nameD10customer_addressD11contact_nameD12customer_emailD13customer_phoneD14notesB27items      r=   quantityrowcolumnr*      rQ      rP      r      color   mirror_type   rv   r   rY   No)TYesr   Yr   r   	   
   rZ      pricez
Cut Sheet B9B10B11r_   B12rb   B13re   B14rj   B15rl   B16ro   B17B18rw   B19rz   B20r   B21B22B23r   B24InvoiceG1G2G3G4contact_info      )PageMargins)PageSetupPropertiesc                     g | ]}d |v|	S )zPrice Sheetra   ).0r8   s     r3   
<listcomp>z!fill_template.<locals>.<listcomp>  s"    GGG!Q0F0FA0F0F0Fr5   z	Cut Sheetportrait	landscapeg      ?g333333?)leftrighttopbottomheaderfooterzA1:B29zA1:L32zA1:G25z - COMPLETED.xlsxSaved: )&openpyxlImportErrorprintsysexitload_workbookr   openpyxl.stylesr   r   font	alignment	enumeratecell
sheetnamesr   openpyxl.worksheet.pager   openpyxl.worksheet.propertiesr   
page_setuporientation	paperSize
fitToWidthfitToHeightsheet_properties	worksheet
propertiesSheetPropertiespageSetUpPr	fitToPagepage_margins
print_areaospathsplitextbasenamesave)template_path
order_dataoutput_pathr   wbcs_Font_Align_cb_font	_cb_alignr   r   idxitemr   mutin_yn_display
sheet_nameresultcutinvr   r   print_sheetssnwsr   s                             r3   fill_templater/  g  s      UVVV 
				>	>B 
O	B~~k2..BtH~~fb))BtH~~or22BtH~~k2..BtH CBBBBBBBu.r===H(X>>>IBtHBtHM"BtHBtHBtHM"BtH33BuI1266BuI~r22BuI/44BuI/44BuINN7B''E 5	 NN7B''Eu%% ./ ./	T3h88E 	C*a)@)@AAA
C(B)?)?@@@
C(B)?)?@@@
C+r)B)BCCC
C'2)>)>???
C-)D)DEEE
C)])K)KLLL$(HHZ$>$>B`$`$`55fj
C)9:::
C$((=!*D*DEEE
C$((7A*>*>??? ,#'++
R]**"4((n HHXq))D	HHXr**D	HH["--D	XXgr**E
XXmR00E
M*E
K(E
L)E
K(E
,-E
O,E
XXi77E
M*E
M*E
-.E
%E
XXmQ//E
-.E

 Y-C{B//CIvr**CI33CI{B//CI33CI1266CI33CJu%% 
@ 
@	T3h88ES#'222S$((8R*@*@AAAS$((8R*@*@AAAS$((;*C*CDDDS$((7B*?*?@@@S$((="*E*EFFFS$((7A*>*>???? 433333AAAAAA HGr}GGGL % %V"(2BM%%(3BM%"##$ $%!&"*"4"?"O"O"Q"QB*2.A.A.C.CB+48'1%+CSs
 
 
 "$BMM?""$BMM9__$BM w 0 0 ? ?@@C000GGK	
!K
!
!"""s    -77z#M-3000 2-panel 60x80 Brushed Nickelr=   r   60x80zBrushed NickelMirrorr   )rQ   rP   r   r   r   rv   rY   rZ   )r   dataz'M-1000 3-panel 72x96 Bronze with mutinsr   r   72x96Bronzer}   zM-2000 2-panel 48x80 Whiter   48x80WhitezCut To Size TTzM-3000 4-panel 96x96 Nickelr   96x96zExtra Length TTr   zM-1000 2-panel 60x80 Whitec            	      F   t          d           t          d           t          d           d} t          D ]}t          dd            t          d|d                     t          d            	 t          |d                   }d	D ]}t          d
|dd||                     t          d
dd           # t          $ r}t          d|            d} Y d}~d}~ww xY wt          dd            t          d| rdnd            t          d            dS )z*Run built-in test cases and print results.zH========================================================================u#   CUT SHEET CALCULATOR — Test SuiteT
u   ────────────────────────────────────────────────────────────────────────zTest: r   r2  )
r_   rb   re   rj   rl   ro   rw   rz   r   r   z  25sz = u   ✓ PASSz>30su     ✗ FAIL: FNz	Overall: zALL PASSzSOME FAILURES)r   
TEST_CASESr   	Exception)all_passtcr)  keyes        r3   	run_testsrA  W  s~   	(OOO	
/000	(OOOH  :   #r&z##$$$o		&r&z22FN 6 6 43444vc{445555(z((()))) 	 	 	$$$%%%HHHHHH	 
/x//	
CHAjj/
C
CDDD	X-s   4A	B>>
C&C!!C&zStandard Door OrderzMirror-Only OrderzNon-Standard Order)doormirrorunknownc                     |                      d          }|                      dd          }|                      dd          }|rdS |dv rdS dS )	zw
    Detect what kind of order this is based on available fields.

    Returns one of: "door", "mirror", "unknown"
    rP   r   r   mirror_onlyFrC  )r   r   r   i  rB  )r   )r   rP   r   rF  s       r3   detect_order_typerG  z  sd     ]]8$$Fk2..I--u55K  x )))v 8r5   c                     |                      dg           }|sdg fS g }|D ]&}t          |          }|                    |           'ddlm}  ||          }|                    d          d         d         }||fS )zWRun detection on all items in an order. Returns the dominant type + per-item breakdown.r   rD  r   )Counterr   )r   rG  appendcollectionsrI  most_common)r  r   resultsr&  trI  countsdominants           r3   detect_order_typesrQ    s    NN7B''E "}G  d##q $#####WWF!!!$$Q'*HWr5   c                    	 ddl }ddlm}m}m}m}m} n3# t          $ r& t          d           t          j
        d           Y nw xY w|                                }|j        }	d|	_         |ddd	
          }
 |ddd	
          } |dd          } |ddd	d          } |ddd	d          } | |d           |d           |d           |d                    } |ddd          }d}d}|	                    ||||dz              |	                    ||d          }||_         |d          |_        |dz  }|	                    ||||dz              |	                    ||d          }|
|_        |dz  }|	                    ||||dz              |	                    ||d          }||_        |dz  }|	                    ||||dz              |	                    ||d           }||_        |dz  }d!|                     d"d#          fd$|                     d%d#          fd&|                     d'd#          fd(|                     d)d#          fd*|                     d+d#          fd,|                     d-d#          fd.d/|                     d0d1           ffD ]f\  }}||	                    |||          _        |	                    ||dz   ||dz              ||	                    ||dz   |          _        |dz  }g|dz  }g d2}t'          |          D ]5\  }}|	                    |||z   |          }||_        ||_        ||_        6|dz  }t'          |                     d3g           d          D ]\  }}|                    d4d#          }|                    d5d6          }|                    d7d#          }||	                    |||          _        ||	                    ||8          _        ||	                    ||dz   |                    d9d                    _        ||	                    ||dz   8          _        ||	                    ||dz   |          _        ||	                    ||dz   8          _        ||	                    ||d:z   |          _        ||	                    ||d:z   8          _        ||	                    ||d;z   |          _        ||	                    ||d;z   8          _        |dz  }|dz  }|                     d7          rj||	                    ||d<          _        |	                    ||dz   |dz   |dz              ||	                    ||dz   | d7                   _        |dz  }d|	j        d=         _        d>|	j        d?         _        d@|	j        dA         _        dB|	j        dC         _        dD|	j        dE         _        |dF|                     d"dG           dH}|                    |           t          dI|            |S )Ju   
    Generate a simple work order .xlsx for mirror-only orders.
    No BOM calculations needed — just customer info + mirror specs.
    r   N)r   r   BorderSidePatternFillz0openpyxl required. Install: pip install openpyxlr   zMirror Work OrderCalibrir   Tr   r   )r   r   444444)r   r   r   r      CC0000thin)style)r   r   r   r   F2F2F2solid)start_color	end_color	fill_typer   )	start_rowstart_columnend_row
end_columnu6   ⚠️ NON-STANDARD ORDER — Kenny review recommendedr   r   )r   r=   zMCCOY DOORS & MOREz&505 N Smith Ave #101, Corona, CA 92878zTel: (951) 393-0300zOrder # / Projectr   r   Dater   Customerr   Addressr   Contactr   zPO #r   SourcezVendor: vendorzN/A)zItem #QtyDescriptionzSize (W x H)Notesr   r   r   r1  r   )r   r   r   r   r   zInstructions:Ar   B&   C   D   EzMirror Order - rD  z.xlsxr   )r   r  r   r   rS  rT  rU  r   r   r   r   Workbookactivetitlemerge_cellsr  r  r  r   r  fillbordercolumn_dimensionswidthr  )r  r  r   r   r   rS  rT  rU  r  r.  
title_fontheader_font	body_font
label_font	flag_fontthin_borderheader_fillcolr   r  labelr*   items_headersir\   r%  r&  r   r   r   s                                 r3   fill_mirror_templater    s   
NNNNNNNNNNNNNNN   @AAA 
				B	B"BH 92D999J$IBT:::K)"---I92DIIIJ)"4xHHHI&Td   Dvt&!!!	  K +(hRYZZZK
C
C NNSsCCRSGNTTT77s3.f7ggDDIY(333DN1HC NNSsCCRSGNTTT77s3.B7CCDDI1HCNNSsCCRSGNTTT77s3.V7WWDDI1HCNNSsCCRSGNTTT77s3.C7DDDDI1HC 
jnn["==>	++,	Z^^OR889	JNN#5r::;	JNN>2667	R001	?jnnXu==??@  u :DC5116
37CTWZ[T[\\\=FCau55:q1HC NMMM-(( " "1ww3sQwaw88		!1HC z~~gr::A>>  	THH["--	hh}h77"%%7@C3//4.9C$$+OXCatxx
A/F/FGGL2=Ca((/CLCa{;;@2=Ca((/AJCay99>2=Ca((/=FCau55:2=Ca((/q1HC ~~g CMC?;;@
37C!GX[^_X_```KTCaz'/BCCHq ')B#&(B#&(B#&(B#&(B# U
{I(N(NUUUGGK	
!K
!
!"""s    -AAc                  h   t          j        d          } |                     dddg dd           |                     d	dd
           |                     ddd           |                     dd           |                     dd           |                                 }|j        dk    rt                       d S d }|j        rAt          |j                  5 }t          j	        |          }d d d            n# 1 swxY w Y   n"dddddddd t          d d         D             d}|j        dk    rQt          |          \  }}t          dt                              ||                      t          d |            d S |j        d!k    rt          |          \  }}t          d"t                              ||                      |d#k    rF|j        s#t          d$           t!          j        d%           t%          |j        ||j                   nC|d&k    rt)          ||j                   n't          d'| d(           t!          j        d%           d S |j        d)k    rG|j        s#t          d*           t!          j        d%           t%          |j        ||j                   d S d S )+NzMcCoy Doors order processor)descriptionactionr   test)r  rz  detectautozk'test' run tests, 'fill' populate door template, 'detect' show order type, 'auto' route to correct template)nargsdefaultchoiceshelptemplatez(Path to template .xlsm (for door orders))r  r  z--outputz-ozOutput path)r  z--order-jsonz!Path to JSON file with order dataz--items-jsonz-Path to JSON array of line items (for detect)zTest Customerz123 Main Stz
06-29-2026z
07-15-2026zTEST-001zPO-12345g     !@c                     g | ]
}|d          S )r2  ra   )r   r>  s     r3   r   zmain.<locals>.<listcomp>@  s    :::Rbj:::r5   r   )r   r   r   r   r   r   tax_rater   r  zOrder type: zPer item:   r  z
Detected: rB  z/Error: door orders need a template path (.xlsm)r   rC  zUnknown order type 'u   ' — cannot processrz  z+Error: fill action requires a template path)argparseArgumentParseradd_argument
parse_argsr  rA  
order_jsonopenjsonloadr;  rQ  r   ORDER_TYPESr   r  r   r   r/  outputr  )parserargsr  fdomper_items         r3   mainr  !  s.   $1NOOOF
V B B B K  L L L 
#4^___

D}===
-PQQQ
-\]]]D{f J 
$/"" 	&a1J	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&
 - - )##:::bqb>:::	
 	

 {h*:66X8[__S#6688999'X''((({f*:66X6;??34466777&=== GHHH$-T[AAAAH__ T[9999BBBBCCCHQKKK{f} 	?@@@HQKKKdmZ=====	 s   C==DD__main__)r   F)Fr7   )N)%__doc__	fractionsr   r  copyr  r    r  r   pathlibr   rN   r4   r9   rL   rS   r_   rb   re   rj   rl   ro   rw   rz   r   rt   r   r   r/  r;  rA  r  rG  rQ  r  r  __name__ra   r5   r3   <module>r     s   &           				 



       " $# $#&!!%   #  -" $#'"!&  " $# $#&!!% 3'
 '
X#D #D #D #DL   1> 1> 1>lg g g     (    
	1 	1 	1  
1 1 1= = =
= = =
% % %$   1 1 13 3 3pf f f fZ 6 %#$	
 	
  : #%	
 	
  - #'	
 	
  . %#(	
 	
  - #$	
 	
 kB
J  < "!#   .  *y y y yv<> <> <>~ zDFFFFF r5   