+
    ~WÂjêK  ã                   ó<  € R t ^ RIt^ RIt^ RIt^ RIHtHt ^ RIHtHtH	t	H
t
Ht ^ RIHtHt ^ RIHt ^ RIHtHtHt ^ RIHt ^ RIHt ^ R	IHt ^ R
IHt ^ RIHtHtH t H!t! ^ RI"t"]! R.R7      t#]"PH                  PK                  ]"PH                  PK                  ]"PH                  PK                  ]"PH                  PM                  ]'4      4      4      4      t(]! ]"PH                  PS                  ](R4      R7      t*^t+^t,RRRRRRRR/t-RRNRRNRRORRPRRQR RR/t.RR"RR#RR$R!R%/t/R& t0R' t1R( t2R) t3R* t4R+ t5R, t6R- t7R. t8]#Ps                  R/]R07      ]! ]4      3R1 R2 ll4       t:]#Ps                  R3]R07      ^ ^]! ]4      3R4 R5 ll4       t;]#Py                  R34      ]	! R64      ]	! ^4      ]	! R64      ]	! R64      ]	! R74      ]! ]4      3R8 R9 ll4       t=R: t>]#Ps                  R;]R07      ]! ]4      3R< R= ll4       t?R> t@]! ]! ]! R?4      4      .R@.RA7      tA]APs                  RB]R07      ]! ]4      3RC RD ll4       tB]APy                  RE4      ]! ]4      3RF RG ll4       tC]APy                  RH4      ]! ]4      3RI RJ ll4       tD]APy                  RK4      ]! ]4      3RL RM ll4       tER# )SaÒ  
Katalog voucher publik + mekanisme pembelian online.

Batas tanggung jawab file ini: SAMPAI SEBELUM Midtrans.
Yang sudah berfungsi:
  - katalog paket (harga dari hotspot_profiles, tidak di-hardcode)
  - checkout: bikin order + RESERVASI voucher secara atomik
  - halaman status order untuk pembeli
  - admin (login) bisa melihat order, tandai lunas, serahkan, batalkan

Yang BELUM ada dan disengaja tidak ada:
  - panggilan API Midtrans, halaman pembayaran, webhook

Alasan: reservasi voucher adalah bagian paling rawan (bisa menyebabkan
voucher terjual dua kali atau hilang permanen). Itu harus bisa diuji sendiri
sebelum payment ditumpuk di atasnya. Titik integrasi Midtrans nanti ada di
`admin_mark_paid()`.

Anti-penjualan ganda: reservasi memakai UPDATE bersyarat
`WHERE id=? AND status='available'`, dan voucher baru dianggap terpegang kalau
`rowcount == 1`. Dua order yang membaca baris yang sama hanya akan berhasil
satu, jadi mustahil satu voucher dipegang dua order.
N)ÚdatetimeÚ	timedelta)Ú	APIRouterÚDependsÚFormÚHTTPExceptionÚRequest)ÚHTMLResponseÚRedirectResponse)ÚJinja2Templates)ÚfuncÚselectÚupdate)ÚAsyncSession)Úget_db)Údecrypt_secret)Úrequire_roles)ÚHotspotProfileÚOnlineOrderÚVoucherÚVoucherBatchÚshop)Útagszapp/templates)Ú	directoryÚsÚDetikÚmÚMenitÚhÚJamÚdÚHariÚpendingÚamberÚreservedÚpaidÚemeraldÚ	deliveredÚexpiredÚslateÚ	cancelledÚrosez2bg-amber-500/10 text-amber-400 border-amber-500/25z8bg-emerald-500/10 text-emerald-400 border-emerald-500/25z2bg-slate-500/10 text-slate-400 border-slate-500/25z/bg-rose-500/10 text-rose-400 border-rose-500/25c                ó(  € V '       g   R# \         P                  ! R\        V 4      \         P                  4      pV'       g   \        V 4      # \	        VP                  ^4      4       R\        VP                  ^4      P                  4       ,           2# )z2'10h' -> '10 Jam'. None kalau format tak dikenali.Nz\s*(\d+)\s*([smhd])\s*Ú )ÚreÚ	fullmatchÚstrÚ
IGNORECASEÚintÚgroupÚ_UNITSÚlower)Úvaluer   s   & Ú(/var/www/html/bestweb/app/routes/shop.pyÚhumanize_durationr8   E   se   € çÙÜ
�ŠÐ.´°E³
¼B¿M¹MÓJ€AßÜ�5‹zÐÜ�!—'‘'˜!“*‹oÐ˜a¤ q§w¡w¨q£z×'7Ñ'7Ó'9Õ :Ð;Ð<Ð<ó    c                ó–   € V '       g   R# \        V 4      p V ^ 8:  d   R# R F!  w  rW,          ^ 8X  g   K  W,           RV 2u # 	  V  R2# )z:43200 -> '12 Jam'. Masa berlaku voucher bersifat opsional.Nr-   z Detik))i€Q r!   )i  r   )é<   r   )r2   )ÚsecondsÚsizeÚunits   &  r7   Úhumanize_secondsr?   O   sU   € çÙÜ�'‹l€GØ�!„|ÙÛE‰
ˆØ�>˜QÖØ•oÐ& a¨ vÐ.Ò.ñ Fð ˆY�fÐÐr9   c                óT   € R\        T ;'       g    ^ 4      R 2P                  RR4      # )z5000 -> 'Rp5.000'.ÚRpÚ,Ú.)r2   Úreplace)r6   s   &r7   ÚrupiahrE   \   s)   € à”�E—J�J˜Q“ Ð"Ð#×+Ñ+¨C°Ó5Ð5r9   c                 ó~   € R\         P                  ! 4       R R\        P                  ! ^4      P	                  4        2# )zCKode unik. 3 byte hex acak + stempel waktu, cukup untuk volume ini.zORD-z%y%m%dÚ-)r   ÚnowÚsecretsÚ	token_hexÚupper© r9   r7   Únew_order_coderM   a   s3   € à”(—,’,“. Ð(¨¬'×*;Ò*;¸AÓ*>×*DÑ*DÓ*FÐ)GÐHÐHr9   c                 óæ   € V '       g   . #  \         P                  ! V 4      p\        V\        4      '       d   V Uu. uF  p\	        V4      NK  	  up# . # u upi   \
        \        3 d    . u # i ; i©N)ÚjsonÚloadsÚ
