
    ]i;                        d Z ddlmZ ddlmZmZmZ ddlmZm	Z	 ddl
mZ ddlmZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZmZ ddlm Z  defdZ!dedefdZ"d,dede#defdZ$dede%fdZ&	 	 	 	 	 d-dede'dedz  de(dz  de'de'de)e*e   e'f   fdZ+dede'de'fdZ,dede'de'defdZ-dede'de'ddfdZ.dede'd ed!e'def
d"Z/dede'de'd edef
d#Z0dede'de'd$e(def
d%Z1ded&e2defd'Z3dede'de'd(e2d)e(d*e(defd+Z4y).u@   Penebusan service — business logic for BBM procurement module.    )Decimal)deletefuncselect)IntegrityErrorSQLAlchemyError)AsyncSession)	PenebusanPenebusanItemStatusPenebusan)
Penerimaan)Produk)penebusan_repository)ParsedPDFItemParsedPDFResultPenebusanCreatePenebusanDetailResponsePenebusanItemInputPenebusanItemResponsePenebusanResponsePenebusanUpdate)parse_pertamina_pdfreturnc                    | j                   }t        | j                  | j                  |r|j                  nd|r|j
                  nd| j                  | j                  | j                  | j                  | j                  	      S )z-Build enriched item response from ORM object. )	id	produk_idproduk_namaproduk_kodekode_item_pertaminavolume_pesanvolume_diterimatanggal_kirimsent_to_text)produkr   r   r   namakoder    r!   r"   r#   r$   )itemr%   s     @/var/www/html/spbu.com/backend/app/services/penebusan_service.py_build_item_responser*      si    [[F 77..#)FKKr#)FKKr 44&&,,((&&
 
    pc                    | j                   xs g }t        d |D        t        d            }t        d |D        t        d            }g }|D ]H  }|j                  r|j                  j                  nd}|j                  | d|j                  dd       J dj                  |      }t        | j                  | j                  | j                  | j                  | j                  | j                  | j                  t!        |      |||| j"                  | j$                  | j&                  r| j&                  j(                  nd	| j*                  
      S )z,Build a summary response from an ORM object.c              3   4   K   | ]  }|j                     y wN)r!   .0is     r)   	<genexpr>z,_build_penebusan_response.<locals>.<genexpr>1   s     95a1>>5   0c              3   4   K   | ]  }|j                     y wr/   )r"   r0   s     r)   r3   z,_build_penebusan_response.<locals>.<genexpr>2   s     ?Aa//r4   ?z (z,.0fzL)z, N)r   spbu_idtanggalbooking_codeno_sostatustotal
item_counttotal_volume_pesantotal_volume_diterimaproducts_summary
pdf_do_urlpdf_bukti_bayar_urlcreated_by_name
created_at)itemssumr   r%   r&   appendr!   joinr   r   r8   r9   r:   r;   r<   r=   lenrB   rC   
created_bynamerE   )r,   rF   total_vol_pesantotal_vol_diterimaprod_summary_partsr(   r&   rA   s           r)   _build_penebusan_responserP   .   s   GGMrE95973<HO??N #';;t{{C!!TF"T->->t,DB"GH  yy!3444				^^ggxxggu:*0)<<11-.\\))t<< r+   has_penerimaanc                 D   t        |       }| j                  xs g D cg c]  }t        |       }}t        di |j	                         || j
                  | j                  | j                  | j                  | j                  | j                  | j                  |d	S c c}w )z@Build a full detail response including items and cost breakdown.)	rF   subtotaldiscountppnpph22pbbkbroundingdebit_creditrQ    )rP   rF   r*   r   
model_dumprS   rT   rU   rV   rW   rX   rY   )r,   rQ   summaryr(   item_responsess        r)   _build_detail_responser^   N   s    '*G>?ggmmMmT*40mNM" 



