
    j                        d Z ddlZddlmZ ddlmZmZ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 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  ee      Z eddg      Z G d de      Z  G d de      Z! eejD                        fdedefdZ#ejI                  d       ee#       eejJ                        fdedefd       Z&ejI                  d       ee#       eejJ                        fdedefd       Z'ejI                  d      ddd ee#       eejJ                        fdee(   de)d e)dedef
d!       Z*ejI                  d"      ddd ee#       eejJ                        fdee(   de)d e)dedef
d#       Z+ejI                  d$       ee#       eejJ                        fd%e(dedefd&       Z,ej[                  d'       ee#       eejJ                        fd(e(d)e dedefd*       Z.ejI                  d+      d, ee#       eejJ                        fd-e)dedefd.       Z/ejI                  d/       ee#       eejJ                        fdedefd0       Z0ejI                  d1       e	d2d34       ee#       eejJ                        fde(dedefd5       Z1ejI                  d6       e	d7d84       ee#       eejJ                        fd9e(dedefd:       Z2ej[                  d;       e	d7       e	d7       ee#       eejJ                        fd(e(d<e(dedefd=       Z3ej[                  d>      d ee#       eejJ                        fd(e(d?ee(   dedefd@       Z4ejI                  dA       e	ddB4       ee#       eejJ                        fd(ee(   dedefdC       Z5ej[                  dD       ee#       eejJ                        fd(e(dEe(dedefdF       Z6ddGl
mZ ddHlm7Z7  G dI dJe      Z8 G dK dLe      Z9 G dM dNe      Z:ej[                  dO       ee#       eejJ                        fd(e(d)e8dedefdP       Z;ej[                  dQ       ee#       eejJ                        fd(e(d)e9dedefdR       Z<ej[                  dS       ee#       eejJ                        fd(e(d)e:dedefdT       Z= G dU dVe      Z>ej[                  dW       ee#       eejJ                        fd%e(d)e>dedefdX       Z?ej[                  dY       ee#       eejJ                        fd%e(dedefdZ       Z@ G d[ d\e      ZAej[                  d]       ee#       eejJ                        fd%e(d)eAdedefd^       ZBejI                  d_       ee#       eejJ                        fdedefd`       ZCejI                  da       ee#       eejJ                        fdbe(dedefdc       ZDejI                  dd       ee#       eejJ                        fd%e(dedefde       ZE G df dge      ZF G dh die      ZGej[                  dj       ee#       eejJ                        fd)eFdedefdk       ZHej[                  dl       ee#       eejJ                        fd%e(d)e!dedefdm       ZIejI                  dn       e	ddo4       ee#       eejJ                        fdee(   dedefdp       ZJej[                  dq       ee#       eejJ                        fdbe(d)eGdedefdr       ZKejI                  ds       ee#       eejJ                        fdte(dedefdu       ZLejI                  dv       ee#       eejJ                        fd(e(dedefdw       ZM G dx dye      ZNej[                  dz       ee#       eejJ                        fdbe(d)eNdedefd{       ZO G d| d}e      ZPej[                  d~       ee#       eejJ                        fd)ePdedefd       ZQy)z_
Fetch China - Partner API Routes
Partner-only endpoints for managing their clients and orders
    N)Optional)	APIRouterDependsHTTPExceptionstatusQuery)	BaseModelFieldHttpUrl)Session)deps)UserUserRoleParcel)ParcelStatus)AuditService)
get_loggerz/partnerpartner)prefixtagsc                   @    e Zd ZU eed<   dZee   ed<   dZee   ed<   y)RejectItemRequestreasonNnoteproposed_price_cny)	__name__
__module____qualname__str__annotations__r   r   r   float     /tmp/partner_pr231.pyr   r      s$    KD(3-*..r$   r   c                   X    e Zd ZU  eddd      Zeed<    eddd      Zeed<   eed<   y	)
WarehouseReceiveRequest.   d   
min_length
max_lengthdomestic_tracking_no2   internal_barcodeqc_image_urlN)r   r   r   r
   r-   r    r!   r/   r#   r$   r%   r'   r'      s0     %caC H#H!#!CcCr$   r'   current_userreturnc                     | j                   t        j                  j                  k7  rt	        t
        j                  d      | S )z$Dependency to ensure user is partnerzPartner access requiredstatus_codedetail)roler   PARTNERvaluer   r   HTTP_403_FORBIDDEN)r1   s    r%   get_current_partnerr;   %   s?     H,,22211:S
 	
 r$   z
/dashboarddbc                 J    ddl m} |j                  || j                        }|S )u   获取合伙人仪表板数据r   PartnerService)app.services.partner_servicer?   get_partner_statsid)r1   r<   r?   statss       r%   get_partner_dashboardrD   0   s"     <,,RAELr$   z/clientsc           
         ddl m} ddlm} |j	                  || j
                        }g }|D ]  }|j                  |      j                  |j                  |j
                  k(        j                         }|j                  |j
                  |j                  |j                  t        |j                  xs d      dz  ||j                  r|j                  j!                         ndd        |S )u   获取我的客户列表r   r>   )Orderr)   N)rB   email	is_activepartner_commission_ratetotal_orders
created_at)r@   r?   app.models.orderrF   get_partner_clientsrB   queryfilteruser_idcountappendrG   rH   r"   rI   rK   	isoformat)r1   r<   r?   rF   clientsresultcorder_counts           r%   get_my_clientsrX   <   s     <&00\__EGF 
hhuo,,U]]add-BCIIKdd[[+01J1J1Oa+PSV+V +:;,,all446D		

 Mr$   z/orders/summaryr.   r   skiplimitc                    ddl m} |j                  ||j                  |       }||||z    }g }|D ]  }|j                  }	t        |j                        }
|j                  |j                  |j                  |j                  t        |j                        t        |j                        |j                  |	r|	j                  nd|
|j                  r|j                  j!                         ndt        |j"                        t        |j$                        |j&                  r|j&                  j!                         ndd        |S )u   获取我的订单列表（轻量级摘要版本，用于列表页）

    性能优化：
    - 只返回列表页需要的字段
    - 不加载QC图片等详细信息
    - 减少数据传输量
    r   r>   UnknownN)rB   order_numberr   	total_usdservice_fee_usdrP   client_emailitems_countrK   	total_cnyexchange_rate
