
    i                       d dl mZmZmZmZmZmZmZmZ d dl	m
Z
mZmZmZ d dlmZmZmZ d dlZd dlmZ d dl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 d dl m Z  d dl!m"Z"m#Z#m$Z$ d dl%m&Z&  e de'd      Z(e(jS                  d      e
d               Z*e(jS                  d      e
ejV                  d                      Z, ejZ                  e'      Z.d dlmZmZ ddZ/d Z0d Z1y)    )render_templateredirectrequestsessionjsonifyflashurl_forcurrent_app)login_requiredcurrent_userlogout_user
login_user)datetimedate	timedeltaNCategoryUser)	TimeEntrynotification_serviceNotificationType)dblimitercsrf)	Blueprint)or_and_cast)JSONBmainz/api)
url_prefixz/stats/<period>c           	         ddl m} ddlm}m}m} ddlm}m} |j                  j                  dt        d      } | ||             } |j                  |j                        }	|	j                  |      }
|
 ||
j                               z
  }|j                  dddd	      }| |d
      z   }|
j                   }|
j"                  }d}d}d}d}|j$                  j'                  t(        j*                        j-                         }|D ]:  }|j.                  r|j.                  j1                         nd }|rt3        |j4                  xs d      }nt3        |j6                  xs d      }|j8                  dv r|dz  }|j8                  dv r||z  }|j:                  s|j:                  }|j<                  |j                  |j                        }|j                  |      }||cxk  xr |k  nc }|j                   |k(  xr |j"                  |k(  }|j                   |k(  }| dk(  r|s| dk(  r|s| dk(  s-|s1|dz  }||z  }=  |||t?        |d      t?        |d      | |d      S )Nr   Contractr   r   timezoner   r   offsettypedefaultminutesdayshourminutesecondmicrosecond           	worker_idpending_agreementcontractor_signedworker_signedactive   pending_reviewpending_ratingtzinfoweeklymonthlyyearly   )active_jobscompleted_jobspending_amounttotal_earningsperiodtimezone_offset) app.models.contractr'   r   r   r)   flaskr   r   argsgetintnowutc
astimezoneweekdayreplaceyearmonthquery	filter_byr   idallpaymentsfirstfloatnet_to_workeragreed_ratestatusmutual_rating_completed_daterF   round)rO   r'   r   r   r)   r   r   offset_minutesuser_tznow_utc	now_local
week_startweek_endcurrent_yearcurrent_monthrK   rL   rM   rN   	contractscpaymentworker_payoutcompleted_date_utccompleted_local	is_weekly
is_monthly	is_yearlys                               app/main_routes.py	get_statsr{      sl    -66& \\%%hS!%DNy.9:G hll8<<(G""7+I YI,=,=,?@@J##1QA#NJI1--H>>LOOMKNNN((<??(CGGII "0()

!**""$!'"7"7"<1=M "!--"415M88\\1K88;;m+N))!"!?!?!((0%7%?%?x||%?%T"0;;GDO"o@@I$$4 7%%6  (,,<I("y)#
("y!#-/E"0H "(22)      z/contractor-stats/<period>c           	      ^   ddl m} ddlm} ddlm}m}m} ddlm}m	} |j                  j                  dt        d      } | ||             }	 |j                  |j                        }
|
j                  |	      }| ||j!                         	      z
  }|j#                  dddd
      }| |d	      z   }|j$                  }|j&                  }d}d}d}d}|j(                  j+                  t,        j.                        j1                         }|D ]  }|j2                  r|j2                  }|j4                  |j#                  |j                        }|j                  |	      }||cxk  xr |k  nc }|j$                  |k(  xr |j&                  |k(  }|j$                  |k(  }| dk(  r|s| dk(  r|s| dk(  r|r|dz  }t7        |d      s|j8                  s|t;        |j8                  D cg c]  }|j<                  dk(  s| c}      z  } |j(                  j+                  t,        j.                        j1                         }|D ]B  }t?        |j@                  xs d      }|j<                  dv r|dz  }|j<                  dv s>||z  }D  ||||tC        |d      | |d      S c c}w )Nr   r&   Jobr(   r*   r+   r,   r/   r1   r3   r8   r9   contractor_idrE   rG   rH   rI   rA   applicationspendingr<   rB   rJ   )posted_jobspending_applicationsactive_contractspending_payoutsrO   rP   )"rQ   r'   app.models.jobr   r   r   r)   rR   r   r   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r   r_   r`   date_postedrF   hasattrr   lenrf   rc   re   rh   )rO   r'   r   r   r   r)   r   r   ri   rj   rk   rl   rm   rn   ro   rp   r   r   r   r   jobsjjob_date_utc	job_localrw   rx   ry   arq   rr   rates                                  rz   get_contractor_statsr   \   s    -"66& \\%%hS!%DNy.9:G hll8<<(G""7+I YI,=,=,?@@J##1QA#NJI1--H >>LOOM KO 99\__=AACD ^====L""*+338<<3H$//8I"i:(:I,. 1=0  ",6I("y)#
("yq  1n%!.. CANN(\qahhR[F[(\$]] +^0 ((|(GKKMI 	$Q]]'a( 88\\! 88;;t#O	$ " 4, !4)   )]s   .J*J*)r   r   c                     | yt        | t        t        f      r| j                  |      S t        | t              r'	 t        j
                  |       }|j                  |      S | S # t        $ r | cY S w xY w)N )
isinstancer   r   strftimestrfromisoformat
ValueError)valueformatdts      rz   datetimeformatr      ss    }%(D)*~~f%%%	''.B;;v&& L  	L	s   %A$ $A21A2c           
         t        | j                        t        | j                        t        | j                        t        | j                        t        | j
                        t        | j                        d}t        |j                               }t        |      }t        ||z  dz        ||||j                         D cg c]
  \  }}|r	| c}}dS c c}}w )z=Calculate profile completion percentage for onboarding widget)phototradelocationabn	insurancephoned   )
percentage	completedtotalsteps
incomplete)boolprofile_pictureprimary_trader   
abn_numberpublic_liability_insurancephone_numbersumvaluesr   rh   items)userr   r   r   kvs         rz   calculate_profile_completionr      s     d**+d(()'DOO$$99:d''(E ELLN#IJEI-34%*[[]<TQ!q< 
 =s   
CCc                 x     j                  d      d        } j                  d      d        } j                  d      t        d               } j                  d      t        d               } j                  d	d
g      t        d               } j                  d      t        d               } j                  d        } j                  t               g d} j                  d      d        }	 j                  d      d        }
 j                  d      d        } j                  d      d        } j                  d      d        } j                  d      t        d               } j                  d      t        d               } j                  d      d         } j                  d!d
g      d"        } j                  d#d
g      d$        } j                  d%d
g      t
        j                  d&               } j                  d'd(d
g      d)        } j                  d*      d+        } j                  d,d
g      t        d-               } j                  d.d(d
g      d/        } j                  d0d(d
g      d1        } j                  d2      d3        } j                  d4d(d
g      t        d5               } j                  d6d(d
g      t         fd7              } j                  d8d(g      t        d9               } j                  d:d(g      t        d;               } j                  d<d(g      d=        } j                  d>d(d
g      d?        } j                  d@      dA        }  j                  dBd(d
g      dC        }! j                  dD      t        dE               }" j                  dF      t         fdG              }# j                  dH      t         fdI              }$ j                  dJ      t         fdK              }% j                  dL      t         fdM              }& j                  dN      t        dO               }' j                  dP      dQ        }( j                  dR      dS        }) j                  dTd(d
g      t        dU               }* j                  dVd(d
g      t        dW               }+ j                  dXd(d
g      t        dY               }, j                  dZd
g      t        d[               }- j                  d\d
g      t        d]               }. j                  d^d
g      t        d_               }/ j                  d`d(g      t        da               }0 j                  dbd
g      t        dc               }1 j                  dd      t        t        j                  de                      }2 j                  dfd
g      t        dg               }3 j                  dhd
g      t        di               }4 j                  djd
g      t        dk               }5 j                  dl      t        dm               }6 j                  dn      t        do               }7 j                  dpd(d
g      t        dq               }8 j                  dr      t        ds               }9 j                  dt      t        du               }: j                  dv      t        dw               }; j                  dx      t        dy               }< j                  dz      t        d{               }= j                  d|      t        d}               }> j                  d~      t        d               }? j                  d      t        d               }@ j                  d      t        d               }A j                  d      t        d               }B j                  dd(d
g      t         fd              }C j                  dd
g      t        d               }D j                  d      t        d               }E j                  d      t        d               }F j                  d      t        d               }G j                  d      t        d               }H j                  d      t        d               }I j                  d      t        d               }J j                  d      t        d               }K j                  d      t        d               }L j                  d      t        d               }M j                  d      t        d               }N j                  dd(d
g      t        d               }O j                  d      t        d               }P j                  d      t        d               }Q j                  dd
g      t         fd              }R j                  d      t         fd              }S j                  d      t         fd              }T j                  d      t        d               }U j                  d      t         fd              }V j                  d      t        d               }W j                  dd(d
g      t        d               }X j                  d      t        d               }Y j                  dd
g      t        d               }Z j                  ddg      t        d               }[ j                  ddg      t        d               }\ j                  d      t        d               }] j                  dd
g      t        d               }^ j                  dd
g      t        d               }_ j                  dd
g      t        d               }` j                  dë      t        dĄ               }a j                  dū      t        dƄ               }b j                  dǫ      t        dȄ               }c j                  dɫ      t        dʄ               }d j                  d˫      t        d̄               }ed̈́ }f j                  dΫ      dτ        }g j                  dЫ      t        dф               }hy)z$Register main web application routesz/workersc                  |    ddl m}  | j                  j                  d      j	                         }t        d|      S )zList workers pager   r   workerrolezworkers/list.html)workers)app.models.userr   r]   r^   r`   r   )r   r   s     rz   r   z%register_main_routes.<locals>.workers   s5     	)**&&H&599;2GDDr|   z/api/workersc            	      H   ddl m}  | j                  j                  d      j	                         }|D cg c]X  }|j
                  |j                  |j                  |j                  |j                  r|j                  j                         nddZ }}t        |      S c c}w )z API endpoint to get workers listr   r   r   r   N)r_   email
first_name	last_name
created_at)r   r   r]   r^   r`   r_   r   r   r   r   	isoformatr   )r   r   wworkers_datas       rz   api_workersz)register_main_routes.<locals>.api_workers   s     	)**&&H&599; 	
  ddll[[:;,,all446D	
 	
 |$$	
s   ABz/find-workersc                     ddl m}  ddlm} ddlm} ddlm}m} t        j                  dvr t        dd       t        t        d	            S t        j                  j!                  d
d      j#                         }t        j                  j%                  d      }t        j                  j!                  d      dk(  }t        j                  j!                  d      dk(  }t        j                  j!                  d      dk(  }	| j&                  j)                  dd      }
ddlm} |
j-                   || j.                  j1                  d       |d       |d                  }
|rPd| d}|
j-                   || j2                  j5                  |      | j6                  j5                  |                  }
|rqg }|D ]T  }|j9                   || j:                  j5                  d| d      | j<                  j5                  d| d                   V |r|
j-                   ||       }
|r|
j-                  | j>                  dk(        }
|r|
j-                  | j@                  dk(        }
|	r*|
j-                  | jB                  jE                  d            }
|
jG                         }|j&                  j)                  d      jI                  |jJ                  |jL                        jG                         }tO        d||      S )z$Find workers page - contractors onlyr   r   r   )contractor_required)r   r    
contractoremployerz,This page is only accessible to contractors.error	dashboardsearchr   r   gst_registeredtrueinsured
white_cardr   T)r   	is_activetextNz1preferences->'privacy'->>'profile_public' IS NULLz4preferences->'privacy'->>'profile_public' != 'false'%r   zcontractors/find_workers.html)r   
categories)(r   r   app.models.categoryr   app.utils.auth_decoratorsr   
sqlalchemyr   r    r   r   r   r   r	   r   rS   rT   stripgetlistr]   r^   r   filterpreferencesis_r   iliker   appendr   secondary_trader   r   white_card_numberisnotr`   order_by
sort_ordernamer   )r   r   r   r   r    search_querytrade_filters
gst_filterinsured_filterwhite_card_filterr]   r   search_patterntrade_conditionsr   r   r   s                    rz   find_workersz*register_main_routes.<locals>.find_workers   s    	)0A( $>>@'JGK011 ||''"5;;=,,W5\\%%&676A
 )))4>#LL,,\:fD 

$$(d$C 	$  $$T*HIKL
  a0NLLOO)).9NN((8E !&  ''**001UG1>,,22QugQ<@  S*:%;< LL!4!4!<=ELL!@!@D!HIELL!7!7!=!=d!CDE))+ ^^---=FFxGZGZ\d\i\ijnnp
>\fggr|   z/api/contractor/my-jobsc            	      *   ddl m}  t        j                  dvrt	        ddi      dfS | j
                  j                  t        j                  d      j                  | j                  j                               j                         }|D cg c]p  }|j                  |j                  |j                  |j                  r|j                  j                  nd	|j                  r|j                  j!                         nd	d
r }}t	        d|i      S c c}w )z,API endpoint to get contractor's posted jobsr   r~   r   r   Unauthorized  openr   rf   N)r_   titler   categoryr   r   )
app.modelsr   r   r   r   r]   r^   r_   r   r   descr`   r   r   r   r   r   )r   r   job	jobs_datas       rz   get_contractor_jobsz1register_main_routes.<locals>.get_contractor_jobs?  s     	# $>>G^45s:: yy""&// # 
 (3??'')
*335 	 	
  ffLL14CLL--4>Aoos88:SW	
	 	
 	*++	
s   A5Dz/api/invite-worker-to-jobPOST)methodsc                     ddl m} m} ddlm} ddlm} t        j                  dvrt        ddi      dfS t        j                         }|j                  d	      }|j                  d
      }|r|st        ddi      dfS | j                  j                  |t        j                        j!                         }|st        ddi      dfS |j                  j                  |d      j!                         }|st        ddi      dfS 	  |j"                  |j                  d|j$                   t        j&                   dt        j(                   d|j$                   d|j*                   d|j,                  |j                  d|j                          t        ddd      S # t.        $ rD}	t0        j2                  j5                  dt7        |	              t        ddi      dfcY d }	~	S d }	~	ww xY w)!z2API endpoint to invite a worker to apply for a jobr   )r   r   r   r   r   r   r   r   r;   job_idzMissing required fields  )r_   r   zJob not found or unauthorized  r   r_   r   Worker not foundzJob Invitation:  z has invited you to apply for 'z' in z . Click to view the job posting.z/jobs/)user_idr   messagenotification_type
related_id
action_urlTzInvitation sent successfullysuccessr  zError sending job invitation: zFailed to send invitation  N)r   r   r   !app.services.notification_servicer   app.models.notificationr   r   r   r   r   get_jsonrT   r]   r^   r_   rb   create_notificationr   r   r   r   JOB_INVITATION	Exceptionr
   loggerr   r   )
r   r   r   r   datar;   r  r   r   es
             rz   invite_worker_to_jobz2register_main_routes.<locals>.invite_worker_to_job\  s    	)J< $>>G^45s::!HH[)	(#G%>?@#EE ii!!&// " 
 %' 	
 G%DEFKK %%%BHHJG%7893>>	H4 44		(4'2231\5K5K4LLklolulukvv{|  }I  }I  |J  Jj  k"2"A"A66#CFF8, 9    	H$$'Ec!fX%NOG%@ABCGG	Hs   BF   	G-)9G("G-(G-z#/api/worker-details/<int:worker_id>c           	      
   	 ddl m} ddlm} t        j
                  dvrt        ddi      dfS |j                  j                  | d	      j                         }|st        dd
i      dfS |j                  xs i }|j                  di       }|j                  dd      st        ddi      dfS |j                  dd      }|j                  dd      }|j                  dd      }|j                  j                  |       j                  |j                  j                               j                  d      j!                         }	g }
|	D ]  }|j                  j                  |j"                        }|s+|j
                  dv s:|
j%                  |j&                   d|j(                   |j*                  rt-        |j*                        nd|j.                  |j                  r|j                  j1                         ndd        ddlm} ddlm} g }|r.|j                  j                  | d      j                  |j:                  j                               j                  d      j!                         }|D ]  }|j<                  s|j<                  j>                  }tA        |d      r|jB                  }|j%                  |j<                  jD                  ||j<                  jF                  |jH                  r|jH                  j1                         n|j:                  j1                         |jK                         d        |r*|j                  j                  |       jM                         nd}i d |jN                  d!|j&                  d"|j(                  d#|r|jP                  ndd$|r|jR                  ndd%|jF                  d&|jT                  d'|jV                  d(|jX                  d)|jZ                  d*|j\                  d+|r|j^                  ndd,|r!|j`                  rt-        |j`                        nd-d.|d/|jb                  rt-        |jb                        nd-d0|jd                  d1|jf                  rt-        |jf                        nd|jh                  |jj                  r|jj                  j1                         nd|r|
ng |r|ng d2}t        d|i      S # tl        $ rX}tn        jp                  js                  d3tu        |              ddl;}|jy                          t        dd4i      d5fcY d}~S d}~ww xY w)6zAAPI endpoint to get detailed worker information including reviewsr   r   Ratingr   r   r   r   r   r  r  r  privacyprofile_publicTzWorker profile is not publiccontact_info_visibleFrating_visiblejob_history_visible)rated_id   r  N)reviewer_nameratingcommentr   r&   r~   r   r;   rf   
   r   )r   r   r   completed_datecontractor_namer_   r   r   r   r   r   r   r   r   r   r   jobs_completedaverage_ratingr9   total_reviewsresponse_rater   public_liability_amount)r   white_card_expiryreviewsrL   zError getting worker details: Internal server errorr  )=r   r   app.models.ratingr  r   r   r   r]   r^   rb   r   rT   r   rating_dater   limitr`   rater_idr   r   r   overall_scorerc   review_textr   rQ   r'   r   r   
updated_atr   r   r   r   r   r   worker_completion_dateget_contractor_namecountr_   r   r   r   r   r   r   r   r*  r+  r-  r   r.  r   r/  r  r
   r  r   r   	traceback	print_exc)r;   r   r  r   worker_prefsprivacy_prefscontact_visibler  r   r0  reviews_datareviewreviewerr'   r   rL   rq   contractcategory_nametotal_review_countworker_datar  r<  s                          rz   get_worker_detailsz0register_main_routes.<locals>.get_worker_details  s;   c	D'0   (BB893>> ZZ))YX)FLLNF);<=sBB "--3L(,,Y;M $$%5t<)GHI3NN ,//0FNO*../?FN"/"3"34I4"P ll,," - hv))..01%%(335  L! 	::>>&//:1K K '',4,?,?+@(BTBTAU)VAGAUAU%(<(<"=[\#)#5#5HNHZHZf&8&8&B&B&D`d	) 		 5*N"$NN44'& 5  (8..3356uuRy 
 !* H||(0(=(="=&9,9,>,>M&--%-\\%7%7(5(0(=(=]e]|]|h.M.M.W.W.Y  CK  CV  CV  C`  C`  Cb/7/K/K/M/   Xf!7!7!7!K!Q!Q!Sklfiif// V-- d	
  3 3D FOO "6#9#9  !5!5 "6#9#9 f// !&"7"7 !;N&"7"7TU !>V\VkVk%(=(=">ru  !3  @T@Tv';';!<Z]  -f.O.O!" *TZTrTr51O1O+Px|#$ &,%=%=MSMeMeV%=%=%G%G%Iko+9<r4G.R+K0 Hk233 	D$$'Ec!fX%NO!G%<=>CC		DsE   ,S% ;S% +AS% .CS% 3S% DS% IS% %	U.AU;UUc                  N   ddl m}  ddlm}m} |j
                  j                  d      s|t        d|j
                          t        d| j                          t        dt         |j                                       | j                  rt        d| j                          y	y	y	)
z:Debug any automatic authentication that might be happeningr   r   )r   r   z/api/z[?] Route: z#[?] current_user.is_authenticated: z[?] session keys: z'[?]  User automatically authenticated: N)flask_loginr   rR   r   r   path
startswithprintis_authenticatedlistkeysr   )r   r   r   s      rz   debug_authentication_statez8register_main_routes.<locals>.debug_authentication_state  s     	-* ||&&w/K~./78U8U7VWX&tLGLLN';&<=>,,?@R@R?STU -	 0r|   )	EARLYBIRDBETA2025	RATERIGHTz/clear-betac                  \    t        j                  dd       t        j                  dd       y)zClear beta access for testingbeta_accessNbeta_access_timestampz3Beta access cleared. <a href='/'>Return to home</a>)r   pop r|   rz   
clear_betaz(register_main_routes.<locals>.clear_betaf  s$     	M4(+T2Dr|   z/debug-sessionc                  ,    ddl m}  dt        |        dS )zShow current session contentsr   r   z<pre>Session contents: </pre>)rR   r   dictr]  s    rz   debug_sessionz+register_main_routes.<locals>.debug_sessionq  s     	"(gv>>r|   /c                      t        d      S )Nzcountdown.htmlr   rZ  r|   rz   indexz#register_main_routes.<locals>.indexw  s     /00r|   z/testc                       y)zSimple test routezk<h1>[?] RateRight Test Route Working!</h1><p>If you see this, the Flask server is responding correctly.</p>rZ  rZ  r|   rz   testz"register_main_routes.<locals>.test|  s     }r|   z/test/dbc                     ddl m}  ddlm}m}m}m}m} ddlm	} ddl
}ddlm} g }		 | j                  j                   |d             |	j                  dd	d
d       |j                  j!                         |j                  j!                         |j                  j!                         |j                  j!                         |j                  j!                         d}
|	j                  dd|
d       |j                  j#                  |j$                  j'                               j)                  d      j+                         }|	j                  dd|D cg c]M  }|j,                  |j.                  |j0                  |j$                  r|j$                  j3                         nddO c}d       |j                  j#                  |j$                  j'                               j)                  d      j+                         }|	j                  dd|D cg c]M  }|j,                  |j4                  |j6                  |j$                  r|j$                  j3                         nddO c}d       d|j9                  |	d       d |j:                         j3                          d}|S c c}w c c}w # t<        $ rD}ddt?        |      tA        |      jB                  d}d|j9                  |d       dcY d}~S d}~ww xY w)z*Test database connection and show contentsr   r   )r   r   r'   Applicationr   r   Nr   SELECT 1zDatabase Connectionu   ✅ SUCCESSz$Database is connected and responding)rf  rf   r  )UsersJobs	ContractsApplications
CategorieszRecord Countsu   ℹ️ INFO)rf  rf   countsr"  zRecent Users)r_   r   r   r   )rf  rf   r  zRecent Jobs)r_   r   rf   r   u  
            <html>
            <head>
                <title>Database Test Results</title>
                <style>
                    body { font-family: monospace; padding: 20px; }
                    pre { background: #f4f4f4; padding: 15px; border-radius: 5px; }
                    .success { color: green; }
                    .error { color: red; }
                    .info { color: blue; }
                </style>
            </head>
            <body>
                <h1>🔍 Database Test Results</h1>
                <pre>rJ   )indentz,</pre>
                <p><em>Generated at: z></em></p>
            </body>
            </html>
            u	   ❌ ERROR)rf  rf   r   r-   u  
            <html>
            <head>
                <title>Database Test Error</title>
                <style>
                    body { font-family: monospace; padding: 20px; }
                    pre { background: #ffebee; padding: 15px; border-radius: 5px; }
                    .error { color: red; }
                </style>
            </head>
            <body>
                <h1>❌ Database Test Error</h1>
                <pre>z;</pre>
            </body>
            </html>
            )"app.extensionsr   r   r   r   r'   ri  r   r   r   jsonr   r   executer   r]   r;  r   r   r   r4  r`   r_   r   r   r   r   rf   dumpsrV   r  r   r-   __name__)r   r   r   r'   ri  r   r   rt  r   responsetable_countsrecent_usersr   recent_jobsr   html_responser  error_responses                     rz   test_dbz%register_main_routes.<locals>.test_db  s    	&II#%]	JJtJ/0OO-'A  ))+		)%^^113 + 1 1 7 7 9&nn224L OO''&   ::..t/C/C/EFLLQOSSULOO&' +,
 	 ''!ZZ IIAE$//";";"=VZ	 ,	 	 )),,S^^-@-@-BCII!LPPRKOO%' )*
 	 && YY!jj@C#..":":"<TX	 *	 	! jj!j45 6&&2hlln&>&>&@%A BM& ! S,*<  	-%QQ((	N jjj:; < 	s@   D,J. AJ$&A*J. AJ)"AJ. $