isinstanceÚlistr2   Ú
ValueErrorÚ	TypeError)ÚrawÚparsedÚxs   &  r7   Ú_decode_idsrY   f   sb   € ßØˆ	ðÜ—’˜C“ˆÜ+5°f¼d×+CÒ+C¡Ó'¡˜1”�A–¡Ñ'ÐKÈÐKùÒ'øÜœ	Ð"ô ØŠ	ðús(   Œ0A ¼AÁA ÁA ÁA ÁA0Á/A0c                 ój   € \         P                  ! V  Uu. uF  p\        V4      NK  	  up4      # u upi rO   )rP   Údumpsr2   )ÚidsÚis   & r7   Ú_encode_idsr^   p   s'   € Ü�:Š:¡sÓ+¡s !”s˜1–v¡sÑ+Ó,Ð,ùÒ+s   •0c           	   ƒ   óÔ  "  € T P                  \        \        P                  \        P
                  ! \        P                  4      4      P                  \        P                  R 8H  \        P                  P                  T;'       g    ^ .4      4      P                  \        P                  4      4      G Rj  x€L
 P                  4       pV UUu/ uF  w  r4W4bK	  	  upp#  L(u uppi 5i)Ú	availableN)Úexecuter   r   Ú
profile_idr   ÚcountÚidÚwhereÚstatusÚin_Úgroup_byÚall)ÚdbÚprofile_idsÚrowsÚpidrc   s   &&   r7   Ú
_stock_maprn   t   s¬   é € à�j‰jÜ”7×%Ñ%¤t§z¢z´'·*±*Ó'=Ó>ß‰UÜ—‘ +Ñ-Ü×"Ñ"×&Ñ& {×'9Ð'9°q°cÓ:ó÷ ‰X”g×(Ñ(Ó)ó
÷ 	
÷ 
�cƒeð 	ñ *.Ô.©™:˜3ˆCŠJ©Ò.Ð.ñ	
ùó /ùs$   ‚B5C(Â7C Â8C(ÃC"ÃC(Ã"C(c              ƒ   ó
  "  € V P                  \        \        4      P                  \        P                  R 8H  4      P                  \        P                  \        P                  4      4      G Rj  x€L
 P                  4       P                  4       p\        Y Uu. uF  q"P                  NK  	  up4      G Rj  x€L
 p. pV F²  p\        VP                  4      pVP                  VP                  ^ 4      pTP                  RVP                  RT;'       g    VP                  RVP                  RVP                  R\!        VP                  4      RVR\#        VP$                  4      R	VR
V^ 8„  /	4       K´  	  V#  EL	u upi  LÈ5i)TNrd   ÚlabelÚnameÚpriceÚ
price_textÚdurationÚvalidityÚstockÚin_stock)ra   r   r   re   Ú	is_activeÚorder_byrr   rd   Úscalarsri   rn   r8   Úsession_timeoutÚgetÚappendrq   rE   r?   Úvoucher_expiry_seconds)rj   rl   Úprv   Úpackagesrt   r`   s   &      r7   Ú_load_packagesr�   ‚   s6  é € à�j‰jÜ”>Ó"ß‰U”>×+Ñ+¨tÑ3Ó4ß‰X”n×*Ñ*¬N×,=Ñ,=Ó>ó
÷ 	
÷
 �gƒi—‘“ð 	ô ˜R°Ó!5±¨1§$¤$±Ñ!5Ó6×6€EØ€HÛˆÜ$ Q×%6Ñ%6Ó7ˆØ—I‘I˜aŸd™d AÓ&ˆ	Ø�‰Ø�!—$‘$Ø�X×'Ð' §¡Ø�A—F‘FØ�Q—W‘WØœ& §¡›/Ø˜ØÔ(¨×)AÑ)AÓBØ�YØ˜	 A™ð

ö 
	ñ ð €Oò/	
ùò "6Ñ6ùs8   ‚A.FÁ0E9Á1)FÂE<
Â.
FÂ8FÂ9AFÄA$FÅ<Fc              ƒ  ó  "  € \         P                  ! 4       pV P                  \        \        4      P                  \        P                  P                  R4      \        P                  P                  R4      \        P                  V8  4      4      G Rj  x€L
 P                  4       P                  4       pV Fœ  p\        VP                  4      pV'       dv   V P                  \        \        4      P                  \        P                   P                  V4      \        P                  R8H  4      P#                  RRR7      4      G Rj  x€L
  RVn        Kž  	  V'       d   V P%                  4       G Rj  x€L
  \'        V4      #  Lí L< L5i)aW  
Order yang lewat batas bayar dilepas; vouchernya dikembalikan ke stok.

WAJIB mengembalikan status ke 'available'. Kalau tidak, setiap orang yang
checkout lalu berubah pikiran akan mengikis stok permanen sampai habis.
Hanya voucher yang masih 'reserved' yang disentuh, supaya kalau sudah
terlanjur sold atau used tidak ada data yang ditimpa.
r$   Nr`   ©rf   Úcommentr(   ©r"   r$   )r   Úutcnowra   r   r   re   rf   rg   Ú
expires_atÚisnotrz   ri   rY   Úreserved_voucher_idsr   r   rd   ÚvaluesÚcommitÚlen)rj   rH   ÚstaleÚorderÚvoucher_idss   &    r7   Ú_release_expiring_ordersr�   ž   s$  é € ô �/Š/Ó
€Cà�j‰jÜ”;Ó×%Ñ%Ü×"Ñ"×&Ñ&Ð'>Ó?Ü×&Ñ&×,Ñ,¨TÓ2Ü×&Ñ&¨Ñ,óó
÷ 	
÷ �gƒi—‘“ð 
ó ˆÜ! %×"<Ñ"<Ó=ˆßØ—*‘*Ü”w“ß‘”w—z‘z—~‘~ kÓ2´G·N±NÀjÑ4PÓQß‘˜{°D�Ó9ó÷ ð ð
 !ˆŽñ ÷ Ø�i‰i‹k×ÐÜˆu‹:Ðñ)	
ññ 	ùs=   ‚BF	ÂFÂB2F	ÅFÅ	F	Å F	Å3FÅ4F	ÆF	ÆF	ú/shop)Úresponse_classc                ó0   € V ^8„  d   QhR\         R\        /# ©é   Úrequestrj   ©r   r   )Úformats   "r7   Ú__annotate__r™   Ã   s   € ÷ ñ ¤ð ¬\ñ r9   c              ƒ  óÌ   "  € \        V4      G Rj  x€L
  \        V4      G Rj  x€L
 p\        P                  V RRVR\	        V4      R\        R V 4       4      /R7      #  LN L=5i)z.Katalog paket. Publik, read-only, tanpa login.Nz	shop.htmlr€   Útotal_productsÚin_stock_countc              3   óF   "  € T F  qR ,          '       g   K  ^x € K  	  R# 5i)rw   NrL   )Ú.0r   s   & r7   Ú	<genexpr>Úshop_catalog.<locals>.<genexpr>Í   s   é € Ð!G©X¨¸:¿¹§!¢!«Xùs   ‚!—
!©r–   rq   Úcontext)r�   r�   Ú	templatesÚTemplateResponserŒ   Úsum)r–   rj   r€   s   && r7   Úshop_catalogr¦   Â   sk   é € ô # 2Ó
&×&Ð&Ü# BÓ'×'€HÜ×%Ñ%ØØà˜Øœc (›mØœcÑ!G©XÓ!GÓGð
ð &ó ð ñ 'Ù'ùs   ‚A$‘A ’A$¤A"¥<A$Á"A$z/shop/checkoutc                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r•   r–   rb   Úquantityrj   )r   r2   r   )r˜   s   "r7   r™   r™   Õ   s0   € ÷ ñ Üðäðô ðô 	ñ	r9   c              ƒ  ód  "  € \        V4      G Rj  x€L
  \        V4      G Rj  x€L
 pV Uu/ uF  qUR,          VbK  	  ppW9  d   \        RRR7      # \        P	                  T RRTRTR	\        ^\        \        T;'       g    ^4      \        4      4      R