updated_at)r@   r?   get_partner_ordersrB   userlenitemsrR   r]   r   r"   r^   r_   rP   rG   rK   rS   rb   rc   rd   )r   rY   rZ   r1   r<   r?   ordersrU   oclientra   s              r%   get_my_orders_summaryrl   V   s    < ..r<??FKFD4%<(FF 
 !''ldd !(("1;;/#():):#;9906I*:;,,all446D"1;;/!&q!7:;,,all446D	

. Mr$   z/ordersc                    ddl m} |j                  ||j                  |       }||||z    }g }|D ]  }|j                  }	g }
|j
                  D ]  }|j                  D cg c]7  }|j                  |j                  r|j                  j                         ndd9 }}|
j                  i dt        |j                        dt        |j                        d|j                  d|j                  d	|j                  d
|j                  dt!        |j"                        d|j$                  rt!        |j$                        ndd|j&                  rt!        |j&                        ndd|j(                  d|j*                  d|j,                  d|j.                  d|j0                  d|j2                  d|j4                  rt!        |j4                        ndd|j6                  ||j8                  rt!        |j8                        nd|j:                  rt!        |j:                        nd|j<                  rt!        |j<                        nd|j>                  |j@                  r|j@                  j                         nd|jB                  rt!        |jB                        nd|jD                  |jF                  rt!        |jF                        nd|jH                  |jJ                  |jL                  |jN                  rt!        |jN                        ndd        |j                  |j                  |jP                  |j0                  t!        |jR                        t!        |jN                        |jT                  |	r|	jV                  nd|
|j                  r|j                  j                         ndt!        |jX                        t!        |jZ                        |j\                  |j^                  |j`                  rt!        |j`                        nd|jb                  r|jb                  j                         ndd        |S c c}w )u0   获取我的订单列表（性能优化版本）r   r>   N	image_urluploaded_atrB   item_idproduct_nameproduct_urlspecificationquantityunit_price_cnyunit_price_usd        domestic_shipping_cnyis_freight_collectplan_buser_image_urlr-   r   declared_name_endeclared_value_usdis_sensitive	qc_imagesfreight_collect_frozen_cnyfreight_collect_actual_cnyactual_cost_cnyr/   warehouse_datestorage_fee_usdreturn_tracking_noreturn_shipping_fee_cnyreturn_reasonreturn_addressmain_qc_image_urlr_   r\   )rB   r]   r   r^   r_   rP   r`   rh   rK   rb   rc   rejection_reasonrejection_noter   rd   )2r@   r?   re   rB   rf   rh   r   ro   rK   rS   rR   r    rr   rs   rt   ru   r"   rv   rw   ry   rz   r{   r|   r-   r   r}   r~   r   r   r   r   r/   r   r   r   r   r   r   r   r_   r]   r^   rP   rG   rb   rc   r   r   r   rd   )r   rY   rZ   r1   r<   r?   ri   rU   rj   rk   
items_dataitemimgqc_images_datas                 r%   get_my_ordersr      s    < ..r<??FKFD4%<(FF F
 
GG ,	D  >>
  "%AD3>>#;#;#=UYN   #dgg, s477|  #D$5$5  "4#3#3	 
 $T%7%7    %eD,?,?&@  %DDWDWeD,?,?&@]`  ,RVRlRlU43M3M-Nru  )$*A*A  dkk  %d&9&9  +D,E,E  dkk  '(=(=   )DLcLc%0G0G*Him! " #D$5$5# $ "0\`\{\{%8W8W2X  BE\`\{\{%8W8W2X  BFFJFZFZuT-A-A'B`d(,(=(=IMI\I\d&9&9&C&C&EbfFJFZFZuT-A-A'B`c*.*A*AVZVrVruT5Q5Q/Rx|%)%7%7&*&9&9)-)?)?FJFZFZuT-A-A'B`c? ",	Z 	dd !(("1;;/#():):#;9906I#:;,,all446D"1;;/!&q!7$%$6$6"#"2"2EFEYEYeA,@,@&A_c:;,,all446D!	