J. .	K;79K60K;6K;z/applicationsc                     ddl m}  ddlm} t        j
                  dk(  rt	        j                         \  }}|rHd|v r t        dd       t        t        d            S d	|v r t        d
d       t        t        d            S | j                  j                  t        j                  d      j                  | j                  j                               j                         }| j                  j                  t        j                  d      j                  | j                  j                               j                         }| j                  j                  t        j                  d      j                  | j                  j                               j                         }t!        d|||      S t        j
                  dk(  rddl m} |j$                  j                  |       j'                  |      j)                  |j*                  t        j                  k(        }t,        j.                  j1                  d      }	|	r*	 t3        |	      }	|j)                  |j                  |	k(        }|j                  | j                  j                               j                         }
t!        d|
      S t        dd       t        t        d            S # t4        t6        f$ r t        dd       Y w xY w)z5View user's job applications or received applicationsr   ri  rh  r   profile)Please complete your profile setup first.warningonboarding_profilers   )Please complete your payment setup first.onboarding_paymentr   r&  acceptedrejectedzapplications/list.html)r   accepted_applicationsrejected_applicationsr   r~   r  Invalid job ID providedr   !applications/contractor_list.htmlr   Access denied.r   )r   ri  rs  r   r   r   needs_onboardingr   r   r	   r]   r^   r_   r   r   r`   r   r   r   joinr   r   r   rS   rT   rU   	TypeErrorr   )ri  r   r  missing_stepsr   r  r  r   r]   r  r   s              rz   my_applicationsz-register_main_routes.<locals>.my_applications  sq    	+%(.:.K.K.M+m-EyQ#G,@$ABB-/EyQ#G,@$ABB $/#4#4#>#>&//  $? $ h{~~**,-cce !
 %0$5$5$?$?&//! %@ % h{~~**,-cce "
 %0$5$5$?$?&//! %@ % h{~~**,-cce "
 ##;4H5J5JL L
 ,.&JJ$$[166s;BB!!\__4E
 \\%%h/F> [F!LL6)9:E !>>+..*=*=*?@DDFL"#FUabb "G,GK011 ":. >3W=>s    )K K+*K+z/jobsc                  >   t         j                  dk(  rat        j                         \  } }| rHd|v r t        dd       t	        t        d            S d|v r t        dd       t	        t        d            S t         j                  d	k(  rt        d
d       t        d      S )z"Browse available construction jobsr   r  8Please complete your profile setup before browsing jobs.r  r  rs   8Please complete your payment setup before browsing jobs.r  r   z^As a contractor, you can post jobs and review applications. Workers browse and apply for jobs.infojobs/browse.html)r   r   r  r   r   r	   r   )r  r  s     rz   browse_jobsz)register_main_routes.<locals>.browse_jobs)  s    
 (.:.K.K.M+m-TV_`#G,@$ABB-/TV_`#G,@$ABB,rtz{122r|   z/searchc                      t        d      S )zSearch for jobsr  rc  rZ  r|   rz   r   z$register_main_routes.<locals>.search<  s     122r|   z/api/capture-leadc                     ddl m}  ddlm} t	        dt
        j                           G d d|       } |       }|j                         r|j                  j                  |j                  j                  |j                  j                  |j                  j                  |j                  j                  |j                  j                  d}t
        j                  t
        j                   xs dt
        j"                  j%                  d	d
      d} |||      }|d   rd}nd}t'        d||d   d      S t	        d|j(                          t'        d|j(                  dd      dfS )z7Handle lead capture - direct to Slack only, no databaser   )LeadCaptureForm)send_lead_to_gsheetsz[DEBUG] Form data received: c                        e Zd Z G d d      Zy)Iregister_main_routes.<locals>.capture_lead.<locals>.LeadCaptureFormNoCSRFc                       e Zd ZdZy)Nregister_main_routes.<locals>.capture_lead.<locals>.LeadCaptureFormNoCSRF.MetaFN)rw  
__module____qualname__r   rZ  r|   rz   Metar  N  s    r|   r  N)rw  r  r  r  rZ  r|   rz   LeadCaptureFormNoCSRFr  M  s     r|   r  )r   is_beta_testerwants_updatescompany_sizebiggest_challengeconstruction_focusDirect
User-AgentUnknownipreferrer
user_agentr  zIAwesome! You're on the beta list. We'll reach out soon with early access.z0Great! We'll notify you when RateRight launches.T)r  r  is_betaz[DEBUG] Form errors: Fz Please check all required fields)r  errorsr  r  )	app.formsr  app.utils.slackr  rN  r   formvalidate_on_submitr   r  r  r  r  r  r  remote_addrr  headersrT   r   r  )r  r  r  r  	lead_datarequest_infor  r  s           rz   capture_leadz*register_main_routes.<locals>.capture_leadC  sX    	.8 	,W\\N;<	O 	 %&""$ "&"5"5":":!%!3!3!8!8 $ 1 1 6 6%)%;%;%@%@&*&=&=&B&BI ))#,,8%oo11,	JL +9lCG )*eL"$%56   	%dkk]34kk9
  	 	r|   z/api/report-bugc                  ^	   ddl m}  ddl}ddl}t	        d       t	        dt
        j                          t	        dt
        j                          t	        dt        t
        j                  j                                       |j                  j                  d      }t	        d	t        |              |rt	        d
|dd  d       t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }	t
        j                  j                  dd      j                         }
t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t	        dt        |              t	        d|        t	        d|        t	        d|        t	        d|        |st	        d       t!        ddd       d!fS t        |      d"k  r(t	        d#t        |       d$       t!        dd%d       d!fS |st	        d&       t!        dd'd       d!fS |r2d(}|j#                  ||      st	        d)|        t!        dd*d       d!fS |||xs d+|xs t
        j$                  xs d+|r|nd|	|
|||r|nd,d-
}t
        j&                  t
        j$                  xs d.t
        j(                  j                  d/d+      d0}t	        d1       	  | ||      }t	        d2|        |rt	        d3       t!        d4d5d       S t	        d6       t!        d4d5d       S # t*        $ rO}t	        d7t-        |              ddl}t	        d8|j1                                 t!        d4d5d       cY d}~S d}~ww xY w)9z6Handle bug reports - direct to Slack only, no databaser   )send_bug_report_to_slackNu.   
🐛 [BUG REPORT API] New bug report receivedu&   🐛 [BUG REPORT API] Request method: u$   🐛 [BUG REPORT API] Content-Type: u!   🐛 [BUG REPORT API] Form keys: SLACK_WEBHOOK_URLu0   🐛 [BUG REPORT API] Slack webhook configured: u#   🐛 [BUG REPORT API] Webhook URL: 2   z...descriptionr   severitypage_featurer   page_urlbrowser_infoscreen_sizedevice_typeconsole_errorsr  u*   🐛 [BUG REPORT API] Description length: u    🐛 [BUG REPORT API] Severity: u$   🐛 [BUG REPORT API] Page Feature: u   🐛 [BUG REPORT API] Device: u   🐛 [BUG REPORT API] User ID: u4   🐛 [BUG REPORT API] ERROR: No description providedFzPlease tell us what's brokenr  r  r"  u4   🐛 [BUG REPORT API] ERROR: Description too short (z chars)zPlease provide more detailsu1   🐛 [BUG REPORT API] ERROR: No severity providedz"Please select how bad the issue isz0^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$u3   🐛 [BUG REPORT API] ERROR: Invalid email format: z"Please enter a valid email addressr  	Anonymous)
r  r  r  r  r   r  r  r  r  r  r  r  r  u9   🐛 [BUG REPORT API] Prepared data - sending to Slack...u)   🐛 [BUG REPORT API] Slack send result: u8   🐛 [BUG REPORT API] SUCCESS: Bug report sent to Slack!TzThanks! We'll look into this.uM   🐛 [BUG REPORT API] FAILED: Slack send failed but returning success to useru!   🐛 [BUG REPORT API] EXCEPTION: u&   🐛 [BUG REPORT API] Full traceback: )r  r  reosrN  r   methodcontent_typerP  r  rQ  environrT   r   r   r   r   matchr  r  r  r  r   r<  
format_exc)r  r  r  webhook_urlr  r  r  r   r  r  r  r  r  r  email_patternbug_datar  r  r  r<  s                       rz   
report_bugz(register_main_routes.<locals>.report_bug|  sz    	=?A6w~~6FGH4W5I5I4JKL1$w||7H7H7J2K1LMN jjnn%89@kAR@STU7CR8H7IMN ll&&}b9??A<<##J399;||'';AAC  "-335 <<##J399;||'';AACll&&}b9??All&&}b9??A ))*:B?EEG,,""9b1779:3{;K:LMN0
;<4\NCD.{m<=/y9: HJ :   
 {aH[IYHZZabc 8   
 EG ?    OM88M51KE7ST$C     ' (5I AG$4$4A	#U(&&,")w{
 %%((4H!//--lIF
 	IK	.xFG=gYGHPR#?   
 eg#?     		5c!fX>?:9;O;O;Q:RST ;  		s%   	1Q ;Q 	R,AR'!R,'R,z/api/cookie-consentc                  >   ddl m}  	 t        j                         }|j	                  d      }|j	                  d      }|dvrt        ddd      d	fS  | |t        j                  t        j                  j	                  d
      |t        j                  d      t        j                  |j	                  d      t        j                  rt        j                  ndd|j	                  d      
      }t        j                  j                  |       t        j                  j                          t        dd|j                  d      S # t         $ rO}t#        dt%        |              t        j                  j'                          t        ddd      dfcY d}~S d}~ww xY w)z1Track user cookie consent preferences in databaser   )CookieConsentconsent_typebrowser_fingerprint)r`   	necessaryFzInvalid consent typer  r  r  _idr  Nz1.0country_code)
r  
ip_addressr  r  
session_idreferrer_urlr  r  consent_versionr  TzCookie preferences saved)r  r  
consent_idzError saving cookie consent: zFailed to save preferencesr  )app.models.cookie_consentr  r   r  rT   r   r  r  r   r  r   rO  r_   r   addcommitr  rN  r   rollback)r  r  r  r  consentr  s         rz   save_cookie_consentz1register_main_routes.<locals>.save_cookie_consent  sl    	<)	##%D88N3L"&((+@"A #77$5     $)".."??..|<$7";;u-$--*-+7+H+Hd %!XXn5G JJNN7#JJ5%jj    	1#a&:;JJ! 7   	s&   A	E C1E 	FAFFFz
/jobs/postGETc                  
   ddl m}  ddlm}m} ddlm} ddlm} | j                  s2t        dd       t        d      t        d	<   t        t        d
            S | j                  dk7  r t        dd       t        t        d            S t        j                   dk(  r	 t        j"                  j%                  dd      j'                         }t        j"                  j%                  dd      j'                         }t        j"                  j%                  dt(              }t        j"                  j%                  dd      j'                         }t        j"                  j%                  d      }	t        j"                  j%                  d      }
t        j"                  j%                  d      }t        j"                  j%                  dd      j'                         }dt        j"                  v }dt        j"                  v }t        j"                  j%                  dd      j'                         }t        j"                  j%                  dd      j'                         }t        j"                  j%                  dd      j'                         }t        j"                  j%                  dt(              }g }|s|j+                  d        |s|j+                  d!       |s|j+                  d"       |s|j+                  d#       |r:|j,                  j%                  |      }|r|j.                  s|j+                  d$       d%}d%}d%}	 |	r' |t1        |	            }|dk  r|j+                  d&       	 |
r' |t1        |
            }|dk  r|j+                  d(       	 |r' |t1        |            }|dk  r|j+                  d*       |r|r||kD  r|j+                  d,       d%}|r8	 |rt7        j8                  | d-| d.      }nt7        j8                  | d/d.      }|rE	 t)        |      }|d1k  r|j+                  d2       n"|d3kD  r|j+                  d4       nt1        |      }|"	 t)        |      }|d<k  r|j+                  d=       |rn|D ]  }t        |d        |j,                  j;                  d?@      j=                  |j>                  |j@                        jC                         }tE        dA|B      S  |||| jF                  ||||||xs dCj@                   dD|jH                   dE||dF||r|nd%|r|nd<G      }|j                  jK                  |       |j                  jM                          	 ddHl'm(} |j,                  jS                  |j                  dIk(  |j.                  d?k(  |jT                  jW                  dJ| dJ            jC                         } | D ]]  }!tY        jZ                  |!jF                  t\        j^                  dKdLj@                   dM| dN| t        dO|jF                  dPQ      R       _ ta        dStc        |        dT       t        dVdW       t        t        dO|jF                  X            S |j,                  j;                  d?@      j=                  |j>                  |j@                        jC                         }tE        dA|B      S # t2        t4        f$ r |j+                  d'       Y w xY w# t2        t4        f$ r |j+                  d)       Y w xY w# t2        t4        f$ r |j+                  d+       Y w xY w# t2        $ r |j+                  d0       Y Tw xY w# t2        $ r$ d5d6d7d8d9d:d;}|j%                  |      }|r|}n	 Y =w xY w# t2        t4        f$ r |j+                  d>       Y @w xY w# td        $ r}"ta        dU|"        Y d%}"~"d%}"~"ww xY w# td        $ r}#|j                  jg                          t        dYt1        |#       d       |j,                  j;                  d?@      j=                  |j>                  |j@                        jC                         }tE        dA|B      cY d%}#~#S d%}#~#ww xY w)Zz,Post a new construction job (requires login)r   rJ  )r   r   rh  DecimalzPlease login to post a jobr  post_jobnext_urlloginr   zOnly contractors can post jobsr   r   r   r   r   r  category_idr-   r   
budget_min
budget_maxhourly_ratewhs_requirementswhite_card_requiredinsurance_required
start_date
start_timedurationworkers_neededzJob title is requiredzJob description is requiredzJob category is requiredzJob location is requiredzInvalid job category selectedNz!Minimum budget cannot be negativezInvalid minimum budget amountz!Maximum budget cannot be negativezInvalid maximum budget amountzHourly rate cannot be negativezInvalid hourly rate amountz4Minimum budget cannot be greater than maximum budgetr  z%Y-%m-%d %H:%Mz 00:00zInvalid start date/time format   z!Duration must be at least 8 hoursr  z Duration cannot exceed 500 hours4810163240)half_dayfull_daylong_day2_days3_5_days1_week_plusrA   z+Number of workers needed must be at least 1z#Invalid number of workers specifiedTr   zjobs/post.html)r   z
Category: z. Risk Level: .r   )r   r  r   r  r   r  r  r  r  r  r  rf   start_datetimer  r  r   r   r   zNew Job PostedzNew z job: z in job_detailsFr  	_externalr  r	  r   contentr  z1[NOTIFICATION] Job posting notifications sent to z workersz?[NOTIFICATION ERROR] Failed to send job posting notifications: zJob posted successfully!r  r  zError posting job: )4rK  r   r   r   r   rs  r   decimalr  rO  r   r	   r   r   r   r   r  r  rT   r   rU   r   r]   r   r   r   r  r   strptimer^   r   r   r   r`   r   r_   whs_risk_levelr  r  r   r   r   r   r   r   send_notificationr   	JOB_MATCHrN  r   r  r  )$r   r   r   r   r  r   r  r  r   r  r  r  r  r  r  r  r  r  r  r  r   budget_min_decimalbudget_max_decimalhourly_rate_decimalr  duration_hoursduration_mappingmapped_durationr   r   r   r   nearby_workersr   notification_errorr  s$                                       rz   r  z&register_main_routes.<locals>.post_job'  s    	-,%#,,.	:")*"5GJGG,--,2G<GK011>>V#wP(("5;;=%ll..}bAGGI%ll..}3.G"<<++J;AAC$\\--l;
$\\--l;
%ll..}=#*<<#3#34F#K#Q#Q#S &;w||&K#%9W\\%I" %\\--lB?EEG
$\\--lB?EEG
"<<++J;AAC!(!1!12B!1!M MM"9:"MM"?@"MM"<=MM"<= '~~11+>H#8+=+=&EF &*"%)"&*#C!-4S_-E*-1"MM*MNC!-4S_-E*-1"MM*MN@".5c+6F.G+.2"MM*JK
 &*<ASVhAhMM"XY "&H%-5->->*Qzl?[]m-nN .6->->*V?TVf-gN
 !),X)A-"MM*MN+c1"MM*LM (+>':H* "-M),^)<)A-"MM*WX !' .eW-.!)!9!9D!9!I!R!RS[SfSfhphuhu!v!z!z!|J*+;
SS  +".// +%11 3%5%}:hmm_Tbckczczb{{|9}(;'9!#1)1Xt5C>$ 

s#

!!#r4%)ZZ%6%6		X-$.++azO<& ce	 # #1 ,>>$*II.>.H.H"2&*8==/wd8*$U'.}SVVW\'] McR`NaMbbjkl
 0)<cff EFF ^^---=FFxGZGZ\d\i\ijnnp
/JGGY #I. CMM"ABC #I. CMM"ABC #I. @MM">?@" & H&FGH & ! ),(+(,&*(,+/,( +;*>*>x*H*'6H !#!2 '	2 M&KLMh ! r[\n[opqqr  P

##%+CF84g>%^^555ENNxObObdldqdqrvvx
&'7JOO	Ps   J_" ;)[ %)[7 )\ 8_" 7] _" A]& _" !^ 9A/_" )A=_" 'C"^= 	+_"  [40_" 3[44_" 7 \_" \_"  ]>_" ]_" ]#_" "]##_" &)^_" ^_"  ^:6_" 9^::_" =	___" __" "	b+Ba=7b=bz/jobs/<int:job_id>c                 (   ddl m}m} |j                  j	                  |       }d}t
        j                  rPt
        j                  dk(  r=|j                  j                  | t
        j                        j                         }|du}t        d||      S )	zView specific job detailsr   r   ri  Fr   r  r;   Nzjobs/details.html)r   user_applied)r   r   ri  r]   
get_or_404r   rO  r   r^   r_   rb   r   )r  r   ri  r   r  existing_apps         rz   r	  z)register_main_routes.<locals>.job_details  s     	0ii""6* ((\->->(-J&,,66&// 7  eg  (t3L2,WWr|   z/jobs/<int:job_id>/applyc                    t         j                  dk(  rddlm} ddlm} ddlm} t        j                  dk7  r"t        dd       t        t        d	| 
            S t        j                         \  }}|rHd|v r t        dd       t        t        d            S d|v r t        dd       t        t        d            S |j                  j                  |       }|j                  dk7  r"t        dd       t        t        d	| 
            S |j                  j!                  | t        j"                        j%                         }|r"t        dd       t        t        d	| 
            S t         j&                  j)                  d      }t         j&                  j)                  dd      j+                         }	d}
|r4	 t-        |      }
|
dk  r"t        dd       t        t        d	| 
            S 	  || t        j"                  |
|	dt        j2                  d      }	 |j4                  j7                  |       |j8                  xs ddz   |_        |j4                  j;                          	 t=        j>                  |j@                  tB        jD                  d t        jF                   d!t        jH                   d"|jJ                   d#t        d	|j"                  d$%      &       tM        d'|j@                          t        d)d*       t        t        d+            S y# t.        t0        f$ r% t        dd       t        t        d	| 
            cY S w xY w# tN        $ r}tM        d(|        Y d}~td}~ww xY w# tN        $ r`}|j4                  jQ                          t        d,tS        |       d       tM        d-|        t        t        d	| 
            cY d}~S d}~ww xY w).zApply to a jobr   r   r  rh  r~   r   zOnly workers can apply to jobs.r   r	  r  r  z;Please complete your profile setup before applying to jobs.r  r  rs   z;Please complete your payment setup before applying to jobs.r  r   z-This job is no longer accepting applications.r  z%You have already applied to this job.proposed_ratecover_letterr   Nz!Proposed rate cannot be negative.zInvalid proposed rate.Tr   )r  r;   r#  r$  abn_verifiedinsurance_verifiedrf   rA   zNew Applicationr  z applied to ''Fr
  r  z;[NOTIFICATION] Application notification sent to contractor z>[NOTIFICATION ERROR] Failed to send application notification: z#Application submitted successfully!r  r   zError submitting application: zDatabase error: )*r   r  r   ri  rs  r   r   r   r   r   r   r	   r  r]   r   rf   r^   r_   rb   r  rT   r   rc   r   r  r   r   r  applications_countr  r   r  r   r   JOB_APPLICATION_UPDATEr   r   r   rN  r  r  r   )r  ri  r   r   r  r  r   r!  r#  r$  proposed_rate_decimalapplicationr  r  s                 rz   apply_to_jobz*register_main_routes.<locals>.apply_to_job  s|    >>V#.)&  H,7Af EFF /;.K.K.M+m-WYbc#G,@$ABB-/WYbc#G,@$ABB))&&v.CzzV#EwOf EFF ',,66&// 7  eg 
 =yIf EFF $LL,,_=M"<<++NB?EEGL %)!K,1-,@),q0A7K'f(MNN 1 &&//3)!#/#J#J KG

{+*-*@*@*EA)J&

!!#q(:: # 1 1*:*Q*Q/#/#:#:";1\=S=S<TTabebkbkallm n#*=SX#Y WX[XiXiWjkl
 ;YG 455k $^ #I. K2G<#GM&$IJJKB ! qZ[mZnoppq  G

##%6s1vh?I(,-f EFF	Gs]   81L AM0 %BM 4M0 1M	M		M-M(#M0 (M--M0 0	O9AOOOz/loginc                  D   ddl m}  ddlm} t        j
                  rt        t        d            S t        j                  dk(  r{	 t        j                  j                  d      }t        j                  j                  d      }|r|s'|st        dd	       |st        d
d       t        d      S t        d|        	 ddlm} |j"                  j%                   |d             t        d       	 | j(                  j+                  |      j-                         }t        d|du        |rl|j/                  |      rZ|j0                  rM|j2                  st        dd       t        d      S t5        |t        j                  j                  d             |j6                  }t9        j:                         |_        |j"                  j=                          |du t"        d<   t        dd       t#        j>                  dd      }	|	rt        |	      S |j@                  d k(  r9|jC                         \  }
}|
r$d!|v r t        d"d#       t        t        d$            S |j@                  d k(  r|jE                         st        d%d&       t        t        d            S |st        d'd	       nt        d(d       t        d      S t        d      S # t&        $ r/}t        d|        t        dd       t        d      cY d}~S d}~ww xY w# t&        $ r/}t        d|        t        dd       t        d      cY d}~S d}~ww xY w# t&        $ rU}t        d)tG        |              ddl$}t        |jK                                t        d*d       t        d      cY d}~S d}~ww xY w)+z$User login page and web form handlerr   r   rh  r   r   r   passwordEmail is requirederror_emailzPassword is requirederror_passwordzauth/login_alt.htmlzLogin attempt for email: r   rk  u   âœ… Database connection OKu"   âŒ Database connection error: z2Database connection error. Please try again later.r   Nr   zUser found: u   âŒ User query error: z4Error retrieving user information. Please try again.zWPlease verify your email before logging in. Check your inbox for the verification link.remember)r3  is_first_loginzLogin successful!r  r  r   r  z5Welcome! Please complete your profile to get started.r  r  zEReminder: Set up your payment method in Settings to receive payments.r  z No account found with this emailzInvalid passwordu   âŒ Login error: z1An error occurred during login. Please try again.)&r   r   rs  r   r   rO  r   r	   r   r  r  rT   r   r   rN  r   r   r   ru  r  r]   r^   rb   check_passwordr   email_verifiedr   
last_loginr   utcnowr  rY  r   r  is_payment_setup_completer   r<  r  )r   r   r   r.  r   db_errorr   query_errorprevious_loginr  r  r  r  r<  s                 rz   r  z#register_main_routes.<locals>.loginh  sC    (),, 455~~'TB#LL,,W5E&||//
;H $!"5}E'!"8:JK./DEE 5eW=>F3