RRRRRRRR//R7      #  L• L„u upi 5i)zEFormulir checkout. Paket yang tidak aktif tidak bisa dibuka langsung.Nrd   r‘   é/  ©ÚurlÚstatus_codeúshop_checkout.htmlr€   Úselected_idr¨   ÚerrorÚoldrq   Ú ÚphoneÚemailr¡   )	r�   r�   r
   r£   r¤   ÚmaxÚminr2   ÚMAX_PER_ORDER)r–   rb   r¨   rj   r€   r   Úby_ids   &&&&   r7   Úshop_checkout_formr¹   Ô   s¼   é € ô # 2Ó
&×&Ð&Ü# BÓ'×'€HÙ!)Ó*¡˜Aˆt�W�aŠZ¡€EÐ*ØÔÜ G¸Ô=Ð=Ü×%Ñ%ØØ!à˜Ø˜:Øœ˜Aœs¤3 x§} }°1Ó#5´}ÓEÓFØ�TØ�F˜B ¨¨W°bÐ9ð
ð &ó 
ð 
ñ 'Ù'ùÚ*ùs0   ‚B0‘B'’B0¤B)¥B0­B+¿A)B0Â)B0Â+B0.r²   c                ól   € V ^8„  d   QhR\         R\        R\        R\        R\        R\        R\        /# )r•   r–   rb   r¨   Úcustomer_nameÚcustomer_phoneÚcustomer_emailrj   )r   r2   r0   r   )r˜   s   "r7   r™   r™   ï   s`   € ÷ bTñ bTÜðbTäðbTô ðbTô ð	bTô
 ðbTô ðbTô 	ñbTr9   c              ƒ  óÌ	  "  €  \        T;'       g    ^4      p\        ^\	        V\
        4      4      pT;'       g    RP                  4       pT;'       g    RP                  4       pT;'       g    RP                  4       ;'       g    Rp	\        V4      ^8  d   \        WWRWxV	4      G Rj  x€L
 # \        \        P                  ! RRV4      4      ^8  d   \        WWRWxV	4      G Rj  x€L
 # V	'       d5   \        P                  ! RV	4      '       g   \        WWRWxV	4      G Rj  x€L
 # \        V4      G Rj  x€L
  VP                  \        V4      G Rj  x€L
 p
