
    :is(                         d dl mZmZmZ d dlmZmZmZ d dlm	Z	 d dl
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 d d	lmZ  G d
 d      Zy)    )ListOptionalTuple)selectfuncor_)AsyncSession)HTTPExceptionstatus)Product)	Violation)ScrapingResult)ProductCreateProductUpdate)calculate_pack_pricesc                   2   e Zd Zedededefd       Zedededefd       Ze	 	 	 	 ddeded	ed
e	de
e	   deee   ef   fd       Zedededefd       Zededededefd       Zedededdfd       Zedededefd       Zededee   defd       Zy)ProductServicedb
product_idreturnc                   K   | j                  t        t              j                  t        j                  |k(               d{   }|j                         j                         }|sy| j                  t        t        j                  t        j                              j                  t        j                  |j                  k(               d{   }|j                         xs dS 7 7 w)z(Count violations for a specific product.Nr   )executer   r   whereidscalarsfirstr   countr   product_namescalar)r   r   product_resultproductcount_results        B/var/www/html/marco-python-backend/app/services/product_service.pyget_violation_countz"ProductService.get_violation_count   s       "zz&/*?*?

j@X*YZZ ((*002  ZZ4::ill+,22&&'*>*>>
 

 ""$)) [
s%   AC/C+BC/C-C/-C/r!   c                 "  K   | j                  t        t        j                  t        j
                              j                  t        j                  |j                  k(               d{   }|j                         xs d}||_	        |S 7 !w)zUAdd violation_count to a product object by querying violations matching product name.Nr   )
r   r   r   r   r   r   r   r   r   violation_count)r   r!   r"   r&   s       r#   enrich_product_with_violationsz-ProductService.enrich_product_with_violations    sv       ZZ4::ill+,22&&'*>*>>
 

 '--/41"1
s   A)B+B,"BNpagelimitsort_bysearchc                   K   |dz
  |z  }t        t              }|r2|j                  t        j                  j	                  d| d            }|dk(  r |j                  t        j                        }nw|dk(  r |j                  t        j                        }nR|dk(  r.|j                  t        j                  j                               }n|j                  t        j                        }t        t        j                               j                  |j                               }| j                  |       d {   }|j                  |      j                  |      }| j!                  |       d {   }	|	j#                         j%                         }
g }|
D ]1  }t&        j)                  | |       d {   }|j+                  |       3 ||fS 7 7 `7 w)N   %mspr   last_scraped_date)r   r   r   r   ilikeorder_byr/   
updated_atdescr   r   select_fromsubqueryr   offsetr)   r   r   allr   r'   append)r   r(   r)   r*   r+   r7   querycount_querytotalresultproductsenriched_productsr!   s                r#   get_productszProductService.get_products-   s     (e#wKK 4 4 : :Qvha= IJE eNN7;;/E&NN7#7#78E++NN7#5#5#:#:#<=ENN7#7#78E TZZ\*66u~~7GHii,, V$**51zz%((>>#'')  	.G*II"gVVG$$W-	. !%'' - ) Ws7   D6G8G98G1G2AG4G5GGG
product_inc                   K   t        t        |j                              }t        |j                  |j
                  |j                  |j                  |j                  |d   |d   |d   |d   |d   |d   |d         }| j                  |       | j                          d	{    | j                  |       d	{    |S 7 7 w)
z6Create a new product with auto-calculated pack prices.r-                     reference_idr   barcoder/   r   price_1_packprice_2_packprice_3_packprice_4_packprice_5_packprice_6_packprice_12_packN)r   floatr/   r   rJ   r   rK   r   addcommitrefresh)r   rA   pack_prices
db_products       r#   create_productzProductService.create_productW   s      ,E*..,AB#00#00&&$$$Q$Q$Q$Q$Q$Q%b/

 	ziikjj$$$ 	$s$   B!C#C$C<C=CCc           
        K   t         j                  | |       d{   }|j                  d      }d|v rGt        |d         }t	        |      }|j                  |d   |d   |d   |d   |d	   |d
   |d   d       |j                         D ]  \  }}t        |||        | j                          d{    | j                  |       d{    |S 7 7 !7 
w)z8Update product. If MSP changes, recalculate pack prices.NT)exclude_unsetr/   r-   rC   rD   rE   rF   rG   rH   )rL   rM   rN   rO   rP   rQ   rR   )
r   get_product_by_id
model_dumprS   r   updateitemssetattrrU   rV   )	r   r   rA   r!   update_datanew_msprW   fieldvalues	            r#   update_productzProductService.update_productq   s     
 '88ZHH ++$+? KK./G/8K +A +A +A +A +A +A!,R   (--/ 	+LE5GUE*	+ iikjj!!!/ I* 	!s4   CCBC6C7CCCCCc                 |  K   | j                  t        t              j                  t        j                  |k(               d {   }|j                         j                         }|st        t        j                  d      | j                  |       d {    | j                          d {    y 7 q7 7 	wNzProduct not found)status_codedetail)r   r   r   r   r   r   r   r
   r   HTTP_404_NOT_FOUNDdeleterU   r   r   r=   rX   s       r#   delete_productzProductService.delete_product   s     zz&/"7"7

j8P"QRR^^%++-
"55* 
 ii
###iik S 	$s7   AB<B6AB<B8B<0B:1B<8B<:B<c                 T  K   | j                  t        t              j                  t        j                  |k(               d {   }|j                         j                         }|st        t        j                  d      t        j                  | |       d {   }|S 7 _7 wrg   )r   r   r   r   r   r   r   r
   r   rj   r   r'   rl   s       r#   r\   z ProductService.get_product_by_id   s     zz&/"7"7

j8P"QRR^^%++-
"55* 
 *HHZXX
 S Ys%   AB(B$AB(B&B(&B(products_listc                 2  K   t        |      }d}d}d}g }| j                  t        t        j                        j                  t                     d{   }t        |j                         j                               }t        |d      D ]  \  }	}
	 |
j                  |v r3|dz  }|j                  |	|
j                  d|
j                   dd       Ht        t        |
j                              }t        |
j                  |
j                  |
j                  |
j                  |
j                   |d   |d   |d   |d	   |d
   |d   |d         }| j#                  |       |j#                  |
j                         |dz  } |dkD  r	 | j+                          d{    |||||d| d| d| ddS 7 `# t$        $ r;}|dz  }|j                  |	|
j                  dt'        |       d       Y d}~jd}~wt(        $ r;}|dz  }|j                  |	|
j                  dt'        |       d       Y d}~d}~ww xY w7 # t(        $ rI}| j-                          d{  7   ||z  }d}|j                  ddt'        |       i       Y d}~d}~ww xY ww)a6  
        Bulk create multiple products. Applies the same logic as create_product:
        - Auto-calculates pack prices based on MSP
        - Preserves all discount and pack pricing logic
        - Checks for duplicate barcodes
        
        Returns a summary dict with:
        - total_processed: Number of products in input list
        - successful: Number of products successfully created
        - failed: Number of products that failed
        - skipped_duplicates: Number of duplicate barcodes skipped
        - errors: List of errors encountered
        r   Nr-   zDuplicate barcode: z already exists)rowr!   errorrC   rD   rE   rF   rG   rH   rI   zValidation error: zDatabase error: rr   zFailed to commit all products: zBulk upload completed: z
 created, z	 failed, z duplicates skipped)total_processed
successfulfailedskipped_duplicateserrorsmessage)lenr   r   r   rK   r5   setr   r8   	enumerater9   r   r   rS   r/   rJ   r   rT   
ValueErrorstr	ExceptionrU   rollback)r   ro   rs   rt   ru   rv   rw   existing_barcodes_resultexisting_barcodesidxrA   rW   rX   es                 r#   bulk_create_productsz#ProductService.bulk_create_products   s    " m,
 *,7??#//8*
 $
    8 @ @ B F F HI(: 0	OC/%%)::&!+&MM"#-#:#:#6z7I7I6J/!Z# 
  4E*..4IJ %!+!8!8!+!8!8&.."%,,!,Q!,Q!,Q!,Q!,Q!,Q"-b/
 z"!%%j&8&89a
C0	f >iik!!  /$"40JvhiXjWkk~
 	
G$
P  !)661#a&:  
  !)66/Ax8   " kkm##*$
>s1vhG  	s   AJF4=JA F7JB-F7J	I I I !J7	H= 0G60J6H=0H82J8H==J I 	JJI!+J
JJJ)r-   
   r   N)__name__
__module____qualname__staticmethodr	   intr$   r   r'   r}   r   r   r   r@   r   rY   r   re   rm   r\   dictr        r#   r   r      s   *l * * * *" 
 
 
T[ 
 
  % $'('('( '( 	'(
 '( 
tG}c!	"'( '(R  = W  2 &)7D	 : 
 
3 
4 
 
 
L 
c 
g 
 
 a
a
)-m)<a
	a
 a
r   r   N)typingr   r   r   
sqlalchemyr   r   r   sqlalchemy.ext.asyncior	   fastapir
   r   app.models.productr   app.models.violationr   app.models.scraping_resultr   app.schemas.productr   r   app.services.pricing_servicer   r   r   r   r#   <module>r      s2    ( ( ( ( / ) & * 5 < >~
 ~
r   