**4
+;<>?F#zz33%3@FFHT-=,>?@  3 3H =$..#22!"{  ~E  F#23H#II #4',,2B2B:2NO *. +3//*;

))+ 5Cd4J 0119= $+;;z4#@##+H#55  990>B>S>S>U;,m/#,#=$)*aci$j+3G<P4Q+R$R  9909W9W9Y!"iktu'(<==#!"DmT!"46FG ##8::?#8::E % F B8*MNRT[\./DEEF % F 9+GHTV]^./DEEFd ! B0Q9:$)..01MwW*+@AABs   A(M /M >2K 1:L +AM 0B"M AM >M M 	L$K>8L9M >LM 	L>$L93L>4M 9L>>M 	N
A
NNNz	/registerc                  X   ! t         j                  rt        t        d            S t        j
                  dk(  rddlm}  ddlm	} t        j                  j                  dd      j                         j                         }t        j                  j                  d      }t        j                  j                  d	      }t        j                  j                  d
d      j                         }t        j                  j                  dd      j                         }t        j                  j                  d      }t        j                  j                  dd      j                         }t        j                  j                  dd      j                         }	t        j                  j                  dd      j                         }
|
j                  dd      j                  dd      }t        j                  j                  d      dk(  }t        j                  j                  d      dk(  }g }d}|s|j                  d       n9| j                   j#                  |d      j%                         rt'        dd       d}|rt)        |      dk  r|j                  d       n||k7  r|j                  d       |s|j                  d       |s|j                  d       |d vr|j                  d!       |s|j                  d"       |	s|j                  d#       |rt)        |      d$k7  r|j                  d%       | j                   j#                  |d&      j%                         rt'        d'd(       d}| j                   j#                  |d)      j%                         rt'        d*d+       d}|s|r|D ]  }t'        |d,        t+        d-      S 	 |j-                  d.      d   }d/}|d0k(  rdd/l!dd/l}|j2                  j                  d1d      j                  d2d      |j4                  j                  d3d      j                  d4d      z    t7        d5      D ]U  }dj9                   !fd6t7        d7      D              }| j                   j#                  |d08      j%                         }|rU nG nE|d9k(  r@t        j                  j                  d:d      j                         }|r|j;                         } | |||||||	||ddt=        j>                         d|;      }|jA                  |       |jB                  jE                  |       |jB                  jG                          dd<l$m%}m&}  ||jN                  |jP                  ||rt=        j>                         nd/=      }|jB                  jE                  |       |jS                         }|jB                  jU                          dd>l+m,} t        d?|d@      }|jZ                   d|j\                   }|j_                  |j`                  ||       t'        dAdB       t        t        dC            S t+        d-      S # tb        $ rG}|jB                  je                          t'        dDtg        |       d,       t+        d-      cY d/}~S d/}~ww xY w)Ez"User registration page and handlerr   r   r   r   rh  r   r   r.  confirm_passwordr   r   r   r   r   r   r  -is_gst_registeredonmarketing_consentFr/  )r   
is_deletedz This email is already registeredr0  T   &Password must be at least 6 charactersPasswords do not matchzFirst name is requiredzLast name is required)r   r   zPlease select a valid rolezPhone number is requiredzLocation is required   zValid 11-digit ABN is required)r   rC  z'This Phone Number is already registerederror_phone)r   rC  zThis ABN is already registered	error_abnr   zauth/register_alt.html@Nr   OI01r'  c              3   @   K   | ]  }j                          y wN)choice).0_charssecretss     rz   	<genexpr>z9register_main_routes.<locals>.register.<locals>.<genexpr>  s     3\aGNN54I3\s   r  )referral_coder   r   rW  )usernamer   r   r   r   r   r   r   r   privacy_consentterms_acceptedterms_accepted_dater6  rW  NotificationPreferencer   )r  r	  consent_givenconsent_dateemail_serviceverify_emailtokenr  zZRegistration successful! Please check your inbox to verify your account before logging in.r  r  zRegistration failed: )4r   rO  r   r	   r   r  r   r   rs  r   r  rT   r   lowerrZ   r   r]   r^   rb   r   r   r   splitrU  stringascii_uppercasedigitsranger  upperr   r8  set_passwordr   r  flushr  r]  r   r_   SYSTEM_ANNOUNCEMENTgenerate_verification_tokenr  app.services.email_servicera  r   r   send_verification_emailr   r  r  r   )"r   r   r   r.  r>  r   r   r   r   r   abn_number_rawr   r@  rB  r  
has_errorsr   rX  rW  rg  rS  existingworker_referralr   r]  r   marketing_prefverification_tokenra  verification_url	user_namer  rT  rU  s"                                   @@rz   registerz&register_main_routes.<locals>.register  s    ,, 455~~'0-  (("5;;=CCE"<<++J7#*<<#3#34F#G $\\--lB?EEG
#LL,,["=CCE	||''/&||//CIIK"<<++J;AAC!(!1!1,!C!I!I!K+33C<DDS"M
$+LL$4$45H$IT$Q!$+LL$4$45H$IT$Q! "
MM"56ZZ))%)HNNP<mL!%J3x=1#4MM"JK!11MM":;!MM":; MM"9:77MM">?#MM"<=MM"89!S_%:MM"BC::''\e'TZZ\C]S!%J::'':%'PVVX:KH!%JZ!' .eW-.*+CDDPE  %{{3/2H %)M|+&% & 6 6 > >sB G O OPSUW X[a[h[h[p[pqtvx[y  \B  \B  CF  HJ  \K  !K!&r &A,.GG3\SXYZS[3\,\M'+zz';';-^j';'k'q'q'sH#+ %& )*1,,*:*:?B*O*U*U*W*,;,A,A,CM!)##-"+!%1!)#-'8(,'+,4OO,=',&3D  %%h/JJNN4(JJ$$& a &< $*:*N*N&7:KX__%6QU	&N JJNN>2 *.)I)I)K&JJ%%' I'.~EWcg'h$#'??"31T^^4D EI!99

(! v  yB  C#GG$455 ##;<< ! EJJ'')1#a&:GD*+CDDEs&   CY (F%Y 	Z)"<Z$Z)$Z)z/logoutc                      ddl m}  t                t        j                           | d      }|j                  ddd       |j                  ddd       |S )z-Logout user and completely clear all sessionsr   make_responsea  <!DOCTYPE html>
    <html><head><title>Logging out...</title></head>
    <body><h3>Logging out...</h3>
    <script>
    // Clear all localStorage
    localStorage.clear();
    // Clear all sessionStorage
    sessionStorage.clear();
    // Clear specific tokens
    localStorage.removeItem('access_token');
    localStorage.removeItem('user_data');
    localStorage.removeItem('rateright_token');
    // Force redirect immediately
                        window.location.href = '/login';
    </script></body></html>r   r   )expiresremember_token)rR   r}  r   r   clear
set_cookie)r}  rx  s     rz   logoutz$register_main_routes.<locals>.logout^  sX     ,MMMO % &  H" 	2q9 0"a@Or|   z/onboarding/profilec                  6
   ddl m}  ddlm} t        j
                  dk7  rt        t        d            S t	        j                         r<t	        j                         st        t        d            S t        t        d            S t        j                  dk(  r	 t        j                  j                  dt        j                        t        _        t        j                  j                  d	t        j                        t        _        t        j                  j                  d
t        j                         t        _        t        j                  j                  dt        j"                        t        _        t        j                  j                  dt        j$                        t        _        dt        j                  v rt        j                  j'                  d      }|rdj)                  |dd       t        _        nlt-        dd       | j.                  j1                  d      j3                  | j4                  | j6                        j9                         }t;        dt        |      S dt        j                  v r;t        j                  j'                  d      }|rdj)                  |      t        _        dt        j                  v }|slt-        dd       | j.                  j1                  d      j3                  | j4                  | j6                        j9                         }t;        dt        |      S |t        _        dt        j                  v t        _         t        j                  j                  d      r1tC        t        j                  j                  d            t        _"        t        j                  j                  d      rMddl#m#}  |jH                  t        j                  j                  d      d      jK                         t        _&        |jN                  jQ                          t	        j                         r t-        dd        t        t        d            S t-        d!d       	 | j.                  j1                  d      j3                  | j4                  | j6                        j9                         }t;        dt        |      S # tR        $ r<}|jN                  jU                          t-        d"tW        |       d       Y d}~d}~ww xY w)#z$Worker profile setup onboarding stepr   r   rh  r   r   r  r   r   r   r   r   r   r   ,N   z(Please select at least one primary trader   Tr   zonboarding/profile.htmlr   r   r   r   z>Public liability insurance is required to work on the platformworkers_compensationr.  insurance_expiry_daterj  %Y-%m-%dzProfile setup complete!r  z#Please complete all required fieldszError saving profile: ),r   r   rs  r   r   r   r   r	   is_profile_completer9  r   r  r  rT   r   r   r   r   r   r   r  r   r   r]   r^   r   r   r   r`   r   r   r   workers_comp_insurancerc   r.  r   r  r   r  r   r  r  r  r   )r   r   selected_tradesr   selected_secondary_tradespublic_liabilityr   r  s           rz   r  z0register_main_routes.<locals>.onboarding_profile}  s    	1% (GK011 ++-99;(< =>>GK011>>V#5B*1,,*:*:<I`I`*a')0)9)9+|G]G])^&,3LL,<,<^\MfMf,g)(/(8(8\EZEZ([%*1,,*:*:<I`I`*a' #gll2&-ll&:&:?&KO&58XXobq>Q5R2H'R%-^^%=%=%=%M%V%VW_WjWjltlyly%z%~%~  &A
./H|hrss %4070D0DEV0W-07:xx@Y7Z4 $@7<<#O 'Z\cd!)!9!9D!9!I!R!RS[SfSfhphuhu!v!z!z!|J*+D<dnoo:J76LPWP\P\6\3 <<##$=>;@AQAQRkAl;mL8<<##$;<19J9J9J7<<K[K[\sKt  wA  :B  :G  :G  :IL6

!!#  3353Y?#G,@$ABB?I ^^---=FFxGZGZ\d\i\ijnnp
8|Xbcc  B

##%.s1vh7AABs-   GS )CS 6D/S &S 	T2TTz/onboarding/paymentc                     ddl m}  t        j                  dk7  rt	        t        d            S t        j                         s t        dd       t	        t        d            S t        j                         r t        dd	       t	        t        d            S t        j                  rdd
l
m} 	 |j                  t        j                        }|d   t        _        |d   t        _        |d   t        _        | j                   j#                          t        j                         r t        dd	       t	        t        d            S 	 t+        dt              S # t$        $ r(}j&                  j)                  d|        Y d}~=d}~ww xY w)z?Worker payment setup onboarding step - optional but recommendedr   rh  r   r   z"Please complete your profile firstr  r  z'Your payment setup is already complete!r  stripe_servicedetails_submittedpayouts_enabledcharges_enabledz=Payment setup complete! You can now start receiving payments.zError checking Stripe status: Nzonboarding/payment.htmlr   )rs  r   r   r   r   r	   r  r   r9  stripe_account_idapp.services.stripe_servicer  get_account_statusstripe_onboarding_completestripe_payouts_enabledstripe_charges_enabledr   r  r  r  r   r   )r   r  account_statusr  apps       rz   r  z0register_main_routes.<locals>.onboarding_payment  sR    	& (GK011 //16	BG$89:: 113;YGGK011 ))BG!/!B!B<CaCa!b ;II\:]76DEV6W36DEV6W3

!!#  99;Y[de#GK$899 < 8|LL	  G

  #A!!EFFGs   .BE 	F FFz/onboardingc                     ddl m}  t        t              }|d   dk  r\t        j                  rt        j
                  st        t        d            S t        j                         st        t        d            S t        t        d            S )z4Smart onboarding - redirect to first incomplete stepr   r   r   r   r  r  r   )	r   r   r   r   r   r   r   r	   r9  )r   
completions     rz   onboarding_wizardz/register_main_routes.<locals>.onboarding_wizard  so     	11,?
l#c)--\5J5J(< =>>99;(< =>> ,--r|   z/api/profile-completionc                  :    t        t              } t        |       dfS )z(API endpoint for profile completion data   )r   r   r   )r  s    rz   get_profile_completionz4register_main_routes.<locals>.get_profile_completion	  s     2,?
z"C''r|   z"/unsubscribe/<int:user_id>/<token>c                    ddl m} ddlm}m} ddlm} 	  |j                  ||       }|st        dd       t        dd	      S |j                  j                  |j                  
      j                         }|r|D ]  }d|_        d|_         n; ||j                  |j                   dd      }|j"                  j%                  |       |j"                  j'                          t        dd       t        dd|      S # t(        $ r^}	|j"                  j+                          t,        j/                  dt1        |	              t        dd       t        dd	      cY d}	~	S d}	~	ww xY w)z!Handle email unsubscribe requestsr   r   r\  rh  z\Invalid unsubscribe link. Please contact support if you continue to receive unwanted emails.r   zauth/unsubscribe.htmlF)r  r  NT)r  r	  r^  email_enabledzYou have been successfully unsubscribed from marketing emails. You will still receive important account and transactional notifications.r  )r  r   zUnsubscribe error: zaAn error occurred while processing your unsubscribe request. Please try again or contact support.)r   r   r  r]  r   rs  r   verify_unsubscribe_tokenr   r   r]   r^   r_   r`   r^  r_  rn  r   r  r  r  r  r  r   r   )
r  rd  r   r]  r   r   r   prefsprefr  s
             rz   unsubscribez)register_main_routes.<locals>.unsubscribe  sL    	$T%"	K0400@Dtv}~&'>NN +00::477:KOOQE! -D).D&(,D%-
 . GG&6&J&J"'"&	 

t$JJ  ]  _h  i"#:DtTT 	KJJ!LL.s1vh78uw~"#:EJJ		Ks%   -C? B:C? ?	E&AE!E&!E&z/forgot-passwordc                     ddl m}  ddlm} ddlm} t        j                  dk(  r"t        j                  j                  d      dk(  nd}t        j                  r|st        t        d	            S t        j                  dk(  rut        j                  j                  d
d      j                         j                         }|st!        dd       t#        d      S | j$                  j'                  |      j)                         }|r	 |j+                         }|j,                  j/                          t        d|d      }|j0                  r|j0                   d|j2                   nd}|j5                  |j6                  ||      }	|	r#t8        j:                  j=                  d|        n"t8        j:                  j?                  d|        |r t!        dd       t        t        d	            S t!        dd       t#        d      S # t@        $ rF}
|j,                  jC                          t8        j:                  jE                  d|
        Y d}
~
d}
~
ww xY w)zHandle forgot password requestsr   r   rh  r`  r   from_settingsr   Fr   r   r   r/  r   zauth/forgot_password.htmlr2  reset_passwordTrc  r  NzPassword reset email sent to z)Email service not configured. Reset URL: zError generating reset token: zIPassword reset link has been sent to your email. Please check your inbox.r  zZIf this email is registered, a password reset link has been sent. Please check your inbox.)#r   r   rs  r   rp  ra  r   r  r  rT   r   rO  r   r	   r   re  r   r   r]   r^   rb   generate_reset_tokenr   r  r   r   send_password_reset_emailr   r
   r  r  r  r  r  r   )r   r   ra  r  r   r   rd  	reset_urlry  
email_sentr  s              rz   forgot_passwordz-register_main_routes.<locals>.forgot_password;  s    	$%< HO~~Y_G_((9VCej((GK011>>V#LL$$Wb1779??AE)73&'BCC::''e'4::<D S 557EJJ%%' !((8QU VIIM4??"31T^^4D E^bI "/!H!H

!!"J "#**//2OPUw0WX $**225^_h^i3jk aclm 455rt}~:;; ! SJJ'')&&,,/MaS-QRRSs   CH 	I<IIz/verify-email/<token>c                    ddl m} ddlm} t        j
                  r t        dd       t        t        d            S |j                  j                  |       j                         }|s t        dd	       t        t        d
            S |j                  |       s t        dd	       t        t        d
            S 	 d|_        d|_        d|_        |j                   j#                          t%        d      S # t&        $ rP}|j                   j)                          t        dt+        |       d	       t        t        d
            cY d}~S d}~ww xY w)z$Handle email verification with tokenr   r   rh  zYour email is already verified!r  r   )email_verification_tokenzQInvalid verification link. Please contact support if you continue to have issues.r   r  zMThis verification link has expired. Please register again or contact support.TNzauth/email_verified.htmlzError verifying email: )r   r   rs  r   r   rO  r   r   r	   r]   r^   rb   verify_email_tokenr6  r  email_verification_expiresr   r  r   r  r  r   )rd  r   r   r   r  s        rz   rb  z*register_main_routes.<locals>.verify_emailv  s    	$%((3V<GK011 zz##U#CIIKegnoGG,--&&u-acjkGG,--	."&D,0D).2D+JJ ##=>> 	.JJ!+CF84g>GG,--	.s   ;9C5 5	E>AE	E	Ez/reset-password/<token>c                    ddl m} ddlm} t        j
                  rt        t        d            S |j                  j                  |       j                         }|r|j                  |       s t        dd       t        t        d            S t        j                  d	k(  rt        j                  j!                  d
      }t        j                  j!                  d      }|rt#        |      dk  rt        dd       t%        d|       S ||k7  rt        dd       t%        d|       S 	 |j'                  |       |j)                          |j*                  j-                          t        dd       t        t        d            S t%        d|       S # t.        $ r_}|j*                  j1                          t2        j4                  j7                  d|        t        dd       t%        d|       cY d}~S d}~ww xY w)z Handle password reset with tokenr   r   rh  r   )password_reset_tokenz8Invalid or expired reset link. Please request a new one.r   r  r   r.  r>  rD  rE  zauth/reset_password.html)rd  rF  z>Your password has been reset successfully! You can now log in.r  r  zError resetting password: z$An error occurred. Please try again.N)r   r   rs  r   r   rO  r   r	   r]   r^   rb   verify_reset_tokenr   r   r  r  rT   r   r   rl  clear_reset_tokenr   r  r  r  r
   r  r   )rd  r   r   r   r.  r>  r  s          rz   r  z,register_main_routes.<locals>.reset_password  s    	$%((GK011 zz###?EEG42259LgVG$5677>>V#||''
3H&||//0BCs8}q0>H&'AOO++.8&'AOOP!!(+&&(

!!#VXab 011 9GG  P

##%""((+EaS)IJ<gF&'AOO	Ps    'AF 	G7AG2,G72G7z
/dashboardc                     ddl m}  t        j                  dk(  r1t        j                         \  }}|rd|v rt        t        d            S t        j                  dk(  rt        t        d            S t        j                  dk(  rt        t        d            S t        j                  d	k(  rt        t        d
            S y)Nr   )onboarding_requiredr   r  r  dashboard_workerr   dashboard_contractorsuper_admindashboard_admin)zInvalid roler   )r   r  r   r   r  r   r	   )r  r  r  s      rz   r   z'register_main_routes.<locals>.dashboard  s     	B (.:.K.K.M+m-#G,@$ABB(G$6788,.G$:;<<-/G$5677"r|   z/dashboard/contractorc                  (   ddl } 	 ddlm}m}m}m} ddlm} t        j                  rt        j                  dk7  rt        t        d            S g }g }g }g }	d}
d}t        j                         }	 |j                  j!                  t        j"                        j%                  |j&                  j)                               j+                         }t-        dt/        |       d	       	 |j2                  j                  |      j5                  |      j7                  |j8                  t        j"                  k(        j%                  |j:                  j)                               j+                         }t-        dt/        |       d       	 |j2                  j                  |      j5                  |      j7                  |j8                  t        j"                  k(  |j<                  dk(        j+                         }t-        dt/        |       d       	 |j                  j7                  |j8                  t        j"                  k(  |j<                  j?                  g d            j%                  |j@                  j)                               j+                         }	t-        dt/        |	       d       	 d}
|	D ]-  }|j<                  dv s|
tC        |jD                  xs d      z  }
/ t-        d|
        t/        |      }|j                  j5                  |      j7                  |jF                  t        j"                  k(  |jH                  jK                  d      |j<                  dk(        j%                  |jL                  j)                               jO                  d      j+                         }tQ        d|||||	|
||tS        d      z   |
      S # t0        $ r}t-        d
|        g }Y d}~d}~ww xY w# t0        $ r}t-        d|        g }Y d}~d}~ww xY w# t0        $ r}t-        d|        g }Y d}~.d}~ww xY w# t0        $ r}t-        d|        g }	Y d}~d}~ww xY w# t0        $ r}t-        d|        d}
Y d}~d}~ww xY w# t0        $ r}| jU                         }t-        dtW        |              t-        d|        jX                  j[                  dd      rd tW        |       d!| d"d#t]               v rt        j                  nd$ d%d#t]               v r t_        t        d&      rt        j                  nd$ d'd#t]               v r t_        t        d(      rt        j"                  nd$ d)d*fcY d}~S Y d}~y+d}~ww xY w),zContractor dashboardr   N)r   ri  r'   r  rh  r   r  r   u   âœ… Fetched z posted jobsu#   âŒ Error fetching posted jobs: z recent applicationsu+   âŒ Error fetching recent applications: r   z pending applicationsu,   âŒ Error fetching pending applications: r=   r>   r?   r@   rC   rD   r   z active contractsu(   âŒ Error fetching active contracts: )r@   rC   u%   âœ… Calculated pending payouts: $u*   âŒ Error calculating pending payouts: r   r  zdashboard/contractor.htmlr8   r1   )	r   total_applicationsrecent_applicationsr   r   r   todays_dateone_week_span
my_reviewsu   âŒ DASHBOARD ERROR: zFull traceback:
DEBUGFzM
                    <h1>Dashboard Error</h1>
                    <h2>Error: z</h2>
                    <pre>zy</pre>
                    <h3>Debug Info:</h3>
                    <ul>
                        <li>User authenticated: r   r  z-</li>
                        <li>User role: r   z+</li>
                        <li>User ID: r_   z4</li>
                    </ul>
                    r  )z.Internal server error. Please contact support.r  )0r<  r   r   ri  r'   r  rs  r   r   rO  r   r   r	   r   todayr]   r^   r_   r   r   r   r`   rN  r   r  r   r  r   r   date_appliedrf   in_r   rc   re   r!  r7  r   r3  r4  r   r   r  r   configrT   localsr   )r<  r   ri  r'   r  r   r   r  r   r   r   r  r  r  rD  r  error_detailsr  s                    rz   r  z2register_main_routes.<locals>.dashboard_contractor  s0    kQII-#448I8I\8Y#GG$455 !&(#')$#% "#%&""jjl%"%))"5"5LOO"5"T"]"]^a^m^m^r^r^t"u"y"y"{K,S-=,>lKL-*,***:*:;*G*L*LS*Q*X*X))\__<+h{77<<>? ( ,S1D-E,FFZ[\.+-::+;+;K+H+M+Mc+R+Y+Y))\__<#**i7, ce ) ,S1E-F,GG\]^*'/~~'<'< ..,//A ++  -c  d( hx22779:335 % ,S1A-B,CCTUV(&'O$4 P#??.JJ+uX5I5I5NQ/OOOP A/ARST
 &))<%="#\\..x8??OO|6&&,,T2OO{2 (6--2245eeAhssu	  ''B1<8J9L:N6F5D1<3>PQAR3R0:	< 	<o ! %?sCD"$K% ! -GsKL*,'- ! .HLM+-(. ! *DQCHI')$* ! (FqcJK&'O(.  Q ) 4 4 60Q9:)-9: ::>>'51   #Ax (' )1 SadjdlRl1N1Nr{0| }(=Kvx=W\cdprx\y(9(9  @I  (J J&9G689SX_`lnrXsloo  zC  &D D
 
 
 Q)Qs   AR  R 1A7O )B!O; BP" BQ	 4Q0 