V
'       d   V
P                  '       g   \!        RR	R
7      # VP#                  \%        \&        P(                  \&        P*                  4      P-                  \&        P.                  V
P(                  8H  \&        P0                  R8H  4      P3                  \&        P(                  4      P5                  V^,          4      4      G Rj  x€L
 P7                  4       p. p^ pV FÀ  w  rï\        V4      V8¼  d    M­VP#                  \9        \&        4      P-                  \&        P(                  V8H  \&        P0                  R8H  4      P;                  RRR7      4      G Rj  x€L
 pVP<                  ^8X  g   K“  VP?                  V4       Yß;'       g    V
P*                  ,          pKÂ  	  \        V4      V8  d½   V'       dv   VP#                  \9        \&        4      P-                  \&        P(                  PA                  V4      \&        P0                  R8H  4      P;                  RRR7      4      G Rj  x€L
  VPC                  4       G Rj  x€L
  \        WWR\        V4       RV R2WxV	4      G Rj  x€L
 # \E        \G        4       VVV	V
P(                  V
PH                  \K        V
PL                  4      VVR\O        V4      \P        PR                  ! 4       \U        \V        R7      ,           R7      pVPY                  V4       VPC                  4       G Rj  x€L
  VP[                  V4      G Rj  x€L
  \!        RVP\                   2R	R
7      #   \        \        3 d    ^p EL¥i ; i EL ELÛ EL¢ EL’ ELw EL¥ EL ELF EL1 EL Lo LX5i)z6Buat order dan reservasi voucher dalam satu transaksi.r²   NzNama minimal 2 karakter.z\DzNomor HP/WA tidak valid.z[^@\s]+@[^@\s]+\.[^@\s]+zFormat email tidak valid.r‘   rª   r«   r`   r$   zdipesan onlinerƒ   zStok tersisa z voucher, tidak cukup untuk rC   )Úminutes)Ú
order_coder»   r¼   r½   rb   Úprofile_nameÚduration_labelr¨   Útotal_pricerf   r‰   r‡   z/shop/order/)/r2   rU   rT   rµ   r¶   r·   ÚstriprŒ   Ú_checkout_errorr.   Úsubr/   r�   r|   r   rx   r
   ra   r   r   rd   rr   re   rb   rf   ry   Úlimitri   r   rŠ   Úrowcountr}   rg   r‹   r   rM   rq   r8   r{   r^   r   r†   r   ÚRESERVE_MINUTESÚaddÚrefreshrÀ   )r–   rb   r¨   r»   r¼   r½   rj   rq   r³   r´   ÚprofileÚ
candidatesÚreserved_idsÚtotalÚ
voucher_idÚvoucher_priceÚresultrŽ   s   &&&&&&&           r7   Úshop_checkoutrÓ   î   s  é € ðÜ�x—}�} 1Ó%ˆô �1”c˜(¤MÓ2Ó3€Hà×Ð˜R×&Ñ&Ó(€DØ×!Ð!˜r×(Ñ(Ó*€EØ×!Ð!˜r×(Ñ(Ó*×2Ð2¨d€Eä
ˆ4ƒy�1„}Ü$ W°*Ø%?ÀÈeóU÷ Uð 	Uä
Œ2�6Š6�%˜˜UÓ#Ó$ qÔ(Ü$ W°*Ø%?ÀÈeóU÷ Uð 	Uç”R—\’\Ð"=¸u×EÒEÜ$ W°*Ø%@À$ÈuóV÷ Vð 	Vô # 2Ó
&×&Ð&à—F‘Fœ>¨:Ó6×6€Gß˜'×+×+Ð+Ü G¸Ô=Ð=ð
 �j‰jÜ”7—:‘:œwŸ}™}Ó-ß‰U”7×%Ñ%¨¯©Ñ3´W·^±^À{Ñ5RÓSß‰X”g—j‘jÓ!ß‰U�8˜a•<Ó ó	
÷ 	
÷ 
�cƒeð ð €LØ€EÛ%/Ñ!ˆ
Üˆ|Ó Ô(ÙØ—z‘zÜ”7‹Oß‰U”7—:‘: Ñ+¬W¯^©^¸{Ñ-JÓKß‰V˜:Ð/?ˆVÓ@ó
÷ 
ˆð �?‰?˜aÖØ×Ñ 
Ô+Ø×3Ð3 g§m¡mÕ3ŠEñ &0ô ˆ<Ó˜8Ô#çØ—*‘*Ü”w“ß‘”w—z‘z—~‘~ lÓ3´W·^±^ÀzÑ5QÓRß‘˜{°D�Ó9ó÷ ð ð
 �i‰i‹k×ÐÜ$Ø˜ØœC Ó-Ð.Ð.JÈ8È*ÐTUÐVØ˜ó
÷ 
ð 	
ô Ü!Ó#ØØØØ—:‘:Ø—\‘\Ü(¨×)@Ñ)@ÓAØØØÜ(¨Ó6Ü—?’?Ó$¤y¼Ô'IÕIô€Eð ‡F�Fˆ5„MØ
�)‰)‹+×ÐØ
�*‰*�UÓ
×Ðô  ,¨u×/?Ñ/?Ð.@Ð AÈsÔSÐSøôm ”zÐ"ô Ø‹ðúòUòUòVò 'â6ò	
ò
òò
 	ò
ñ* Ùùs>  ‚S$„R( ™"S$¼S$ÁS$Á0S$Â%S$Â-SÂ.<S$Ã*SÃ+S$Ã7S$ÄS$Ä&SÄ'S$Ä9SÄ:S$ÅSÅS$Å$S$Å6B6S$È,SÈ-BS$Ë SËS$ËS$Ë2.S$Ì!A0S$ÎSÎS$Î)SÎ*&S$ÏSÏBS$Ñ0S Ñ1S$Ò	S"Ò
S$Ò(R?Ò;S$Ò>R?Ò?S$ÓS$ÓS$ÓS$ÓS$ÓS$ÓS$ÓS$ÓS$ÓS$Ó S$Ó"S$c              ƒ   óš   "  € \        V4      G R j  x€L
 p\        P                  T RRTRTRTRTRRTRTR	T;'       g    R
//RR7      #  L75i)Nr®   r€   r¯   r¨   r°   r±   rq   r³   r´   r²   i¦  ©r–   rq   r¢   r­   )r�   r£   r¤   )	r–   rj   rb   r¨   Úmessagerq   r³   r´   r€   s	   &&&&&&&& r7   rÅ   rÅ   T  sk   é € Ü# BÓ'×'€HÜ×%Ñ%ØØ!à˜Ø˜:Ø˜Ø�WØ�F˜D '¨5°'¸5¿;¸;ÀBÐGð
ð ð &ó ð ñ (ùs   ‚A‘A	’+A¾Az/shop/order/{order_code}c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r•   rÀ   r–   rj   )r0   r   r   )r˜   s   "r7   r™   r™   g  s!   € ÷ .ñ .¬ð .´gð .Ä<ñ .r9   c              ƒ  óª  "  € \        V4      G Rj  x€L
  VP                  \        \        4      P	                  \        P
                  V 8H  4      4      G Rj  x€L
 P                  4       pV'       g   \        P                  VRRRRV /RR7      # . pVP                  R9   d   \        W#4      G Rj  x€L
 p\        P                  VP                  VP                  R34      w  rVRpVP                  R	8X  du   VP                  '       dc   VP                  P                  RR
7      pV\        P                   ! 4       ,
          P#                  4       p	\%        ^ \'        V	^<,          4      4      p\        P                  VRRRRVRVRVR\(        P                  V\(        R,          4      RVR\+        VP,                  4      RVR\.        /	R7      #  EL¹ ELv EL 5i)z™
Halaman status untuk pembeli.

Kode voucher HANYA ditampilkan setelah order lunas. Sebelum itu sengaja
disembunyikan supaya tidak bisa dibaca dari URL.
Nzshop_order.htmlÚfoundFrÀ   é”  rÕ   r)   r$   )ÚtzinfoTrŽ   Ústatus_labelÚstatus_toneÚ
tone_classÚvouchersrs   Úminutes_leftÚreserve_minutesr¡   ©r%   r'   )r�   ra   r   r   re   rÀ   Úscalar_one_or_noner£   r¤   rf   Ú_decrypt_vouchersÚSTATUS_LABELr|   r‡   rD   r   r†   Útotal_secondsrµ   r2   Ú
TONE_CLASSrE   rÃ   rÉ   )
rÀ   r–   rj   rŽ   rß   rp   Útonerà   Úexpires_naiveÚdeltas
   &&&       r7   Úshop_order_statusrë   f  s¢  é € ô # 2Ó
&×&Ð&ð �j‰jœ¤Ó,×2Ñ2´;×3IÑ3IÈZÑ3WÓXÓY×YßÑÓð 
÷ Ü×)Ñ)ØØ"Ø˜e \°:Ð>Øð	 *ó 
ð 	
ð €HØ‡|�|Ð,Ô,Ü*¨2Ó5×5ˆä×"Ñ" 5§<¡<°%·,±,ÀÐ1HÓI�K€EØ€LØ‡|�|�zÔ! e×&6×&6Ð&6Ø×(Ñ(×0Ñ0¸Ð0Ó=ˆØ¤§¢Ó!2Õ2×AÑAÓCˆÜ˜1œc %¨2¥+Ó.Ó/ˆä×%Ñ%ØØà�TØ�UØ˜EØ˜4Øœ*Ÿ.™.¨¬z¸'Õ/BÓCØ˜Øœ& ×!2Ñ!2Ó3Ø˜LØœð

ð &ó ð ò3 'ò 	Zò 6ùsB   ‚G‘G
’AGÁGÁGÁ2>GÂ0GÂ1AGÄCGÇGÇGc              ƒ  ó,  "  € \        VP                  4      pV'       g   . # V P                  \        \        P
                  4      P                  \        P
                  P                  V4      4      4      G Rj  x€L
 P                  4       P                  4       p/ pV'       Ed   V P                  \        \        P                  4      P                  \        P
                  P                  V4      4      4      G Rj  x€L
 P                  4       P                  4       pV'       d�   V P                  \        \        P
                  \        P                  4      P                  \        P
                  P                  V4      4      4      G Rj  x€L
 P                  4       pV UUu/ uF  w  rxWxbK	  	  pppV P                  \        \        P                  \        P                  \        P                  \        P                   \        P"                  \        P$                  \        P                  4      P                  \        P
                  P                  V4      4      4      G Rj  x€L
 P                  4       p	. p
V	 Fo  w  r¼rØrïpRpV'       d    \'        V4      pT;'       g    TpVe%   VV8X  g   VR9   g   VP+                  V4      R8X  d   TpV
P-                  RVRVRVRVRV/4       Kq  	  V
#  ELw EL÷ ELku uppi  Lš  \(         d    Rp Lwi ; i5i)	a  
Bentuk daftar voucher siap tampil untuk pembeli.

Password disimpan terenkripsi hanya untuk mode 'separate'; mode 'same'
berarti password sama dengan username. Kegagalan decrypt satu voucher
tidak boleh menggagalkan seluruh halaman, jadi ditangani per baris.
NÚsameÚcodeÚusernameÚpasswordrf   Úuptime)Úlegacy_samerí   )rY   r‰   ra   r   r   rd   re   rg   rz   ri   Úbatch_idr   Ú	user_moderî   rï   Úpassword_ciphertextÚcredential_moderf   Úlimit_uptimer   Ú	Exceptionr|   r}   )rj   rŽ   r�   rl   Úbatch_modesÚ	batch_idsrÙ   ÚbidÚmodeÚrecordsÚpreparedrî   rï   ÚcipherÚvstatusrñ   ró   rð   Úusername_or_codes   &&                 r7   rä   rä   ˜  sw  é € ô ˜e×8Ñ8Ó9€KßØˆ	ð �j‰jÜ”7—:‘:Ó×$Ñ$¤W§Z¡Z§^¡^°KÓ%@ÓAó
÷ 	
÷ �gƒi—‘“ð	 	ð €Kß€tà—*‘*Ü”w×'Ñ'Ó(×.Ñ.¬w¯z©z¯~©~¸kÓ/JÓKó÷ ÷ ‰'‹)—C‘C“Eð	 	÷
 à—j‘jÜœ<Ÿ?™?¬L×,BÑ,BÓCß‘Uœ<Ÿ?™?×.Ñ.¨yÓ9Ó:ó÷ ÷ ‰c‹eð ñ 7<Ô<±e©¨˜3š9±eˆKÑ<ð �j‰jÜÜ—‘œg×.Ñ.´×0KÑ0KÜ×'Ñ'¬¯©¼×9MÑ9MÜ× Ñ ó÷ ‰e”G—J‘J—N‘N ;Ó/Ó0ó
÷ 	
÷ 
�cƒeð ð €HÛCJÑ?ˆ˜ g°xØˆßð Ü)¨&Ó1�ð $×+Ð+ tÐàÒØÐ+Ô+ØÐ.Ô.Ø�‰˜xÓ(¨FÔ2à'ˆHØ�‰Ø�DØÐ(Ø˜Ø�gØ�fð
ö 	ñ DKð, €Oòm	
òòùó
 =ñ	
øô ô  Ø’ð üsŽ   ‚A7LÁ9K0Á:*LÂ%ALÃ<K3Ã='LÄ%A&LÆK6ÆLÆ#K9Æ0B4LÉ$K?É%(LÊLÊLÊ"ALË3LË6LË9LÌLÌLÌLÌLÚadmin_csz
shop-admin)Údependenciesr   ú/shop/ordersc                ó0   € V ^8„  d   QhR\         R\        /# r”   r—   )r˜   s   "r7   r™   r™   ä  s   € ÷ ñ ¤ð ¬\ñ r9   c              ƒ  óÈ  a"  € \        V4      G Rj  x€L
  VP                  \        \        4      P	                  \        P
                  P                  4       4      P                  ^d4      4      G Rj  x€L
 P                  4       P                  4       p/ pR	 F  o\        V3R lV 4       4      VS&   K  	  \        P                  V RRVR\        R\        RV/R7      #  LË Lm5i)