EEgggg^^%  Ns   Br(   c                 v    | j                   | j                  | j                  | j                  | j                  dS )z8Convert a PenebusanItemInput to a dict for DB insertion.r   r    r!   r#   r$   r`   )r(   s    r)   _item_input_to_dictra   `   s9     ^^#77))++)) r+   Ndbr8   r<   r:   skiplimitc           	         K   t        j                  | ||||||       d{   \  }}|D 	cg c]  }	t        |	       c}	|fS 7 "c c}	w w)z9Return a paginated list of PenebusanResponse for an SPBU.N)r   get_all_penebusanrP   )
rb   r8   r9   r<   r:   rc   rd   rowsr=   rs
             r)   list_penebusanri   o   s\      ->>
GWflD% KD% 377$Q%a($7>> 8s   AAAAAApenebusan_idc                   K   | j                  t        t        j                               j	                  t
              j                  t
        j                  |k(               d {   }|j                         xs dS 7 w)Nr   )	executer   r   countselect_fromr   whererj   scalar)rb   rj   results      r)   _count_penerimaanrr      sa     ::tzz|((4:::;R;RVb;bc F ==?as   A#B %A>&B c                    K   t        j                  | ||       d{   }|t        d      t        | |       d{   }t	        ||dkD        S 7 57 w)z0Return a fully enriched PenebusanDetailResponse.NPenebusan tidak ditemukanr   )rQ   )r   get_penebusan_by_id
ValueErrorrr   r^   rb   r8   rj   r,   penerimaan_counts        r)   get_penebusan_detailry      s`      #66r<QQAy455.r<@@!!4Dq4HII	 	R As   AA AAAAc                 n  K   t        j                  | ||       d{   }|t        d      t        | |       d{   }|dkD  rt        d      	 | j	                  |       d{    | j                          d{    y7 h7 I7 !7 # t        $ r | j                          d{  7    w xY ww)zADelete a penebusan. Blocked if any penerimaan records are linked.Nrt   r   zFPenebusan tidak dapat dihapus karena sudah ada penerimaan yang terkait)r   ru   rv   rr   r   commitr   rollbackrw   s        r)   delete_penebusanr}      s      #66r<QQAy455.r<@@!T
 	
iiliik 	R A 	 kkmsg   B5B B5BB5B (B
)B  BB B5B5
B B B2*B-+B22B5datauser_idc                   K   t        j                  | ||j                         d{   }|t        d|j                   d      |j                  D ]  }| j                  t        t              j                  t        j                  |j                  k(  t        j                  j                  d                   d{   }|j                         t        d|j                   d       |j                  t        j                   nt        j"                  }||j$                  |j                  |j                  ||j&                  |j(                  |j*                  |j,                  |j.                  |j0                  |j2                  |j4                  |d}|j                  D cg c]  }t7        |       }	}	 t        j8                  | ||	       d{   }
| j;                          d{    t        j<                  | |
j                  |       d{   }
t?        |
      S 7 7 lc c}w 7 [7 E7 # t@        $ r% | jC                          d{  7   t        d      tD        $ r | jC                          d{  7    w xY ww)zCreate a new penebusan record.NPenebusan dengan booking code '' sudah ada
Produk id= tidak ditemukan)r8   r9   r:   r;   r<   rS   rT   rU   rV   rW   rX   rY   r=   created_by_id:Data penebusan duplikat atau melanggar constraint database)#r   get_penebusan_by_booking_coder:   rv   rF   rl   r   r   ro   r   r   
deleted_atis_scalar_one_or_noner;   r   
WAITING_SO	SUBMITTEDr9   rS   rT   rU   rV   rW   rX   rY   r=   ra   create_penebusanr{   ru   r^   r   r|   r   )rb   r8   r~   r   existingr(   rq   initial_status	data_dict
item_dictsr,   s              r)   r   r      s%     *GG
GT&& H :4;L;L:M[YZZ 

zz6N  dnn!<f>O>O>S>STX>YZ
 
 $$&.z$..)99IJKK  48::3E_//?KdKdN <<)) MMMMxxMM)) I  9=

C
%d+
JC
&77IzRRiik&::2qttWMM%a((O
2 D SM WkkmUVV kkms   %JH(BJ?H+ JCJ(H.:J=H9 H3H9 /H50(H9 H7H9 'J+J.J3H9 5H9 7H9 9J	I+J	JJ		Jc           	      h  K   t        j                  | ||       d{   }|t        d      t        | |       d{   }|dkD  r|j                  t        d      i }dD ]  }t        ||      }||||<    d|v rH|d   |j                  k7  r6t        j                  | ||d          d{   }	|	t        d|d    d      |j                  0|j                  t        j                  k(  rt        j                  |d	<   d}
|j                  |j                  D ]  }| j                  t        t              j!                  t        j"                  |j$                  k(  t        j&                  j)                  d                   d{   }|j+                         t        d
|j$                   d       |j                  D cg c]  }t-        |       }
}	 t        j.                  | |||
       d{   }| j1                          d{    t        j                  | |j"                  |       d{   }t3        |      S 7 ,7 7 7 c c}w 7 `7 J7 ## t4        $ r% | j7                          d{  7   t        d      t8        $ r | j7                          d{  7    w xY ww)zEUpdate an existing penebusan. Line items locked if penerimaan exists.Nrt   r   zFLine items tidak dapat diubah karena sudah ada penerimaan yang terkait)r9   r:   r;   rS   rT   rU   rV   rW   rX   rY   r=   r:   r   r   r<   r   r   r   )r   ru   rv   rr   rF   getattrr:   r   r;   r<   r   r   r   rl   r   r   ro   r   r   r   r   r   ra   update_penebusanr{   r^   r   r|   r   )rb   r8   rj   r~   r,   rx   update_fields
field_namevaluer   r   r(   rq   s                r)   r   r      s     #66r<QQAy455.r<@@!

 6abb M
 j)(-M*% &=+HANN+Z-KK~6
 
 >}^?\>]]hijj zz!((o.H.H"H"1";";h JzzJJD::v$$VYY$..%@&BSBSBWBWX\B]^ F ((*2 :dnn-==M!NOO  =AJJGJD)$/J
G
&77A}jYYiik&::2qttWMM%a((Y 	R A 

 H ZM WkkmUVV kkms   J2I	 J2I5J25:J2/I0CJ2
IJ2 (J2IJ2I 8I9I I(I 9I:I J2J2J2J2J2I I I J/;I><+J/'J*(J//J2r;   c                 `  K   t        j                  | ||       d{   }|t        d      |j                  t        j
                  k7  rt        d      	 t        j                  | |t        j                  |       d{   }| j                          d{    t        j                  | |j                  |       d{   }t        |      S 7 7 R7 <7 # t        $ r% | j                          d{  7   t        d      t        $ r | j                          d{  7    w xY ww)zDSet SO number on a WAITING_SO penebusan, transitioning to SUBMITTED.Nrt   z?Set SO hanya bisa dilakukan pada penebusan berstatus WAITING_SO)r;   r   )r   ru   rv   r<   r   r   update_penebusan_statusr   r{   r   r^   r   r|   r   )rb   r8   rj   r;   r,   s        r)   set_sor     s     #66r<QQAy455xx?---Z[[&>>?,,E
 
 iik&::2qttWMM%a(( 	R
 	M WkkmUVV kkmsu   D.C9D.*C CC C(C CC D.C C C D+7C:8+D+#D&$D++D.	pdf_bytesc                   K   t        |      }| j                  t        t              j	                  t        j
                  j                  d      t        j                  j                  d                   d{   }t        |j                         j                               }dddddddddd		}t        |j                        }g }|j                  D ]r  }d}	|j                  j                         j                         }
|D ]#  }|j                   j                         |
k(  s!|}	 n |	;|j#                  |
      }|r(|D ]#  }|j                   j                         |k(  s!|}	 n |	C|D ]>  }|j                   j                         |