,Q0 6CR 	O8O3-R 3O88R ;	PPR PR "	Q+Q;R QR 		Q-Q("R (Q--R 0	R9R	R RR 	V C!VVVz/dashboard/workerc            
      0   ddl } ddlm}m} ddlm}m} ddlm}m	}m
} 	 t        j                  rt        j                  dk7  rt        t        d            S t        j                          \  }}	|r0d|	v rt        t        d	            S d
|	v rt        t        d            S  |j"                         }
|j$                  j'                  t        j(                        j+                  |j,                  j/                               j1                         }|j$                  j3                  |j4                  t        j(                  k(  |j6                  j9                  g d            j+                  |j:                  j/                               j1                         }|j$                  j=                  |      j3                  |j>                  t        j(                  k(  |j@                  jC                  d      |j6                  dk(        j+                  |jD                  j/                               jG                  d      j1                         } |jH                         5  ddl%m&}  |d      }|jO                         }ddd        |d|
|
 |d      z   |||d      S # 1 sw Y   #xY w# tP        $ re}| jS                         }tU        dtW        |              tU        |       jX                  j[                  dd      rd| ddfcY d}~S Y d}~yd}~ww xY w)zWorker dashboardr   Nr   r   )r   r
   )ri  r'   r  r   r  r  r  rs   r  r:   r  r   r  )r{   rG   zdashboard/worker.htmlr8   r1   )r  r  r   r   r  
stats_dataview_periodu   ❌ WORKER DASHBOARD ERROR: r  Fz<pre>r^  r  r1  r  ).r<  r   r   r   rR   r   r
   r   ri  r'   r  r   rO  r   r   r	   r  r  r]   r^   r_   r   r  r   r`   r   r;   rf   r  r   r  r!  r7  r   r3  r4  test_request_contextapp.main_routesr{   r  r  r  rN  r   r  rT   )r<  r   r   r   r
   ri  r'   r  r  r  r  r   r   r  r{   stats_responser  r  r  r  s                      rz   r  z.register_main_routes.<locals>.dashboard_workerL  s    	,6<<4	000L4E4E4Q 011 /;.K.K.M+m-#G,@$ABB-/#G,@$ABB$$**,K&,,666QZZ[f[s[s[x[x[z{  BL'~~44""loo5## %   hx**//12335   **84;;<??2""((.;. hv))..01%%(335	  2113 75!*8!4+446
7
 #'')I1,==)!1%%$	 	7 7   	0%002M0Q9:- zz~~gu-}oV4c99/	0sI   6J' 0J' 	J' !F9J' J9!J' J$ J' '	L0ALLLz/dashboard/adminc                     ddl m} m} ddlm}m}m}m} ddlm	}m
}m}m}	m}
 ddlm} ddlm} ddl}	 t&        j(                  rt&        j*                  dk7  r |d	d
        | |d            S  | j,                         }|j.                  j1                         |j.                  j3                  d      j1                         |j.                  j3                  d      j1                         |j.                  j3                  d      j1                         |j.                  j1                         |j.                  j3                  d      j1                         |j.                  j1                         |j.                  j5                  |j6                  j9                  g d            j1                         |	j.                  j1                         |	j.                  j3                  d      j1                         |
j.                  j3                  d      j1                         |j:                  j/                  |j=                  |	j>                              j5                  |	j6                  dk(        jA                         xs dd}|j.                  jC                  |jD                  jG                               jI                  d      jK                         }|j.                  jC                  |jL                  jG                               jI                  d      jK                         }|j.                  jC                  |jN                  jG                               jI                  d      jK                         }tQ        d||||      S # tR        $ re}|jU                         }tW        dtY        |              tW        |       jZ                  j]                  dd      rd| ddfcY d}~S Y d}~yd}~ww xY w) z*Super Admin dashboard with system overviewr   r  )r
   r   r   r	   )r   r   r'   PaymentDisputerh  )funcNr  z)Access denied. Admin privileges required.r   r   Tr   r   r   r   r   rf   )r@   r=   r>   r?   r   )total_usersactive_userstotal_workerstotal_contractors
total_jobs	open_jobstotal_contractsr   total_paymentscompleted_paymentspending_disputestotal_payment_volumer"  zadmin/dashboard.html)statsrz  r{  recent_contractsu   ❌ ADMIN DASHBOARD ERROR: r  Fz#<h1>Admin Dashboard Error</h1><pre>r^  r  r  )/r   r   r   rR   r
   r   r   r	   r   r   r   r'   r  r  rs  r   r   r  r<  r   rO  r   r  r]   r;  r^   r   rf   r  r   r   gross_amountscalarr   date_createdr   r4  r`   r   r   r   r  r  rN  r   r  rT   )r   r   r
   r   r   r	   r   r   r'   r  r  r   r  r<  r  r  rz  r{  r  r  r  r  s                        rz   r  z-register_main_routes.<locals>.dashboard_admin  s    	-??DD%#-	000L4E4E4VA7K 455$$**,K  $zz//1 $

 4 4t 4 D J J L!%!5!58!5!D!J!J!L%)ZZ%9%9|%9%L%R%R%T!iioo/ YY000?EEG#+>>#7#7#9$,NN$9$9OO''(mn%%'")--"5"5"7&-mm&=&=[&=&Q&W&W&Y$+MM$;$;6$;$J$P$P$R(*

(8(8HHW112)&;67)FDE!E(  ::..t/@/@/E/E/GHNNqQUUWL)),,S__-A-A-CDJJ1MQQSK'~~66x7J7J7O7O7QRXXYZ[__a"#9)'!1	   	0%002M/Ax89- zz~~gu-<]O6RTWWW/	0s%   9N /LN 	O/
AO*O/*O/z/my-jobsc                     	 ddl m}  ddlm} t        j
                  dk(  rb| j                  j                  t        j                        j                  | j                  j                               j                         }d}n|j                  j                  t        j                        j                  |j                  j                               j                         }|D cg c]  }|j                  s|j                   }}d}t        ||	      S c c}w # t         $ rQ}j"                  j%                  d
t'        |              t)        dd       t+        t-        d            cY d}~S d}~ww xY w)zDisplay user's jobsr   r~   r&   r   r   jobs/employer_jobs.htmlr:   jobs/worker_jobs.htmlr   zError in my_jobs route: z&Unable to load jobs. Please try again.r   r   N)r   r   rQ   r'   r   r   r]   r^   r_   r   r   r   r`   r   r   r   r  r  r   r   r   r   r	   )r   r'   r   templaterq   rD  r  r  s          rz   my_jobsz%register_main_routes.<locals>.my_jobs  s)   6.8  $$499..\__.MVVWZWfWfWkWkWmnrrtD8H !) 8 8".// !9 !hx22779:335  :CSXhllHLLSDS6H&xd;; T  6

  #;CF8!DE>H 455	6s7   C$D 'D9DD D 	E7&AE2,E72E7z	/earningsc                  b    	 t        t        d            S #  t        t        d            cY S xY w)zRedirect to worker analyticsanalytics_workerpayoutsr   r	   rZ  r|   rz   earningsz&register_main_routes.<locals>.earnings  s/    
4(: ;<<4	 233s    .z/profilec                     t         j                  s t        dd       t        t	        d            S t         j
                  dk(  rIt        j                         \  } }| r0d|v rt        t	        d            S d|v rt        t	        d            S d	d
lm} t         j
                  dk(  rd	dl	m
} |j                  j                  t         j                        j                         }|j                  j                  t         j                  d      j                         }t        d||      S |j                  j                  t         j                  d      j                         }t        d|      S )z+User profile page - role-specific templatesz#Please login to access your profiler  r  r   r  r  rs   r  r   r&   r   r~   r   r@   r   zauth/contractor_profile.html)r   r   r   r&  zauth/worker_profile.html)rL   )r   rO  r   r   r	   r   r  rQ   r'   r   r   r]   r^   r_   r;  r   )r  r  r'   r   r   r   rL   s          rz   r  z%register_main_routes.<locals>.profile  sN     00;YG 011   H,2>2O2O2Q/ -# M1'0D(EFF"m3'0D(EFF 5  L0. "ii111PVVX#+>>#;#;".//# $< $ %' !
 ''E2=7GI I
 &^^55&//" 6  eg 
 ##=1?A Ar|   z/healthc                  N    ddt        j                         j                         dS )z+Simple health check for the web applicationhealthyz$RateRight web application is running)rf   r  	timestamp)r   r8  r   rZ  r|   rz   
app_healthz(register_main_routes.<locals>.app_health	  s'     $A%__.88: r|   z*/applications/<int:application_id>/respondc                    ddl m} ddlm} ddlm} t
        j                  dk7  r t        dd       t        t        d            S |j                  j                  |       }|j                  j                  t
        j                  k7  r t        d	d       t        t        d            S t        j                   d
k(  rt#        d|      S t        j$                  j'                  d      }|dk(  r'|j                  j)                         s t        dd       t        t        d            S d|_        |j                  j-                         }|r_|j                  j/                  |j0                  d      j3                  |j                  | k7        j5                         }|D ]	  }d|_         ddlm}	 ddlm}
m} |j                  j>                  r%|j                  j>                  j;                         }n |
j@                         }ddddddddddddd}|j                  jB                  }|j'                  |d      }| ||      z   }|jD                  }|j                  jF                  xs |j                  jH                  xs d}||n|}tK        d       tK        d|        tK        d |j                  jF                          tK        d!|j                  jH                          tK        d"|        |j                  jH                  rd#nd$}tL        j                  j'                  |j                  j                        }tL        j                  j'                  |jN                        } |	d]i d%|j0                  d&|j                  j                  d'|jN                  d(|r|jP                   d)|jR                   ndd*|r|jP                   d)|jR                   ndd+|r|jT                  ndd,|r|jV                  ndd-|r|jX                  ndd.|r|jZ                  ndd/|r|jT                  ndd0|r|jV                  ndd1|r|jX                  ndd2|r|jZ                  ndd3|d4|d5|d6|d7|j                  j\                  xs d8d9d:}|j^                  ja                  |       	 |j^                  jc                          tK        d;|j                          |	j                  j'                  |j                        }tK        d<|jd                          tK        d=tg        |jd                                	 ti        jj                  |jN                  tl        jn                  d>d?|j                  jp                   d@|j                   dAt        dB|j                  dCD      dEdFG       tK        dH|jN                          |j                  r t        t        dB|j                  J            S t        dKdL       t        t        d            S |dOk(  rd|_        	 ti        jj                  |jN                  tl        jx                  dPd?|j                  jp                   dQt        dRdCS      dTU       tK        dV|jN                          t        dX|jz                  jP                   d)|jz                  jR                   dYdZ       	 |j^                  jc                          t        t        d\            S # tr        $ r}tK        dI|        Y d}~Nd}~ww xY w# tr        $ r^}|j^                  ju                          t        dMtw        |       d       tK        dN|        t        t        d            cY d}~S d}~ww xY w# tr        $ r}tK        dW|        Y d}~d}~ww xY w# tr        $ rD}|j^                  ju                          t        d[d       t        t        d\            cY d}~S d}~ww xY w)^z2Accept or reject job application (contractor only)r   rh  r  r~   r   z-Only contractors can respond to applications.r   r   z7You can only respond to applications for your own jobs.r  zapplications/respond.html)r+  actionacceptz1This job has already reached its worker capacity.r  r  r   r  rf   r  r&   r  rA      rD  )r  r  r  r  r  r  4 hours8 hours10 hours2 days3-5 daysz1+ weeks   r1   Nz[?] Contract Rate Debug:z   Application proposed_rate: z   Job budget_max: z   Job hourly_rate: z   Final agreed_rate: hourlyr   r  r   r;   r)  r  worker_namecontractor_emailcontractor_phonecontractor_abncontractor_business_nameworker_emailworker_phone
worker_abnworker_business_namere   	rate_typer  end_datescope_of_workz Contract work as per job postingrf   r=   z&[?] Contract created successfully: ID z/[?] VERIFICATION - Saved contract agreed_rate: z([?] VERIFICATION - Saved contract type: Application Accepted!Your application for '' was accepted. Contract # created and ready for review.contracts_reviewFcontract_idr  r  
job_alerts)r  r	  r   r  r  priorityr   z=[NOTIFICATION] Contract creation notification sent to worker z;[NOTIFICATION ERROR] Failed to send contract notification: r  z@Contract created but ID assignment failed. Check your dashboard.r  zError creating contract: zContract creation error: rejectzApplication Updatez' was not accepted this time.r  )r  r"  r  r	  r   r  r  r  zA[NOTIFICATION] Application rejection notification sent to worker z<[NOTIFICATION ERROR] Failed to send rejection notification: zApplication from z
 rejected.r  z-Error updating application. Please try again.applications_contractorrZ  )>rs  r   r   ri  r   r   r   r   r   r	   r]   r   r   r   r_   r   r  r   r  rT   has_space_for_workersrf   increment_accepted_workersr^   r  r   r`   r'   r   r   r   r  r  r  r#  r  r  rN  r   r;   r   r   r   r   r   business_namer  r   r  r  re   r-   r   r  r   CONTRACT_AWARDEDr   r  r  r   r)  r   )application_idr   ri  r   r+  r  is_job_fullother_applications	other_appr'   r   r   r  duration_days_mapr  days_to_addr  r#  fallback_rate
final_rater  r   r   rD  saved_contractr  r  s                              rz   respond_to_applicationz4register_main_routes.<locals>.respond_to_application#	  s    *.&  L0EwO 455%++66~FK ,,?OQXY 455~~&&'BP[\\\\%%h/F!"<<>MwW#G,B$CDD%/" *ooHHJ)4):):)D)D*11( *E * f[^^~=>ssu '
 &8 6	+5	(6 04 ??11!,!?!?!D!D!FJ!+J
 !" ! ! !#$   ! ! !%!" '??33/33HbA &	{(CC !, 9 9 + : : ^koo>Y>Y ^]^.;.G]]
026}oFG+KOO,F,F+GHI,[__-H-H,IJK.zl;< )4(C(CH	 "ZZ^^KOO,I,IJ
(=(=> $ &--"-//"?"? *33 Zdz'<'<&=Qz?S?S>T$Uim	
 NT6#4#4"5Qv7G7G6H IY] :DZ%5%5 AKZ%<%<PT =G:#8#8D JTZ-E-EY] 28T 9?!4!4D 5;v00 BH)=)=T !+ (   *!" &#$ #.//"="="cAc%& /'. 

x($EJJ%%'B8;;-PQ &.^^%7%7%DNKNLfLfKghiDT.JdJdEeDfghr,>>$/$9$9.>.O.O"9&<[__=R=R<SSmnvnynymz  {Y  %Z'./Ax{{fk'l%&%1  ]^i^s^s]tuv
  {{'0BPXP[P[(\]]`bkl'0F(GHH 8#%/"o(:: + 5 5*:*Q*Q2"89N9N8OOl m#*=E#J!" ]^i^s^s]tuv )+*<*<*G*G)H+J\J\JfJfIggqrtz{D

!!# G$=>??W % r [\n[opqqr ! EJJ'')5c!fX>H5aS9:#G,B$CDD	E( ! oXYkXlmnno  D

##%EwO(A BCCDs   0B\ B[9 +\ 4\ !A.^ ^- 9	\\\ \\ 	^'A^ :^ ^	^*^%%^*-	_:69_5/_:5_:z#/contracts/<int:contract_id>/reviewc                    ddl m} ddlm} ddlm} ddlm} ddlm	} |j                  j                  |       }t        j                  |j                  |j                  fvr t!        dd       t#        t%        d	            S 	 |j'                  |       }|r|j)                  d
d      sdddddddg d}|j                  j/                  |       j1                         }	g }
|	D ]  }|j                  j)                  |j2                        }|j                  j)                  |j4                        }|
j7                  |||j8                  |j:                  |j<                  |j>                  |j@                  |j@                  |jB                  dd
        tE        d||
|      S # t*        $ r%}t-        d|        dddddddg d}Y d }~d }~ww xY w)Nr   r&   r  r   rh  time_tracking_service(You do not have access to this contract.r   r   r  Fpending_entriesapproved_entriestotal_hourstotal_regular_hourstotal_overtime_hoursr  summaryentriesError loading hours data: r  T
rC  revieweeoverall_ratingquality_ratingcommunication_ratingreliability_ratingprofessionalism_ratingsafety_ratingr%  would_work_againcontracts/review.html)rD  r0  
hours_data)#r   r'   r2  r  r   r   rs  r   "app.services.time_tracking_servicer1  r]   r   r   r_   r   r;   r   r   r	   get_contract_hoursrT   r  rN  r^   r`   r5  r!  r   r6  quality_scorecommunication_scorereliability_scoreprofessionalism_scorer7  r   )r  r'   r  r   r   r1  rD  rG  r  ratingsr0  r$  rC  r>  s                 rz   r  z.register_main_routes.<locals>.contracts_review	  s    	(,(%L>>,,[9 ??8#9#98;M;M"NN<gFGK011	.AA+NJZ^^Iu%E$+,,-'(/001   "