z6Daftar order online untuk admin. Butuh login admin_cs.Nc              3   óL   <"  € T F  qP                   S8X  g   K  ^x € K  	  R# 5i)é   N)rf   )rž   Úorf   s   & €r7   rŸ   Úadmin_orders.<locals>.<genexpr>ì  s   øé € ÐE© 1·(±(¸fÑ2DŸQšQ«ùs   ƒ$š
$zshop_orders.htmlÚordersrÜ   rÞ   Úcountsr¡   )r$   r%   r'   r(   r*   )r�   ra   r   r   ry   Ú
created_atÚdescrÇ   rz   ri   r¥   r£   r¤   rå   rç   )r–   rj   r  r  rf   s   &&  @r7   Úadmin_ordersr  ã  sÇ   øé € ô # 2Ó
&×&Ð&à�j‰jœ¤Ó,×5Ñ5´k×6LÑ6L×6QÑ6QÓ6SÓT×ZÑZÐ[^Ó_Ó`×`ß�gƒi—‘“ð ð €FÛKˆÜÔE©ÓEÓEˆˆv‹ñ Lä×%Ñ%ØØà�fØœLØœ*Ø�fð	
ð &ó 	ð 	ñ 'á`ùs#   ƒC"’C“AC"Á2C Á3A,C"Ã C"z/shop/orders/{order_id}/payc                ó0   € V ^8„  d   QhR\         R\        /# ©r•   Úorder_idrj   ©r2   r   )r˜   s   "r7   r™   r™   ú  s   € ÷ Añ A¤Cð A¬\ñ Ar9   c              ƒ  ó&  "  € VP                  \        V 4      G Rj  x€L
 pV'       g   \        RRR7      hVP                  R	9  d:   RVn        \        P
                  ! 4       Vn        VP                  4       G Rj  x€L
  \        RRR7      #  Lp L5i)
zÑ
Tandai lunas manual. Untuk pembayaran di luar Midtrans (transfer, tuner)
dan jalur pemulihan kalau webhook gagal.

Integrasi Midtrans nanti memanggil logika yang sama lewat webhook, bukan
lewat endpoint ini.
NrÚ   úOrder tidak ditemukan©r­   Údetailr%   r  rª   r«   râ   )	r|   r   r   rf   r   r†   Úpaid_atr‹   r
   )r  rj   rŽ   s   && r7   Úadmin_mark_paidr  ù  ss   é € ð —&‘&œ hÓ/×/€EßÜ¨Ð4KÔLÐLØ‡|�|Ð0Ô0ØˆŒÜ ŸšÓ)ˆŒØ�i‰i‹k×ÐÜ ¸CÔ@Ð@ñ 0ñ 	ùs'   ‚BœB�B©ABÁ;BÁ<BÂBz/shop/orders/{order_id}/deliverc                ó0   € V ^8„  d   QhR\         R\        /# r  r  )r˜   s   "r7   r™   r™     s   € ÷ Añ A¤#ð A¬<ñ Ar9   c              ƒ  óv  "  € VP                  \        V 4      G Rj  x€L
 pV'       g   \        RRR7      hVP                  R8X  dß   \	        VP
                  4      pV'       d‰   VP                  \        \        4      P                  \        P                  P                  V4      \        P                  R8H  4      P                  R\        P                  ! 4       R7      4      G Rj  x€L
  R	Vn        \        P                  ! 4       Vn        VP!                  4       G Rj  x€L
  \#        R