gF
N Ms    <Qz/orders/{order_id}order_idc                    ddl m}m} ddlm} |j                  |      j                  |j                  | k(        j                         }|st        t        j                  d      |j                  t              j                  t        j                  |j                  k(        j                         }|r"|j                  t        |j                        k7  rt        t        j                   d      |j                  |      j                  |j"                  |j                  k(        j%                         }g }	|D ]  }
|j                  |      j                  |j&                  |
j                  k(        j%                         }|D cg c]7  }|j(                  |j*                  r|j*                  j-                         ndd9 }}|	j/                  i d	t        |
j                        d
t        |
j                        d|
j0                  d|
j2                  d|
j4                  d|
j6                  dt9        |
j:                        d|
j<                  rt9        |
j<                        ndd|
j>                  rt9        |
j>                        ndd|
j@                  d|
jB                  d|
jD                  d|
jF                  d|
j                  d|
jH                  d|
jJ                  rt9        |
jJ                        ndd|
jL                  ||
jN                  rt9        |
jN                        nd|
jP                  rt9        |
jP                        nd|
jR                  rt9        |
jR                        nd|
jT                  |
jV                  r|
jV                  j-                         nd|
jX                  rt9        |
jX                        nd|
jZ                  |
j\                  rt9        |
j\                        nd|
j^                  |
j`                  |
jb                  |
jd                  rt9        |
jd                        ndd       	 ddlm3} d}|r|d   }|jh                  r|j                  |      j                  |j                  |jh                  k(        j                         }|rt        |j                        |jj                  |j                  |jl                  rt9        |jl                        nd|jn                  rt9        |jn                        nd|jp                  rt9        |jp                        nd|jr                  rt9        |jr                        ndd}i d	|j                  d|jt                  d|j                  dt9        |jv                        d t9        |jd                        d!|j                  d"|j*                  r|j*                  j-                         ndd#t9        |jx                        d$t9        |jz                        d%|j|                  d&|j~                  d'|j                  rt9        |j                        ndd(|j                  r|j                  j-                         ndd)|	d*|j                  |j                  |j                  rt9        |j                        ndd+d,|}|S c c}w )-u!   获取订单详情（任务1.2）r   rF   	OrderItem)QCImage   订单不存在r4      无权访问此订单Nrn   rB   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   r-   r   r}   r~   r   r   r   )	parcel_idparcel_numberr   	weight_kg	length_cmwidth_cm	height_cmr]   r^   r_   rP   rK   rb   rc   r   r   r   rd   rh   rk   )rB   rG   balance_usdparcel)DrL   rF   r   app.models.parcelr   rN   rO   rB   firstr   r   HTTP_404_NOT_FOUNDr   rP   
partner_idr    r:   r   allorder_item_idro   rK   rS   rR   rr   rs   rt   ru   r"   rv   rw   ry   rz   r{   r|   r-   r}   r~   r   r   r   r   r/   r   r   r   r   r   r   r   r_   r   r   r   r   r   r   r   r]   r^   rb   rc   r   r   r   rd   rG   r   )r   r1   r<   rF   r   r   orderrk   rh   r   r   r   r   r   r   parcel_data
first_itemr   rU   s                      r%   get_order_detailr      s4    2) HHUO""588x#78>>@E11:K
 	

 XXd^""477emm#;<BBDFV&&#loo*>>11*
 	
 HHY&&y'9'9UXX'EFJJLEJ -
HHW%,,W-B-Bdgg-MNRRT	 !

  !]]=@^^s~~779QU
 
 	 c$''l 3tww<   1 1  t//	 
  !3!3  DMM  !%(;(;"<  !@S@S%(;(;"<Y\  (dNhNht/I/I)Jnq  %d&=&=  $++  !$"5"5  '(A(A  $++  #D$9$9   %H_H_eD,C,C&Dei! "  1 1# $ ,X\XwXweD4S4S.T  ~AX\XwXweD4S4S.T  ~BBFBVBV5)=)=#>\`$($9$9EIEXEX$"5"5"?"?"A^bBFBVBV5)=)=#>\_&*&=&=RVRnRn51M1M+Ntx!%!3!3"&"5"5%)%;%;BFBVBV5)=)=#>\_? "	
-
` )K1X
XXf%,,VYY*:N:N-NOUUWF!$VYY%+%9%9$mm<B<L<Lv'7'7!8RV<B<L<Lv'7'7!8RV:@//foo 6t<B<L<Lv'7'7!8RVehh** 	%,, 	U5??+	
 	5!6!67 	5== 	e6F6Fe&&002D 	U5??+ 	u223 	E22 	%.. 	AYAYeE$<$<=_c 	e6F6Fe&&002D  	!$ 	))\\8>8J8J5!3!34PS
%0 	+1F6 Mw
s   	<[ z/items/{item_id}/rejectrq   requestc                    ddl m} 	 |j                  || t        |j                        |j
                  |j                  |j                         d| |j
                  dS # t        $ r)}t        t        j                  t        |            d}~wt        $ r)}t        t        j                  t        |            d}~ww xY w)a  
    [Partner] Mark an item as cannot be purchased with a reason.
    Reasons: out_of_stock, price_mismatch, prohibited, fake_goods, other

    For price_mismatch, proposed_price_cny is required.
    This will notify the user and allow them to accept the new price or cancel.
    r   )OrderService)r<   rq   r   r   r   r   T)successrq   r   r4   N)app.services.order_servicer   reject_item_cannot_purchaser    rB   r   r   r   
ValueErrorr   r   HTTP_400_BAD_REQUEST	ExceptionHTTP_500_INTERNAL_SERVER_ERROR)rq   r   r1   r<   r   es         r%   reject_itemr   ]  s     8
00<??+>>&99 	1 	
  Gw~~NN T(C(CCPQFSS 
==c!f
 	

s$   AA   	C)$BC$B==Cz/revenue   daysc                 H    ddl m} |j                  ||j                  |       S )u   获取我的收入统计r   r>   )r@   r?   get_partner_revenuerB   )r   r1   r<   r?   s       r%   get_my_revenuer     s      <--b,//4HHr$   z/warehouse/statsc                 0    ddl m} |j                  |      S )z"Get warehouse dashboard statisticsr   r>   )r@   r?   get_warehouse_stats)r1   r<   r?   s      r%   r   r     s     <--b11r$   z/warehouse/receiving
processingzFilter by status)descriptionc                 P    ddl m} |j                  ||       }|t        |      dS )z-Get items pending to be received at warehouser   r>   )r   rh   total)r@   r?   get_pending_itemsrg   )r   r1   r<   r?   rh   s        r%   r   r     s+     <,,R,?ESZ00r$   z/warehouse/search.z#Tracking number or internal barcodeqc                 T    ddl m} |j                  ||       }|st        dd      |S )z!Find an item for rapid processingr   r>     zItem not foundr4   )r@   r?   find_item_by_trackingr   )r   r1   r<   r?   r   s        r%   search_itemr     s/     <//A6D4DEEKr$   z/warehouse/bindbarcodec                     ddl m} 	 |j                  || |t        |j                              }d|j                  |j
                  dS # t        $ r}t        dt        |            d}~ww xY w)z&Rapidly bind barcode and check-in itemr   r>   r   )r   rq   
new_status  r4   N)r@   r?   bind_barcoder    rB   r   r   r   )rq   r   r1   r<   r?   r   r   s          r%   r   r     sa     <<**2w\__AUV#t{{SS <CF;;<s   A A	 		A-A((A-z/warehouse/receiving/{item_id}tracking_noc                 4   ddl m} 	 |j                  || |t        |j                              }d|j                  |j
                  |j                  r|j                  j                         dS ddS # t        $ r}t        dt        |            d}~ww xY w)	z%Mark an item as received at warehouser   r>   )rq   r   r   TN)r   rq   r   r   r   r4   )