4 ,,(([(AEEG 	Fzz~~foo6Hzz~~foo6HNN$$"("6"6"("6"6(.(B(B&,&>&>*0*F*F!'!=!=!--$( 	  #!	
 	
E  	.qc23 '(()#$+,,- 
J	s   1F" "	G+GGz!/contracts/<int:contract_id>/signc           	      h   ddl m} ddlm} ddlm} ddl}ddl}|j                  j                  |       j                  t        j                        s"t        dd       t        t        d| 	            S t        j                  j                   k(  rd
_        n$t        j                  j$                  k(  rd
_        t(        j*                  dk(  rq	 t(        j,                  j/                  d      }|rvd}|j1                  |d
       d|v r|j3                  d      d   }d|  dt        j                   d}|j4                  j7                  ||      }	t9        |	d      5 }
|
j;                  |j=                  |             ddd        |       }|j?                  | t        j                  |	d      }t@        jB                  jE                  d|        |r|j4                  jG                  |      rw	 ddl$m%}  |       }|jM                  ||       }|r2t@        jB                  jE                  d|  d|        t        dd       n#t@        jB                  jO                  d|  d       jW                  t        j                        }|re|jX                  j[                          dd!l.m/} fd"} ||#      ja                          jb                  d$k(  rt        d%d       nt        d&d       nt        d'd       t(        jd                  j/                  d)      d*k(  rtg        d
d0d1      S t        t        d| 	            S ti        d2d
3      S # 1 sw Y   xY w# tP        $ r9}t@        jB                  jS                  d|  d tU        |              Y d}~0d}~ww xY w# tP        $ r}t@        jB                  jS                  d(tU        |              t(        jd                  j/                  d)      d*k(  rtg        d+tU        |      d,      d-fcY d}~S t        d.d/       Y d}~,d}~ww xY w)4z:Enhanced signing with signature capture and PDF generationr   r&   rh  )ContractPDFServiceNz+You cannot sign this contract at this time.r   r  r  Tr   	signaturezcontracts/signatures)exist_okzdata:image/png;base64,r  rA   
signature_rS  z.pngwb)r  r  signature_filerD  zGenerated signed contract PDF: DriveOAuthServicez	Contract z( successfully uploaded to Google Drive: z9Contract PDF uploaded to Google Drive for secure storage.r  z!Drive upload failed for contract z - OAuth may need renewalz Drive upload error for contract : )Threadc                     j                   dk(  r	 t        j                  j                  k(  rot	        j
                  j                  t        j                  ddj                   dj                  j                   dt        dj                  d      d	
       nnt	        j
                  j                  t        j                  ddj                   dj                  j                   dt        dj                  d      d	
       t        d       y 	 t        j                  j                  k(  rj                  nj                  }t	        j
                  |t        j                  ddj                   dj                  j                   dt        dj                  d      d	
       t        d|        y # t        $ r} t        d|         Y d } ~ y d } ~ ww xY w# t        $ r} t        d|         Y d } ~ y d } ~ ww xY w)Nr@   zContract Fully Signed!z
Contract # for 'z ' is now active. Work can begin!r  Fr  r  r  z' is now active.z4[NOTIFICATION] Contract activation notification sentz=[NOTIFICATION ERROR] Failed to send activation notification: z Contract Awaiting Your Signaturez=' has been signed by the other party. Please review and sign.z<[NOTIFICATION] Contract signature notification sent to user z<[NOTIFICATION ERROR] Failed to send signature notification: )rf   r   r_   r   r   r  r;   r   r$  r   r   r	   rN  r  )r  other_party_idrD  s     rz   send_contract_notificationszQregister_main_routes.<locals>.contracts_sign.<locals>.send_contract_notifications{
  s   #??h6|#/??h6L6L#L$8$J$J080B0B:J:[:[.F2<X[[MPXP\P\PbPbOc  dD  1E3:;M[c[f[frw3x12%& %9$J$J080F0F:J:[:[.F2<X[[MPXP\P\PbPbOccs0t3:;M[c[f[frw3x12%& !&(\ ^
{GSZbZpZpGp1C1Cv~  wM  wM 4 F F,:6F6W6W*L.8VHLLL^L^K_  `]  -^/67IW_WbWbns/t-.!" !&(desdt&u v $- | %(efxey&z { {| $- { %(dewdx&y z z{s1   DG B'G& 	G#GG#&	H/HH)targetr@   z,Contract fully executed! Work can now begin.z6Contract signed successfully. Waiting for other party.zFailed to sign contract.zSignature processing error: zX-Requested-WithXMLHttpRequestFr  r   r  z<Signature processing failed, but contract signing completed.r  zContract signed successfullyr  rF  )rD  show_sign_form)5r   r'   rs  r   app.services.pdf_servicerP  base64r  r]   r   can_signr   r_   r   r   r	   r   contractor_reviewedr;   worker_reviewedr   r  r  rT   makedirsrf  rL  r  r   write	b64decodegenerate_contract_pdfr
   r  r  exists app.services.drive_oauth_servicerW  upload_signed_contractr  r  r   r   sign_contractr   r  	threadingrY  startrf   r  r   r   )r  r'   r   rP  rc  r  signature_datasignatures_dirsignature_filenamesignature_pathfpdf_servicepdf_pathrW  drive_service
drive_linkdrive_errorr  rY  r]  r  rD  s                        @rz   contracts_signz,register_main_routes.<locals>.contracts_sign*
  s    	(%?>>,,[9  1?IG$6KPQQ ??h444+/H(__ 2 22'+H$>>V#ta!(!1!1+!>!%;NKKK> 0>A)7)=)=c)B1)E ,6k]!LOOCTTX)Y&%'WW\\.BT%UNnd3 Bq 0 0 @AB #5"6K*@@'2#/??*8$,	B  H  &&++.MhZ,XY  BGGNN8$<!Z,=,?M)6)M)MhXc)dJ) + 2 2 7 7)K=Px  zD  yE  9F  !G %&acl m + 2 2 : :=^_j^k  lE  <F  !G #00AJJ%%' 1){X "=>DDF(2LiXVXab4g> ""#56:JJ4<Z[\\G$6KPQQ 6Z^__YB B8  ) !'..447WXcWddfgjkvgwfx5yz !D  a""((+GAx)PQ??&&'9:>NN"us1v#FGLLTV_``ask   BN& $!MA2N& 8A6M! .BN& MN& !	N#*.NN& N##N& &	P1/A%P,P1P,,P1z*/contracts/<int:contract_id>/mark-completec                    ddl m} ddlm} |j                  j                  |       }|j                  t        j                  k7  r"t        dd       t        t        d|             S |j                  dk7  r"t        d	d       t        t        d|             S d
|_        |j                  j                  d      j                         }|rd|_        d|_        |j"                  j%                          	 t'        j(                  |j*                  t,        j.                  dd|j                   d|j0                  j2                   dt        d|j                  d      d       t5        d|j*                          t        dd       t        t        d|             S # t6        $ r}t5        d|        Y d}~>d}~ww xY w)z&Worker marks contract work as completer   r&   rh  z*Only the worker can mark work as complete.r   contract_closeoutr  r@   z)Contract must be active to mark complete.rC   held_escrowr  pending_releaseTzWork Marked Completez-Worker has marked work complete on contract #r[  z'. Please review.Fr  r  r  z?[NOTIFICATION] Work completion notification sent to contractor z=[NOTIFICATION ERROR] Failed to send completion notification: Nz5Work marked as complete - awaiting contractor review.r  )r   r'   rs  r   r]   r   r;   r   r_   r   r   r	   rf   ra   r^   rb   release_conditions_metr   r  r   r  r   r   CONTRACT_COMPLETEDr   r   rN  r  )r  r'   r   rD  rs   r  s         rz   mark_contract_completez4register_main_routes.<locals>.mark_contract_complete
  s    ,)~~00=H !!\__4BGL(; UVV(*A7K(; UVV /HO ''111GMMOG!215.JJl$66$22&6&I&I0KHKK=X^_g_k_k_q_q^r  sD  E&':_de WX`XnXnWopq I9UG$7[QRR	  lUVhUijkkls   4BF 	F=%F88F=z//contracts/<int:contract_id>/approve-completionc                    ddl m} ddlm} ddlm} ddlm} |j                  j                  |       }|j                  t        j                  k7  r"t        dd       t        t        d| 	            S |j                  d
k7  r"t        dd       t        t        d| 	            S |j!                  | t        j                        }|d   su|j#                  d      r?|j%                  |       }|d   rt        t        d| 	            S t        d|d    d       nt        |d   d       t        t        d| 	            S |j&                  j)                  d      j+                         }|rbd|_         |j,                         |_        	 |j1                         }	|	r2t3        d|	j4                          t        d|	j4                   dd       |j9                           |j,                         |_        |j<                  j?                          t        dd       t        t        d| 	            S # t6        $ r}
t3        d|
        Y d}
~
~d}
~
ww xY w)z?Contractor approves work completion - ENFORCES MANDATORY RATINGr   r&   rh  rating_servicerj  z+Only the contractor can approve completion.r   r}  r  rC   *Contract is not pending completion review.can_completerequires_ratingr  rate_contractz%Error transitioning to rating stage: r  r  releasedu   📄 Auto-generated invoice: zInvoice z" has been automatically generated.r  u"   ⚠️ Invoice generation failed: NzXWork approved and payment released successfully! Contract completed with mutual ratings.) r   r'   rs  r   app.services.rating_servicer  r   r]   r   r   r   r_   r   r   r	   rf   $validate_contract_completion_requestrT   #transition_contract_to_rating_stagera   r^   rb   r8  date_releasedauto_generate_invoicerN  invoice_numberr  mark_as_completedrg   r   r  )r  r'   r   r  r   rD  completion_validationrating_transitionrs   invoiceinvoice_errors              rz   approve_contract_completionz9register_main_routes.<locals>.approve_contract_completion
  s!    ,)B)~~00=H %%8CWM(; UVV"22BGL(; UVV %3$W$W\__%! )8(,,->?(6(Z(Z[f(g%(3  ([(YZZ EFWX_F`Eabdkl/8'B(; UVV ''119J1KQQSG!+(7(9%P%;;=G =g>T>T=UVW)?)?(@@bcekl
 &&(4CHOO4EH1JJlnwxG$7[QRR ! P>}oNOOPs   AH. .	I7I

Iz//contracts/<int:contract_id>/dispute-completionc                 b   ddl m} ddlm} |j                  j                  |       }|j                  t        j                  k7  r"t        dd       t        t        d|             S |j                  dk7  r"t        d	d       t        t        d|             S t        j                  j                  d
d      }d|_        |j                   j#                  d      j%                         }|rd|_        |j&                  j)                          t        d| d       t        t        d|             S )z#Contractor disputes work completionr   r&   rh  z+Only the contractor can dispute completion.r   r}  r  rC   r  reasonzWork does not meet requirementsdisputedr  r  zCompletion disputed: r  )r   r'   rs  r   r]   r   r   r   r_   r   r   r	   rf   r   r  rT   ra   r^   rb   r   r  )r  r'   r   rD  dispute_reasonrs   s         rz   dispute_contract_completionz9register_main_routes.<locals>.dispute_contract_completion.  s     ,)~~00=H %%8CWM(; UVV"22BGL(; UVV$\\--h8YZN )HO ''119J1KQQSG!+JJ).)9:IFG$7[QRRr|   z
/contractsc                     ddl m}  t        j                  dk(  rat        j                         \  }}|rHd|v r t        dd       t        t        d            S d|v r t        d	d       t        t        d
            S t        j                  dk(  r`| j                  j                  t        j                        j                  | j                  j                               j                         }n_| j                  j                  t        j                        j                  | j                  j                               j                         }t        d|      S )z#List all contracts for current userr   r&   r   r  r  r  r  rs   r  r  r   r   r:   contracts/list.html)rq   )r   r'   r   r   r  r   r   r	   r]   r^   r_   r   r   r   r`   r   )r'   r  r  rq   s       rz   contracts_listz,register_main_routes.<locals>.contracts_listN  s    ,   H,2>2O2O2Q/ -# M1I9U'0D(EFF"m3I9U'0D(EFF  L0$NN44<??4S\\]e]p]p]u]u]wx||~	$NN44|4OXXYaYlYlYqYqYstxxz	"#8INNr|   z)/applications/<int:application_id>/acceptc                    ddl m}m} ddlm}m} t        j                  rt        j                  dk7  r t        dd       t        t        d            S |j                  j                  |       }|j                  j                  t        j                   k7  r t        dd       t        t        d	            S |j"                  d
k7  r t        dd       t        t        d	            S 	 d|_        d|j                  _         |j$                          |d      z   }| |d      z   }t&        j                  j)                  |j*                        } |d=i d|j,                  dt        j                   d|j*                  dt        j.                   dt        j0                   d|r|j.                   d|j0                   nddt        j2                  dt        j4                  dt        j6                  dt        j8                  d|r|j2                  ndd|r|j4                  ndd|r|j6                  ndd |r|j8                  ndd!|j:                  |j:                  n1|j                  j<                  xs |j                  j>                  xs d"d#d$d%|d&|d'|j                  j@                  d(d)d*d+}	tB        jD                  jG                  |	       |j                  jI                  |j,                  d
,      jK                  |j                   | k7        jM                         }
|
D ]	  }d-|_         tB        jD                  jO                          	 tQ        jR                  |j*                  tT        jV                  d.d/|j                  jX                   d0|	j                    d1t        d2|	j                   d34      d56       t[        d7|j*                          t        d9|	j                    d:d;       t        t        d	            S # t\        $ r}t[        d8|        Y d}~Jd}~ww xY w# t\        $ r@}tB        jD                  j_                          t        d<ta        |       d       Y d}~|d}~ww xY w)>z,Accept a job application and create contractr   )ri  r'   r  r   z(Only contractors can accept applicationsr   r  z2You can only accept applications for your own jobsapplications_contractor_listr   z&Application has already been processedr  r  assignedr8   r1      r  r   r;   r)  r  r  Nr	  r
  r  r  r  r  r  r  re   g     @r  r   r  r  r  payment_termsr  rf   r=   r  r  r  r  r  z	 created.r  Fr  r  )r  r	  r   r  r  r   z?[NOTIFICATION] Contract acceptance notification sent to worker zF[NOTIFICATION ERROR] Failed to send contract acceptance notification: z Application accepted! Contract #r  r  zError accepting application: rZ  )1r   ri  r'   r   r   r   r   rO  r   r   r   r	   r]   r   r   r   r_   rf   r  r   rT   r;   r  r   r   r   r   r   r#  r#  r  r  r  r   r   r  r^   r   r`   r  r   r  r   r$  r   rN  r  r  r   )r%  ri  r'   r   r   r+  r  r  r   rD  r'  r(  r  r  s                 rz   accept_applicationz0register_main_routes.<locals>.accept_applicationf  sq    9000L4E4E4U@'J 011%++66~FK ,,?JGT(F GHH!!Y.>	J(F GHHGI%/" *4& (TZZ\I1,==
%	r(:: (=(=># &--".// *33 (4'>'>&?qAWAW@X$Y	
 NT6#4#4"5Qv7G7G6H IY] &2%7%7 &2%>%> $0#:#: .:-G-G 28T 9?!4!4D 5;v00 BH)=)=T >I=V=V=b 9 9itixix  jD  jD  jn  HS  HW  HW  Hc  Hc  jn  gn &   *!" &#$ #.//"="=%& #/'( /). 

x( &1%6%6%@%@&--$ &A & &>9:335 #
 "4 2I'1I$2 

!!#y(:: + 5 5*:*K*K5"89N9N8OOijrjujuivv  !A#*+=8;;bg#h!- [\g\q\q[rst
 8Ecdfop G$BCDD ! ybcubvwxxy  I

##%5c!fX>HHIsD   &I2P1 BP P1 	P.P)$P1 )P..P1 1	Q::6Q55Q:z./api/contracts/<int:contract_id>/time-trackingc                    ddl m} ddlm} |j                  j                  |       }t        j                  |j                  |j                  fvrt        ddi      dfS t        j                  j                  | |j                        j                  t        j                  j                               j!                         }t#        d |D              }t#        d	 |D              }t#        d
 |D              }|D cg c]A  }|j$                  t'        j(                         j+                         t-        d      z
  k\  s@|C }	}t#        d |	D              }
t        j                  j                  | |j                  d      j/                         }t        t1        |d      t1        |d      t1        |d      t1        |
d      t3        |      |r|j                  j5                         nd|r|j                  nd|dd D cg c]  }|j                  |j$                  j7                  d      |j                  j7                  d      |j8                  r|j8                  j7                  d      nd|j:                  xs d|j<                  xs d|j:                  xs d|j<                  xs dz   |j>                  xs d|j@                  xs d|jB                  rdndd
 c}d      S c c}w c c}w )z5API endpoint to get time tracking data for a contractr   r&   rh  r   Access deniedr   )r  r;   c              3   <   K   | ]  }|j                   xs d   ywr   N)overtime_hoursrR  entrys     rz   rV  zBregister_main_routes.<locals>.time_tracking_api.<locals>.<genexpr>  s     REe227a7R   c              3   <   K   | ]  }|j                   xs d   ywr  )regular_hoursr  s     rz   rV  zBregister_main_routes.<locals>.time_tracking_api.<locals>.<genexpr>  s     P%U005A5Pr  c              3   ^   K   | ]%  }|j                   xs d |j                  xs d z    ' ywr  r  r  r  s     rz   rV  zBregister_main_routes.<locals>.time_tracking_api.<locals>.<genexpr>  s-     mW\5..3!8L8L8QPQRm   +-r8   r1   c              3   ^   K   | ]%  }|j                   xs d |j                  xs d z    ' ywr  r  r  s     rz   rV  zBregister_main_routes.<locals>.time_tracking_api.<locals>.<genexpr>  s,     lV[%--2u7K7K7PqQlr  Nr  r;   	clock_outrJ   r"  r  z%H:%Mr   approvedr   )
r_   r   r  end_timer  r  r6  break_minutesr  rf   )total_regulartotal_overtimer6  
week_hoursis_clocked_inclock_in_timeactive_entry_idrecent_entries)"r   r'   rs  r   r]   r   r   r_   r   r;   r   r   r^   r   clock_inr   r`   r   	work_dater   rV   r   r   rb   rh   r   r   r   r  r  r  total_break_minutesr  is_approved)r  r'   r   rD  time_entriesr  r  r6  r  week_entriesr  active_entrys               rz   time_tracking_apiz/register_main_routes.<locals>.time_tracking_api  s   
 	(%>>,,[9 ??8#9#98;M;M"NNG_56;; !00#(( 1 
 (9%%**,
-cce 	 R\RRP<PPm`lmm+7z%5??x||~ObObOdgpvwgxOx;yzzl_kll
 !00#(( 1 
 %'	 	 "=!4#NA6 a0
A.!,/BN\22<<>TX2>|D (+-  hh00<#nn55g>AFEOO44W=VZ!&!4!4!9"'"6"6";! % 3 3 8qU=Q=Q=VUVW!&!:!:!?a$006B(-(9(9*y  -
  	 {$-s   =AK$?K$?CK)z)/api/contracts/<int:contract_id>/clock-inc           
         ddl m} ddlm} |j                  j                  |       }t        j                  |j                  k7  rt        ddi      dfS t        j                  j                  | t        j                  d      j                         }|rt        dd	i      d
fS t        | t        j                  t        j                         j                         t        j                          t"        j$                  j'                  dd            }|j(                  j+                  |       |j(                  j-                          t        d|j                  |j.                  j1                         d      S )zClock in for a contractr   r&   rh  r   zOnly the worker can clock inr   Nr  zAlready clocked inr  r  r   )r  r;   r  r  r  T)r  entry_idr  )r   r'   rs  r   r]   r   r   r_   r;   r   r   r^   rb   r   rV   r   r8  r   rt  rT   r   r  r  r  r   )r  r'   r   rD  r  r  s         rz   clock_in_apiz*register_main_routes.<locals>.clock_in_api  s+    	(%>>,,[9 ??h000G%CDEsJJ !00#"oo 1 
 %'	 	 G%9:;S@@ #"oolln))+__&((;
 	

u


002
  	r|   z*/api/time-entries/<int:entry_id>/clock-outc                 J   ddl m} t        j                  j	                  |       }|j
                  t        j                  k7  rt        ddi      dfS |j                  rt        ddi      dfS t        j                         |_	        t        j                  j                  d|j                        |_        |j!                          |j"                  j%                          t        d	|j                  j'                         |j(                  xs d|j*                  xs dz   d
      S )zClock out of current time entryr   rh  r   r   r   zAlready clocked outr  r  T)r  r  r6  )rs  r   r   r]   r   r;   r   r_   r   r  r   r8  r   rt  rT   r  calculate_total_timer   r  r   r  r  )r  r   r  s      rz   clock_out_apiz+register_main_routes.<locals>.clock_out_api(  s     	&**84 ??loo-G^45s::??G%:;<cAA #//+#LL,,]E<M<MN""$


224!//419M9M9RQRS
  	r|   z&/api/time-entries/<int:entry_id>/breakc                    ddl m} t        j                  j	                  |       }|j
                  t        j                  k7  rt        ddi      dfS |j                  rt        ddi      dfS |j                  r|j                  s|j                         }d}n|j                         }d	}|r3|j                  j                          t        d
||j                   d      S t        ddi      dfS )zToggle break for a time entryr   rh  r   r   r   z$Cannot modify breaks after clock outr  break_endedbreak_startedT)r  rf   r  zInvalid break operation)rs  r   r   r]   r   r;   r   r_   r   r  break_start	break_end	end_breakstart_breakr   r  r  )r  r   r  r  rf   s        rz   toggle_break_apiz.register_main_routes.<locals>.toggle_break_apiD  s     	&**84 ??loo-G^45s::??G%KLMsRR U__oo'G"F '')G$FJJ ','@'@   G%>?@#EEr|   z/contracts/<int:contract_id>c                    ddl m} ddlm} ddlm} ddlm} ddlm	} |j                  j                  |       }t        j                  |j                  |j                  fvr t!        dd       t#        t%        d	            S 	 |j'                  |       }|r|j)                  d
d      sdddddddg d}|j                  j/                  |       j1                         }	g }
|	D ]  }|j                  j)                  |j2                        }|j                  j)                  |j4                        }|
j7                  |||j8                  |j:                  |j<                  |j>                  |j@                  |j@                  |jB                  dd
        t-        d|  d       t-        d|jD                  jF                   dtI        |jD                  jF                        jJ                   d       	 tM        |jD                  jF                        }t-        d|        tS        |jT                        |z  }t-        d$|        t-        d$|        t-        d%|jT                          t-        d&|        |jV                  }|r|jX                  nd}|r|d'z  }||z   }nd}|}t[        d(|||
|||||)	      S # t*        $ r%}t-        d|        dddddddg d}Y d}~-d}~ww xY w# tN        tP        f$ rt}t-        d|        ddddddddddddd }|j)                  |jD                  jF                  d      }t-        d!|jD                  jF                   d"| d#       Y d}~Jd}~ww xY w)*z Review contract details and signr   r&   r  r   rh  r0  -You are not authorized to view this contract.dangerr   r  Fr3  r9  r<  Nr  Tr=  u#   🔍 DEBUG Payment Calc - Contract :z   Job duration (raw): 'z	' (type: )u)      ✅ SUCCESS: Parsed as numeric hours: u      ❌ FAILED to parse as int: r   r  r'         (   r  r  r  r  r  r  r  r  r  r  r  z1 week+z   Using mapping: u    → z hoursz   Hours calculated: z
   Rate: $z   Base payment: $皙?rF  )rD  rG  r0  hoursbase_payment
gst_amounttotal_paymentworker_gst_registered).r   r'   r2  r  r   r   rs  r   rH  r1  r]   r   r   r_   r   r;   r   r   r	   rI  rT   r  rN  r^   r`   r5  r!  r   r6  rJ  rK  rL  rM  r7  r   r  r-   rw  rU   r   r  rc   re   r   r   r   )r  r'   r  r   r   r1  rD  rG  r  rN  r0  r$  rC  r>  r  r  r  r   r  r  r  s                        rz   contract_reviewz-register_main_routes.<locals>.contract_reviewg  s    	(,(%L>>,,[9 ??8#9#98;M;M"NNA8LGK011	.AA+NJZ^^Iu%E$+,,-'(/001   "

4 ,,(([(AEEG 	Fzz~~foo6Hzz~~foo6HNN$$"("6"6"("6"6(.(B(B&,&>&>*0*F*F!'!=!=!--$( 	$ 	3K=BC()>)>(?yhllNcNcIdImImHnnopq	R--.E=eWEF* X112U: 	%eW-.%eW-.
8//012"<.12 9? 5 5U %,J(:5MJ(M #!%!'"7

 
	
c  	.qc23 '(()#$+,,- 
J	R I& 	R3A378!N #&&x||'<'<a@E&x||'<'<&=U5'PQQ%	Rs1   1J8 0-K) 8	K&K!!K&)M,8A)M''M,z%/contracts/<int:contract_id>/closeoutc                 z   ddl m} ddlm} |j                  j                  |       }t        j                  |j                  |j                  fvr t        dd       t        t        d            S t        |j                        dk(  r,t        dd       t        t        d|j                  	            S dd
lm} |j"                  }|r|j$                  nd}|j&                  j)                         }d}d}	d}
|r4|d   }|j*                  }
|r|
 |d      z  }| |d      z  }	n
|
} |d      }	t-        d||||	|
      S )zContract close-out interfacer   r&   rh  r  r   r   zGYou must have at least one time entry before marking the work complete.r  r  r  FNz1.10z0.10rM  zcontracts/closeout.html)rD  r  base_amountr  total_amount)r   r'   rs  r   r]   r   r   r_   r   r;   r   r   r	   r   r  r  r  r   r   ra   r`   r  r   )r  r'   r   rD  r  r   r  payment_listr  r  r  rs   s               rz   r}  z/register_main_routes.<locals>.contract_closeout  s:    	(%>>,,[9 ??8#9#98;M;M"NNA7KGK011 x$$%*[]deG$6HKKPQQ 	$9? 5 5U  ((,,.
"1oG"//L %*WV_<(76?:
*$S\
 8&.3H)4(2*68 	8r|   z!/contracts/<int:contract_id>/ratec                 8   ddl m} ddlm} ddlm} |j                  j                  |       }|j                  | t        j                        }|d   s%t        |d   d       t        t        d|             S t        j                  d	k(  r	 t!        t        j"                  j%                  d
            }t!        t        j"                  j%                  d            }t!        t        j"                  j%                  d            }t!        t        j"                  j%                  d|            }	t!        t        j"                  j%                  d|            }
t        j"                  j%                  dd      j'                         }||||	|
g}|D ]*  }d|cxk  rdk  rn t        dd       t)        d|      c S  ||||	|
|dd}|j+                  | t        j                  |      }|d   rqt        |d   d       |j,                  j/                  |       |j0                  dk(  rt        t        d|             S t        dd       t        t        d|             S t        d|d    d       t)        d|      S |j:                  r|j:                  j=                         nd }t)        d||!      S # t2        t4        f$ r#}t        dd       t)        d|      cY d }~S d }~wt6        $ r/}t        dt9        |       d       t)        d|      cY d }~S d }~ww xY w)"zGRate contract performance (both parties can rate) - USES RATING SERVICEr   r&   r  rh  can_rater   r  r  r   r?  r@  rA  rB  rC  r%  r   rA   r"  z$All ratings must be between 1 and 5.zcontracts/rate.html)rD  T)r6  rJ  rK  rL  rM  r7  	is_publicr  r  r   view_ratingszVThank you for your rating! Waiting for the other party to rate before payment release.r  zError submitting rating: zInvalid rating values provided.N)rD  rs   )rQ   r'   r  r  rs  r   r]   r   validate_rating_eligibilityr   r_   r   r   r	   r   r  rU   r  rT   r   r   create_ratingr   refreshrf   r   r  r  r   ra   rb   )r  r'   r  r   rD  eligibilityr?  r@  rA  rB  rC  r%  rating_valuesr$  rating_dataresultr  rs   s                     rz   r  z+register_main_routes.<locals>.rate_contract  s    5B)~~00=H )DD[R^RaRabKz*k'*G4(: TUU~~'3U%()9)9:J)K%LN%()9)9:J)K%LN+.w||/?/?@V/W+X(),W\\-=-=>RTb-c)d&-01A1ABZ\j1k-l*%ll..y"=CCEG &4^EY[m  pF  %GM"/ ] !V 0q 0!"H'R#23HS[#\\] *8)7/C-?1G'.%)#K ,99+|XcdFi(fY/; 

**84#??k9#+GNP[,\#]] ""z  }C  D#+G4FT_,`#aa 9&/9JKWU./DxXX 4<3D3Dh''--/$G"#88U\]] #I. U;WE*+@8TT  U5c!fX>H*+@8TTUsJ   DJ1 J1 :A?J1 :!J1 J1 1L KLL*$LLLz$/contracts/<int:contract_id>/ratingsc                    ddl m} ddlm} ddlm} |j                  j                  |       }t        j                  |j                  |j                  fvr t        dd       t        t        d            S |j                  j                  |       j!                         }g }|D ]  }|j                  j#                  |j$                        }|j                  j#                  |j&                        }	|j)                  ||	|j*                  |j,                  |j.                  |j0                  |j2                  |j2                  |j4                  d	d

        t7        d||      S )z%View ratings for a completed contractr   r&   r  r   z-You do not have access to view these ratings.r   r   r  Tr=  zcontracts/ratings.html)rD  r0  )rQ   r'   r2  r  r   r   r]   r   r   r_   r   r;   r   r   r	   r^   r`   rT   r5  r!  r   r6  rJ  rK  rL  rM  r7  r   )