RR7      #  EL LM L5i)zGTandai voucher sudah diserahkan ke pembeli; status voucher jadi 'sold'.NrÚ   r  r  r%   r$   Úsold)rf   Úsold_atr'   r  rª   r«   )r|   r   r   rf   rY   r‰   ra   r   r   re   rd   rg   rŠ   r   r†   Údelivered_atr‹   r
   ©r  rj   rŽ   r�   s   &&  r7   Úadmin_deliverr     sá   é € ð —&‘&œ hÓ/×/€EßÜ¨Ð4KÔLÐLØ‡|�|�vÔÜ! %×"<Ñ"<Ó=ˆßØ—*‘*Ü”w“ß‘”w—z‘z—~‘~ kÓ2´G·N±NÀjÑ4PÓQß‘˜v¬x¯ªÓ/@�ÓAó÷ ð ð
 #ˆŒÜ%Ÿ_š_Ó.ˆÔØ�i‰i‹k×ÐÜ ¸CÔ@Ð@ò 0ññ 	ùs9   ‚D9œD2�D9©B>D9Ã'D5Ã(8D9Ä D7Ä!D9Ä5D9Ä7D9z/shop/orders/{order_id}/cancelc                ó0   € V ^8„  d   QhR\         R\        /# r  r  )r˜   s   "r7   r™   r™   !  s   € ÷ Añ A¤ð A¬,ñ Ar9   c              ƒ  ó  "  € VP                  \        V 4      G Rj  x€L
 pV'       g   \        RRR7      hVP                  R9   d²   \	        VP
                  4      pV'       dv   VP                  \        \        4      P                  \        P                  P                  V4      \        P                  R8H  4      P                  RRR7      4      G Rj  x€L
  RVn        VP                  4       G Rj  x€L
  \        R	R