r@   r?   receive_itemr    rB   r   r   rS   r   r   )rq   r   r1   r<   r?   r   r   s          r%   r   r     s     <<**[SEY + 
 wwkk"" #11;;=	
 	
 
 	
  <CF;;<s   A&A3 /A3 3	B<BBz/warehouse/qcz#Optional: fetch specific item by IDc                 P    ddl m} |j                  ||       }|t        |      dS )z3Get items needing QC photos, or specific item by IDr   r>   )rq   r   )r@   r?   get_items_for_qcrg   )rq   r1   r<   r?   rh   s        r%   r   r     s+     <++B+@ESZ00r$   z/warehouse/qc/{item_id}ro   c                     ddl m} 	 |j                  || |t        |j                              }d|j                  |j
                  dS # t        $ r}t        dt        |            d}~ww xY w)	zUpload QC image for an itemr   r>   )r   T)r   rq   ro   r   r4   N)r@   r?   upload_qc_imager    rB   r   r   r   )rq   ro   r1   r<   r?   r   r   s          r%   r   r     su     <
<--s<??/C . 
 ww//
 	

  <CF;;<s   AA
 
	A.A))A.)r	   )Listc                       e Zd ZU ee   ed<   y)MultipleImagesRequestimagesN)r   r   r   r   r    r!   r#   r$   r%   r   r     s    Ir$   r   c                       e Zd ZU eed<   y)QCFailRequestr   N)r   r   r   r    r!   r#   r$   r%   r   r     s    Kr$   r   c                   "    e Zd ZU eed<   eed<   y)ShipReturnRequestr   fee_cnyN)r   r   r   r    r!   r"   r#   r$   r%   r   r   
  s    Nr$   r   z /warehouse/qc/{item_id}/multiplec                    |j                   rt        |j                         dk  rt        dd      t        |j                         dkD  rt        dd      ddlm} 	 |j                  || |j                   t        |j                              }d	|j                  t        |j                         d
S # t        $ r}t        dt        |            d}~ww xY w)z%Upload multiple QC images for an itemr(   r   zAt least 1 image requiredr4      zMaximum 5 images allowedr   r>   T)r   rq   image_countN)	r   rg   r   r@   r?   upload_qc_imagesr    rB   r   rq   r   r1   r<   r?   r   r   s          r%   r   r     s     >>S0144OPP
7>>Q4NOO;<..\__)=
  DGGCDWXX <CF;;<s   AB2 2	C;CCz/warehouse/qc/{item_id}/failc                 
   ddl m} 	 |j                  || |j                  t	        |j
                              }d|j
                  |j                  |j                  dS # t        $ r}t        dt	        |            d}~ww xY w)z'Mark an item as QC failed with a reasonr   r>   T)r   rq   r   r   r   r4   N)	r@   r?   mark_qc_failedr   r    rB   r   r   r   r   s          r%   fail_qcr   &  sy     <<,,\__)=
 ww++nn	
 	
  <CF;;<s   AA 	B'A==Bz#/warehouse/qc/{item_id}/ship-returnc           	          ddl m} 	 |j                  || |j                  |j                  t        |j                              }d|j                  |j                  |j                  dS # t        $ r}t        dt        |            d}~ww xY w)z5Mark item as returning and deduct return shipping feer   r>   T)r   rq   r   r   r   r4   N)r@   r?   ship_returnr   r   r    rB   r   r   r   r   r   s          r%   r   r   =  s     <<)),,goos<???S
 wwkk"&"9"9	
 	
  <CF;;<s   A A) )	B2BBc                   0    e Zd ZU dZeed<   dZee   ed<   y)CompleteReturnRequestTreturn_successNnotes)	r   r   r   r   boolr!   r   r   r    r#   r$   r%   r   r   T  s    NDE8C=r$   r   z"/orders/{order_id}/complete-returnc                 $   ddl m} 	 |j                  || t        |j                        |j
                  |j                        }d|j                  |j                  |j                  ddS # t        $ r}t        dt        |            d	}~ww xY w)
z
    [Partner] Complete return process for an order
    - Changes order status to 'cancelled'
    - Refunds the customer
    - Updates all order items to 'cancelled'
    r   r>   )r<   r   r   r   r   Tz"Return completed and refund issued)r   r   r]   r   messager   r4   N)r@   r?   complete_returnr    rB   r   r   r]   r   r   r   r   r   r1   r<   r?   r   r   s          r%   r   r   Y  s     <<..<??+"11-- / 
 !..ll;
 	
  <CF;;<s   A"A+ +	B4B

Bz#/orders/{order_id}/start-purchasingc                 2   ddl m} 	 |j                  || t        |j                              }d|j                  |j
                  |j                  r|j                  j                         dS ddS # t        $ r}t        dt        |            d}~ww xY w)	u&   
    [Partner] 开始采购订单
    r   r>   )r<   r   r   TN)r   r   r   purchasing_started_atr   r4   )
r@   r?   start_purchasingr    rB   r   r   rS   r   r   )r   r1   r<   r?   r   r   s         r%   r   r   |  s     <<//<??+ 0 
 llPUPkPkU%@%@%J%J%L	
 	
 rv	
 	
  <CF;;<s   A%A2 .A2 2	B;BBc                   J    e Zd ZU dZee   ed<   dZee   ed<   dZ	ee   ed<   y)MarkPurchasedRequestNr   r   ro   )
r   r   r   r   r   r    r!   r   r"   ro   r#   r$   r%   r   r     s,    !%K#%'+OXe_+#Ix}#r$   r   z*/orders/{order_id}/mark-awaiting-warehousec                 t   ddl m} 	 |j                  || t        |j                        |j
                  |j                  |j                        }d|j                  |j                  |j                  r|j                  j                         dS ddS # t        $ r}t        dt        |            d}~ww xY w)	u)   
    [Partner] 标记订单待入库
    r   r>   )r<   r   r   r   r   ro   TN)r   r   r   awaiting_warehouse_atr   r4   )r@   r?   mark_awaiting_warehouser    rB   r   r   ro   r   r   rS   r   r   r   s          r%   r   r     s     <<66<??+++#33'' 7 
 llPUPkPkU%@%@%J%J%L	
 	
 rv	
 	
  <CF;;<s   BB B 	B7B22B7z/parcels/pending-shipmentc                    ddl m} ddlm} |j	                  |      j                  t        |j                  t        j                  k(        j                  t        j                  t        | j                        k(  |j                  dk(        j                         }g }|D ]V  }|j	                  t              j                  t        j                  |j                  k(        j                         }|j	                  |      j                  |j                  |j                  k(        j                         }|j!                  t        |j                        |j"                  |r|j$                  nd|j&                  t)        |      |D 	cg c]:  }	t        |	j                        |	j*                  |	j,                  |	j.                  d< c}	|j0                  r|j0                  j3                         ndd       Y |t)        |      dS c c}	w )	uP   
    [Partner] 获取待出库的包裹列表（需要填写重量体积）
    r   r   r   packing_requestedN)rB   rr   ru   r   )r   r   