r  r'   r  r   rD  rN  r0  r$  rC  r>  s
             rz   r  z*register_main_routes.<locals>.view_ratingsd  s*    	1,(>>,,[9??8#9#98;M;M"NNA7KGK011,,(([(AEEG 	Fzz~~foo6Hzz~~foo6HNN$$"("6"6"("6"6(.(B(B&,&>&>*0*F*F!'!=!=!--$( 		" 7&.%,. 	.r|   z/payoutsc                     ddl m} m} ddlm} t
        j                  dk(  r9t        j                         \  }}|rHd|v r t        dd       t        t        d            S d	|v r t        d
d       t        t        d            S |j                  j                  |       j                  |      j                  |j                  t
        j                   k(  | j"                  j%                  g d            j'                  | j(                  j+                               j-                         }t/        d |D              }t/        d |D              }t1        d|||      S t
        j                  dk(  r|j                  j                  |       j                  |      j                  |j2                  t
        j                   k(        j'                  | j(                  j+                               j-                         }t/        d |D              }t/        d |D              }	t1        d|||	      S t        dd       t        t        d            S )zView payouts for workersr   r  r'   rh  r   r  r  r  r  rs   z7Please complete your payment setup to receive payments.r  )payment_failed	cancelledrefundedc              3   R   K   | ]  }|j                   d v s|j                   ! yw)r  transferredNrf   rd   rR  ps     rz   rV  z8register_main_routes.<locals>.payouts.<locals>.<genexpr>  s      "pqToHo1??"p   ''c              3   R   K   | ]  }|j                   d v s|j                   ! ywr   r~  r  Nr  r  s     rz   rV  z8register_main_routes.<locals>.payouts.<locals>.<genexpr>  s.       &F!188  XE  LEaoo  &Fr   zpayouts/worker.html)ra   total_earnedr   r   c              3   R   K   | ]  }|j                   d v s|j                   ! ywr  rf   r  r  s     rz   rV  z8register_main_routes.<locals>.payouts.<locals>.<genexpr>  s       mAQXXQlEl mr   c              3   R   K   | ]  }|j                   d v s|j                   ! ywr  r  r  s     rz   rV  z8register_main_routes.<locals>.payouts.<locals>.<genexpr>  s.       'F!188  XE  LEq~~  'Fr   zpayouts/contractor.htmlra   
total_paidpending_paymentsr  r   r   )rQ   r  r'   rs  r   r   r   r  r   r   r	   r   r]   r  r   r;   r_   rf   notin_r   date_initiatedr   r`   r   r   r   )
r  r'   r   r  r  ra   r  r   r	  r
  s
             rz   r  z%register_main_routes.<locals>.payouts  s    >)  H,2>2O2O2Q/ -# M1I9U'0D(EFF"m3WYbc'0D(EFF ::++G499(CJJ&&,//9NN))*UV (7116689##%   #"pH"pp"%  &Fx  &F  #F&'<.62>5DF F
 ""l2::++G499(CJJ**loo=(7116689##% 
 ! m mm
#&  'Fx  'F  $F &'@.60:6FH H &0 455r|   z/payouts/downloadc                     ddl m} m} ddlm} ddlm} ddlm} 	 ddl	m
} ddlm}m} ddlm}m}	m}
m}m} dd	lm}m} dd
lm} ddlm}m} t@        jB                  dk7  r t;        dd       t=        t?        d            S |jD                  jG                  |       jI                  |      jK                  |jL                  t@        jN                  k(        jQ                  | jR                  jU                               jW                         }tY        d |D              }tY        d |D              } |       } |||dddd      }g } |       } |d|d   d|j[                  d      d|      } |d|d   d|j[                  d      d !      } |d"|      }|j]                  |       t@        j^                  r#t@        j^                   d#t@        j`                   nt@        jb                  }d$|gd%t@        jd                  gd&tg        jh                         jk                  d'      gd(tm        to        |            gg} |	|d)|z  d*|z  g+      }|jq                   |
d,d-d.d/d0d1|j[                  d      fd2d3d4g             |j]                  |       |j]                   |d5d6              |d7|      }|j]                  |       d8d9|d:d;gd<d9|d:d;gg}  |	| d=|z  d>|z  g+      }!|!jq                   |
d,d?d@d/d0d0|j[                  dA      fd/dBdB|j[                  dA      fd/dCdC|j[                  dD      fd/dEdE|j[                  dD      fd2dFdGdHd0d1|j[                  dI      fdJd0d1d5|j[                  dK      fg             |j]                  |!       |j]                   |d5d              |dL|      }"|j]                  |"       g dMg}#|D ]  }$|$jr                  r*|$jr                  ju                  dNd#      jw                         ndO}%|#j]                  |$jx                  xs dO|$jR                  r|$jR                  jk                  dP      ndO|$jz                  rd9t}        |$jz                        dQndR|$j~                  rd9t}        |$j~                        dQndR|$j                  rd9t}        |$j                        dQndR|%g         |	|#dS|z  d5|z  dT|z  dT|z  d5|z  d)|z  g+      }&|&jq                   |
dHd0dU|j[                  dV      fd/d0dU|j                  fdWdXdYdZd[d\d]d^d_d`d0d1da|j                  fdbdCd1|j                  |j[                  dc      gfdddeg             |j]                  |&       |j                  |       |j                         }'|j                          dftg        jh                         jk                  dg       dh}( ||'didjdk|( il      S # t8        $ r# t;        dd       t=        t?        d            cY S w xY w)mzDownload earnings record as PDFr   r  rh  )Response)BytesIO)colors)letterA4)SimpleDocTemplateTable
TableStyle	ParagraphSpacer)getSampleStyleSheetParagraphStyle)inch)	TA_CENTERTA_RIGHTz=PDF generation library not available. Please contact support.r   r  r   r  r   c              3   d   K   | ](  }|j                   d v st        |j                         * ywr  rf   rc   rd   r  s     rz   rV  zAregister_main_routes.<locals>.download_payouts.<locals>.<genexpr>  s%     oaqxxSnGn51o   00c              3   d   K   | ](  }|j                   d v st        |j                         * ywr  r  r  s     rz   rV  zAregister_main_routes.<locals>.download_payouts.<locals>.<genexpr>  s3       E!((  WD  KDeAOO4  Er  r     )pagesizerightMargin
leftMargin	topMarginbottomMarginCustomTitleHeading1   z#2C3E50)parentfontSize	textColor
spaceAfter	alignmentCustomHeadingHeading2   z#34495E   )r*  r+  r,  r-  zEarnings Recordr  zWorker:zEmail:z
Generated:z%Y-%m-%d %H:%M:%SzTotal Records:g      ?r   )	colWidths)FONTr   r   r   Helvetica-Bold)r4  rA   r   rA   r7  	Helvetica)FONTSIZEr5  r7  r7  r'  	TEXTCOLORr5  r=  )ALIGNr5  r6  RIGHT)r?  r9  r:  LEFT)BOTTOMPADDINGr5  r=  rD  rA      Summaryz$Total Earned (Released/Transferred):$z,.2fz AUDzPending Payouts:g      @rJ   )r4  r9  r:  r8  )r<  r5  r=  rG  z#27AE60r9  r   rA   z#F39C12)rA   rA   )r?  r9  r:  r@  )rB  r5  r=  r  
BACKGROUNDz#ECF0F1BOXz#BDC3C7zPayment History)RefDateGrossFeeNetStatusrS  zN/Ar  z.2fz$0.00g333333?g?r7  r   z#3498DB)r?  r5  rO  CENTER)FONTNAMEr5  rO  r8  )r<  r5  rO  r'  )rB  r5  rO  r2  )rQ  rF  r=  r;  )r<  rF  r=  r  )r?  )rJ   rA   )r   r7  r@  )r?  rF  r:  rA  )r?  )r"  rA   )r"  r7  rP  GRIDg      ?ROWBACKGROUNDSz#F8F9FA)
TOPPADDINGrF  r=  rD  )rB  rF  r=  rD  earnings_record_z%Y%m%d_%H%M%Sz.pdfapplication/pdfContent-Dispositionzattachment; filename=)mimetyper  )GrQ   r  r'   rs  r   rR   r  ior  reportlab.libr  reportlab.lib.pagesizesr  r  reportlab.platypusr  r  r  r  r  reportlab.lib.stylesr  r  reportlab.lib.unitsr  reportlab.lib.enumsr  r  ImportErrorr   r   r	   r   r   r   r]   r  r   r;   r_   r   r  r   r`   r   HexColorr   r   r   rX  r   r   rV   r   r   r   setStylerf   rZ   r   payment_referencer  rc   platform_feerd   
whitesmokegreywhitebuildgetvalueclose))r  r'   r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  ra   r  r   bufferdocelementsstylestitle_styleheading_styler   r  	info_data
info_tablesummary_headingsummary_datasummary_tablehistory_headingr  rs   status_texttablepdf_datafilenames)                                            rz   download_payoutsz.register_main_routes.<locals>.download_payouts  s(    	:%"		0,:bbP0?
 ("G,GK011 ::##G,11(;BB,//1

(7))..0
1##% 	
 o8oo  Eh  E  E RTVbdsuv  %&$*%ooi0
 '*%ooi0
 +[9 P\OfOf001<3I3I2JKlx  mB  mB$|))*8<<>223FGHs3x=12	
	 9T1T60BC
J72.&(FOOI,FG/.2(
  	 	
#q"& $I}=( 4qd8K45PQ1_T$:$!?@

 ls4x46HIz77.&&&//)*DE&&&//)*DE&&&//)*DE&&&//)*DE//268V__Y-GHFHa)CD+
   	 	&q"& $$5}E( AA 		GFMnn'..00c:@@BZ_KKK))2U?F?U?U&&//
;[`9@9M9M!E'../45SZ9@9M9M!E'../45SZ:A:O:O!E'//056U\ 		 ds4x4T3t8QtVUXY]U]&^_ 	z67FOOI,FG&'6+<+<=0;-2 8-/.0VXsFKK8vx&,,PY@Z1[\/2%#
  	* 	 			( ??$ &hlln&=&=o&N%OtT&*.CH:,NO
 	
o  	0QSZ[GI.//	0s   2W	 	)W54W5z	/messagesc                      ddl m}  ddlm} 	 t	        dt
        g       S # t        $ r*}t        dd       t        t        d            cY d	}~S d	}~ww xY w)
z-Messages interface - connects to existing APIr   r   rh  messages/chat.html)r   conversationsz!Messages temporarily unavailable.r  r   N)
r   r   rs  r   r   r   r  r   r   r	   )r   r   r  s      rz   messages_wrapperz.register_main_routes.<locals>.messages_wrapperk  sR     ()6&';2>357 7  699E 4556s     	AAAAz/messages/<int:message_id>c                    	 ddl m} ddlm} |j                  j                  |       }t        j                  |j                  |j                  fvr t        dd       t        t        d            S t        j                  |j                  k(  r|j                  n|j                  }t        j                  |j                  k(  r2|j                  s&ddlm} |j!                  | t        j                         t        t        d|	            S # t"        $ rE}t$        j'                  d
|  d|        t        dd       t        t        d            cY d}~S d}~ww xY w)zCView specific message by ID - redirects to conversation with senderr   )Messagerh  z'You do not have access to this message.r   r  )message_servicemessages_viewr  zError accessing message rX  zMessage not found.N)app.models.messager  rs  r   r]   r   r   r_   	sender_idreceiver_idr   r   r	   read_atapp.services.message_servicer  mark_message_as_readr  r  r   )
message_idr  r   r  other_user_idr  r  s          rz   message_view_by_idz0register_main_routes.<locals>.message_view_by_id|  s   =6- "--22:>  ??7+<+<g>Q>Q*RRCWM#G,>$?@@ 6B__H[H[5[ 1 1ahatat  ??g&9&99'//L#88\__U   OPP =7
|2aSIJ*G4(: ;<<=s%   A.D 1BD 	E:EEEz/messages/viewc                  &   ddl m} m} ddlm} 	 t
        j                  j                  dt              }t
        j                  j                  dt              }d}d}|rc|j                  j                  |      }t        j                  |j                  |j                  fvr t        dd	       t!        t#        d
            S |rw| j                  j                  |      }|rZt        j                  |j                  k(  r|j                  n|j                  }||k7  r t        dd	       t!        t#        d
            S t%        dt        ||g d      S # t&        $ r6}t        dt)        |       d	       t!        t#        d
            cY d}~S d}~ww xY w)z:Contract-context messaging view with bidirectional supportr   )r   r'   rh  r  r  r  Nr2  r   r   zInvalid user for this contract.r}  T)r   rD  
other_userr~  contract_contextzError accessing messages: )r   r   r'   rs  r   r   rS   rT   rU   r]   r   r   r_   r   r;   r   r   r	   r   r  r   )	r   r'   r   r  r  rD  r  expected_user_idr  s	            rz   r  z+register_main_routes.<locals>.messages_view  sj    2)'6%ll..}3.G!,,**93*?  !
 '~~88EH $x/E/ExGYGY.ZZH'R'(<== !%!6!6w!?J  AMT\TjTjAj8+=+=px  qG  qG("&66!"CWM#+GK,@#AA '';2>.60:356:< <  623q6(;WE 4556s+   B2E A8E <E 	F+FFFz/notificationsc                     	 t        j                  t        j                  ddd      } t        j                  t        j                        }t        dt        |        dt        j                          t        d|        t        d| |	      S # t        $ r8}t        d
|        t        dd       t        t        d            cY d}~S d}~ww xY w)z2Notifications interface - connects to existing APIr  r   F)r  r4  r+   unread_onlyz[NOTIFICATION DEBUG] Found z notifications for user z#[NOTIFICATION DEBUG] Unread count: znotifications/list.html)notificationsunread_countz2[NOTIFICATION ERROR] Error loading notifications: z&Notifications temporarily unavailable.r  r   N)r   get_user_notificationsr   r_   get_unread_countrN  r   r   r  r   r   r	   )r  r  r  s      rz   notifications_wrapperz3register_main_routes.<locals>.notifications_wrapper  s    6 4 K K(OO %	!  4DD\__U3C4F3GG_`l`o`o_pqr;L>JK&'@3@2>@ @  6J1#NO>	J 4556s   BB 	C-CCCz/jobs/employerc                     ddl m}  t        j                  dvr t	        dd       t        t        d            S 	 | j                  j                  t        j                        j                  | j                  j                               j                         }t        d|	      S # t        $ r6}t	        d
t!        |       d       t        t        d            cY d}~S d}~ww xY w)z!Employer job management dashboardr   r~   r   (Access denied. Employer access required.r   r   r   r  r  Error loading jobs: N)r   r   r   r   r   r   r	   r]   r^   r_   r   r   r   r`   r   r  r   )r   	user_jobsr  s      rz   jobs_employerz+register_main_routes.<locals>.jobs_employer  s     '  (BB@'J 4556II//loo/NWWX[XgXgXlXlXnossu	&'@yQQ 6,SVH5w? 4556s   A+B& &	C%/+C C% C%z/jobs/workerc                  x   ddl m} m} ddlm} t
        j                  dk7  r t        dd       t        t        d            S t        j                         \  }}|rHd|v r t        d	d
       t        t        d            S d|v r t        dd
       t        t        d            S 	 |j                  j                  |j                        j                  t
        j                        j!                         }| j                  j#                  | j$                  dk(  | j                  j'                  |             j)                  | j*                  j-                               j/                         }t1        d|      S # t2        $ r6}t        dt5        |       d       t        t        d            cY d}~S d}~ww xY w)z%Worker job discovery and applicationsr   r  rh  r   z&Access denied. Worker access required.r   r   r  r  r  r  rs   r  r  r:   r   r  r  r  N)r   r   ri  rs  r   r   r   r   r   r	   r  r   r]   r  r^   r_   subqueryr   rf   r  r   r   r   r`   r   r  r   )r   ri  r   r  r  applied_job_idsavailable_jobsr  s           rz   jobs_workerz)register_main_routes.<locals>.jobs_worker  sn    4)  H,>H 455 /;.K.K.M+m-TV_`#G,@$ABB-/TV_`#G,@$ABB6"$**"2"2;3E3E"F"P"P[g[j[j"P"k"t"t"v!$!1!1JJ&(VVZZ00" (3??//12335 
 ''>^TT 6,SVH5w? 4556s   $CE: :	F9+F4.F94F9z/applications/receivedc                     ddl m} m} ddlm} t
        j                  dvr t        dd       t        t        d            S 	 |j                  j                  |       j                  |      j                  |j                  t
        j                  k(        }t         j"                  j%                  d      }|r*	 t'        |      }|j                  |j                  |k(        }|j-                  | j.                  j1                               j3                         }t5        d
|      S # t(        t*        f$ r t        d	d       Y aw xY w# t6        $ r6}t        dt9        |       d       t        t        d            cY d}~S d}~ww xY w)zEmployer application managementr   )ri  r   rh  r   r  r   r   r  r  r  r  zError loading applications: N)r   ri  r   rs  r   r   r   r   r   r	   r   r]   r  r   r   r_   r   rS   rT   rU   r  r   r   r  r   r`   r   r  r   )ri  r   r   r]   r  received_applicationsr  s          rz   applications_receivedz3register_main_routes.<locals>.applications_received  sF    4)  (BB@'J 4556