R7      #  Lè L2 L5i)z0Batalkan order; voucher dilepas kembali ke stok.NrÚ   r  r  r$   r`   rƒ   r*   r  rª   r«   r…   )r|   r   r   rf   rY   r‰   ra   r   r   re   rd   rg   rŠ   r‹   r
   r  s   &&  r7   Úadmin_cancelr#     sÌ   é € ð —&‘&œ hÓ/×/€EßÜ¨Ð4KÔLÐLØ‡|�|Ð.Ô.Ü! %×"<Ñ"<Ó=ˆßØ—*‘*Ü”w“ß‘”w—z‘z—~‘~ kÓ2´G·N±NÀjÑ4PÓQß‘˜{°D�Ó9ó÷ ð ð
 #ˆŒØ�i‰i‹k×ÐÜ ¸CÔ@Ð@ñ 0ññ 	ùs9   ‚DœD�D©B+DÃDÃDÃ3D	Ã4DÄDÄ	D)zMenunggu Pembayaranr#   )ÚLunasr&   )ÚSelesair&   )ÚKedaluwarsar)   )Ú
Dibatalkanr+   )FÚ__doc__rP   r.   rI   r   r   Úfastapir   r   r   r   r   Úfastapi.responsesr	   r
   Úfastapi.templatingr   Ú