user_emailr   
item_countrh   rK   parcelsr   )r   r   rL   r   rN   joinr   rP   rB   rO   r   r    parcel_statusr   r   r   rR   r   rG   r   rg   rr   ru   r   rK   rS   )
r1   r<   r   r   r   rU   r   rf   rh   r   s
             r%   get_pending_shipment_parcelsr    s    )* hhv##fnn'f3|// 33 
ce  F xx~$$TWW%>?EEG#**9+>+>&))+KLPPRVYY#11(,$**$mme*  !
 	 $''l $ 1 1 MM%)%;%;	 ! <B;L;L&++557RV
 		& F44!s   ?Hz/parcels/{parcel_id}r   c                    ddl m}m} ddlm} |j                  |      j                  |j                  | k(        j                         }|st        dd      |j                  t              j                  t        j                  |j                  k(        j                         }|r"|j                  t        |j                        k7  rt        dd      |j                  |      j                  |j                  | k(        j                         }|j                  |      j                  |j                  |j                   k(        j                         }	g }
d	}|D ]  }|j"                  rd
}|
j%                  t        |j                        |j&                  |j(                  |j*                  |j"                  |j,                  |j.                  |j0                  r|j0                  j3                         ndd        d}|	r[|	j4                  |	j6                  |	j8                  |	j:                  |	j<                  |	j>                  |	j@                  |	jB                  d}i dt        |j                        d|jD                  d|jF                  dt        |j                        d|r|jH                  ndd|jJ                  rtM        |jJ                        ndd|jN                  rtM        |jN                        ndd|jP                  rtM        |jP                        ndd|jR                  rtM        |jR                        ndd|jT                  rtM        |jT                        ndd|jV                  rtM        |jV                        ndd|jX                  d|jZ                  d|j\                  d|d|
d||j^                  r|j^                  j3                         ndta        |d       r&|jb                  r|jb                  j3                         nd|jd                  r|jd                  j3                         nd|jf                  r|jf                  j3                         d!S dd!S )"u   
    [Partner] 获取包裹详情
    
    返回包裹完整信息，包括：
    - 包裹基本信息（重量、尺寸、状态）
    - 商品列表（含敏感品标记）
    - 收货地址
    - 用户信息
    r   r   Addressr   r      包裹不存在r4     u   无权访问此包裹FTN)rq   rr   rt   ru   r   r/   r   r   recipient_namephoneaddress_line1address_line2citystate_provincecountrypostal_coder   r   r  rP   r   r   r   r   r   shipping_quote_usdr   rx   internal_tracking_nointernational_tracking_nopacking_notehas_sensitive_itemsrh   address	packed_at)rK   r  awaiting_shipment_at
shipped_at)4r   r   r  rL   r   rN   rO   rB   r   r   r   rP   r   r    r   r   
address_idr   rR   rr   rt   ru   r/   r   r   rS   r
  r  r  r  r  r  r  r  r   r  rG   r   r"   r   r   r   r  r   r  r  r  rK   hasattrr  r  r  )r   r1   r<   r   r  r   r   rf   rh   r  r   has_sensitiver   address_infos                 r%   get_parcel_detailr    s    2* XXf$$VYY)%;<BBDF4EFF 88D>  FNN!:;AACD4??c,//&::4KLL HHY&&y':':i'GHLLNE hhw&&wzzV5F5F'FGMMOG JM  M477| --!// -- $ 5 5!%!7!7AEATATd11;;=Z^	
 			  L%44]]$22$22LL%44"..	
S^-- 	-- 	3v~~&	
 	Ddjjd 	0@0@U6++,d 	0@0@U6++,d 	fooE&//*4 	0@0@U6++,d 	&B[B[eF$=$=>ae 	F<R<R5!7!78X[ 	 ; ; 	$V%E%E 	++ 	}  	!" 	<#$ 8>7H7Hf''113d5<V[5QV\VfVfV%%//1lpKQKfKf ; ; E E Glp7=7H7Hf''113+ * OS+ r$   z/orders/{order_id}/parcelc                    ddl m}m} ddlm} |j                  |      j                  |j                  | k(        j                         }|st        dd      |j                  t              j                  t        j                  |j                  k(        j                         }|r"|j                  t        |j                        k7  rt        dd      |j                  |      j                  |j                  |j                  k(        j                         }|st        dd	      |d   j                   }	|	st        dd
      |j                  |      j                  |j                  |	k(        j                         }
|
st        dd      t        |
j                        |
j"                  |
j$                  dS )u   获取订单的包裹信息r   r   r   r   r   r4   r  r      订单无商品u   订单未关联包裹r  )r   r   r   )rL   rF   r   r   r   rN   rO   rB   r   r   r   rP   r   r    r   r   r   r   r  )r   r1   r<   rF   r   r   r   rk   rh   r   r   s              r%   get_order_parcelr"  A  sg    2( HHUO""588x#78>>@E4EFF XXd^""477emm#;<BBDFV&&#loo*>>4KLL HHY&&y'9'9UXX'EFJJLE4EFFa""I4KLLXXf$$VYY)%;<BBDF4EFF ^--&& r$   c                   ^    e Zd ZU eed<   eed<   dZee   ed<   dZee   ed<   dZ	ee   ed<   y)SetParcelDimensionsRequestr   r   Nr   r   r   )
r   r   r   r    r!   r"   r   r   r   r   r#   r$   r%   r$  r$  i  s7    N!%Ix% $Hhuo$!%Ix%r$   r$  c                   X    e Zd ZU dZeed<   dZee   ed<   dZee   ed<   dZ	ee   ed<   y)SubmitPackingRequestuV   用于 /parcels/{parcel_id}/submit-packing 端点的请求模型（不含 parcel_id）r   Nr   r   r   )
r   r   r   __doc__r"   r!   r   r   r   r   r#   r$   r%   r&  r&  q  s5    `!%Ix% $Hhuo$!%Ix%r$   r&  z/parcels/set-dimensionsc                 $   ddl m} ddlm} 	 |j	                  |      j                  |j                  | j                  k(        j                         }|st        d      ddl
m} |j	                  |      j                  |j                  |j                  k(        j                         }|r"|j                  t        |j                        k7  rt        d      |j                  || j                  | j                   | j"                  | j$                  | j&                        }d|j                  |j(                  |j*                  |j                   rt-        |j                         nd	d
dS # t        $ r}t/        dt        |            d	}~ww xY w)uA   
    [Partner] 设置包裹重量体积（出库前必填）
    r   ShippingServicer   Parcel not found)r   *This parcel does not belong to your clientr<   r   r   r   r   r   TNu$   包裹尺寸已设置，等待报价)r   r   r   r   r   r   r   r4   )app.services.shipping_servicer*  r   r   rN   rO   rB   r   r   r   app.models.userr   rP   r   r    set_parcel_dimensionsr   r   r   r   r   r   r"   r   )	r   r1   r<   r*  r   r   r   rf   r   s	            r%   r0  r0  y  sP    >(<&!((g6G6G)GHNNP/00 	)xx~$$TWW%>?EEGt#loo*>>IJJ !66''''''%%'' 7 
 #11mm4:4D4Dv//0$=
 	
  <CF;;<s   EE+ +	F4F

