<cfcomponent>
	<cffunction name="init" access="public" returntype="queries">
        <cfargument name="dataSrc" type="string" required="yes">
        <cfargument name="prefixDbLookup" type="string" required="yes">
        
        <cfset variables.dataSrc = trim(arguments.dataSrc)>
        <cfset variables.prefixDbLookup = trim(arguments.prefixDbLookup)>

        <cfreturn this>
	</cffunction>

    <cffunction name="getSuperUser" access="public" returntype="query">
        <cfargument name="userName" type="string" required="yes">

        <cfset var qUser = ''>

        <cfquery name="qUser" datasource="#variables.DataSrc#">
            SELECT SuperUsers.User_Id AS Emp_ID,SuperUsers.Username FROM #variables.prefixDbLookup#.SuperUsers
            WHERE Username = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.userName)#" maxlength="30">
        </cfquery>

        <cfreturn qUser>
	</cffunction>

    <cffunction name="checkLoginSuperUser" access="public" returntype="query">
        <cfargument name="userName" type="string" required="yes">
        <cfargument name="password" type="string" required="yes">

        <cfset var qLogin = ''>

        <cfquery name="qLogin" datasource="#variables.DataSrc#">
            SELECT pEmployee.Emp_ID AS Login_Id,SuperUsers.User_Id AS Emp_ID,SuperUsers.Username, 
                Agency.Agency_ID, Agency.Super_ID, Agency.Agency_Login, pEmployee.Emp_Email AS Emp_Email,
                pEmployee.Emp_Telephone AS Emp_Telephone ,SuperUsers.Two_FA_Type AS Two_FA_Type
            FROM  #variables.prefixDbLookup#.SuperUsers, #variables.prefixDbLookup#.pEmployee 
            <!--- LEFT  OUTER JOIN #variables.prefixDbLookup#.Physician ON Employee.Emp_ID = Physician.Emp_ID --->
            LEFT  JOIN #variables.prefixDbLookup#.Agency ON pEmployee.Loc_ID = Agency.Agency_ID
            WHERE SuperUsers.Super_ID = Agency.Super_ID 
            AND   Agency_Login =        <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.userName)#" maxlength="30">
            AND   SuperUsers.Username = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.password)#" maxlength="30">
            AND Agency.Status = 'active'
        </cfquery>

        <cfreturn qLogin>
	</cffunction>

    <cffunction name="checkLoginEmployee" access="public" returntype="query">
        <cfargument name="Username" type="string" required="yes">
        <cfargument name="encryptedPassword" type="string" required="yes">

        <cfset var qLogin = ''>

        <cfquery name="qLogin" datasource="#variables.DataSrc#">
            SELECT pEmployee.Emp_ID,pEmployee.Username, pEmployee.Password, pEmployee.Emp_ID AS Login_Id,Agency.Agency_Id,Agency.Agency_Login, pEmployee.Emp_Email,1 AS PPInUse             
            ,pPhysicians.Emp_ID, pPhysicians.Phys_ID,0 AS Portal , pEmployee.Emp_Telephone , pEmployee.Two_FA_Type  
            FROM #variables.prefixDbLookup#.pEmployee  
            LEFT JOIN #variables.prefixDbLookup#.Agency ON pEmployee.Loc_ID = Agency.Agency_ID 
            LEFT OUTER JOIN #variables.prefixDbLookup#.pPhysicians ON pEmployee.Emp_ID = pPhysicians.Emp_ID 
            WHERE pEmployee.Username = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.Username)#" maxlength="64">
            AND pEmployee.Password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.encryptedPassword)#">
            AND pEmployee.Emp_Type != 'Physician'
            AND Agency.Status = <cfqueryparam cfsqltype="cf_sql_integer" value="0" maxlength="8">
            AND pEmployee.Status = <cfqueryparam cfsqltype="cf_sql_integer" value="0" maxlength="8">
        </cfquery>

        <cfreturn qLogin>
	</cffunction>

    <cffunction name="getInfoEmployee" access="public" returntype="query">
        <cfargument name="employeeId" type="numeric" required="yes">

        <cfset var qEmployee = ''>

        <cfquery name="qEmployee" datasource="#variables.DataSrc#">
            SELECT pEmployee.Emp_ID , pEmployee.Emp_Email, pEmployee.Emp_Telephone , pEmployee.Two_FA_Type , pEmployee.Two_FA_Code , Two_FA_CreationTime
            FROM #variables.prefixDbLookup#.pEmployee              
            WHERE pEmployee.Emp_ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(arguments.employeeId)#">
        </cfquery>

        <cfreturn qEmployee>
	</cffunction>

    <cffunction name="getLastLoggedTimeUser" access="public" returntype="query">
        <cfargument name="employeeId" type="numeric" required="yes">

        <cfset var qLogon = ''>

        <cfquery name="qLogon" datasource="#variables.DataSrc#">
            SELECT Logon_Date 
            FROM #variables.prefixDbLookup#.Logon              
            WHERE Emp_ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(arguments.employeeId)#">
            order by Logon_Date DESC limit 1
        </cfquery>

        <cfreturn qLogon>
	</cffunction>

    <cffunction name="checkTwoFACode" access="public" returntype="query">
        <cfargument name="code" type="numeric" required="yes">
        <cfargument name="employeeId" type="numeric" required="no">

        <cfset var qGetTwoFACode = ''>

        <cfquery name="qGetTwoFACode" datasource="#variables.DataSrc#">
            SELECT Two_FA_Code FROM #variables.prefixDbLookup#.pEmployee
            WHERE Two_FA_Code = <cfqueryparam value ="#trim(arguments.code)#" cfsqltype ="cf_sql_integer">
            <cfif StructKeyExists(arguments, "employeeId") AND IsValid(integer, arguments.employeeId)>
                WHERE Emp_ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(arguments.employeeId)#">
            </cfif>
        </cfquery>

        <cfreturn qGetTwoFACode>
	</cffunction>

    <cffunction name="updateTwoFACode" access="public" returnType="boolean">
        <cfargument name="code" type="string" required="yes">
        <cfargument name="employeeId" type="numeric" required="no">

        <cfset var qUpdateTwoFaCode = ''>
        <cfset var success = false>

        <cftry>
            <cfquery name="qUpdateTwoFaCode" datasource="#Variables.dataSrc#">
                UPDATE #variables.prefixDbLookup#.pEmployee
                SET Two_FA_Code = <cfqueryparam value ="#trim(arguments.code)#" cfsqltype ="cf_sql_integer" null="#(arguments.code EQ 0)#">,
                Two_FA_CreationTime = <cfqueryparam value ="#now()#" cfsqltype ="cf_sql_timestamp" null="#(arguments.code EQ 0)#">
                <cfif StructKeyExists(arguments, "employeeId") AND IsValid('integer', arguments.employeeId)>
                    WHERE Emp_ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(arguments.employeeId)#">
                </cfif>   
            </cfquery>
            <cfset success = true>            
        <cfcatch>
            <cfset success = false>
        </cfcatch>
        </cftry>

        <cfreturn success>
	</cffunction>

    <cffunction name="updateTwoFAMethod" access="public" returnType="boolean">
        <cfargument name="authenticationType" type="numeric" required="yes">
        <cfargument name="emailOrTelephone" type="string" required="yes">
        <cfargument name="employeeId" type="numeric" required="yes">

        <cfset var qUpdateTwoFaCode = ''>
        <cfset var success = false>

        <cftry>
            <cfquery name="qUpdateTwoFaMethodAuthentication" datasource="#Variables.dataSrc#">
                UPDATE #variables.prefixDbLookup#.pEmployee
                SET Two_FA_Type = <cfqueryparam value ="#trim(arguments.authenticationType)#" cfsqltype ="cf_sql_integer">
                <cfif trim(arguments.emailOrTelephone) neq ""> 
                    <cfif trim(arguments.authenticationType) eq 1>
                        , Emp_Email = <cfqueryparam value ="#trim(arguments.emailOrTelephone)#" cfsqltype ="cf_sql_varchar" maxlength="100">
                    <cfelseif arguments.authenticationType eq 2>
                        , Emp_Telephone = <cfqueryparam value ="#trim(arguments.emailOrTelephone)#" cfsqltype ="cf_sql_varchar" maxlength="64">
                    </cfif>                
                </cfif>
                WHERE Emp_ID = <cfqueryparam value ="#trim(arguments.employeeId)#" cfsqltype ="cf_sql_integer">     
            </cfquery>
            <cfset success = true>            
        <cfcatch>
            <cfset success = false>
        </cfcatch>
        </cftry>

        <cfreturn success>
	</cffunction>

     <cffunction name="getPendingOrders" access="remote" returntype="query">
        <cfargument name="patient_Id" type="numeric" required="yes">

        <cfset var qPendingOrders = ''>

        <cfquery name="qPendingOrders" datasource="hhapowerpath">
            SELECT pPatients.Patient_ID,pCMS4857.Order_ID,pCMS4857.Date_Create,pCMS4857.Form_Type,LEFT(pCMS4857.Order_description , 25) AS description
            FROM #Request.prefix_db_agency#.pCMS4857 
            LEFT OUTER JOIN #Request.prefix_db_agency#.pAssessments ON pAssessments.Assmt_ID =  pCMS4857.Assmt_ID AND pAssessments.status =0 
            LEFT OUTER JOIN #Request.prefix_db_agency#.pPatients ON pPatients.Patient_ID =  pAssessments.Patient_ID AND pAssessments.status < 2
            WHERE 
             pCMS4857.Form_status = 'Sent via Fax' 
            AND pCMS4857.status = 0 
            AND pPatients.Patient_ID = <cfqueryparam value ="#trim(arguments.patient_Id)#" cfsqltype ="cf_sql_integer">
            GROUP BY pCMS4857.Order_ID
        </cfquery>

        <cfreturn qPendingOrders>
    </cffunction>


    <cffunction name="fax_udpate"   access="remote" returnFormat= "JSON" >
            <cfargument name="Order_ID" type="numeric" required="yes">
            <cfargument name="Fax_ID" type="numeric" required="yes">

           <cfquery name="Update_orders" datasource="#Application.DataSrc#">
               UPDATE #Request.prefix_db_agency#.pCMS4857  SET  Form_status = 'Signed & Received via Fax',
               Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
               WHERE Order_ID =   <cfqueryparam value ="#trim(arguments.Order_ID)#" cfsqltype ="cf_sql_integer">
            </cfquery>

            <cfquery name="update_Received_faxes" datasource="#Application.DataSrc#">
               UPDATE #Request.prefix_db_lookup#.Received_faxes  SET  
               Order_ID =  <cfqueryparam value ="#trim(arguments.Order_ID)#" cfsqltype ="cf_sql_integer">,
               Agency_ID =  <cfqueryparam value ="#trim(session.agencyid)#" cfsqltype ="cf_sql_integer">,
                Change_by =  <cfqueryparam value ="#trim(session.employeeid)#" cfsqltype ="cf_sql_integer">,
                Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
               WHERE ID =   <cfqueryparam value ="#trim(arguments.Fax_ID)#" cfsqltype ="cf_sql_integer">
            </cfquery>
            
            <cfset response_key={"statusCode"= 200,"statusText"= 'success',"data"= 'success' } />
            <cfreturn  response_key >
    </cffunction>


     <cffunction name="fax_patientudpate"   access="remote" returnFormat= "JSON" >
            <cfargument name="Patient_ID" type="numeric" required="yes">
            <cfargument name="Fax_ID" type="numeric" required="yes">
            <cfargument name="Order_ID" type="numeric" required="no" default="0">
            <cfif arguments.Order_ID NEQ 0 >
                 <cfquery name="Update_orders" datasource="#Application.DataSrc#">
                   UPDATE #Request.prefix_db_agency#.pCMS4857  SET  Form_status = 'Signed & Received via Fax',
                   Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
                   WHERE Order_ID =   <cfqueryparam value ="#trim(arguments.Order_ID)#" cfsqltype ="cf_sql_integer">
                </cfquery>
            </cfif>

            <cfquery name="update_Received_faxes" datasource="#Application.DataSrc#">
               UPDATE #Request.prefix_db_lookup#.Received_faxes  SET  
               <cfif arguments.Order_ID NEQ 0 >
                    Order_ID =  <cfqueryparam value ="#trim(arguments.Order_ID)#" cfsqltype ="cf_sql_integer">,
                </cfif>
               Patient_ID =  <cfqueryparam value ="#trim(arguments.Patient_ID)#" cfsqltype ="cf_sql_integer">,
               Agency_ID =  <cfqueryparam value ="#trim(session.agencyid)#" cfsqltype ="cf_sql_integer">,
               Change_by =  <cfqueryparam value ="#trim(session.employeeid)#" cfsqltype ="cf_sql_integer">,
               Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
               WHERE ID =   <cfqueryparam value ="#trim(arguments.Fax_ID)#" cfsqltype ="cf_sql_integer">
            </cfquery>
            
            <cfset response_key={"statusCode"= 200,"statusText"= 'success',"data"= 'success' } />
            <cfreturn  response_key >
    </cffunction>


    <cffunction name="fax_delete"   access="remote" returnFormat= "JSON" >
            <cfargument name="Fax_ID" type="numeric" required="yes">
            <cfargument name="status" type="numeric" required="no" default="0">

            <cfquery name="update_Received_faxes" datasource="#Application.DataSrc#">
               UPDATE #Request.prefix_db_lookup#.Received_faxes  SET  
                status =  <cfqueryparam value ="#trim(arguments.status)#" cfsqltype ="cf_sql_integer">,
                Change_by =  <cfqueryparam value ="#trim(session.employeeid)#" cfsqltype ="cf_sql_integer">,
               Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
               WHERE ID =   <cfqueryparam value ="#trim(arguments.Fax_ID)#" cfsqltype ="cf_sql_integer">
            </cfquery>           
            <cfset response_key={"statusCode"= 200,"statusText"= 'success',"data"= 'success' } />
            <cfreturn  response_key >
    </cffunction>

    <!--- #10714: undo a fax-to-order pairing. The fax goes back to the Received FAX list (Order_ID = 0);
         the order goes back to 'Sent via Fax' unless another active fax is still paired to it. --->
    <cffunction name="fax_unassign" access="remote" returnFormat="JSON">
            <cfargument name="Fax_ID" type="numeric" required="yes">
            <cfset var getFax = "" />
            <cfset var otherFax = "" />
            <cfset var agencyId = (isDefined("session.agencyid") AND isNumeric(session.agencyid)) ? Val(session.agencyid) : 0 />
            <cfset var empId = (isDefined("session.employeeid") AND isNumeric(session.employeeid)) ? Val(session.employeeid) : 0 />
            <cfset var orderReverted = false />

            <cfif agencyId LTE 0 OR empId LTE 0>
                <cfreturn {"statusCode" = 401, "statusText" = "error", "data" = "Session expired. Please log in again."} />
            </cfif>

            <cfquery name="getFax" datasource="#Application.DataSrc#">
               SELECT ID, Order_ID FROM #Request.prefix_db_lookup#.Received_faxes
               WHERE ID = <cfqueryparam value="#arguments.Fax_ID#" cfsqltype="cf_sql_integer">
               AND Agency_ID = <cfqueryparam value="#agencyId#" cfsqltype="cf_sql_integer">
               AND Order_ID > 0
               AND status = 0
            </cfquery>
            <cfif getFax.recordcount EQ 0>
                <cfreturn {"statusCode" = 404, "statusText" = "error", "data" = "Fax not found or already unassigned."} />
            </cfif>

            <cftransaction>
                <cfquery name="unassignFax" datasource="#Application.DataSrc#">
                   UPDATE #Request.prefix_db_lookup#.Received_faxes SET
                   Order_ID = 0,
                   Change_by = <cfqueryparam value="#empId#" cfsqltype="cf_sql_integer">,
                   Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
                   WHERE ID = <cfqueryparam value="#getFax.ID#" cfsqltype="cf_sql_integer">
                </cfquery>
                <cfquery name="otherFax" datasource="#Application.DataSrc#">
                   SELECT COUNT(*) AS n FROM #Request.prefix_db_lookup#.Received_faxes
                   WHERE Agency_ID = <cfqueryparam value="#agencyId#" cfsqltype="cf_sql_integer">
                   AND Order_ID = <cfqueryparam value="#getFax.Order_ID#" cfsqltype="cf_sql_integer">
                   AND status = 0
                </cfquery>
                <cfif Val(otherFax.n) EQ 0>
                    <cfquery name="revertOrder" datasource="#Application.DataSrc#" result="revertResult">
                       UPDATE #Request.prefix_db_agency#.pCMS4857 SET
                       Form_status = 'Sent via Fax',
                       Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">,
                       Change_by = <cfqueryparam value="#empId#" cfsqltype="cf_sql_integer">
                       WHERE Order_ID = <cfqueryparam value="#getFax.Order_ID#" cfsqltype="cf_sql_integer">
                       AND Status = 0
                       AND Form_status = 'Signed & Received via Fax'
                    </cfquery>
                    <cfset orderReverted = (revertResult.recordcount GT 0) />
                </cfif>
            </cftransaction>

            <cflog file="faxLog" type="information" text="Fax unassign: Agency #agencyId# fax row #getFax.ID# unpaired from Order_ID #getFax.Order_ID# by Emp_ID #empId#; order reverted to Sent via Fax: #orderReverted#" />
            <cfreturn {"statusCode" = 200, "statusText" = "success", "data" = "success", "order_reverted" = orderReverted} />
    </cffunction>

    <cffunction name="cron_fax_update" access="public" returnType="struct">
        <cfargument name="agency_id" type="string" required="yes">
        <cfargument name="order_id" type="string" required="yes">
        <cfargument name="ID" type="string" required="yes">
        <cfset var response_key = {} />
        <cfset var resolvedAgencyId = Trim(ToString(arguments.agency_id)) />
        <cfset var resolvedOrderId = Trim(ToString(arguments.order_id)) />
        <cfset var slashParts = [] />
        <cfset var concatPrefixLen = 5 />
        <cfset var candidateOrderId = "" />

        <cftry>

            <!--- OCR sometimes returns "1150/20725" as a single order_id --->
            <cfif Find("/", resolvedOrderId)>
                <cfset slashParts = ListToArray(resolvedOrderId, "/") />
                <cfif ArrayLen(slashParts) GTE 2 AND isNumeric(Trim(slashParts[1])) AND isNumeric(Trim(slashParts[2]))>
                    <cfset resolvedAgencyId = Trim(ToString(slashParts[1])) />
                    <cfset resolvedOrderId = Trim(ToString(slashParts[2])) />
                </cfif>
            </cfif>

            <!--- Safety net: if still concatenated (e.g. 1150120475), strip first 5 digits when left matches Agency_ID --->
            <cfif isNumeric(resolvedOrderId)
                AND isNumeric(resolvedAgencyId) AND Val(resolvedAgencyId) GT 0
                AND Len(resolvedOrderId) GT concatPrefixLen
                AND Left(resolvedOrderId, Len(resolvedAgencyId)) EQ resolvedAgencyId>
                <cfset candidateOrderId = Right(resolvedOrderId, Len(resolvedOrderId) - concatPrefixLen) />
                <cfif isNumeric(candidateOrderId) AND Val(candidateOrderId) GT 0>
                    <cfset resolvedOrderId = Trim(ToString(candidateOrderId)) />
                </cfif>
            </cfif>

            <cfif NOT isNumeric(resolvedAgencyId) OR NOT isNumeric(resolvedOrderId) OR Val(resolvedAgencyId) LTE 0 OR Val(resolvedOrderId) LTE 0>
                <cfset response_key = {
                    "statusCode" = 400,
                    "statusText" = "error",
                    "data" = "Invalid agency_id or order_id after OCR resolve",
                    "agency_id" = resolvedAgencyId,
                    "order_id" = resolvedOrderId,
                    "raw_order_id" = arguments.order_id
                } />
                <cfreturn response_key />
            </cfif>

            <cfset Request.prefix_db_agency = "agency_" & resolvedAgencyId />
            <!--- Update the pCMS4857 table with Form_status --->
            <cfquery name="Update_orders" datasource="#Application.DataSrc#">
               UPDATE #Request.prefix_db_agency#.pCMS4857 
                SET  Form_status = 'Signed & Received via Fax',
               Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
               WHERE Order_ID =   <cfqueryparam value="#resolvedOrderId#" cfsqltype="cf_sql_integer">
               AND Status = 0
            </cfquery>
             <!--- Update the Received_faxes table with agency_id and order_id --->
            <cfquery name="update_Received_faxes" datasource="#Application.DataSrc#">
               UPDATE #Request.prefix_db_lookup#.Received_faxes  SET  
               Order_ID =  <cfqueryparam value="#resolvedOrderId#" cfsqltype="cf_sql_integer">,
               Agency_ID =  <cfqueryparam value="#resolvedAgencyId#" cfsqltype="cf_sql_integer">,
                Change_by =  2,
                Date_Change = <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
               WHERE ID =   <cfqueryparam value="#trim(arguments.ID)#" cfsqltype="cf_sql_integer">
               ANd status = 0
            </cfquery>
            <cfset response_key = {
                "statusCode" = 200,
                "statusText" = "success",
                "data" = "success",
                "agency_id" = resolvedAgencyId,
                "order_id" = resolvedOrderId
            } />
            <cfreturn response_key />
         <cfcatch>
            <cfset response_key = {"statusCode" = 500, "statusText" = "error", "data" = "Error updating fax: #CFCATCH.Message#"} />
            
            <!--- Send error notification email --->
            <cftry>
                <cfmail to="velmurugan@myhomecarebiz.com" 
                        from="noreply@myhomecarebiz.com" 
                        subject="OCR Fax Processing Error" 
                        type="html">
                    <h3>OCR Fax Processing Error</h3>
                    <p><strong>Error Details:</strong></p>
                    <ul>
                        <li><strong>Error Message:</strong> #CFCATCH.Message#</li>
                        <li><strong>Error Detail:</strong> #CFCATCH.Detail#</li>
                        <li><strong>Error Type:</strong> #CFCATCH.Type#</li>
                        <li><strong>Timestamp:</strong> #now()#</li>
                    </ul>
                    <p><strong>Fax Information:</strong></p>
                    <ul>
                        <li><strong>Agency ID:</strong> #arguments.agency_id#</li>
                        <li><strong>Order ID:</strong> #arguments.order_id#</li>
                        <li><strong>Fax ID:</strong> #arguments.ID#</li>
                    </ul>
                    <p>Please investigate this error and take appropriate action.</p>
                </cfmail>
            <cfcatch>
                <!--- If email fails, log it but don't break the main process --->
                <cflog file="faxLogerror" text="Failed to send error notification email: #CFCATCH.Message#" type="error">
            </cfcatch>
            </cftry>
        </cfcatch>
        </cftry>

        <cfreturn response_key />
    </cffunction>


</cfcomponent>