v s|
|j                   j                         v s<|}	 n |	|j%                  d
|j                   d       |j%                  t'        |j(                  |j                  |	r|	j*                  nd|	r|	j                   nd|j,                  |j.                  |j0                  |j2                               u t5        |j6                  |j8                  ||j:                  |j<                  |j>                  |j@                  |jB                  |jD                  |jF                  |jH                  |      S 7 Lw)z7Parse a Pertamina PDF and match products to DB records.NTpertamax turbopertamax	pertalitebiosolardexlitepertadex)	r   zpertamax,bulkr   r   zbiosolar b40r   z	bio solarr   r   zProduk 'z' tidak ditemukan di database)r    product_namer   r   volume_literr;   r#   r$   )r:   r9   rF   rS   rT   rU   rV   rW   rX   rY   r=   warnings)%r   rl   r   r   ro   r   r   	is_activelistscalarsallr   rF   r   lowerstripr&   getrH   r   r    r   r   r;   r#   r$   r   r:   r9   rS   rT   rU   rV   rW   rX   rY   r=   )rb   r   parsedrq   all_products	alias_mapr   	pdf_itemsr(   matched_produk
name_lowerr,   resolved_names                r)   	parse_pdfr   7  sp    
 !+F ::vV..2248&:J:J:N:Nt:TU F (,,./L +# "
I FOO$H%'I&&,,.446
 Avv||~+!"  !%MM*5M%Avv||~6)* & !!66<<>Z/:3O%&N "
 !OOht'8'8&99VWX $ 8 8**+9n''t/=++4****,,**	
 		; P ((JJllll((ll {s'   A7K9K:B*K%<K"AK'DK
file_bytesfilename	file_typec                   K   ddl m}m} t        j                  | ||       d{   }|t        d      ddl m}	 |dk(  rd}
n|dk(  rd	}
nt        d
      t        ||
d      }ddl m}  || |j                         d{   } ||d|j                        } ||||       d{   }	 t        j                  | ||
|       d{   }| j                          d{    t        j                  | |j                  |       d{   } |	|       d{    t#        |      S 7 7 7 7 g7 Q7 *# t        $ r% | j                          d{  7   t        d      t         $ r | j                          d{  7    w xY w7 ow)z$Upload a DO PDF or bukti bayar file.r   )save_uploadUploadContextNrt   )delete_filedorB   buktirC   z!file_type harus 'do' atau 'bukti')get_spbu_code	penebusanz$Gagal menyimpan URL file ke database)app.utils.file_uploadr   r   r   ru   rv   r   r   r   r8   r9   update_file_urlr{   r   r   r|   r   r^   )rb   r8   rj   r   r   r   r   r   r,   r   r   old_urlr   	spbu_codectxurls                   r)   upload_filer     sp     A"66r<QQAy4551D!
	g	*
<==aT*G3#B		22I
	;		
:CJ#6
6C	&66r1j#NNiik&::2qttWMM g
!!$$; 	R 3
6 OM Akkm?@@ kkm s   #FD)AFD,%F'D.(F-D6 D0	D6  D2!(D6 	D4
D6 FF	F,F.F0D6 2D6 4D6 6FE+F>F?FF)F)NNNr      )5__doc__decimalr   
sqlalchemyr   r   r   sqlalchemy.excr   r   sqlalchemy.ext.asyncior	   app.models.penebusanr
   r   r   app.models.penerimaanr   app.models.productr   app.repositoriesr   app.schemas.penebusanr   r   r   r   r   r   r   r   app.utils.pdf_parserr   r*   rP   boolr^   dictra   intstrtupler   ri   rr   ry   r}   r   r   r   bytesr   r   rZ   r+   r)   <module>r      so   F  + + : / J J , % 1	 	 	 5"7   /@ @i  Ja $0 T $ %)#??? d"	?
 *? ? ? 4!"C'(?    C  C  JJ"J25JJ  
	,555 5 	5
 5p999 9 	9
 9x  	
 8RRR Rj(%(%(% (% 	(%
 (% (% (%r+   