Fz$/orders/{order_id}/warehouse-receivec           
         ddl m} 	 |j                  || |j                  |j                  |j
                  r|j
                  ndt        |j                              }t        j                  d|j                   d|j                   d|j                          d|j                  d	d
S # t        $ r)}t        t        j                  t        |            d}~ww xY w)u   
    仓库收货入库

    合伙人扫描包裹信息并上传质检图片，完成入库操作。
    订单状态从 awaiting_warehouse 变为 in_warehouse。
    r   r>   N)r<   r   r-   r/   r0   r   z&Warehouse receive completed: order_id=, partner_id=z, internal_barcode=Tu   入库成功)r   r   r   r4   )r@   r?   warehouse_receiver-   r/   r0   r    rB   loggerinfor   r   r   r   r   s          r%   r3  r3    s     <
00!(!=!=$55181E1E--4<??+ 1 
 	4UXXJ ?&//* +  ' 8 89;	
 %
 	

  
33q6
 	

s   B!B* *	C3$CCz/parcelsuO   筛选包裹状态: packing_requested, awaiting_shipment, paid, shipped_waitingc                    ddl m}m} ddlm} ddlm} t        j                  j                  t        j                  j                  t        j                  j                  g}|j                  |      j                  t        |j                  t        j                   k(        j#                   ||j$                         ||j&                         ||j(                              j+                  t        j,                  t/        |j                         k(        }| rog d}	| |	vr)t1        | j2                  ddj                  |	             | d	k(  rt        j                  j                  } |j+                  |j4                  | k(        }n*|j+                  |j4                  j7                  |            }|j9                         }
g }|
D ]  }|j$                  }|j&                  }|j(                  }|j;                  t/        |j                         |j<                  |j4                  t?        |      |j@                  rtC        |j@                        nd
|jD                  rtC        |jD                        nd
|jF                  rtC        |jF                        nd
|jH                  rtC        |jH                        nd
|jJ                  |jL                  |jN                  rtC        |jN                        nd
|r|jP                  nd
|rJ|r|jR                  nd
|r5|jT                   d|jV                   d|jX                   d|jZ                   nd
dnd
|D cg c]:  }t/        |j                         |j\                  |j^                  |j`                  d< c}|jb                  r|jb                  je                         nd
d        |t?        |      dS c c}w )u~  
    [Partner] 获取需要合伙人处理的包裹列表

    支持状态筛选：
    - packing_requested: 待打包（需要填写重量尺寸）
    - awaiting_shipment: 待发货（等待管理员报价）
    - paid: 已支付运费（等待发货）
    - shipped_waiting: 已发货等待国际单号

    如果不指定status参数，返回所有需要处理的包裹
    r   r  r   )
joinedload)r   awaiting_shipmentpaidshipped_waitingu#   无效的状态参数。有效值: z, r4   r9  N)r
  full_address)rq   rr   ru   r/   )r   r   r  r   r   r   r   r   tracking_numberr  r  r   shipping_addressrh   rK   r   )3r   r   r  rL   r   sqlalchemy.ormr7  r   PACKING_REQUESTEDr9   AWAITING_SHIPMENTSHIPPED_WAITINGrN   r  r   rP   rB   optionsrf   rh   r  rO   r   r    r   r   r  in_r   rR   r   rg   r   r"   r   r   r   r  r  r  rG   r
  r  r  r  r  rr   ru   r/   rK   rS   )r   r1   r<   r   r  r   r7  partner_relevant_statusesrN   valid_statusesr   rU   r   rf   rh   r  r   s                    r%   get_partner_parcelsrF    s.   " 2*) 	&&,,&&,,$$**! HHV!!fnn'g6;;6<< 6>>" f3|// 
 ^'"77<TYY~=V<WX  V!1177FV11V;< V11556OPQiikGF {{..VYY#11#11e*4:4D4Dv//0$4:4D4Dv//0$28//foo.t4:4D4Dv//0$%??$*$?$?FLF_F_%(A(A"Bei(,$**$  =D'"8"8 |C7#8#8"9GLL>GLbLbKccefmfufuev w  IM! #  !
 	 tww< $ 1 1 MM$($9$9	 ! <B;L;L&++557RV/
 	@ F44!s   ?O$z#/parcels/{parcel_id}/submit-packingc                    ddl m} ddlm} ddlm} ddlm} 	 |j                  |      j                  |j                  | k(        j                         }|st        d      |j                  t              j                  t        j                  |j                  k(        j                         }	|	r"|	j                  t        |j                        k7  rt        d      |j!                  || |j"                  |j$                  |j&                  |j(                        }|j+                         |_        |j/                          |j1                  |       t2        j5                  d	|  d
|j                   d|j"                          dt        |j                        |j6                  |j8                  |j,                  r|j,                  j;                         dS ddS # t        $ r}
t=        dt        |
            d}
~
ww xY w)u   
    [Partner] 提交包裹打包信息

    合伙人填写包裹重量尺寸后提交，包裹状态从 packing_requested 变为 awaiting_shipment。
    同时设置 packed_at 和商品的 outbound_at 时间戳。
    r   r)  r   r   )datetimer+  r,  r-  z$Parcel packing submitted: parcel_id=r2  z, weight_kg=TN)r   r   r   r  r  r   r4   )r.  r*  r   r   rL   r   rH  rN   rO   rB   r   r   r   rP   r   r    r0  r   r   r   r   utcnowr  commitrefreshr4  r5  r   r  rS   r   )r   r   r1   r<   r*  r   r   rH  r   rf   r   s              r%   submit_parcel_packingrL  6  s    >(*!)<&!((i)?@FFH/00 xx~$$TWW%>?EEGt#loo*>>IJJ !66''''%%'' 7 
 $??,
		


629+ >&//* + **+-	
 VYY#11#119?9I9I))335
 	

 PT
 	
  <CF;;<s   F=G G 	H %G;;H z/orders/{order_number}/itemsr]   c                    ddl m}m} ddlm} |j                  |      j                  |j                  | k(        j                         }|st        dd      |j                  t              j                  t        j                  |j                  k(        j                         }|r"|j                  t        |j                        k7  rt        dd      |j                  |      j                  |j                  |j                  k(        j                         }|st        dd	      d
}	|j                   rS|j                  |      j                  |j                  |j                   k(        j                         }
|
r|
j"                  }	| t        |j                        |j$                  |j&                  |j(                  |j*                  |	ddS )u   
    [Partner] 通过订单号查询商品（客户投诉场景）

    返回订单的商品信息，包括内部条码和出库包裹号。
    r   r   r   r   r   r4   r  r   r!  N)rq   rr   ru   r/   item_statusr   )r]   r   )rL   rF   r   r   r   rN   rO   r]   r   r   r   rB   rP   r   r    r   r   r   rr   ru   r/   rN  )r]   r1   r<   rF   r   r   r   rk   r   r   r   s              r%   get_order_items_by_numberrO  t  ss    2( HHUO""5#5#5#EFLLNE4EFF XXd^""477emm#;<BBDFV&&#loo*>>4KLL 88I%%i&8&8EHH&DEKKMD4EFF M~~&!((dnn)DEKKM"00M %477| -- $ 5 5++*

 
r$   z!/items/{item_id}/tracking-historyc                 f   ddl m}m} ddlm} |j                  |      j                  |j                  | k(        j                         }|st        dd      |j                  |      j                  |j                  |j                  k(        j                         }|st        dd      |j                  t              j                  t        j                  |j                  k(        j                         }|r"|j                  t        |j                        k7  rt        dd	      g }	|j                  r7|	j!                  d
|j                  j#                         |j$                  d       |j&                  r7|	j!                  d|j&                  j#                         |j(                  d       |j*                  r,|	j!                  d|j*                  j#                         d       |j,                  rd}
|j.                  rS|j                  |      j                  |j                  |j.                  k(        j                         }|r|j0                  }
|	j!                  d|j,                  j#                         |
d       t        |j                        |j2                  |j(                  |	dS )uY   
    [Partner] 获取商品追踪历史

    返回商品的完整流转时间线。
    r   r   r   r   u   商品不存在r4   r   r  u   无权访问此商品	purchased)event	timestampr]   warehouse_checkin)rR  rS  r   qc_completed)rR  rS  Noutbound)rR  rS  r   )rq   rr   r/   timeline)rL   rF   r   r   r   rN   rO   rB   r   r   r   r   rP   r   r    rK   rR   rS   r]   qc_started_atr/   qc_completed_atoutbound_atr   r   rr   )rq   r1   r<   rF   r   r   r   r   rk   rW  r   r   s               r%   get_item_tracking_historyr[    s/    2( 88I%%illg&=>DDFD4EFF HHUO""588t}}#<=CCEE4EFFXXd^""477emm#;<BBDFV&&#loo*>>4KLL H  224!..
 	 (++557,,
 	 #--779
 	 >>XXf%,,VYY$..-HIOOQF & 4 4))335*
 	 tww<)) 11	 r$   c                   .    e Zd ZU  eddd      Zeed<   y)ShipParcelRequest.r(   r)   r*   r  N)r   r   r   r
   r  r    r!   r#   r$   r%   r]  r]    s     %caC H#Hr$   r]  z/parcels/{parcel_id}/shipc                    |j                  t              j                  t        j                  | k(        j	                         }|st        t        j                  d      |j                  t              j                  t        j                  |j                  k(        j	                         }|r"|j                  t        |j                        k7  rt        t        j                  d      |j                  t        j                  j                   k7  r)t        t        j"                  d|j                   d      |j$                  }	 |j$                  |_        |j'                  |       |j)                          |j+                  |       	 t7        j8                  |t        |j                        ddt        |j                        d|j$                   t;        j<                  ||j$                  |j>                  d             t0        jC                  d|j                   d|  d|j$                          dt        |j                        |j                  dS # t,        $ rM}|j/                          t0        j3                  d|  d| d	       t        t        j4                  d
      d}~ww xY w# t,        $ r%}t0        jA                  d|  d|        Y d}~d}~ww xY w)u   
    [Partner] 合伙人发货 - 填写中间物流单号

    合伙人将包裹发往国际物流前，填写中间物流单号。
    包裹状态必须是 shipped_waiting（已支付运费，等待发货）。
    r  r4   u   无权操作此包裹u%   包裹状态错误：当前状态为 u   ，必须是 shipped_waitingzFailed to update parcel z: T)exc_infou   更新包裹失败Nship_parcelr   u#   合伙人填写中间物流单号: )old_trackingnew_trackingr   r<   admin_idaction_typetarget_type	target_idr   
extra_datazFailed to log audit for parcel zPartner z shipped parcel z, internal_tracking_no: )r   r   r   )"rN   r   rO   rB   r   r   r   r   r   rP   r   r    r:   r  r   rA  r9   r   r  addrJ  rK  r   rollbackr4  errorr   r   
log_actionjsondumpsr   warningr5  )r   r   r1   r<   r   rf   ra  r   s           r%   r`  r`    sy    XXf$$VYY)%;<BBDF11$
 	
 88D>  FNN!:;AACD4??c,//&::11*
 	
 |;;AAA33:6;O;O:PPlm
 	
 ..L
&-&B&B#
v
		


6K)% &))n=g>Z>Z=[\zz , ' < <!'!5!5# 	
  KK
<??##3I; ?!!(!=!= >	@ ^&& ?  

/	{"QC@4P=='
 	

.  K82aSIJJKs3   
AI A:J6 	J3&AJ..J36	K$?KK$c                   0    e Zd ZU  edddd      Zeed<   y)ParcelScanRequest.r(   r.   u   扫描的条形码)r+   r,   r   r   N)r   r   r   r
   r   r    r!   r#   r$   r%   rq  rq  F  s    rG[\GS\r$   rq  z/parcels/scanc                 *   ddl m} |j                  t              j	                  t        j
                  | j                  k(        j                         }|st        t        j                  d      |j                  |      j	                  |j                  |j                  k(        j                         }|j                  t              j	                  t        j                  |j                  k(        j                         }g }|D ]  }|j!                  t#        |j                        |j$                  |j&                  |j(                  |j*                  |j,                  rt/        |j,                        nd|j0                  r|j0                  j3                         nd|j                  d        |j4                  |j6                  |j8                  |j:                  |j<                  |j>                  |j@                  |jB                  d}	t#        |j                        |jD                  |j
                  |jF                  |jH                  rt/        |jH                        nd|jJ                  rt/        |jJ                        nd|jL                  rt/        |jL                        nd|jN                  rt/        |jN                        nd|jP                  rt/        |jP                        nd|jR                  |jT                  |jV                  r|jV                  j3                         ndd|t#        |j                        |jX                  t[        |d	      r|j\                  ndd
|	d}
	 t_        j`                  |t#        |j                        ddt#        |j                        d| j                   tc        jd                  | j                  |jD                  d             |
