FUNCTION Assign_Queues * Function..........: Assign_Queues *) Description: This function is used to assign queueus to employees from the "holding tank" *) Each user is supposed to get queues according his/her profile (Employee_Queue_Profiles) *) * Scope: Public * Parameters: tcQueue_Name_From, tcQueue_Name_To, tcDepartment_Code, tcUserID, tnNumberOfDays *$ Usage: *$ * Returns: *--------------------- Maintenance Section ---------------------- * Change Log: * CREATED 02/18/2005 - NN * MODIFIED 03/10/2005 - NN *---------------------------------------------------------------- LPARAMETERS tcQueue_Name_From, tcQueue_Name_To, tcDepartment_Code, tcUserID, tnNumberOfDays LOCAL ltStartProcessTime, lcSetTalk lcSetTalk = SET('talk') SET TALK OFF ltStartProcessTime = DATETIME() STRTOFILE("Started to run assigning queues process at " + TTOC(m.ltStartProcessTime) + CHR(13) + CHR(10),"AssignQueues.txt",0) #DEFINE START_TIME 28800 && 8 hours LOCAL lcError, lcSetExact, ltScheduledTime, ldScheduled_Date LOCAL ARRAY laOriginallyUsed[1] lnOriginallyUsed = AUSED(laOriginallyUsed) && Save the array of originally used tables lcError = "" lcSetExact = SET('exact') SET EXACT ON LOCAL ldTomorrow ldTomorrow = DATE() + 1 ** Get an array of queueable days SELECT TOP m.tnNumberOfDays Calendar_masters.tDate ; FROM ; mmVisCollect!Calendar_masters ; INNER JOIN mmVisCollect!CALENDAR_CHILDS ; ON Calendar_masters.ccalendar_masters_pk = CALENDAR_CHILDS.ccalendar_masters_fk ; INNER JOIN mmVisCollect!VISCODES ; ON VISCODES.cviscodes_pk = CALENDAR_CHILDS.ccalendar_code_fk ; WHERE Calendar_masters.tDate >= m.ldTomorrow ; AND VISCODES.ccode_value = "QD" ; INTO ARRAY arrQDays ORDER BY Calendar_masters.tDate * Get the PK of UNASSIGNED QUEUE LOCAL ARRAY arrQueue[1] SELECT cDepartment_Code, cQueue_Names_Pk FROM mmVisCollect!Queue_Names; WHERE cQueue_Name = m.tcQueue_Name_From ; AND cDepartment_Code LIKE m.tcDepartment_Code ; INTO ARRAY arrQueue * Get users (or one particular user if passed) SELECT Departments.cDepartment_Code, ; USERS.cUserID, USERS.iID AS iUserID ; FROM ; mmVisCollect!USERS ; INNER JOIN mmVisCollect!UsGrLink; ON USERS.iID = UsGrLink.iUserID ; INNER JOIN mmVisCollect!EMPLOYEE_TEAMS ; ON EMPLOYEE_TEAMS.cEmployee_teams_pk = UsGrLink.cemployee_teams_fk ; INNER JOIN mmVisCollect!Departments ; ON Departments.cdepartments_pk = EMPLOYEE_TEAMS.cemployee_departments_fk ; WHERE USERS.cUserID LIKE m.tcUserID ; AND EMPLOYEE_TEAMS.iActive_flag = 1 ; AND Departments.cDepartment_Code LIKE m.tcDepartment_Code ; AND Departments.iActive_flag = 1 ; AND UsGrLink.iActive_flag = 1 ; GROUP BY 1,2,3 ; ORDER BY 1,2,3 INTO CURSOR c_Users LOCAL lnI FOR lnI = 1 TO m.tnNumberOfDays IF NOT EMPTY(m.lcError) && Error occurred EXIT ENDIF ldScheduled_Date = TTOD(arrQDays[m.lnI]) ltScheduled_Time = DTOT(m.ldScheduled_Date) + START_TIME SELECT c_Users SCAN WHILE EMPTY(m.lcError) lcError = Assign_Accounts_To_User(@arrQueue, ; m.tcQueue_Name_To, c_Users.cDepartment_Code, ; c_Users.cUserID, c_Users.iUserID, ; m.ltScheduled_Time) ENDSCAN NEXT LOCAL lnNowUsed LOCAL ARRAY laCurUsed[1] lnNowUsed = AUSED(laCurUsed) FOR lnI = 1 TO m.lnNowUsed IF ASCAN(laOriginallyUsed,laCurUsed[m.lnI,1],1,m.lnOriginallyUsed,1) = 0 && this table was not used before USE IN (laCurUsed[m.lnI,1]) ENDIF NEXT IF m.lcSetExact = "OFF" SET EXACT OFF ENDIF IF m.lcSetTalk = "ON" SET TALK ON ENDIF LOCAL ltEndProcessTime ltEndProcessTime = DATETIME() STRTOFILE("Finished to run assigning queues process at " + TTOC(m.ltEndProcessTime) + ; CHR(13) + CHR(10) + IIF(!EMPTY(m.lcError), "Error encountered: " + m.lcError, ""), ; "AssignQueues.txt",1) RETURN m.lcError ****************************************** ************************************************************ * FUNCTION Assign_Accounts_To_User() ************************************************************ * Author............: Jzanus Dev Team * Project...........: Visual Collections * Created...........: 03/30/2005 10:38:17 * Copyright.........: (c) Jzanus LTD, 2005 *) Description.......: * Calling Samples...: * Parameter List....: * Major change list.: FUNCTION Assign_Accounts_To_User LPARAMETERS taQueues, tcQueue_Name_To, tcDepartment_Code, ; tcUserID, tiUserID, ttScheduled_Time EXTERNAL ARRAY taQueues LOCAL lcCommission_Owner_UsgrLink_fk, lcQueue_Names_Fk, lcError lcError = "" * now we're going to assign accounts to the individual user (tcUserID) * Let's get all roles for that user SELECT UsGrLink.cUsGrLink_pk, ; Queue_Names.cQueue_Names_Pk, Queue_Names.cQueue_Name, ; Queue_Names.cDepartment_Code, ; Employee_queue_profiles.cemployee_queue_profiles_pk, ; Employee_queue_profiles.ylow_dollar_balance_amount, ; Employee_queue_profiles.yhigh_dollar_balance_amount, ; Employee_queue_profiles.iregular_account_limit, ; Employee_queue_profiles.iqueue_overflow_count, ; Employee_queue_profiles.idelinquent_account_limit ; FROM mmVisCollect!UsGrLink ; INNER JOIN mmVisCollect!Employee_queue_profiles ; ON UsGrLink.cUsGrLink_pk = Employee_queue_profiles.cusgrlink_fk ; INNER JOIN mmVisCollect!Queue_Names ; ON Queue_Names.cQueue_Names_Pk = Employee_queue_profiles.cqueue_names_fk; WHERE UsGrLink.iUserID = m.tiUserID ; AND UsGrLink.iActive_flag = 1 ; AND Employee_queue_profiles.iActive_flag = 1 ; AND Queue_Names.cDepartment_Code LIKE m.tcDepartment_Code ; AND Queue_Names.cQueue_Name = m.tcQueue_Name_To ; ORDER BY UsGrLink.cUsGrLink_pk ; INTO CURSOR c_Profiles IF RECCOUNT('c_Profiles') > 0 LOCAL lnNumAccounts, lnQueue, lnAccountsToAssign * Find the maximum number of accounts to give to that user LOCAL ARRAY laMaxCount[1] SELECT SUM(NVL(iregular_account_limit,0) + NVL(iqueue_overflow_count,0)) ; AS lnNumAccounts FROM c_Profiles INTO ARRAY laMaxCount lnNumAccounts = laMaxCount[1] * Find the FK of the UNASSIGNED QUEUE lnQueue = ASCAN(taQueues, m.tcDepartment_Code, 1, ALEN(taQueues,1), 1) lcQueue_Names_Fk = taQueues [m.lnQueue, 2] && FK is the second element in the array * Get the unassigned accounts SELECT TOP m.lnNumAccounts TRANS.cTrans_Pk, ; Trans_Employees_Queues.cTrans_Employees_Queues_Pk, 0 AS iAssigned, ; SPACE(16) AS cCommission_Owner_UsGrLink_fk, ; SPACE(16) AS cqueue_names_fk ; FROM mmVisCollect!TRANS INNER JOIN mmVisCollect!Trans_Employees_Queues ; ON TRANS.cTrans_Pk = Trans_Employees_Queues.cTrans_fk ; WHERE ISNULL(Trans_Employees_Queues.cCommission_Owner_UsGrLink_fk) ; AND Trans_Employees_Queues.cqueue_names_fk = m.lcQueue_Names_Fk ; ORDER BY TRANS.tDate_Received ; INTO CURSOR curAccounts READWRITE && one more condition TRANS.cCommissioned_Owner =="" GO TOP IN curAccounts IF RECCOUNT('curAccounts') = 0 lcError = "Nothing to assign to the user " + m.tcUserID + " - queues exhausted!" RETURN m.lcError ENDIF LOCAL ltStart, ltEnd ltStart = DTOT(TTOD(m.ttScheduled_Time)) && 12 am ltEnd = DTOT(TTOD(m.ttScheduled_Time)+1)-1 && 1 sec. before midnight SELECT c_Profiles GO TOP SCAN WHILE EMPTY(m.lcError) lcCommission_Owner_UsgrLink_fk = c_Profiles.cUsGrLink_pk lcQueue_Names_Fk = c_Profiles.cQueue_Names_Pk LOCAL ARRAY arrScheduled[1] STORE 0 TO arrScheduled * Find how many accounts are already scheduled for the passed date to that User's role SELECT COUNT(*) AS cntScheduled ; FROM mmVisCollect!Trans_Employees_Queues ; INNER JOIN mmVisCollect!Employee_Queue_Schedules ; ON Trans_Employees_Queues.cTrans_Employees_Queues_Pk = ; Employee_Queue_Schedules.cTrans_Employees_Queues_fk ; WHERE Trans_Employees_Queues.cCommission_Owner_UsGrLink_fk = m.lcCommission_Owner_UsgrLink_fk ; AND Trans_Employees_Queues.cqueue_names_fk = m.lcQueue_Names_Fk ; AND BETWEEN(Employee_Queue_Schedules.tScheduled_Time, m.ltStart, m.ltEnd) ; INTO ARRAY arrScheduled ** This should be quite complicated logic to determine the number of accounts to assign lnAccountsToAssign = c_Profiles.iregular_account_limit - arrScheduled[1] IF m.lnAccountsToAssign > 0 REPLACE ; iAssigned WITH 1 ; cCommission_Owner_UsGrLink_fk WITH m.lcCommission_Owner_UsgrLink_fk, ; cqueue_names_fk WITH m.lcQueue_Names_Fk ; NEXT m.lnAccountsToAssign IN curAccounts IF _TALLY < m.lnAccountsToAssign lcError = "Not enough unassigned accounts to assign to the user " + m.tcUserID ENDIF ENDIF ENDSCAN IF EMPTY(m.lcError) lcError = Update_Queue_Tables('curAccounts', m.ttScheduled_Time, m.tcUserID) ENDIF ENDIF RETURN m.lcError ************************************************************ * FUNCTION Update_Queue_Tables() ************************************************************ * Author............: Jzanus Dev Team * Project...........: Visual Collections * Created...........: 03/30/2005 11:38:57 * Copyright.........: (c) Jzanus LTD, 2005 *) Description.......: * Calling Samples...: * Parameter List....: * Major change list.: FUNCTION Update_Queue_Tables LPARAMETERS tcAlias, ttTime, tcUserID * Open three tables to be updated IF NOT USED('updTrans') USE TRANS IN 0 ALIAS updTrans AGAIN SHARED ORDER TAG cTrans_Pk ENDIF IF NOT USED('updEmp_Queues') USE Trans_Employees_Queues IN 0 ALIAS updEmp_Queues ; AGAIN SHARED ORDER TAG cEmpQue_Pk ENDIF IF NOT USED('updSchedules') USE Employee_Queue_Schedules IN 0 ALIAS updSchedules ; AGAIN SHARED ENDIF LOCAL ; lcTrans_pk, ; lcTrans_Employees_Queues_pk, ; lcCommission_Owner_UsgrLink_fk, ; lcQueue_Names_Fk, lcError, llFailure ** Now let's update Trans, Trans_Employee_Queues and Employee_Queue_Schedules tables BEGIN TRANSACTION SELECT(m.tcAlias) GO TOP lcError = "" llFailure = .F. SCAN FOR iAssigned = 1 AND EMPTY(m.lcError) AND NOT m.llFailure lcTrans_pk = cTrans_Pk lcTrans_Employees_Queues_pk = cTrans_Employees_Queues_Pk lcCommission_Owner_UsgrLink_fk = cCommission_Owner_UsGrLink_fk lcQueue_Names_Fk = cqueue_names_fk IF SEEK(m.lcTrans_pk,"UpdTrans") TRY REPLACE cCommissioned_Owner WITH m.tcUserID IN updTrans CATCH llFailure = .T. ENDTRY ENDIF IF NOT m.llFailure AND SEEK(m.lcTrans_Employees_Queues_pk,"UpdEmp_Queues") TRY REPLACE cCommission_Owner_UsGrLink_fk ; WITH m.lcCommission_Owner_UsgrLink_fk, ; cqueue_names_fk WITH m.lcQueue_Names_Fk ; IN updEmp_Queues CATCH llFailure = .T. ENDTRY ENDIF * I found, that structured error handling doesn't work with Insert/Update commands if triggers are involved * Perhaps it's a VFP bug IF NOT m.llFailure IF NOT SEEK(m.lcTrans_Employees_Queues_pk,"updSchedules", "CEMPQUE_FK") TRY INSERT INTO updSchedules (cTrans_Employees_Queues_fk, cDiary_Code_fk, tScheduled_Time, iActive_At_Day_Start_Flag) ; VALUES ; (m.lcTrans_Employees_Queues_pk, .NULL., m.ttTime, 1) CATCH llFailure = .T. ENDTRY ELSE * This account is already scheduled - should not happen lcError = "The account " + m.lcTrans_Employees_Queues_pk + " is already scheduled!" ENDIF ENDIF ENDSCAN IF m.llFailure IF TYPE('gaTriggerErrors[1]')<>"U" LOCAL lnI FOR lnI = 1 TO ALEN(gaTriggerErrors) lcError = m.lcError + gaTriggerErrors [m.lnI] + CHR(13) NEXT ENDIF ENDIF IF EMPTY(m.lcError) END TRANSACTION ELSE ROLLBACK ENDIF RETURN m.lcError ENDFUNC>Can you show us how these number flow into the fields you provided? Also what those fields are supposed to mean could help.