sqlalchemyr   r   r   Úsqlalchemy.ext.asyncior   Úapp.core.databaser   Úapp.core.device_credentialsr   Úapp.core.securityr   Úapp.models.modelsr   r   r   r   ÚosÚrouterÚpathÚdirnameÚabspathÚ__file__ÚBASE_DIRÚjoinr£   rÉ   r·   r4   rå   rç   r8   r?   rE   rM   rY   r^   rn   r�   r�   r|   r¦   r¹   ÚpostrÓ   rÅ   rë   rä   Úadmin_routerr  r  r   r#  rL   r9   r7   Ú<module>r<     sâ  ðñó. Û 	Û ß (ç DÕ Dß <Ý .ß +Ñ +Ý /å $Ý 6Ý +ß PÓ Pã 	á	˜˜Ô	!€Ø�7‰7�?‰?˜2Ÿ7™7Ÿ?™?¨2¯7©7¯?©?¸2¿7¹7¿?¹?È8Ó;TÓ+UÓVÓW€Ù b§g¡g§l¡l°8¸_Ó&MÔN€	ð €Ø€à
ˆw˜˜W c¨5°#°vÐ	>€ð Ð/ØÐ0Ø
Ð ØÐ'ØÐ'ØÐ'ð€ð ÐAØÐIØÐAØ
Ð=ð	€
ò=ò
ò6ò
Iò
ò-ò/òò8ðH ‡�ˆG L€Ó1Ù<CÀF»Oö ó 2ðð" ‡�Ð¨\€Ó:ð ØÙ˜v“ö	ó ;ðð2 ‡�ÐÓñ ˜3“iÙ˜“GÙ˜c›Ù˜s›)Ù˜r›(Ù˜v“öbTó ðbTòJð$ ‡�Ð&°|€ÓDÙRYÐZ`ÓRaö .ó Eð.òbCñP ¡w©}¸ZÓ/HÓ'IÐ&JÐR^ÐQ_Ô`€ð ×Ñ�.°ÐÓ>Ù<CÀF»Oö ó ?ðð* ×ÑÐ0Ó1Ù<CÀF»Oö Aó 2ðAð$ ×ÑÐ4Ó5Ù:AÀ&»/ö Aó 6ðAð& ×ÑÐ3Ó4Ù9@À»ö Aó 5òAr9   