S # tf        $ r#}th        jk                  d|        Y d}~|
S d}~ww xY w)uF  
    通过条形码扫描查询包裹详情
    
    返回：
    - 包裹详情（parcel_number, parcel_barcode, weight, dimensions, status）
    - 包裹内所有商品列表（商品名称、规格、internal_barcode、入库时间）
    - 客户信息（姓名、联系方式）
    - 订单号
    - 收货地址
    r   r   u$   未找到该条形码对应的包裹r4   N)rB   rr   product_specsr/   ru   	price_cnyreceived_atr   r	  )rB   r   parcel_barcoder   r   r   r   r   r  r  r  rK   r  )rB   rG   r  )r   rh   customerr  scan_parcelr   u    合伙人扫描包裹条形码: )r   r   rc  zFailed to log scan audit: )6rL   r   rN   r   rO   rv  r   r   r   r   r   r   rB   r   r   rP   rR   r    rr   rt   r/   ru   rv   r"   r   rS   snapshot_recipient_namesnapshot_phonesnapshot_address_line1snapshot_address_line2snapshot_citysnapshot_state_provincesnapshot_countrysnapshot_postal_coder   r  r   r   r   r   r  r  r  rK   rG   r  r  r   rl  rm  rn  r   r4  ro  )r   r1   r<   r   r   rh   rf   