((5::3?FF%%8
 !))(3B!$V %SVVv-= >
 ).{7O7O7T7T7V(W([([(]%&'JYnoo &z2 B7AB  64SVH=wG 4556sD   A5E 8)D% !AE %E E EE 	F+F :F Fz	/settingsc                  ~   t         j                  dk(  ri	 t         j                  j                  d      } | dk(  rdt         j                  v dt         j                  v dt         j                  v dt         j                  v dt        j
                  d<   d	d
lm}  |t        d       t        j                  j                          t        dd       n| dk(  rdt         j                  v dt         j                  v dt         j                  v dt         j                  v dt        j
                  d<   d	d
lm}  |t        d       t        j                  j                          t        dd       t        t        d            S d}t        j"                  r6	 d	dlm} d	dl}|j*                  j-                  t        j"                        }d}t7        dt        |      S # t        $ rT}t        j                  j                          t        dt!        |       d       t        t        d            cY d}~S d}~ww xY w# t        $ rz}j.                  j1                  dt        j"                   d|        dt        _        dt        _        dt        _        t        j                  j                          d}Y d}~d}~ww xY w) zUser settings and preferencesr   	form_typer  email_job_alertsemail_applicationsemail_contractsemail_payments)r  r  r  r  r   )flag_modifiedr   z.Notification preferences updated successfully!r  r  r  r  r  r   )r  r  r  r   z&Privacy settings updated successfully!user_settingszError updating settings: r   NFr  TzStripe account z is invalid: zauth/settings.html)r   stripe_account_valid)r   r  r  rT   r   r   sqlalchemy.orm.attributesr  r   r   r  r   r   r	   r  r  r   r  r  r  stripeAccountretriever  r  r  r  r   )r  r  r  r  r  r  accountr  s          rz   r  z+register_main_routes.<locals>.user_settings=  s*    ~~'%> ' 0 0 =I O3 1Cgll0R2F',,2V/@GLL/P.>',,.N	E00A L%lMB

))+NPYZ"i/ /?',,.N4Jgll4Z.>',,.N3HGLL3X	?00; L%lMB

))+F	R#GO$<== $) --1J!$nn55l6T6TUG+/( ##7lauvv/ ! >JJ'')5c!fX>H#GO$<==> ! 1JJ&&9W9W8XXefgeh'ij59L2>CL;:?L7JJ%%'+0(1s8   E'G 5H9 	H6"A	H1+H61H69	J<A0J77J<z/settings/delete-accountc                  :   ddl m}  	 t        j                         }|j	                  dd      j                         j                         }|t        j                  j                         k7  rt        ddd      dfS t        j                  }t                | j                  |d	      \  }}|rt        d
ddd      S t        d|d      dfS # t        $ rE}t        j                  j!                  dt#        |              t        ddd      dfcY d}~S d}~ww xY w)zGAllow user to delete their own account (soft delete with anonymisation)r   )UserDeletionServicer   r   Fz5Email confirmation does not match your account email.r  r  )r  deleted_by_adminTzYour account has been deleted and anonymised. A confirmation email has been sent. Transaction records will be retained for 7 years for tax compliance.ra  )r  r  r   zError deleting account: zFAn error occurred while deleting your account. Please contact support.r  N)"app.services.user_deletion_servicer  r   r  rT   r   re  r   r   r   r_   r   soft_delete_userr  r
   r  r   r   )r  r  confirmed_emailr  r  r  r  s          rz   delete_my_accountz/register_main_routes.<locals>.delete_my_account}  sF    O''')"&((7B"7"="="?"E"E"G"l&8&8&>&>&@@"#(#Z$   
 '//  $7#G#G#%* $H $ 
 "#' $|$'$   ##(#*$   
  ""((+CCF8)LM$g    s+   A2C ;A C <C 	D:DDDz/contracts/pendingc                     ddl m}  	 | j                  j                  d      j	                  | j
                  t        j                  k(  | j                  t        j                  k(  z        j                  | j                  j                               j                         }t        d|dd      S # t        $ r6}t        d	t!        |       d
       t#        t%        d            cY d}~S d}~ww xY w)zContracts awaiting signaturer   r&   r=   r  r  r   zPending Contractsrq   filter_typer   z!Error loading pending contracts: r   r   Nr   r'   r]   r^   r   r   r   r_   r;   r   r   r   r`   r   r  r   r   r   r	   )r'   pending_contractsr  s      rz   contracts_pendingz/register_main_routes.<locals>.contracts_pending  s     ,6$,NN$<$<. %= %&++|>''<??:< (8..3356ssu " ''<->/8)<> >  69#a&BGL 4556   B'B0 0	C/9+C*$C/*C/z/contracts/activec                     ddl m}  	 | j                  j                  d      j	                  | j
                  t        j                  k(  | j                  t        j                  k(  z        j                  | j                  j                               j                         }t        d|dd      S # t        $ r6}t        dt!        |       d	       t#        t%        d
            cY d}~S d}~ww xY w)zActive contracts in progressr   r&   r@   r  r  zActive Contractsr  z Error loading active contracts: r   r   Nr  )r'   r   r  s      rz   contracts_activez.register_main_routes.<locals>.contracts_active  s     ,6#+>>#;#;# $< $&++|>''<??:< (8..3356ssu ! ''<-=/7);= =  68QA7K 4556r  z/contracts/completedc                     ddl m}  	 | j                  j                  d      j	                  | j
                  t        j                  k(  | j                  t        j                  k(  z        j                  | j                  j                               j                         }t        d|dd      S # t        $ r6}t        dt!        |       d	       t#        t%        d
            cY d}~S d}~ww xY w)zCompleted contract historyr   r&   r   r  r  zCompleted Contractsr  z#Error loading completed contracts: r   r   Nr  )r'   completed_contractsr  s      rz   contracts_completedz1register_main_routes.<locals>.contracts_completed  s     ,6&.nn&>&>& '? '&++|>''<??:< (8..3356ssu $ ''<-@/:)>@ @  6;CF8DgN 4556r  z/contracts/needs-ratingc                     ddl m}  	 | j                  j                  d      j	                  | j
                  t        j                  k(  | j                  t        j                  k(  z        j                  | j                  j                               j                         }t        d|dd      S # t        $ r6}t        d	t!        |       d
       t#        t%        d            cY d}~S d}~ww xY w)zContracts needing rating/reviewr   r&   rD   r  r  needs_ratingzContracts Needing Ratingr  z(Error loading contracts needing rating: r   r   Nr  )r'   rating_contractsr  s      rz   contracts_needs_ratingz4register_main_routes.<locals>.contracts_needs_rating  s     ,6#+>>#;#;+ $< $&++|>''<??:< (8..3356ssu ! ''<-=/=)CE E  6@QI7S 4556r  z	/paymentsc                     ddl m} m} ddlm} 	 t
        j                  dv r|j                  j                  |       j                  |      j                  |j                  t
        j                  k(        j                  | j                  j                               j!                         }t#        d |D              }t#        d |D              }t%        d|||      S t'        d	d
       t)        t+        d            S # t,        $ r6}t'        dt/        |       d
       t)        t+        d            cY d}~S d}~ww xY w)zPayment history and managementr   r  rh  r   c              3   T   K   | ]   }|j                   d k(  s|j                   " yw)r  Nr  r  s     rz   rV  zAregister_main_routes.<locals>.payments_history.<locals>.<genexpr>  s      $`U_I_Q^^$`s   ((c              3   R   K   | ]  }|j                   d v s|j                   ! yw))r   r~  Nr  r  s     rz   rV  zAregister_main_routes.<locals>.payments_history.<locals>.<genexpr>  s      *vaqxx[uOu1>>*vr   zpayments/history.htmlr  r  r   r   zError loading payments: N)rQ   r  r'   rs  r   r   r   r   r]   r  r   r   r_   r   r  r   r`   r   r   r   r   r	   r  r   )r  r'   r   ra   r	  r
  r  s          rz   payments_historyz.register_main_routes.<locals>.payments_history  s    >)6$$(BB!zz//8==hGNN ..,//A hw55::<=cce 
 "%$`X$`!`J'**v8*v'v$*+B2:4>:JL L
 *G4#GK$899 60Q97C 4556s$   CC> C> >	D=+D82D=8D=z/payments/pendingc                     ddl m} m} ddlm} ddlm} 	 t        j                  dv r|j                  j                  |       j                  |      j                  |j                  t        j                  k(  | j                  j                  ddg            j!                  | j"                  j%                               j'                         }t)        d| |j*                         j-                         	      S t/        d
d       t1        t3        d            S # t4        $ r6}t/        dt7        |       d       t1        t3        d            cY d}~S d}~ww xY w)zOutstanding paymentsr   r  rh  rj  r   r   r~  zpayments/pending.html)ra   current_dater  r   r   z Error loading pending payments: N)rQ   r  r'   rs  r   r   r   r   r   r]   r  r   r   r_   rf   r  r   r  r   r`   r   r8  r   r   r   r	   r  r   )r  r'   r   r   r
  r  s         rz   payments_pendingz.register_main_routes.<locals>.payments_pending#  s    >))6$$(BB')zz'7'7'@'E'Eh'O'V'V ..,//A**I}+EF( hw55::<=cce %
 ++B2B6Ehoo6G6L6L6NP P *G4#GK$899 68QA7K 4556s$   C!D 8D 	E!+EEEz/payouts/pendingc                     ddl m} m} ddlm} 	 t
        j                  dk(  r|j                  j                  |       j                  |      j                  |j                  t
        j                  k(  | j                  j                  g d            j                  | j                   j#                               j%                         }t'        |      }t)        j*                         j-                         }t/        d|||      S t1        dd	       t3        t5        d
            S # t6        $ r6}t1        dt9        |       d	       t3        t5        d
            cY d}~S d}~ww xY w)zPending contractor payoutsr   r  rh  r   r  zpayouts/pending.html)r  pending_countr  r  r   r   zError loading pending payouts: N)rQ   r  r'   rs  r   r   r   r   r]   r  r   r;   r_   rf   r  r   r  r   r`   r   r   rV   r   r   r   r   r	   r  r   )r  r'   r   r   r  r  r  s          rz   payouts_pendingz-register_main_routes.<locals>.payouts_pending<  s    >)6$$0&(jj&6&6w&?&D&DX&N&U&U **loo=**+XY' hw55::<=cce $
 %($8M#+<<>#6#6#8L*+A1@7D6BD D
 *G4#GK$899 67Ax@'J 4556s$   C3D$ D$ $	E#-+EE#E#z	/invoicesc                  X   ddl m} m}m} 	 | j                  j                  | j                  t        j                  k(        j                         }| j                  j                  |      j                  |      j                  |j                  t        j                  k(        j                         }t        t        ||z               }|j                  d d       t        d|      S # t         $ r6}t#        dt%        |       d	       t'        t)        d
            cY d}~S d}~ww xY w)z!Invoice generation and managementr   )Invoicer  r'   c                     | j                   S rP  )r   )xs    rz   <lambda>z=register_main_routes.<locals>.invoices_list.<locals>.<lambda>k  s
     r|   T)keyreversezinvoices/list.html)invoiceszError loading invoices: r   r   N)r   r  r  r'   r]   r   r   r   r_   r`   r  r;   rP  setsortr   r  r   r   r   r	   )r  r  r'   contractor_invoicesworker_invoicesuser_invoicesr  s          rz   invoices_listz+register_main_routes.<locals>.invoices_listX  s     >=6&-mm&:&:))\__<'#% $
 #*--"4"4W"="B"B8"L"S"S&&,//9##%  
 !%S)<)N%O P""'=t"L&';mTT 60Q97C 4556s   CC* *	D)3+D$D)$D)z+/contracts/<int:contract_id>/payment/returnc                    ddl m} 	 |j                  j                  |       }|j                  t
        j                  k7  r t        dd       t        t        d            S t        dd       t        t        d| 	            S # t        $ r6}t        d
t        |       d       t        t        d            cY d}~S d}~ww xY w)z+Handle return from 3D Secure authenticationr   r&   r  r   r   z>Payment authentication completed. Please check payment status.r  r  r  z!Error processing payment return: N)r   r'   r]   r   r   r   r_   r   r   r	   r  r   )r  r'   rD  r  s       rz   payment_return_handlerz4register_main_routes.<locals>.payment_return_handlerr  s     ,6#>>44[A ))\__<*G4#GK$899 VX^_(: TUU 69#a&BGL 4556s$   AB  !B 	C+B<6C<Cz$/contracts/<int:contract_id>/paymentc                    ddl m}m} ddlm} 	 |j
                  j                  |       }|j                  t        j                  k7  r"t        dd       t        t        d|             S |j
                  j                  |j                  |j                  k(  |j                  j!                  g d            j#                         }|r"t        d	d
       t        t        d|             S 	 t%        |j&                  j(                        }t1        |j2                        |z  }|j4                  }	|	r|	j6                  r|dz  }
||
z   }nd}
|}|j8                  j/                  d      }|s"t        dd       t        t        d|             S t;        d||||
|	r|	j6                  nd|t              S # t*        t,        f$ r8 ddddddddddddd}|j/                  |j&                  j(                  d      }Y w xY w# t<        $ rG}t>        jA                  d|  d|        t        dd       t        t        d|             cY d}~S d}~ww xY w)z0Secure Stripe Elements payment form for contractr   )r'   r  )r
   z*Only the contract owner can make payments.r   r  r  )pending_paymentr~  r  z)Payment already exists for this contract.r  r   r  r'  r  r  r  r  r  STRIPE_PUBLISHABLE_KEYz6Payment system not configured. Please contact support.zpayments/payment_form.htmlF)rD  payment_amountr  r  r  stripe_publishable_keyr   z(Error loading payment form for contract rX  zError loading payment form.N)!r   r'   r  rR   r
   r]   r   r   r   r_   r   r   r	   r   r  rf   r  rb   rU   r   r  r   r  rT   rc   re   r   r   r  r   r  r  r   )r  r'   r  r
   rD  existing_paymentr  r  base_payment_amountr   r  total_payment_amountr  r  s                 rz   contract_payment_formz3register_main_routes.<locals>.contract_payment_form  sL    5)MV#>>44[A ))\__<FP#G,>K$XYY $+==#7#7''8;;6NN&&'\]$ %' !
 $EyQ#G,>K$XYYI 5 56E, ',H,@,@&AE&I# "f33!4t!;J+>+K(!"J+>( *5););)?)?@X)Y&-RT[\#G,>K$XYY ''C.64H1D0:TZ6;P;P`e<R2>@ @O #I. I
 %&$%$&"$$&')#$#$$&"$$&#%&N +..x||/D/DaHE%I`  VG}TVWXVYZ[3W=(: TUUVsQ   AG9 *A?G9 +F/ 
A?G9 
$G9 /AG63G9 5G66G9 9	I	<I>I	I	z/profile/editc                  	   t         j                  dk(  rddlm}  	 t         j                  j                  d      t        _        t         j                  j                  d      t        _        t         j                  j                  d      t        _	        t         j                  j                  d      t        _
        t         j                  j                  d      t        _        t         j                  j                  d	      t        _        t        j                  d
k(  r\dt         j                  v rJt         j                  j                  d      }|rdj                  |dd       t        _        ndt        _        t        j                  d
k(  rYdt         j                  v rGt         j                  j                  d      }|rdj                  |      t        _        ndt        _        t        j                  d
k(  rdt         j                  v r(t         j                  j                  d      t        _        dt         j                  v rPt         j                  j                  d      r1t'        t         j                  j                  d            t        _        dt         j                  v rPt         j                  j                  d      r1t+        t         j                  j                  d            t        _        t        j                  dk(  r:dt         j                  v r(t         j                  j                  d      t        _        dt         j                  v t        _        dt         j                  v t        _        | j4                  j7                          t9        dd       t;        t=        d            S ddl"m#} |jH                  jK                  d      jM                  |jN                  |jP                        jS                         }tU        dt        |       S # t>        $ r}| j4                  jA                          t9        dtC        |       d       ddl"m#} |jH                  jK                  d      jM                  |jN                  |jP                        jS                         }tU        dt        |       cY d}~S d}~ww xY w)!zProfile editing interfacer   r   rh  r   r   r   r   r   r   r   r   r  Nr  r   skillsr  experience_yearsr   company_descriptionr   r  zProfile updated successfully!r  r  zError updating profile: r   r   Tr   zprofile/edit.htmlr  )+r   r  rs  r   r  rT   r   r   r   r   r   r   r   r   r   r  r   r   r  rc   r  rU   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   s         rz   profile_editz*register_main_routes.<locals>.profile_edit  sN    ~~'-5j.5ll.>.>|.LL+-4\\-=-=k-JL*)0)9)9')BL&070@0@0PL-,3LL,<,<Z,HL).5ll.>.>|.LL+ $((H4GLL9X*1,,*>*>*O*9</RTSTBU9VL69=L6 $((H49Jgll9Z4;LL4H4HIZ4[14;>88D];^L8;?L8 $((H4#w||329,,2B2B82LL/(GLL8W\\=M=Mm=\7<W\\=M=Mm=\7]L4-=',,BRBRSeBf<?@P@PQc@d<eL9#((L80GLL@?F||?O?OPe?fL< ?[^e^j^j>jL;:PT[T`T`:`L7JJ%%'99E#GI$677 5!11D1AJJ8K^K^`h`m`mnrrtJ"#6\V`aa ! jJJ'')4SVH=wG<!)!9!9D!9!I!R!RS[SfSfhphuhu!v!z!z!|J*+>\^hiijs   NP 	S$BS;SSz/profile/verificationc                  $    t        dt              S )zDocument verification systemzprofile/verification.htmlr  r   r   rZ  r|   rz   profile_verificationz2register_main_routes.<locals>.profile_verification!  s     ##>\RRr|   z/profile/insurancec                  $    t        dt              S )zInsurance managementzprofile/insurance.htmlr  r  rZ  r|   rz   profile_insurancez/register_main_routes.<locals>.profile_insurance'  s     ##;,OOr|   z/api/upload-profile-picturec                     	 ddl } ddl} ddlm} | j	                  j                  j                  d      j                  j                  d      j                  j                  d             dt        j                  vrt        d	d
d      dfS t        j                  d   }|j                  dk(  rt        d	dd      dfS h d}d|j                  v r-|j                  j                  dd      d   j                         nd}||vrt        d	dd      dfS | j                  j                  |ddt        j                   dddddddddg      }|j                  d      }|t        _        |j"                  j%                          t        d|dd      dfS # t&        $ r=}t)        d t+        |              t        d	d!t+        |       d      d"fcY d}~S d}~ww xY w)#z;Upload profile picture to Cloudinary and update user recordr   Nrh  CLOUDINARY_CLOUD_NAMECLOUDINARY_API_KEYCLOUDINARY_API_SECRET)
cloud_nameapi_key
api_secretr   FzNo file uploadedr  r  r   zNo file selected>   jpgpngjpegr  rA   z+Invalid file type. Only JPG and PNG allowedzrateright/profile_picturesuser_Tfillface)widthheightcropgravityauto)qualityfetch_format)folder	public_id	overwritetransformation
secure_urlz%Profile picture uploaded successfully)r  urlr  r  z!Error uploading profile picture: zUpload failed: r  )
cloudinarycloudinary.uploaderrs  r   r  rT   r   filesr   rz  rsplitre  uploaderuploadr   r_   r   r   r  r  rN  r   )	r  r   fileallowed_extensionsfile_extupload_result	image_urlr  r  s	           rz   upload_profile_picturez4register_main_routes.<locals>.upload_profile_picture-  s   :!*- !!"zz~~.EFJJNN+?@"zz~~.EF "  %GMM9"uAS#TUWZZZ}}%67==B&"uAS#TUWZZZ &<"FIT]]FZ4==//Q7:@@B`b#55"uAn#opruuu !+ 3 3 : :7 %loo%67""%fQWX$*FC$ !; 	! *--l;	 09,

!!##$F   	   9#a&BC$!0Q9    s2   BF 1F AF BF 	G!$2GG!G!z/api/stripe/setup-payoutsc                  F   ddl } ddlm} ddlm} ddlm} 	 t        j                  rW|j                  t        j                        }|d   r"|d   rt        dd	       t         |d
            S t        j                  }nrt        j                  t        j                  t        j                  d}|j                  |      }|j                   }|t        _        |j"                  j%                          ddlm} | j(                  j+                  d      du}	t,        j.                  j+                  dd      }
|
j1                  d      }|	s|rd|j2                   }n|j4                  j7                  d      }| d}| d}j8                  j;                  d| d|        |j=                  |||      }t        |j>                        S # t@        $ r}ddl!}|jE                         }j8                  jG                  dtI        |              j8                  jG                  d|        tI        |      jK                         }d|v sd|v rt        dd       n-d|v rd|v rt        dd       nt        d tI        |       d       t         |d
            cY d}~S d}~ww xY w)!z0Initialize Stripe Connect onboarding for payoutsr   Nr  rh  )r	   r  r  z1Your payout account is already set up and active!r  r  )r   r   r   r   FLY_APP_NAMESTRIPE_SECRET_KEYr   sk_live_zhttps://ra  /api/stripe/onboarding/return/api/stripe/onboarding/refreshz!Stripe onboarding URLs - Return: z, Refresh: zStripe Connect setup error: zFull traceback: zplatform-profilezmanaging losseszStripe Connect not configured. Please complete your Stripe platform profile at https://dashboard.stripe.com/settings/connect/platform-profiler   httpslivemodez}Stripe live mode requires HTTPS. For local testing, use test mode keys (pk_test_/sk_test_) or test on your production server.zError setting up payouts: )&r  r  r  rs  r   rR   r	   r   r  r  r   r   r   r   r   create_connect_accountr_   r   r  r   r  rT   r
   r  rM  hosthost_urlrstripr  r  create_onboarding_linkr  r  r<  r  r   r   re  )r  r  r   r	   r  
account_id	user_datar  r   is_productionstripe_secret_keyis_live_modebase_url
return_urlrefresh_urlonboarding_linkr  r<  r  	error_msgr  s                       rz   stripe_setup_payoutsz2register_main_routes.<locals>.stripe_setup_payoutsn  s    B)%H:11%3%F%F|GeGe%fN%&78^L]=^QS\]'(@AA ".!?!?J ".!3!3&2&=&=%1%;%;!I -CCING!(J 6@L2JJ%%' * !#

~ >d J$/$6$6$:$:;NPR$S!0;;JG !L "*',,8H  '//66s;H (z)FG
!)
*HI

"CJ<{[fZg hi"0"G"G#   3 344 :  ) 4 4 6

  #?Ax!HI

  #3M?!CD  FLLN	%26G96T  j  ls  t	)jI.E  Z  \c  d6s1vh?I 899:s&   AG /EG 	J CJJ J r"  c                  8   ddl m}  ddlm} 	 t        j
                  r| j                  t        j
                        }|d   t        _        |d   t        _        |d   t        _	        |j                  j                          |d   rt        dd       n+|d   rt        d	d
       nt        dd       nt        dd       t#        t%        d            S # t        $ r=}j                  j                  dt!        |              t        dd       Y d}~Ud}~ww xY w)z$Handle return from Stripe onboardingr   r  rh  r  r  r  zBPayout setup completed successfully! You can now receive payments.r  z@Account information submitted. Stripe is reviewing your details.r  z;Setup incomplete. Please complete all required information.r  z&Account setup error. Please try again.r   z Stripe onboarding return error: zError checking account status.Nr  )r  r  rs  r   r   r  r  r  r  r  r   r  r   r  r  r   r   r   r	   )r  r   r  r  r  s       rz   stripe_onboarding_returnz6register_main_routes.<locals>.stripe_onboarding_return  s    C)A11%3%F%F|GeGe%fN ?MM`>aL;:HIZ:[L7:HIZ:[L7JJ%%'%&78bdmn'(;<`bhi[]fgBGL GO455	  A

  #CCF8!LM6@@As   B0C 	D3DDr#  c                  *    t        t        d            S )z+Handle refresh/restart of Stripe onboardingr5  r  rZ  r|   rz   stripe_onboarding_refreshz7register_main_routes.<locals>.stripe_onboarding_refresh  s    
 G$:;<<r|   z/api/stripe/dashboardc                     ddl m}  	 t        j                  s t	        dd       t        t        d            S | j                  t        j                        }t        |j                        S # t        $ rQ}j                  j                  dt        |              t	        dd       t        t        d            cY d	}~S d	}~ww xY w)
z$Redirect to Stripe Express dashboardr   r  z(Please set up your payout account first.r  r  zStripe dashboard error: z2Error accessing dashboard. Please try again later.r   N)r  r  r   r  r   r   r	   create_dashboard_linkr  r  r  r   r   )r  dashboard_linkr  r  s      rz   stripe_dashboardz.register_main_routes.<locals>.stripe_dashboard  s     C:#55DiP#GO$<== "0!E!ElFdFd!e   2 233 :

  #;CF8!DEJGT 899:s#   /A- 3A- -	C6AC<CCz"/contracts/<int:contract_id>/hoursc                 8   ddl m} ddlm} 	 |j                  j                  |       }t        j                  |j                  |j                  fvr t        dd       t        t        d            S |j                  |       }|j                  d      s4t        d|j                  d       d       t        t        d	| 
            S t        d||      S # t         $ r;}t"        j%                  d|  d|        t        t        d	| 
            cY d}~S d}~ww xY w)z View contract time tracking datar   r0  r&   r2  r   r   r  Error loading hours: r  r  zcontracts/hours.htmlrD  rG  zError viewing contract hours rX  N)rH  r1  r   r'   r]   r   r   r_   r   r;   r   r   r	   rI  rT   r   r  r  r   )r  r1  r'   rD  rG  r  s         rz   contract_hours_viewz1register_main_routes.<locals>.contract_hours_view  s    Q+V#>>44[A??8+A+A8CUCU*VVDgN#GK$899 3EEkR
!~~i01*..2I1JKWU#G,>K$XYY&'=.60:< <  V<[MA3OP(: TUUVs+   A"C 1AC C 	D0DDDz'/contracts/<int:contract_id>/hours/editc                    ddl m} ddlm} ddlm} 	 |j                  j                  |       }t        j                  |j                  |j                  fvr t        dd       t        t        d            S t        j                   dk(  rZt        j"                  j%                  d	      }|d
k(  rBt        j"                  j%                  dt&              }t        j"                  j%                  d      }t        j"                  j%                  dd      }t        j"                  j%                  dd      }		 |r |j(                  |      n |j*                         }
|r|dk  r"t        dd       t        t        d|             S |j/                  | |j                  ||
||	      }|j%                  d      rt        |j%                  d      d       nt        d|j%                  d       d       n|dk(  rt        j"                  j%                  dt0              }t        j"                  j%                  dt&              }t        j"                  j%                  d      }t        j"                  j%                  d      }	|s"t        dd       t        t        d|             S |j3                  ||||	t        j                        }|j%                  d      rt        |j%                  d      d       nt        d|j%                  d       d       n|dk(  rt        j"                  j%                  dt0              }|s"t        dd       t        t        d|             S |j5                  |t        j                         }|j%                  d      rt        |j%                  d      d       nt        d!|j%                  d       d       n|d"k(  r|j                  t        j                  k7  r"t        d#d       t        t        d|             S t        j"                  j7                  d$      }|D cg c]  }|j9                         st1        |        }}|j;                  | t        j                  |r|nd%&      }|j%                  d      rt        |j%                  d      d       nt        d'|j%                  d       d       t        t        d|             S |j=                  |       }|j%                  d      s4t        d(|j%                  d       d       t        t        d)|             S t?        d*||t        j                  |j                  k(  +      S # t,        $ r% t        dd       t        t        d|             cY S w xY wc c}w # t@        $ rJ}tB        jE                  d,|  d-|        t        d.| d       t        t        d)|             cY d%}~S d%}~ww xY w)/z'Edit contract hours (fixes user issue!)r   r0  r&   r   r2  r   r   r   r  	add_hoursr  r  r  r  r   r   zInvalid work date format.contract_hours_editr  zHours must be greater than 0.r  r;   r  r  r  r   r  r  zError adding hours: 
edit_entryr  z!Entry ID is required for editing.)r  r  r  r   r  zError editing hours: delete_entryz"Entry ID is required for deletion.r  r  zError deleting hours: approve_hoursz&Only the contractor can approve hours.	entry_idsNr  approver_idrK  zError approving hours: r?  r  zcontracts/hours_edit.html)rD  rG  is_contractorzError editing contract hours rX  z&Error loading hour editing interface: )#rH  r1  r   r'   r   r   r]   r   r   r_   r   r;   r   r   r	   r   r  r  rT   rc   r   r  r   create_time_entryrU   edit_time_entrydelete_time_entryr   isdigitapprove_time_entriesrI  r   r  r  	exception)r  r1  r'   r   rD  r  r  work_date_strr  r   r  r  r  entry_ids_strr_   rK  rG  r  s                     rz   rE  z1register_main_routes.<locals>.contract_hours_edit   s    Q+%{Z#>>44[A??8+A+A8CUCU*VVDgN#GK$899>>V+$\\--h7F, ' 0 0u 0 E(/(8(8(E&-ll&6&6}b&I#*<<#3#3J#CeMZ(:(:(:=(I`j`d`j`j`lI  %
!"A7K#+G4IWb,c#dd "7!H!H(3&.&8&8"'&/(3%- "I " "::i0!&**Y"7C!$8G9L8M"NPWX</#*<<#3#3JS#3#I ' 0 0u 0 E&-ll&6&6}&E#*<<#3#3J#?'!"EwO#+G4IWb,c#dd!6!F!F%-"'(3%-$0OO "G " "::i0!&**Y"7C!$9&**W:M9N"OQXY>1#*<<#3#3JS#3#I'!"FP#+G4IWb,c#dd!6!H!H%-$0OO "I "
 "::i0!&**Y"7C!$:6::g;N:O"PRYZ?2#11\__D!"JGT#+G4IWb,c#dd(/(<(<[(I7D$U

SW$U	$U!6!K!K(3(43<i$ "L " "::i0!&**Y"7C!$;FJJw<O;P"QSZ[#G,A{$[\\ 3EEkR
!~~i01*..2I1JKWU#G,>K$XYY&'B.60:3???hF\F\3\^ ^  * e!"=wG#+G4IWb,c#ddeR %V6  Z$$'D[MQSTUSV%WXB1#FP#G,>K$XYYZs   A"V 7B=V 5%U% (V D V $B?V $B1V #V 9VVBV %AV ;)V %+VV VV 	W.$?W)#W.)W.z*/contracts/<int:contract_id>/hours/summaryc                    ddl m} ddlm} 	 |j                  j                  |       }t        j                  |j                  |j                  fvrt        ddd      dfS |j                  | d      }|j                  d	      r|j                  |j                  t        |j                        |j                   |j"                  j$                   d
|j"                  j&                   |j(                  j$                   d
|j(                  j&                   d|d<   t        |      S t        |      dfS # t*        $ r5}t,        j/                  d|  d|        t        ddd      dfcY d}~S d}~ww xY w)z)Hour summary for contract (JSON response)r   r0  r&   Fr  r`  r   )r  approved_onlyr  r  )r_   rf   re   r  r  r)  rD  r  z%Error getting contract hours summary rX  r1  r  N)rH  r1  r   r'   r]   r   r   r_   r   r;   r   calculate_total_hoursrT   rf   rc   re   r  r   r   r   r   r  r  r   )r  r1  r'   rD  r:  r  s         rz   contract_hours_summaryz4register_main_routes.<locals>.contract_hours_summary  sz    Q+##>>44[A??8+A+A8CUCU*VV"#(!0$    0EE +"' F 
 ;;y) 'kk"*//',X-A-A'B%-%7%7*2//*D*D)EQxG`G`Fa'b.6.A.A.L.L-MQxObObOlOlNm+n+GJ' #7++"7+S00 D[MQSTUSVWX$4    s+   AD4 !CD4 'D4 4	E2=*E-'E2-E2z/api/time-entriesc                     ddl m}  ddlm} 	 t	        j
                         }|st        ddd      dfS |j                  dt        	      }|j                  d
t        	      }|j                  d      }|j                  dd      }|j                  dd      }|r|st        ddd      dfS d}|r	  |j                  |      }ddlm}	 |	j                  j                  |      }
|
st        ddd      dfS t        j                   |
j"                  |
j$                  fvrt        ddd      dfS | j'                  ||
j$                  ||||      }|j                  d      rt        |      dfS t        |      dfS # t        $ r t        ddd      dfcY S w xY w# t(        $ r2}t*        j-                  d|        t        ddd      dfcY d}~S d}~ww xY w)z'API endpoint to create new time entriesr   r0  rC  FJSON data requiredr`  r  r  r  r  r  r  r   r   z"contract_id and hours are requiredN(Invalid work_date format. Use YYYY-MM-DDr&   zContract not foundr  r  r   rF  r     z#Error creating time entry via API: r1  r  )rH  r1  r   r   r   r  r   rT   rU   rc   r   r   r   r'   r]   r   r_   r   r;   rO  r  r  r   )r1  r   r  r  r  rU  r  r   r  r'   rD  r  r  s                rz   api_create_time_entryz3register_main_routes.<locals>.api_create_time_entry  s;    Q%F'')"#(!5$    #hh}3h?u5 !% 5"hh}b988J3 #%"#(!E$    !	  $6D$6$6}$E	 0#>>--k:"#(!5$   
  ??8+A+A8CUCU*VV"#(!0$    /@@ +&00' +% A  ::i("6?C//"6?C//E &  &',%O(         H  B1#FG$4    s_   %F A6F +F 0E9 2F 57F ->F ,F 9FF FF 	G!'GGGz /api/time-entries/<int:entry_id>PUTc                    ddl m} ddlm} 	 t	        j
                         }|st        ddd      dfS |j                  dt        	      }|j                  d
      }|j                  d      }|j                  d      }d}|r	  |j                  |      }|j                  | ||||t        j                        }	|	j                  d      rt        |	      S t        |	      dfS # t        $ r t        ddd      dfcY S w xY w# t        $ r5}
t        j!                  d|  d|
        t        ddd      dfcY d}
~
S d}
~
ww xY w)z*API endpoint to edit existing time entriesr   r0  rC  Fr\  r`  r  r  r  r  r   r  Nr]  )r  r  r  r   r  r  r  zError editing time entry 
 via API: r1  r  )rH  r1  r   r   r   r  r   rT   rc   r   r   rP  r   r_   r  r  r   )r  r1  r   r  r  r  r   rU  r  r  r  s              rz   api_edit_time_entryz1register_main_routes.<locals>.api_edit_time_entry#  sv    Q%-'')"#(!5$    u5"hh}588J/ $ 5 !	  $6D$6$6}$E	 />>% +%'(OO ?  ::i("6?*"6?C//' &  &',%O(         *  8
*QCPQ$4    sN   %D AD C# A D D #C?<D >C??D 	E *D;5E ;E DELETEc                 &   ddl m} 	 |j                  | t        j                        }|j                  d      rt        |      S t        |      dfS # t        $ r5}t        j                  d|  d|        t        dd	d
      dfcY d}~S d}~ww xY w)z#API endpoint to delete time entriesr   r0  rI  r  r  zError deleting time entry rb  Fr1  r`  r  N)
rH  r1  rQ  r   r_   rT   r   r  r  r   )r  r1  r  r  s       rz   api_delete_time_entryz3register_main_routes.<locals>.api_delete_time_entryY  s     Q.@@%(OO A 
 ::i("6?*"6?C// 9(:aSQR$4    s#   <A A 	B*BBBz-/api/contracts/<int:contract_id>/time-entriesc                    ddl m} 	 |j                  |       }|j                  d      rt	        |      S t	        |      dfS # t
        $ r5}t        j                  d|  d|        t	        ddd	      d
fcY d}~S d}~ww xY w)z3API endpoint to get all time entries for a contractr   r0  r  r  z$Error getting contract time entries rb  Fr1  r`  r  N)rH  r1  rI  rT   r   r  r  r   )r  r1  r  r  s       rz   api_get_contract_time_entriesz;register_main_routes.<locals>.api_get_contract_time_entriesq  s     Q.AA+N::i("6?*"6?C// CK=PZ[\Z]^_$4    s"   ,A A 	B *A;5B ;B z./api/contracts/<int:contract_id>/approve-hoursc                 z   ddl m} 	 t        j                         xs i }|j	                  d      }|j                  | t        j                  |      }|j	                  d      rt        |      S t        |      dfS # t        $ r5}t        j                  d|  d|        t        d	d
d      dfcY d}~S d}~ww xY w)z3API endpoint to approve time entries for a contractr   r0  rK  rL  r  r  zError approving hours rb  Fr1  r`  r  N)rH  r1  r   r  rT   rS  r   r_   r   r  r  r   )r  r1  r  rK  r  r  s         rz   api_approve_contract_hoursz8register_main_routes.<locals>.api_approve_contract_hours  s     Q'')/R HH[1	.CC + ,' D  ::i("6?*"6?C// 5k]*QCPQ$4    s$   A&A< /A< <	B:*B5/B:5B:z/api/time-tracking/clock-inc                  
   ddl m}  	 t        j                         }|st	        ddd      dfS |j                  dt              }|j                  d	d
      }|j                  dd
      }|st	        ddd      dfS | j                  t        j                  |||      }|j                  d      rt	        |      S t	        |      dfS # t        $ r2}t        j                  d|        t	        ddd      dfcY d}~S d}~ww xY w)z API endpoint for worker clock-inr   r0  Fr\  r`  r  r  r  r   r   r  zcontract_id is required)r;   r  r   r  r  zError clocking in via API: r1  r  N)rH  r1  r   r  r   rT   rU   r  r   r_   r  r  r   )r1  r  r  r   r  r  r  s          rz   api_clock_inz*register_main_routes.<locals>.api_clock_in  s-    Q#'')"#(!5$   
 #hh}3h?88J3"hh}b9""#(!:$   
 /77*oo +% +	 8  ::i("6?*"6?C// :1#>?$4    s/   %C AC ;>C :C 	D'C=7D=Dz/api/time-tracking/clock-outc                     ddl m}  	 t        j                         xs i }|j	                  dt
              }|j	                  dd      }| j                  t        j                  ||      }|j	                  d      rt        |      S t        |      d	fS # t        $ r2}t        j                  d
|        t        ddd      dfcY d}~S d}~ww xY w)z!API endpoint for worker clock-outr   r0  r  r  r  r   )r;   r  r  r  r  zError clocking out via API: Fr1  r`  r  N)rH  r1  r   r  rT   rU   r  r   r_   r   r  r  r   )r1  r  r  r  r  r  s         rz   api_clock_outz+register_main_routes.<locals>.api_clock_out  s     Q'')/R88JS89"hh}b9.88*oo% + 9  ::i("6?*"6?C// ;A3?@$4    s$   A>B B 	C'C
C
Cz"/api/time-tracking/active-clock-inc                      ddl m}  	 | j                  t        j                        }t        |      S # t        $ r2}t        j                  d|        t        ddd      dfcY d}~S d}~ww xY w)	z,API endpoint to get worker's active clock-inr   r0  z'Error getting active clock-in via API: Fr1  )r@   r   r  N)	rH  r1  get_active_clock_inr   r_   r   r  r  r   )r1  r  r  s      rz   api_get_active_clock_inz5register_main_routes.<locals>.api_get_active_clock_in  sq     Q	.BB<??Sv& FqcJK#4    s   )2 	A-'A("A-(A-z)/contracts/<int:contract_id>/hours/exportc                    ddl m} ddlm} ddlm} ddlm}m} 	 |j                  j                  |       }t        j                  |j                  |j                  fvr t        dd       t        t!        d            S t"        j$                  j'                  d	d
      j)                         }t"        j$                  j'                  d      }t"        j$                  j'                  d      }	t"        j$                  j'                  dd      j)                         dk(  }
d}d}|r	  |j*                  |      }|	r	  |j*                  |	      }|r)|r'||kD  r"t        dd       t        t!        d|             S |dk(  r|j/                  | |||
      }|j'                  d      r2 ||d         }d|j0                  d<   d|d    d|j0                  d<   |S t        d |j'                  d       d       t        t!        d|             S |j3                  | |||
      }|j'                  d      r2 ||d!         }d"|j0                  d<   d|d    d|j0                  d<   |S t        d |j'                  d       d       t        t!        d|             S # t,        $ r% t        dd       t        t!        d|             cY S w xY w# t,        $ r% t        dd       t        t!        d|             cY S w xY w# t4        $ rG}t6        j9                  d#|  d$|        t        d%d       t        t!        d|             cY d}~S d}~ww xY w)&z#Export contract hours as CSV or PDFr   export_servicer&   r|  )r   r   r2  r   r   r   csvr  r  rX  falser   NzInvalid start date format.rA  r  zInvalid end date format.z$Start date cannot be after end date.pdf)r  r  r  rX  r  ry  rV  Content-Typeattachment; filename="rz  "rW  zExport failed: csv_datatext/csvzError exporting contract hours rX  zError generating export.)app.services.export_servicert  r   r'   rR   r}  r   r   r]   r   r   r_   r   r;   r   r   r	   r   rS   rT   re  r   r   export_contract_hours_pdfr  export_contract_hours_csvr  r  r   )r  rt  r'   r}  r   r   rD  export_formatstart_date_strend_date_strrX  r  r  export_resultrx  r  s                   rz   export_contract_hoursz3register_main_routes.<locals>.export_contract_hours  sR    C++/JY#>>44[A??8+A+A8CUCU*VVDgN#GK$899 !( 0 05 A G G I!(!1!1,!?&||//
; ' 0 0' J P P RV\ \ "
!a%7T%7%7%G

  a#54#5#5l#C (zH/D@'J#G,A{$[\\ !E)$2$L$L$/#-!)&3	 %M %M %((3#0z1J#K;L((8DZ[his[tZuuvBw(()>?'0A0A'0J/KLgV'0ES^(_`` %3$L$L$/#-!)&3	 %M %M %((3#0z1J#K;E((8DZ[his[tZuuvBw(()>?'0A0A'0J/KLgV'0ES^(_``c & a:GD'0ES^(_``a & a8'B'0ES^(_``aX  Y>{m2aSQR0':(=; WXXYs   A"K4 ?B#K4 #J 5K4 8K 
*K4 5AK4 3K4 AK4 3K4 +K =K4 ?K  K4 +K1.K4 0K11K4 4	M=<L?9M?Mz+/contracts/<int:contract_id>/payroll/exportc                 ,   ddl m} ddlm} ddlm} ddlm} 	 |j                  j                  |       }t        j                  |j                  k7  r t        dd       t        t        d            S t         j"                  j%                  d	      }t         j"                  j%                  d
      }|r|s"t        dd       t        t        d|             S 	  |j&                  |      } |j&                  |      }	|j+                  t        j                  ||	d      }
|
j%                  d      r2 ||
d         }d|j,                  d<   d|
d    d|j,                  d<   |S t        d|
j%                  d       d       t        t        d|             S # t(        $ r% t        dd       t        t        d|             cY S w xY w# t.        $ rD}t0        j3                  d|        t        dd       t        t        d|             cY d}~S d}~ww xY w)z%Export payroll summary for contractorr   rs  r&   r|  rC  z)Only contractors can export payroll data.r   r   r  r  z8Start date and end date are required for payroll export.rA  r  zInvalid date format.T)r   r  r  rX  r  r{  r|  rx  ry  rz  rz  rW  zPayroll export failed: z!Error exporting payroll summary: z Error generating payroll export.N)r}  rt  r   r'   rR   r}  r   r   r]   r   r   r_   r   r   r   r	   r   rS   rT   r   r   export_payroll_summary_csvr  r  r  r   )r  rt  r'   r}  r   rD  r  r  r  r  r  rx  r  s                rz   export_payroll_summaryz4register_main_routes.<locals>.export_payroll_summaryS  s    C++%*Y#>>44[A??h&<&<<EwO#GK$899 ")!1!1,!?&||//
;%\TV]^#G,A{$[\\]!3!3!3N!CJ1t11,?H !/ I I".//)%"&	 !J ! !$$Y/,]:-FGH7AH$$^4@VWdeoWpVqqr>sH$$%:;#O3M4E4Eg4N3OPRYZ#G,A{$[\\' " ]0':#G,A{$[\\]*  Y@DE8'B(=; WXXYsP   AG 2A#G $F ;A%G !3G +G G GG 	H9HHHz/oauth2callbackc                     	 ddl m}  t        j                  j	                  d      }|s t        dd       t        t        d            S  |        }|j                  |      }|rt        dd       nt        d	d       t        t        d            S # t        $ rK}t        j                  d
t        |              t        dd       t        t        d            cY d}~S d}~ww xY w)z"Handle Google Drive OAuth callbackr   rV  codez<OAuth authorization failed - no authorization code received.r   r   zVGoogle Drive successfully connected! Contract PDFs will now be automatically uploaded.r  z1Failed to connect Google Drive. Please try again.zOAuth callback error: z9Error connecting to Google Drive. Please try again later.N)rl  rW  r   rS   rT   r   r   r	   handle_oauth_callbackr  r  r   r   )rW  authorization_coderx  r  r  s        rz   oauth2callbackz,register_main_routes.<locals>.oauth2callback  s    	2J!(!1!1&!9%TV]^ 455-/M#99:LMGnpyzI7SGK011 	2LL1#a&:;MwWGK011	2s&   AB 	AB 	C$A CC$C$z/drive/connectc                     	 ddl m}   |        }|j                         }t        |      S # t        $ rK}t
        j                  dt        |              t        dd       t        t        d            cY d}~S d}~ww xY w)z&Initiate Google Drive OAuth connectionr   rV  zDrive connect error: zAError initiating Google Drive connection. Please try again later.r   r   N)
rl  rW  get_authorization_urlr   r  r  r   r   r   r	   )rW  rx  auth_urlr  s       rz   drive_connectz+register_main_routes.<locals>.drive_connect  so    	2J-/M$::<HH%% 	2LL0Q9:UW^_GK011	2s   '* 	A>A A93A>9A>c                 2    | j                  d      d        }y)z%Register Edge-specific error handlersr  c                 n   ddl m} ddl}|j                  j	                  dd      }d|v }|ryt        d       t        d|j                          t        d	|j                          t        d
t        |j                                t        dt        |               d}|dfS dt        |        ddfS )z2Enhanced 500 error handler for Edge browser issuesr   r  Nr  r   zEdg/z)[EDGE] 500 error detected in Edge browserz[EDGE] URL: z[EDGE] Method: z[EDGE] Headers: z[EDGE] Error: a  
                <!DOCTYPE html>
                <html><head>
                    <title>RateRight - Loading...</title>
                    <meta http-equiv="refresh" content="2;url=/">
                    <meta charset="UTF-8">
                    <meta name="viewport" content="width=device-width, initial-scale=1.0">
                    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                </head><body>
                    <div style="text-align: center; padding: 50px; font-family: Arial, sans-serif;">
                        <h2>RateRight - Microsoft Edge Compatibility</h2>
                        <p>Optimizing experience for Edge browser...</p>
                        <p>Redirecting automatically...</p>
                        <p><a href="/">Click here if not redirected</a></p>
                    </div>
                    <script>
                        // Force redirect after brief delay for Edge
                        setTimeout(function() {
                            window.location.href = '/';
                        }, 1000);
                    </script>
                </body></html>
                r  zG<h1>500 - Internal Server Error</h1><p>RateRight encountered an error: z</p>)
rR   r   r<  r  rT   rN  r  r  r_  r   )r   r   r<  r  is_edgeedge_error_htmls         rz   handle_edge_500_errorzYregister_main_routes.<locals>.register_edge_error_handlers.<locals>.handle_edge_500_error  s     & ,,\2>J
*GACW[[M23'789(goo)>(?@As5zl34#. '++ ]]`af]g\hhlmorrrr|   N)errorhandler)r  r  s     rz   register_edge_error_handlersz:register_main_routes.<locals>.register_edge_error_handlers  s#     
		#	*	s 
*	sr|   z/scheduling/calendarc                      t        d      S )z$Render the scheduling calendar page.zscheduling/calendar.htmlrc  rZ  r|   rz   scheduling_calendarz1register_main_routes.<locals>.scheduling_calendar  s     9::r|   z/time-trackingc                     ddl m}  ddlm} | j                  j                  | j                  t        j                  k(  | j                  t        j                  k(  z        j                  | j                  j                               j                         }g }d}d}d}d}|D ]i  }|j                  |j                        }	|	j                  d      s0|j!                  ||	d       ||	d   d   z  }||	d   d   z  }||	d   d	   z  }|d
z  }k t#        |d      t#        |d      ||t%        |D 
cg c]  }
|
j&                  dk(  s|
 c}
      d}t)        d||t              S c c}
w )z4Display aggregate time tracking across all contractsr   r&   r0  r  r@  r:  r6  approved_hoursr4  rA   rJ   r@   )r6  r  r4  r  r   ztime_tracking/summary.html)contracts_with_hoursaggregate_summaryr   )r   r'   rH  r1  r]   r   r;   r   r_   r   r   r   r   r`   rI  rT   r   rh   r   rf   r   )r'   r1  rq   r  total_hours_alltotal_approved_alltotal_pending_allr  rD  rG  rr   r  s               rz   time_tracking_summaryz3register_main_routes.<locals>.time_tracking_summary  s    	(L NN))<??2x7M7MQ]Q`Q`7`a

(8&&++-
.ssu 	
  "! 
	%H.AA(++NJ~~i($++ (",-   :i#8#GG"j&;<L&MM"!Z	%:;L%MM!1$
	% !!4#$6:0. #	$R1QXX=QQ$R S
 (!5/%	
 	
 %Ss   /E$E$N)router   before_requestregister_blueprintr#   r   exemptr   )ir  r   r   r   r   r  rH  rR  BETA_ACCESS_CODESr[  r`  rd  rf  r~  r  r  r   r  r  r  r  r	  r,  r  rz  r  r  r  r  r  r  r  rb  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{  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r5  r7  r9  r=  rA  rE  rZ  r_  rc  rf  rh  rj  rl  rn  rq  r  r  r  r  r  r  r  si   `                                                                                                        rz   register_main_routesr     s:    	YYzE E 	YY~% %  	YYIh   IhV 	YY(),  *,6 	YY*VHY=0H  >0Hd 	YY45eD  6eDN 	V V 4  ?t 	YY}E E 	YY ? !?
 	YYs^1 1 	YYw} } 	YYzg gR 	YY:2   :2x 	YYw3  3" 	YYy3 3 	YY"VHY56 66p 	YY 6(Y3w 4wr 	YY$vhY7	[[-  8-^ 	YY|eV_Y5MH 6MH^ 	YY#$X %X  	YY)F8Y<\G  =\G| 	YYx%Y1_; 2_;@ 	YY{UFOY4R= 5R=h 	YYy < 	YY$ufoY>Kd  ?KdZ 	YY$ufoY>'M  ?'MR 	YY}ugY..  /.  	YY(5'Y:(  ;(
 	YY3eWYE(K F(KT 	YY!E6?Y;8< <8<t 	YY&' . ( .D 	YY(5&/YB)H C)HV 	YY|#  #$ 	YY&'oQ  (oQb 	YY"#;0  $;0| 	YY!"60  #60r 	YYz6  64 	YY{4  4 	YYz'A 'AR 	YYy  	YY;eV_YUz@  Vz@x 	YY4ufoYND
  OD
N 	YY2UFOYLR`  MR`j 	YY;fXYN*S  O*SX 	YY@6(YS;S  T;Sz 	YY@6(YSS  TS< 	YY|eWY-O  .O, 	YY:VHYM]E  N]E~ 	YY?@^^3   A3j 	YY:VHYM%  N%N 	YY;fXYN  O4 	YY7&YJF  KFB 	YY-.y
  /y
v 	YY67/8  8/8d 	YY2UFOYLG^  MG^T 	YY56".  7".H 	YYz06  06d 	YY"#h
  $h
V 	YY{6  6 	YY+,=  -=< 	YY ,6  !,6\ 	YY 6  !64 	YY 6  !6 	YY~6  6@ 	YY'(6  )6@ 	YY{UFOY4<w  5<w| 	YY)F8Y<+  =+\ 	YY#$6  %6( 	YY"#6  $6( 	YY%&6  '6( 	YY()6  *6* 	YY{6  66 	YY"#6  $6. 	YY!"6  #64 	YY{6  60 	YY<=6  >6( 	YY56RV  7RVj 	YYY8>b  9>b@ 	YY&'S  (S 	YY#$P  %P 	YY,vhY?<  @<~ 	YY*+O:  ,O:b 	YY./6  06@ 	YY/0=  1=
 	YY&':  (:, 	YY34V  5V8 	YY85&/YRAZ  SAZJ 	YY;<(  =(V 	YY"VHY5K  6KZ 	YY1E7YC2  D2h 	YY1H:YF  G, 	YY>?  @( 	YY?&YR  S4 	YY,vhY?'  @'R 	YY-xY@  A6 	YY34  5" 	YY:;QY  <QYf 	YY<=1Y  >1Yn 	YY !2  "22 	YY 2  !2.s` 	YY%&; '; 	YY +
  !+
r|   )z%d-%m-%Y)2rR   r   r   r   r   r   r   r	   r
   rK  r   r   r   r   r   r   r   loggingr   r   r   r   app.models.time_trackingr   r  r   r  r   rs  r   r   r   r   r   r   r    r!   sqlalchemy.dialects.postgresqlr"   rw  r#   r  r{   r  r   	getLoggerr  r   r   r  rZ  r|   rz   <module>r     s    c c c M M . .     . B 4 , ,  & & 0f5G  GR ()J   *JX 
		8	$ #"*DQ
r|   