items_listr   r  rU   r   s               r%   scan_parcel_by_barcoder  J  sJ     + XXf$$0eg  119
 	
 HHY&&vyy(	ce 

 88D>  FNN!:;AACD J 
dgg, --!// $ 5 57;7J7Jt223PT>B>Q>Q4..88:W[kk	
 		
 !88&&6666$$ 88**22	L fii.#11$33**4:4D4Dv//0$4:4D4Dv//0$28//foo.t4:4D4Dv//0$FLF_F_%(A(A"Bei$*$?$?)/)I)I;A;L;L&++557RV
 dgg,ZZ#*4#9TZZt

  +F29)% &))n:7??:KLzz"??!'!5!5# 	
 M  93A3788M9s   +A9O& &	P/PP)Rr'  rm  typingr   fastapir   r   r   r   r   pydanticr	   r
   r   r>  r   app.apir   r/  r   r   r   r   app.models.parcel_statusr   app.services.audit_servicer   app.core.logging_configr   r   r4  routerr   r'   get_current_active_userr;   getget_dbrD   rX   r    intrl   r   r   postr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r"  r$  r&  r0  r3  rF  rL  rO  r[  r]  r`  rq  r  r#   r$   r%   <module>r     s  
   D D . . "  * $ 1 3 .	H	 
*I;	7/	 /i  !!=!=>	 L !45$++&  J !45$++& 2   !45$++&,SM,
, , 	,
 	, ,^ I  !45$++&VSMV
V V 	V
 	V Vr  ! !!45$++&yyy 	y "yx &' !!45$++&	


 
 		
 (
B J !45$++&I
II 	I I  !45$++&222  2 "#2DE !45$++&111 	1 $1  3$IJ !45$++&



 	
 !
 :: !45$++&	<<< < 		<  < -. "& !45$++&	<<#< < 		< /<0 O"? !!45$++&
1c]
1 	
1
 	
1 
1 &' !!45$++&	<<< < 		< (<*  I I 	 
 /0 !!45$++&	<<"< < 		< 1<, +, !!45$++&	<<< < 		< -<, 23 !!45$++&	<<< < 		< 4<, I  
 12 !!45$++&	<<"< < 		< 3<D 23 !!45$++&<<< 	< 4<4$9 $ 9: !!45$++&	<<!< < 		< ;<< '( !45$++&&5&5&5 )&5R "# !!45$++&WWW 	W $Wt '( !!45$++&$$$ 	$ )$N& &&9 & &' !!45$++&*<'*<*< 	*< (*<Z 34 !!45$++&	'
'
$'
 '
 		'
 5'
\ J!$  5F  G !45$++&\5SM\5\5 	\5 \5~ 23 !!45$++&	:<:<!:< :< 		:< 4:<z *+ !!45$++&--- 	- ,-` /0 !!45$++&HHH 	H 1HVI	 I () !!45$++&	MMM M 		M *M`]	 ] _ !!45$++&hhh 	h hr$   