barcode. Implemented 2D barcode verification in PTI and FQA Label Check Operations. Bug fixes Changed WMI 2D barcode to have 8 fields to keep code base simpler minor changes to error message verbiage Refactored code to use post log. Refactored code to not use multiple returns. Modfield input form fields to force upper case only. changed LSL password verification to be case insensitive to avoid barcode scanning issues when caps lock is on temporary change to allow 1D WMI scans at PTI while we exhaust current supply
1569 lines
69 KiB
Plaintext
1569 lines
69 KiB
Plaintext
Function Work_Order_Services(@Service, @Params)
|
|
/***********************************************************************************************************************
|
|
|
|
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
|
|
permission from SRP Computer Solutions, Inc.
|
|
|
|
Name : Work_Order_Services
|
|
|
|
Description : Handler program for all module related services.
|
|
|
|
Notes : The generic parameters should contain all the necessary information to process the services. Often
|
|
this will be information like the data Record and Key ID.
|
|
|
|
Parameters :
|
|
Service [in] -- Name of the service being requested
|
|
Param1-10 [in/out] -- Additional request parameter holders
|
|
Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure
|
|
|
|
Metadata :
|
|
|
|
History : (Date, Initials, Notes)
|
|
06/16/17 dmb Original programmer. - [EPIOI-8]
|
|
11/23/20 djs Added CreateOutbound service.
|
|
|
|
***********************************************************************************************************************/
|
|
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
$insert APP_INSERTS
|
|
$insert SERVICE_SETUP
|
|
$insert WO_LOG_EQUATES
|
|
$insert EPI_PART_EQUATES
|
|
$insert WO_MAT_EQUATES
|
|
$insert WO_STEP_EQUATES
|
|
$insert WO_SCHEDULE_EQUATES
|
|
$insert WO_SCHEDULE_NG_EQUATES
|
|
$insert RDS_EQUATES
|
|
$insert PROD_SPEC_EQUATES
|
|
$insert PRS_LAYER_EQU
|
|
$insert PROD_VER_EQUATES
|
|
$insert WO_MAT_WFR_EQUATES
|
|
$insert MSG_EQUATES
|
|
$insert POPUP_EQUATES
|
|
$insert LOGICAL
|
|
$insert RLIST_EQUATES
|
|
$insert COMPANY_EQUATES
|
|
$Insert NOTIFICATION_EQUATES
|
|
$Insert WM_IN_EQUATES
|
|
$Insert WM_OUT_EQUATES
|
|
|
|
Declare subroutine Error_Services, Work_Order_Services, Memory_Services, RList, Database_Services, SRP_JSON
|
|
Declare subroutine Btree.Extract, Set_Status, obj_WO_Log, obj_Notes, Print_Wo_Mat_In_Labels, Print_Wo_Mat_Out_Labels
|
|
Declare subroutine Print_Wmi_Labels, Print_Wmo_Labels, ErrMsg, Print_Cass_Labels, Logging_Services, Service_Services
|
|
Declare subroutine obj_WO_Mat_Log, WO_Mat_Services, Work_Order_Services
|
|
Declare function SRP_Array, Work_Order_Services, Memory_Services, Database_Services, SRP_Sort_Array, SRP_JSON
|
|
Declare function Company_Services, obj_Prod_Spec, Schedule_Services, Datetime, obj_WO_Log, obj_WO_Step, Memberof
|
|
Declare function Environment_Services, Logging_Services, Hold_Services, Signature_Services
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Release Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'Notes'
|
|
objReleaseLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Void Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'CassetteId' : @FM : 'Notes'
|
|
objVoidLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
|
|
|
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
|
|
|
GoToService else
|
|
Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.')
|
|
end
|
|
|
|
Return Response else ''
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Service Parameter Options
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Options BOOLEAN = True$, False$
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Services
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetUnscheduledWorkOrders
|
|
//
|
|
// Returns an array of unscheduled work order details based on the arguments provided.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetUnscheduledWorkOrders(ReactorType, SusceptorSize, ReactorNo)
|
|
|
|
WorkOrders = ''
|
|
// Select WO_LOG rows that do not have a closed date.
|
|
OpenWOLogKeyIDs = Database_Services('SearchIndex', 'WO_LOG', 'CLOSE_DATE', '=', True$)
|
|
// Check each WO_LOG Key ID against the WO_SCHEDULE table. If the row does not exist or if the row does not have any
|
|
// SCED_DET Key IDs, exists then it is not scheduled an should be included.
|
|
WOLogKeyIDs = Str(\00\, 100000)
|
|
If OpenWOLogKeyIDs NE '' then
|
|
hWOSchedule = Database_Services('GetTableHandle', 'WO_SCHEDULE')
|
|
If Error_Services('NoError') then
|
|
cPos = 1
|
|
For Each WOLogKeyID in OpenWOLogKeyIDs using @FM
|
|
Read WOScheduleRow from hWOSchedule, WOLogKeyID then
|
|
If WOScheduleRow<WO_SCHEDULE_SCHED_DET_KEY_IDS$> EQ '' then
|
|
WOLogKeyIDs[cPos, Len(WOLogKeyID) + 1] = WOLogKeyID : @FM
|
|
cPos += Len(WOLogKeyID) + 1
|
|
end
|
|
end else
|
|
WOLogKeyIDs[cPos, Len(WOLogKeyID) + 1] = WOLogKeyID : @FM
|
|
cPos += Len(WOLogKeyID) + 1
|
|
end
|
|
Next WOLogKeyID
|
|
end
|
|
end
|
|
Convert \00\ to '' in WOLogKeyIDs
|
|
WOLogKeyIDs[-1, 1] = ''
|
|
|
|
If Error_Services('NoError') then
|
|
For Each WOLogKeyID in WOLogKeyIDs using @FM setting fPos
|
|
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WOLogKeyID)
|
|
EpiPartNo = WOLogRow<WO_LOG_EPI_PART_NO$>
|
|
ProdVerNo = WOLogRow<WO_LOG_PROD_VER_NO$>
|
|
ProdVerRow = Database_Services('ReadDataRow', 'PROD_VER', ProdVerNo)
|
|
PSN = ProdVerRow<PROD_VER_PROC_STEP_PSN$>
|
|
ProdSpecRow = Database_Services('ReadDataRow', 'PROD_SPEC', PSN)
|
|
BlockedReactors = ProdSpecRow<PROD_SPEC_BLOCKED_REACTS$>
|
|
PSNBlock = False$
|
|
If EpiPartNo NE '' then
|
|
AcceptWorkOrder = True$ ; // Assume this work order is acceptable for now.
|
|
ReactType = WOLogRow<WO_LOG_REACT_TYPE$>
|
|
// The following two lines of code are temporary but necessary to allows work orders
|
|
// for ASM to be scheduled on ASM+ and vice-versa.
|
|
If ReactType _EQC 'ASM+' then ReactType = 'ASM'
|
|
If ReactorType _EQC 'ASM+' then ReactorType = 'ASM'
|
|
If (ReactorType NE '') AND (ReactType NE ReactorType) then
|
|
// The reactor type for this work order does not match the required reactor type.
|
|
AcceptWorkOrder = False$
|
|
end
|
|
If AcceptWorkOrder AND SusceptorSize NE '' then
|
|
EpiPart = Database_Services('ReadDataRow', 'EPI_PART', EpiPartNo)
|
|
SuscSize = EpiPart<EPI_PART_SUB_WAFER_SIZE$>
|
|
If SuscSize NE SusceptorSize then
|
|
// The susceptor size for this work order does not match the required susceptor size.
|
|
AcceptWorkOrder = False$
|
|
end
|
|
end
|
|
If (BlockedReactors NE '') AND (ReactorNo NE '') then
|
|
// This work order uses a part spec that is blocked on the current reactor.
|
|
Locate ReactorNo in BlockedReactors using @VM setting vPos then PSNBlock = True$
|
|
end
|
|
If AcceptWorkOrder then
|
|
CustNo = WOLogRow<WO_LOG_CUST_NO$>
|
|
CompanyRow = Database_Services('ReadDataRow', 'COMPANY', CustNo)
|
|
CustName = CompanyRow<42>
|
|
Swap True$ with 'Yes' in PSNBlock
|
|
Swap False$ with '' in PSNBlock
|
|
WorkOrders := WOLogKeyID : @VM : EpiPartNo : @VM : CustName : @VM : ReactType : @VM : PSNBlock : @FM
|
|
end
|
|
end
|
|
Next WOLogKeyID
|
|
|
|
WorkOrders[-1, 1] = ''
|
|
WorkOrders = SRP_Array('SortRows', WorkOrders, 'AR1' : @FM : 'AR2', 'LIST', @FM, @VM)
|
|
end
|
|
|
|
Response = WorkOrders
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetWorkOrderLogDetail
|
|
//
|
|
// Returns the WO_LOG row for the indicated Key ID.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetWorkOrderLogDetail(WorkOrderLogID)
|
|
|
|
WorkOrderDetail = ''
|
|
|
|
TableName = 'WO_LOG'
|
|
If WorkOrderLogID NE '' then
|
|
WorkOrderDetail = Database_Services('ReadDataRow', Tablename, WorkOrderLogID)
|
|
end else
|
|
Error_Services('Add', 'WorkOrderLogID argument was missing from the ' : Service : ' service.')
|
|
end
|
|
|
|
Response = WorkOrderDetail
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetWorkOrder
|
|
//
|
|
// Returns a JSON formatted object of information related to the indicated work order number. The ExtendedData argument
|
|
// determines if extended data related to wafers, product versions, and recipe should be included. The default is false.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetWorkOrder(WorkOrderNo, ExtendedData)
|
|
SRP_Stopwatch('Start', Service)
|
|
If ExtendedData NE True$ then ExtendedData = False$
|
|
|
|
ServiceKeyID := '*' : WorkOrderNo
|
|
WorkOrder = ''
|
|
|
|
If Memory_Services('IsValueCurrent', ServiceKeyID, 15, True$) then
|
|
WorkOrder = Memory_Services('GetValue', ServiceKeyID)
|
|
end else
|
|
If WorkOrderNo NE '' then
|
|
WorkOrderRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo, True$, 15)
|
|
objWorkOrder = ''
|
|
If SRP_JSON(objWorkOrder, 'NEW', 'OBJECT') then
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'WorkOrderNumber', WorkOrderNo, 'STRING')
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'EpiPartNumber', WorkOrderRow<WO_LOG_EPI_PART_NO$>, 'STRING')
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'ReactorType', WorkOrderRow<WO_LOG_REACT_TYPE$>, 'STRING')
|
|
ProdVerNo = WorkOrderRow<WO_LOG_PROD_VER_NO$>
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'ProdVerNumber', ProdVerNo, 'STRING')
|
|
TotalWafers = WorkOrderRow<WO_LOG_WO_QTY$>
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'TotalWafers', TotalWafers, 'STRING')
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'Closed', Oconv(WorkOrderRow<WO_LOG_CLOSE_DATE$> NE '', 'BYes,No'), 'STRING')
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'ClosedDate', Oconv(WorkOrderRow<WO_LOG_CLOSE_DATE$>, 'D4/'), 'STRING')
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'HotLot', Oconv(WorkOrderRow<WO_LOG_HOT_FLAG$> NE '', 'BYes,No'), 'STRING')
|
|
CustomerNo = WorkOrderRow<WO_LOG_CUST_NO$>
|
|
Company = Company_Services('GetCompany', CustomerNo)
|
|
objCompany = ''
|
|
If SRP_JSON(objCompany, 'PARSE', Company) EQ '' then
|
|
SRP_JSON(objWorkOrder, 'SET', 'Company', objCompany)
|
|
SRP_JSON(objCompany, 'RELEASE')
|
|
end
|
|
If ExtendedData EQ True$ then
|
|
WafersRemaining = Work_Order_Services('GetRemainingWafers', WorkOrderNo)
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'WafersRemaining', WafersRemaining, 'STRING')
|
|
If TotalWafers GT 0 then
|
|
PercentComplete = (TotalWafers - WafersRemaining) / TotalWafers * 100
|
|
end else
|
|
PercentComplete = 0
|
|
end
|
|
PercentComplete = Oconv(Iconv(PercentComplete, 'MD2'), 'MD2%S')
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'PercentComplete', PercentComplete, 'STRING')
|
|
ProdVerRow = Database_Services('ReadDataRow', 'PROD_VER', ProdVerNo, True$, 15)
|
|
PSN = ProdVerRow<PROD_VER_PROC_STEP_PSN$>
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'PSN', PSN, 'STRING')
|
|
LayerSpecs = obj_Prod_Spec('GetLayerProp', PSN : @RM : @RM : 1) ; // Returns specs for all layers in internal format.
|
|
LayerSpec = Field(LayerSpecs, @RM, 1) ; // Take the first Layer
|
|
LayerSet = Field(LayerSpec, @FM, 1) ; // Not used here but shown for clarity
|
|
LayerSpec = Field(LayerSpec, @FM, 2, 99) ; // LayerSpec without the LayerSet
|
|
Recipe = LayerSpec<PRS_LAYER_RECIPE$>
|
|
SRP_JSON(objWorkOrder, 'SETVALUE', 'Recipe', Recipe, 'STRING')
|
|
end
|
|
WorkOrder = SRP_JSON(objWorkOrder, 'STRINGIFY', 'FAST')
|
|
Memory_Services('SetValue', ServiceKeyID, WorkOrder)
|
|
SRP_JSON(objWorkOrder, 'RELEASE')
|
|
end else
|
|
Error_Services('Add', 'Error creating objWorkOrder in the ' : Service : ' service.')
|
|
end
|
|
end else
|
|
Error_Services('Add', 'WorkOrder argument was missing from the ' : Service : ' service.')
|
|
end
|
|
end
|
|
|
|
Response = WorkOrder
|
|
SRP_Stopwatch('Stop', Service)
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetRemainingWafers
|
|
//
|
|
// Returns the number of remaining wafers needed to be scheduled for the indicated work order.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetRemainingWafers(WorkOrderNo)
|
|
|
|
RemainingWafers = ''
|
|
|
|
If WorkOrderNo NE '' then
|
|
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo)
|
|
|
|
If Error_Services('NoError') then
|
|
// Get the total number of unreleased work orders.
|
|
TotalWafers = WOLogRow<WO_LOG_WO_QTY$>
|
|
TotalReleased = 0
|
|
WOMatKeys = WOLogRow<WO_LOG_WO_MAT_KEY$>
|
|
For Each WOMatKey in WOMatKeys using @VM
|
|
WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
|
|
TotalReleased += WOMatRec<WO_MAT_WAFER_QTY$>
|
|
Next WOMatKey
|
|
TotalUnreleased = TotalWafers - TotalReleased
|
|
|
|
WOStepKeys = WOLogRow<WO_LOG_WO_STEP_KEY$>
|
|
TotalUnprocessed = 0
|
|
If WOStepKeys NE '' then
|
|
ReactorType = WOLogRow<WO_LOG_REACT_TYPE$>
|
|
For Each WOStepKey in WOStepKeys using @VM
|
|
WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey)
|
|
If Error_Services('NoError') then
|
|
// Get the total released but unprocessed.
|
|
If ReactorType EQ 'EPP' then
|
|
// EpiPro work orders have their own way of calculating.
|
|
StatusCodes = Xlate('WM_IN', WOStepRec<WO_STEP_WM_IN_KEYS$>, 'CURR_STATUS', 'X')
|
|
RFWCnt = Count(StatusCodes, 'RFW')
|
|
TotalUnprocessed = RFWCnt * 25
|
|
end else
|
|
// All other reactor types use this method.
|
|
RDSKeys = WOStepRec<WO_STEP_RDS_KEY$>
|
|
If RDSKeys NE '' then
|
|
For Each RDSKey in RDSKeys using @VM
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey)
|
|
If RDSRec<RDS_DATE_IN$> EQ '' then
|
|
TotalUnprocessed += 25
|
|
end
|
|
Next RDSKey
|
|
end
|
|
end
|
|
end
|
|
Next WOStepKey
|
|
end
|
|
|
|
// Add the two.
|
|
RemainingWafers = TotalUnreleased + TotalUnprocessed
|
|
end
|
|
end else
|
|
Error_Services('Add', 'WorkOrderNo argument was missing from the ' : Service : ' service.')
|
|
end
|
|
|
|
Response = RemainingWafers
|
|
|
|
end service
|
|
|
|
|
|
! This service should be deprecated as it returns inaccurate information for EpiPro.
|
|
! Use GetRemainingWafers service insead.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetUnprocessedWafers
|
|
//
|
|
// Returns the number of released wafers that have not yet been processed.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetUnprocessedWafers(WorkOrderNo)
|
|
|
|
RemainingWafers = ''
|
|
|
|
If WorkOrderNo NE '' then
|
|
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo)
|
|
|
|
If Error_Services('NoError') then
|
|
// Get the total number of unreleased work orders.
|
|
TotalWafers = WOLogRow<WO_LOG_WO_QTY$>
|
|
TotalReleased = 0
|
|
WOMatKeys = WOLogRow<WO_LOG_WO_MAT_KEY$>
|
|
For Each WOMatKey in WOMatKeys using @VM
|
|
WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
|
|
TotalReleased += WOMatRec<WO_MAT_WAFER_QTY$>
|
|
Next WOMatKey
|
|
TotalUnreleased = TotalWafers - TotalReleased
|
|
|
|
WOStepKeys = WOLogRow<WO_LOG_WO_STEP_KEY$>
|
|
TotalUnprocessed = 0
|
|
If WOStepKeys NE '' then
|
|
ReactorType = WOLogRow<WO_LOG_REACT_TYPE$>
|
|
For Each WOStepKey in WOStepKeys using @VM
|
|
WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey)
|
|
If Error_Services('NoError') then
|
|
// Get the total released but unprocessed.
|
|
RDSKeys = WOStepRec<WO_STEP_RDS_KEY$>
|
|
If RDSKeys NE '' then
|
|
For Each RDSKey in RDSKeys using @VM
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey)
|
|
WOMatKey = Xlate('RDS', RDSKey, 'WO_MAT_KEY', 'X')
|
|
CurrStatus = Xlate('WO_MAT', WOMatKey, 'CURR_STATUS', 'X')
|
|
If ( (RDSRec<RDS_DATE_OUT$> EQ '') and (CurrStatus NE 'REJ') and (CurrStatus NE 'MT') ) then
|
|
TotalUnprocessed += RDSRec<RDS_CASS_WAFER_QTY$>
|
|
end
|
|
Next RDSKey
|
|
end
|
|
end
|
|
Next WOStepKey
|
|
end
|
|
|
|
// Add the two.
|
|
RemainingWafers = TotalUnreleased + TotalUnprocessed
|
|
end
|
|
end else
|
|
Error_Services('Add', 'WorkOrderNo argument was missing from the ' : Service : ' service.')
|
|
end
|
|
|
|
Response = RemainingWafers
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetCurrCassNo
|
|
//
|
|
// Returns the next cassette number to be unloaded.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetCurrCassNo(WorkOrderNo)
|
|
|
|
If RowExists('WO_LOG', WorkOrderNo) then
|
|
CurrCassNo = ''
|
|
DateIn = ''
|
|
RDSKeys = Xlate('WO_STEP', WorkOrderNo:'*1', 'RDS_KEY', 'X')
|
|
NumKeys = DCount(RDSKeys, @VM)
|
|
For KeyIndex = NumKeys to 1 Step -1
|
|
RDSKey = RDSKeys<0, KeyIndex>
|
|
DateIn = Xlate('RDS', RDSKey, 'DATE_IN', 'X')
|
|
Until DateIn NE ''
|
|
Next KeyIndex
|
|
If DateIn NE '' then CurrCassNo = Xlate('RDS', RDSKey, 'CASS_NO', 'X')
|
|
Response = CurrCassNo
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetLastCassOut
|
|
//
|
|
// Returns the last cassette number unloaded.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetLastCassOut(WorkOrderNo)
|
|
|
|
If RowExists('WO_LOG', WorkOrderNo) then
|
|
LastCassOut = ''
|
|
DateOut = ''
|
|
RDSKeys = Xlate('WO_STEP', WorkOrderNo:'*1', 'RDS_KEY', 'X')
|
|
NumKeys = DCount(RDSKeys, @VM)
|
|
For KeyIndex = NumKeys to 1 Step -1
|
|
RDSKey = RDSKeys<0, KeyIndex>
|
|
DateOut = Xlate('RDS', RDSKey, 'DATE_OUT', 'X')
|
|
Until DateOut NE ''
|
|
Next KeyIndex
|
|
If DateOut NE '' then LastCassOut = Xlate('RDS', RDSKey, 'CASS_NO', 'X')
|
|
Response = LastCassOut
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetNextRunNo
|
|
//
|
|
// Returns the next run number in the work order.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetNextRunNo(WorkOrderNo, WorkOrderStep)
|
|
|
|
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
|
|
HaveLock = False$
|
|
TimeElapsed = 0
|
|
RequestTime = Time()
|
|
If WorkOrderNo NE '' then
|
|
Loop
|
|
Lock hSysLists, ServiceKeyID then
|
|
HaveLock = True$
|
|
If WorkOrderStep = '' then WorkOrderStep = 1
|
|
StepRDSNos = XLATE('WO_STEP', WorkOrderNo:'*':WorkOrderStep, 'RDS_KEY', 'X')
|
|
CurrRuns = 0
|
|
NumRDS = DCount(StepRDSNos, @VM)
|
|
For I = 1 to NumRDS
|
|
If RowExists('RDS', StepRDSNos<1,I>) then
|
|
CurrRuns += 1
|
|
end
|
|
next I
|
|
NextRunNo = CurrRuns + 1
|
|
Response = NextRunNo
|
|
Unlock hSysLists, ServiceKeyID else Null
|
|
end
|
|
TimeElapsed = Time() - RequestTime
|
|
Until HaveLock EQ True$ or TimeElapsed GT 60
|
|
Repeat
|
|
end
|
|
If TimeElapsed GT 60 then
|
|
Error_Services('Add', 'Error occurred within the ':Service:' service module')
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// CreateOutbound
|
|
//
|
|
// Creates an empty outbound cassette for a GaN work order.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service CreateOutbound(WONo)
|
|
|
|
If WONo NE '' then
|
|
WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
CassNos = WORec<WO_LOG_WO_MAT_KEY$>
|
|
LastCassNo = DCount(CassNos, @VM)
|
|
NextCassNo = LastCassNo + 1
|
|
LastCassID = WONo : '*' : LastCassNo
|
|
NewCassID = WONo : '*' : NextCassNo
|
|
SchedCassQty = Xlate('WO_MAT', LastCassID, 'SCHED_QTY', 'X')
|
|
WOMatWfrRec = Database_Services('ReadDataRow', 'WO_MAT_WFR', NewCassID)
|
|
If WOMatWfrRec EQ '' then
|
|
for WfrCount = 1 to SchedCassQty
|
|
WOMatWfrRec<WO_MAT_WFR_OUT_PREV_WFR_ID$,WfrCount> = NewCassID : '*' : WfrCount
|
|
Next WfrCount
|
|
Database_Services('WriteDataRow', 'WO_MAT_WFR', NewCassID, WOMatWfrRec)
|
|
WOMatRecToCopy = Database_Services('ReadDataRow', 'WO_MAT', LastCassID)
|
|
WOMatRecToCopy<WO_MAT_RDS_FINAL_SIG_ORG$> = ''
|
|
WOMatRecToCopy<WO_MAT_CASS_FINAL_SIG_DTM$> = ''
|
|
Database_Services('WriteDataRow', 'WO_MAT', NewCassID, WOMatRecToCopy)
|
|
WORec = Insert(WORec, WO_LOG_WO_MAT_KEY$, -1, 0, NewCassID)
|
|
Database_Services('WriteDataRow', 'WO_LOG', WONo, WORec)
|
|
end else
|
|
ErrorMessage = 'Error in service ':Service:'. WO_MAT_WFR record ':NewCassID:' already exists!'
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service UpdateUnscheduledQuantities(WOList)
|
|
|
|
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
|
|
Lock hSysLists, ServiceKeyID then
|
|
SchedList = Database_Services('ReadDataRow', 'APP_INFO', 'SCHED_WO_LIST')
|
|
// Select WO_LOG rows that do not have a closed date.
|
|
OpenWOLogKeyIDs = ''
|
|
If WOList NE '' then OpenWOLogKeyIDs = WOList
|
|
If OpenWOLogKeyIDs EQ '' then
|
|
Open 'DICT.WO_LOG' to hWOLogDict then
|
|
Set_Status(0)
|
|
Flag = ''
|
|
Btree.Extract('CLOSE_DATE' : @VM : '' : @FM, 'WO_LOG', hWOLogDict, OpenWOLogKeyIDs, 'S', Flag)
|
|
If Flag NE 0 then
|
|
Status = Get_Status(errCode)
|
|
Error_Services('Add', 'Error in ':Service:' service. Error code ':errCode:'.')
|
|
end
|
|
end
|
|
end
|
|
If ( Error_Services('NoError') and (OpenWOLogKeyIDs NE '') ) then
|
|
SchedList = SRP_Array('Rotate', SchedList, @FM, @VM)
|
|
For Each WONo in OpenWOLogKeyIDs using @VM setting fPos
|
|
UnscheduledWfrQty = Schedule_Services('GetUnscheduledWfrQty', WONo)
|
|
WONos = SchedList<1>
|
|
If UnscheduledWfrQty GT 0 then
|
|
Locate WONo in WONos using @VM setting vPos else vPos = -1
|
|
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
EpiPartNo = WOLogRow<WO_LOG_EPI_PART_NO$>
|
|
CustNo = WOLogRow<WO_LOG_CUST_NO$>
|
|
CompanyRow = Database_Services('ReadDataRow', 'COMPANY', CustNo)
|
|
CustName = CompanyRow<COMPANY_ABBREV$>
|
|
ReactorType = WOLogRow<WO_LOG_REACT_TYPE$>
|
|
SchedList<1, vPos> = WONo
|
|
SchedList<2, vPos> = EpiPartNo
|
|
SchedList<3, vPos> = CustName
|
|
SchedList<4, vPos> = ReactorType
|
|
WOSchedRec = Database_Services('ReadDataRow', 'WO_SCHEDULE_NG', WONo)
|
|
CurrVal = WOSchedRec<WO_SCHEDULE_NG.UNSCHED_QTY$>
|
|
If CurrVal NE UnscheduledWfrQty then
|
|
WOSchedRec<WO_SCHEDULE_NG.UNSCHED_QTY$> = UnscheduledWfrQty
|
|
Database_Services('WriteDataRow', 'WO_SCHEDULE_NG', WONo, WOSchedRec, True$, False$, True$)
|
|
end
|
|
end else
|
|
Locate WONo in WONos using @VM setting vPos then
|
|
SchedList = Delete(SchedList, 1, vPos, 0)
|
|
SchedList = Delete(SchedList, 2, vPos, 0)
|
|
SchedList = Delete(SchedList, 3, vPos, 0)
|
|
SchedList = Delete(SchedList, 4, vPos, 0)
|
|
Database_Services('DeleteDataRow', 'WO_SCHEDULE_NG', WONo)
|
|
end
|
|
end
|
|
Next WONo
|
|
end
|
|
SchedList = SRP_Array('Rotate', SchedList, @FM, @VM)
|
|
If WOList EQ '' then
|
|
// Clear out WO_SCHEDULE_NG table of work orders that no longer have any wafers left to schedule.
|
|
EOF = False$
|
|
Query = 'SELECT WO_SCHEDULE_NG WITH UNSCHED_QTY EQ 0'
|
|
RList(Query, TARGET_ACTIVELIST$, '', '', '')
|
|
Loop
|
|
Readnext WOLogKeyID else EOF = True$
|
|
Until EOF = True$
|
|
Database_Services('DeleteDataRow', 'WO_SCHEDULE_NG', WOLogKeyID)
|
|
Repeat
|
|
end
|
|
SchedList = SRP_Array('SortSimpleList', SchedList, 'DescendingNumbers', @FM)
|
|
Database_Services('WriteDataRow', 'APP_INFO', 'SCHED_WO_LIST', SchedList)
|
|
Unlock hSysLists, ServiceKeyID else Null
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service ReleaseCassettes(WONo)
|
|
|
|
NumRelCass = 0
|
|
ErrorMsg = ''
|
|
If WONo NE '' then
|
|
|
|
PSNo = Xlate('WO_LOG', WONo, 'PS_NO', 'X')
|
|
PSMode = Xlate('PROD_SPEC',PSNo,'SPEC_TYPE','X')
|
|
|
|
If PSMode = 'Q' OR PSMode = 'U' then
|
|
|
|
ReactType = Xlate('WO_LOG', WONo, 'REACT_TYPE', 'X')
|
|
|
|
If ReactType = 'EPP' OR ReactType = 'EpiPro' then
|
|
|
|
OutLoadQty = Xlate('WO_LOG', WONo, 'CUST_EPI_PART_WMO_LOAD_CNT', 'X')
|
|
If OutLoadQty = '' then
|
|
ErrorMsg = 'Outbound Load Cnt is required for ':OCONV(PSMode,'[PROD_SPEC_MODE_CONV]'):' Work Orders.'
|
|
end
|
|
|
|
end else
|
|
|
|
OutLoadQty = Xlate('WO_LOG', WONo, 'CUST_EPI_PART_SHIP_QTY', 'X')
|
|
If OutLoadQty = '' then
|
|
ErrorMsg = 'Cass Ship Qty is required for ':OCONV(PSMode,'[PROD_SPEC_MODE_CONV]'):' Work Orders.'
|
|
end
|
|
end
|
|
end
|
|
|
|
If ErrorMsg EQ '' then
|
|
|
|
CassList = Xlate('WO_LOG', WONo, 'WO_MAT_CASS_NO', 'X')
|
|
RelDTMs = Xlate('WO_LOG', WONo, 'WO_MAT_REL_DTM', 'X')
|
|
SAPCassIDs = Xlate('WO_LOG', WONo, 'WO_MAT_CASS_ID_SAP', 'X')
|
|
CassStatus = Xlate('WO_LOG', WONo, 'WO_MAT_CURR_STATUS', 'X')
|
|
|
|
Loop
|
|
LastLine = CassList[-1,'B':@VM]
|
|
Until LastLine<1,1> NE '' OR LastLine = ''
|
|
CassList[COL1(),COL2()] = ''
|
|
Repeat
|
|
|
|
CassCnt = DCount(CassList, @VM)
|
|
|
|
UnReleasedCassNos = ''
|
|
For I = 1 to CassCnt
|
|
If ( (RelDTMs<0, I> = '') and (CassStatus<0, I> EQ '') ) then
|
|
ErrorMsg = 'Error in obj_WO_Log("ReleaseCassettes"). Cass status is null for ':CassList<0, I>:'!'
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = @USER4
|
|
LogData<3> = ErrorMsg
|
|
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
|
|
end
|
|
If ErrorMsg EQ '' then
|
|
// Log work order, cassette number, status, and release DTM in the event that a release
|
|
// issue occurs again.
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = @User4
|
|
LogData<3> = WONo
|
|
LogData<4> = CassList<0, I> ; // CassNo
|
|
LogData<5> = CassStatus<0, I> ; // Cass Status
|
|
LogData<6> = Quote(RelDTMs<0, I>) ; // Release DTM
|
|
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
|
|
If ( (RelDTMs<0, I> = '') and ( (CassStatus<0, I> = 'RX') or (CassStatus<0, I> = 'MT'))) then
|
|
UnReleasedCassNos<1,-1> = CassList<0, I>
|
|
end
|
|
end
|
|
Until ErrorMsg NE ''
|
|
Next I
|
|
|
|
If ErrorMsg EQ '' then
|
|
|
|
TempWONo = WONo
|
|
Set_Status(0)
|
|
|
|
obj_WO_Log('ReleaseCassettes',TempWONo:@RM:UnReleasedCassNos) ;* This variable gets changed down the line
|
|
errCode = ''
|
|
|
|
If Get_Status(errCode) then
|
|
|
|
ErrorMsg = 'Error in obj_WO_Log("ReleaseCassettes"). Error code ':errCode:'.'
|
|
Database_Services('ReleaseKeyIDLock', 'WO_LOG', WONo)
|
|
|
|
end else
|
|
|
|
NumRelCass = CassCnt
|
|
OrderNo = Get_Property(@WINDOW:'.ORD_NO','TEXT')
|
|
|
|
Recipients = XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
|
|
SentFrom = @USER4
|
|
Subject = 'Work Order Released ':WONo
|
|
Message = 'Work Order Released to Production.'
|
|
NewForm = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X')
|
|
If NewForm then
|
|
AttachWindow = 'NDW_WO_LOG'
|
|
end else
|
|
AttachWindow = 'WO_LOG2'
|
|
end
|
|
AttachKey = WONo
|
|
SendToGroup = ''
|
|
|
|
Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
|
|
obj_Notes('Create',Parms)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Work_Order_Services('UpdateReleasedQty', WONo)
|
|
|
|
If ErrorMsg NE '' then Error_Services('Add', ErrorMsg)
|
|
Response = DCount(UnReleasedCassNos, @VM)
|
|
|
|
end service
|
|
|
|
|
|
Service PrintLabels(WONo)
|
|
|
|
If WONo NE '' then
|
|
|
|
WOSteps = XLATE('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
|
|
|
|
If INDEX(WOSteps,@VM,1) then
|
|
Buttons = ''
|
|
FOR I = 1 TO COUNT(WOSteps,@VM) + (WOSteps NE '')
|
|
Buttons<I> = 'Step ':I
|
|
NEXT I
|
|
SWAP @FM WITH ',' IN Buttons
|
|
Buttons = 'B':Buttons
|
|
|
|
TypeOver = ''
|
|
TypeOver<MTEXT$> = 'Which Work Order step do you wish to print labels for?'
|
|
TypeOver<MTYPE$> = Buttons
|
|
TypeOver<MICON$> = '?'
|
|
TypeOver<MCAPTION$> = 'MultiStep WorkOrder Selection'
|
|
WOStep = Msg(@window, TypeOver)
|
|
MultiStepFlag = WOStep
|
|
end ELSE
|
|
WOStep = 1
|
|
MultiStepFlag = 0
|
|
end
|
|
|
|
If WOStep = 1 then
|
|
PSNo = XLATE('WO_STEP',WONo:'*1',WO_STEP_PROD_SPEC_ID$,'X')
|
|
ReactorType = XLATE('PROD_SPEC',PSNo,PROD_SPEC_REACTOR_TYPE$,'X')
|
|
|
|
If ReactorType = 'GAN' then
|
|
Print_WO_Mat_In_Labels(WONo,'')
|
|
Print_WO_Mat_Out_Labels(WONo,'')
|
|
end
|
|
|
|
If ReactorType = 'EPP' OR ReactorType = 'P' then
|
|
Print_WMI_Labels(WONo,1)
|
|
Print_WMO_Labels(WONo,1)
|
|
end
|
|
end
|
|
|
|
NonEpiPro = ( (ReactorType NE 'GAN') and (ReactorType NE 'EPP') and (ReactorType NE 'P') )
|
|
|
|
If NonEpiPro then
|
|
|
|
If WOStep > 1 then
|
|
|
|
Def = ""
|
|
Def<MTEXT$> = "Adjusting Step ":WOStep:" Scheduled Quantities..."
|
|
Def<MTYPE$> = "U"
|
|
|
|
MsgUp = Msg(@window, Def)
|
|
|
|
RDSNos = obj_WO_Step('AdjStepRDSQtys', WOStep:@RM:WOSteps)
|
|
|
|
If Get_Status(errCode) then
|
|
|
|
ErrMsg(errCode) ;* Display error from the update
|
|
Msg(@WINDOW,MsgUp) ;* Take down the processing message
|
|
|
|
RETURN
|
|
end
|
|
Msg(@WINDOW,MsgUp)
|
|
|
|
end ELSE
|
|
RDSNos = XLATE('WO_STEP',WOSteps<1,1>,WO_STEP_RDS_KEY$,'X')
|
|
end
|
|
|
|
If MemberOf(@USER4,'OI_ADMIN') then
|
|
WOMatKeys = XLATE('WO_LOG',WONo,WO_LOG_WO_MAT_KEY$,'X')
|
|
CONVERT @VM TO @FM IN WOMatKeys
|
|
AllRDSNos = XLATE('WO_MAT',WOMatKeys,WO_MAT_RDS_NO$,'X')
|
|
|
|
RDSNos = ''
|
|
|
|
LOOP
|
|
CassRDSNos = AllRDSNos[1,@FM]
|
|
AllRDSNos[1,COL2()] = ''
|
|
UNTIL CassRdsNos = ''
|
|
RDSNos := CassRdsNos<1,WOStep>:@VM
|
|
REPEAT
|
|
|
|
RDSNos[-1,1] = ''
|
|
|
|
end
|
|
|
|
If INDEX(RDSNos,@VM,1) then
|
|
TypeOver = ''
|
|
TypeOver<PDISPLAY$> = RDSNos
|
|
TypeOver<PFIELD$> = 2
|
|
TypeOver<PTYPE$> = 'K'
|
|
TypeOver<PSHOWGAUGE$> = True$
|
|
|
|
RDSKeys = Popup(@WINDOW,TypeOver,'WO_LOG_RTS')
|
|
|
|
end ELSE
|
|
RDSKeys = RDSNos
|
|
end
|
|
|
|
If RDSKeys = '' then
|
|
ErrMsg('No RDS Numbers Selected or Work Order Not Yet Released to Production.')
|
|
end ELSE
|
|
CONVERT @VM TO @FM IN RDSKeys
|
|
|
|
Print_Cass_Labels(RDSKeys,MultiStepFlag) ;* Updated labels with Akrion Bar Codes
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service UpdateWOStepStatus(WONo)
|
|
|
|
If WONo NE '' then
|
|
WOStepKey = WONo:'*':1
|
|
WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey)
|
|
WOStepCurrStatus = obj_WO_Step('CurrStatus', WOStepKey:@RM:WOStepRec)
|
|
// Get a fresh copy of the record
|
|
WOStepRec = Database_Services('ReadDataRow', 'WO_STEP', WOStepKey)
|
|
WOStepCurrStatusStatic = WOStepRec<WO_STEP_CURR_STATUS_STATIC$>
|
|
If WOStepCurrStatus NE WOStepCurrStatusStatic then
|
|
WOStepRec<WO_STEP_CURR_STATUS_STATIC$> = WOStepCurrStatus
|
|
Database_Services('WriteDataRow', 'WO_STEP', WOStepKey, WOStepRec, True$, False$, True$)
|
|
end
|
|
Database_Services('ReleaseKeyIDLock', 'WO_STEP', WOStepKey)
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service PostWOStepUpdateRequest(WONo)
|
|
|
|
If WONo NE '' then
|
|
StepNo = 1
|
|
WOStepKey = WONo:'*':StepNo
|
|
// Look for a pre-existing request in the queue
|
|
If (RowExists('WO_STEP', WOStepKey) EQ False$) then
|
|
// This is a new request
|
|
RequestKeyID = WOStepKey
|
|
RequestRow = ''
|
|
RequestRow<WO_STEP_CURR_STATUS_STATIC$> = Datetime()
|
|
Database_Services('WriteDataRow', 'WO_STEP_QUEUE', RequestKeyID, RequestRow, False$, False$, False$)
|
|
end else
|
|
// Duplicate request
|
|
Null
|
|
end
|
|
end else
|
|
Error_Services('Add', 'Null parameter passed into service call. All parameters are required.')
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service ProcessWOStepUpdateRequests()
|
|
|
|
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
|
|
Lock hSysLists, ServiceKeyID then
|
|
Open 'WO_STEP_QUEUE' to hTable then
|
|
Select hTable
|
|
EOF = False$
|
|
Loop
|
|
ReadNext RequestKeyID else EOF = True$
|
|
Until EOF EQ True$
|
|
WONo = Field(RequestKeyID, '*', 1)
|
|
Work_Order_Services('UpdateWOStepStatus', WONo)
|
|
If Error_Services('NoError') then
|
|
// Successfully updated the current status, so delete the request from the queue.
|
|
Database_Services('DeleteDataRow', 'WO_STEP_QUEUE', RequestKeyID, True$, True$)
|
|
end
|
|
Repeat
|
|
end else
|
|
ErrorMsg = 'Error opening WO_STEP_QUEUE in ':Service:' service.'
|
|
end
|
|
Unlock hSysLists, ServiceKeyID else Null
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SetHotFlag(WONo, HotFlag=BOOLEAN)
|
|
|
|
If ( ( RowExists('WO_LOG', WONo) and ( (HotFlag EQ True$) or (HotFlag EQ False$) ) ) ) then
|
|
Open 'WO_LOG' to hTable then
|
|
WriteV HotFlag on hTable, WONo, WO_LOG_HOT_FLAG$ else
|
|
Error_Services('Add', 'Error in ':Service:' service. File error: ':@File_Error)
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'Error in ':Service:' service. Invalid parameters passed into service.')
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service GetHotFlag(WONo)
|
|
|
|
HotFlag = ''
|
|
If RowExists('WO_LOG', WONo) then
|
|
Open 'WO_LOG' to hTable then
|
|
ReadV HotFlag from hTable, WONo, WO_LOG_HOT_FLAG$ else
|
|
Error_Services('Add', 'Error in ':Service:' service. File error: ':@File_Error)
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'Error in ':Service:' service. Invalid parameters passed into service.')
|
|
end
|
|
Response = HotFlag
|
|
|
|
end service
|
|
|
|
|
|
Service UpdateReleasedQty(WONo)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Update Released Qty Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'WONo' : @FM : 'Notes'
|
|
objUpRelLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
|
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
|
|
|
ErrorMsg = ''
|
|
If WONo NE '' then
|
|
If RowExists('WO_LOG', WONo) then
|
|
WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
If Error_Services('NoError') then
|
|
RelQty = obj_WO_Log('RelQty', WONo:@RM:WORec)
|
|
WOQty = WORec<WO_LOG_QTY$>
|
|
If RelQty GT WOQty then
|
|
UnRelQty = 0
|
|
end else
|
|
UnRelQty = WOQty - RelQty
|
|
end
|
|
Open 'WO_LOG' to hTable then
|
|
WriteV RelQty on hTable, WONo, WO_LOG_REL_QTY_STATIC$ then
|
|
WriteV UnRelQty on hTable, WONo, WO_LOG_UNREL_QTY_STATIC$ else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to write unreleased quantity ':UnRelQty
|
|
ErrorMsg := ' to the UNREL_QTY_STATIC field of WO_LOG record ':WONo:'.'
|
|
ErrorMsg := '@FILE_ERROR: ':@FILE_ERROR
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to write released quantity ':RelQty
|
|
ErrorMsg := ' to the REL_QTY_STATIC field of WO_LOG record ':WONo:'.'
|
|
ErrorMsg := '@FILE_ERROR: ':@FILE_ERROR
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to open the WO_LOG table.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to read record ':WONo:' from the WO_LOG table. '
|
|
ErrorMsg := 'Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. ':WONo:' does not exist in the WO_LOG table.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Null WONo passed into service'
|
|
end
|
|
|
|
LogData = ''
|
|
LogData<1> = LoggingDtm
|
|
LogData<2> = WONo
|
|
If ErrorMsg EQ '' then
|
|
LogResult = 'Successfully updated WO_LOG record ':WONo:' field REL_QTY_STATIC with released quantity ':RelQty
|
|
LogResult := ' and field UNREL_QTY_STATIC with unreleased quantity ':UnRelQty:'.'
|
|
LogData<3> = LogResult
|
|
Logging_Services('AppendLog', objUpRelLog, LogData, @RM, @FM)
|
|
end else
|
|
LogResult = 'Failed to update WO_LOG record ':WONo:' field REL_QTY_STATIC with released quantity ':RelQty
|
|
LogResult := ' or field UNREL_QTY_STATIC with unreleased quantity ':UnRelQty:'. Error message: ':ErrorMsg
|
|
LogData<3> = LogResult
|
|
Logging_Services('AppendLog', objUpRelLog, LogData, @RM, @FM)
|
|
Error_Services('Add', ErrorMsg)
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service UpdateReceivedQty(WONo)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Update Received Qty Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'WONo' : @FM : 'Notes'
|
|
objUpRecLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
|
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
|
|
|
ErrorMsg = ''
|
|
If WONo NE '' then
|
|
If RowExists('WO_LOG', WONo) then
|
|
WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
If Error_Services('NoError') then
|
|
RXQty = obj_WO_Log('RxQty', WONo:@RM:WORec)
|
|
Open 'WO_LOG' to hTable then
|
|
WriteV RXQty on hTable, WONo, WO_LOG_RX_QTY_STATIC$ else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to write received quantity ':RXQty
|
|
ErrorMsg := ' to the RX_QTY_STATIC field of WO_LOG record ':WONo:'.'
|
|
ErrorMsg := '@FILE_ERROR: ':@FILE_ERROR
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to open the WO_LOG table.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to read record ':WONo:' from the WO_LOG table. '
|
|
ErrorMsg := 'Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. ':WONo:' does not exist in the WO_LOG table.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Null WONo passed into service'
|
|
end
|
|
|
|
LogData = ''
|
|
LogData<1> = LoggingDtm
|
|
LogData<2> = WONo
|
|
If ErrorMsg EQ '' then
|
|
LogData<3> = 'Successfully updated WO_LOG record ':WONo:' field RX_QTY_STATIC with received quantity ':RXQty:'.'
|
|
Logging_Services('AppendLog', objUpRecLog, LogData, @RM, @FM)
|
|
end else
|
|
LogResult = 'Failed to update WO_LOG record ':WONo:' field RX_QTY_STATIC with received quantity ':RXQty
|
|
LogResult := '. Error message: ':ErrorMsg
|
|
LogData<3> = LogResult
|
|
Logging_Services('AppendLog', objUpRecLog, LogData, @RM, @FM)
|
|
Error_Services('Add', ErrorMsg)
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service UpdateShippedQty(WONo)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Update Shipped Qty Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'WONo' : @FM : 'Notes'
|
|
objUpShipLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$,',', Headers, '', False$, False$)
|
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
|
|
|
ErrorMsg = ''
|
|
If WONo NE '' then
|
|
If RowExists('WO_LOG', WONo) then
|
|
WORec = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
If Error_Services('NoError') then
|
|
ShipQty = obj_WO_Log('ShipQty', WONo:@RM:WORec)
|
|
Open 'WO_LOG' to hTable then
|
|
WriteV ShipQty on hTable, WONo, WO_LOG_SHIP_QTY_STATIC$ else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to write ':ShipQty
|
|
ErrorMsg := ' to the SHIP_QTY_STATIC field of WO_LOG record ':WONo:'.'
|
|
ErrorMsg := '@FILE_ERROR: ':@FILE_ERROR
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to open the WO_LOG table.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Failed to read record ':WONo:' from the WO_LOG table. '
|
|
ErrorMsg := 'Error message: ':Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. ':WONo:' does not exist in the WO_LOG table.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Null WONo passed into service'
|
|
end
|
|
|
|
LogData = ''
|
|
LogData<1> = LoggingDtm
|
|
LogData<2> = WONo
|
|
If ErrorMsg EQ '' then
|
|
LogResult = 'Successfully updated WO_LOG record ':WONo:' field SHIP_QTY_STATIC '
|
|
LogResult := 'with shipped quantity ':ShipQty:'.'
|
|
LogData<3> = LogResult
|
|
Logging_Services('AppendLog', objUpShipLog, LogData, @RM, @FM)
|
|
end else
|
|
LogResult = 'Failed to update WO_LOG record ':WONo:' field SHIP_QTY_STATIC with shipped quantity '
|
|
LogResult := ShipQty:'. Error message: ':ErrorMsg
|
|
LogData<3> = LogResult
|
|
Logging_Services('AppendLog', objUpShipLog, LogData, @RM, @FM)
|
|
Error_Services('Add', ErrorMsg)
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service ConvertRecordToJSON(WONo, Record, ItemURL)
|
|
|
|
jsonRecord = ''
|
|
IF WONo NE '' then
|
|
If Record EQ '' then Record = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
If Error_Services('NoError') then
|
|
@DICT = Database_Services('GetTableHandle', 'DICT.WO_LOG')
|
|
@ID = WONo
|
|
@RECORD = Record
|
|
objJSON = ''
|
|
If SRP_JSON(objJSON, 'New', 'Object') then
|
|
objWOLog = ''
|
|
If SRP_JSON(objWOLog, 'New', 'Object') then
|
|
SRP_JSON(objWOLog, 'SetValue', 'KeyId', @ID)
|
|
SRP_JSON(objWOLog, 'SetValue', 'ProdOrdNo', {PROD_ORD_NO})
|
|
SRP_JSON(objWOLog, 'SetValue', 'PSN', {PROD_SPEC_ID})
|
|
SRP_JSON(objWOLog, 'SetValue', 'EpiPartNo', {EPI_PART_NO})
|
|
SRP_JSON(objWOLog, 'SetValue', 'HOT_FLAG', {HOT_FLAG})
|
|
//Create a list of cassettes
|
|
CassIDs = {WO_MAT_KEY}
|
|
objChildCassettes = ''
|
|
If SRP_JSON(objChildCassettes, 'New', 'Array') then
|
|
If CassIDs NE '' then
|
|
for each Cass in CassIDs using @VM setting vPos
|
|
SAPBatchNo = XLATE('WO_MAT', Cass, WO_MAT_SAP_BATCH_NO$, 'X')
|
|
SAPTXDtm = XLATE('WO_MAT', Cass, WO_MAT_SAP_TX_DTM$, 'X')
|
|
RDSNo = XLATE('WO_MAT', Cass, WO_MAT_RDS_NO$, 'X')
|
|
ShipNo = XLATE('WO_MAT', Cass, WO_MAT_SHIP_NO$, 'X')
|
|
//Add in each indv. cassette object
|
|
objChildCassette = ''
|
|
If SRP_JSON(objChildCassette, 'New', 'Object') then
|
|
SRP_JSON(objChildCassette, 'SetValue', 'KeyId', Cass)
|
|
SRP_JSON(objChildCassette, 'SetValue', 'SAPBatchNo', SAPBatchNo)
|
|
SRP_JSON(objChildCassette, 'SetValue', 'SAPTXDtm', OCONV(SAPTXDtm, 'DT'))
|
|
SRP_JSON(objChildCassette, 'SetValue', 'RDSNo', RDSNo)
|
|
SRP_JSON(objChildCassette, 'SetValue', 'ShipNo', ShipNo)
|
|
SRP_JSON(objChildCassettes, 'Add', objChildCassette)
|
|
SRP_JSON(objChildCassette, 'Release')
|
|
end
|
|
|
|
Next Cass
|
|
end else
|
|
SRP_JSON(objWOLog, 'SetValue', 'ChildCassettes', '')
|
|
end
|
|
SRP_JSON(objWOLog, 'Set', 'ChildCassettes', objChildCassettes)
|
|
SRP_JSON(objChildCassettes, 'Release')
|
|
end
|
|
SRP_JSON(objJSON, 'Set', 'WO_Log', objWOLog)
|
|
SRP_JSON(objWOLog, 'Release')
|
|
end
|
|
If itemURL NE '' then
|
|
// The itemURL was passed in so add HAL+JSON properties.
|
|
// Create the _links property and then all link objects needed for this resource.
|
|
objLinks = ''
|
|
If SRP_JSON(objLinks, 'New', 'Object') then
|
|
// Create a self link.
|
|
objLink = ''
|
|
If SRP_JSON(objLink, 'New', 'Object') then
|
|
SRP_JSON(objLink, 'SetValue', 'href', ItemURL, 'String')
|
|
SRP_JSON(objLink, 'SetValue', 'title', 'Self', 'String')
|
|
SRP_JSON(objLinks, 'Set', 'self', objLink)
|
|
SRP_JSON(objLink, 'Release')
|
|
end
|
|
SRP_JSON(objJSON, 'Set', '_links', objLinks)
|
|
SRP_JSON(objLinks, 'Release')
|
|
end
|
|
|
|
// Create the _class property for this resource.
|
|
SRP_JSON(objJSON, 'SetValue', '_class', 'resource')
|
|
end
|
|
jsonRecord = SRP_JSON(objJSON, 'Stringify', 'Styled')
|
|
SRP_JSON(objJSON, 'Release')
|
|
end else
|
|
Error_Services('Add', 'Unable to create JSON representation in the ' : Service : ' service.')
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'KeyID argument was missing in the ' : Service : ' service.')
|
|
end
|
|
Response = jsonRecord
|
|
|
|
end service
|
|
|
|
|
|
Service RemoveWoMatCassetteFromWO(WoMatKey, Username)
|
|
|
|
ErrorMessage = ''
|
|
If RowExists('WO_MAT', WoMatKey) then
|
|
WoNo = Field(WoMatKey, '*', 1)
|
|
WOLogRecord = Database_Services('ReadDataRow', 'WO_LOG', WoNo, True$, 0, False$)
|
|
If Error_Services('NoError') then
|
|
WoMatKeys = WOLogRecord<WO_LOG_WO_MAT_KEY$>
|
|
Locate WoMatKey in WoMatKeys using @VM setting CassPos then
|
|
WoLogRecord<WO_LOG_WO_MAT_KEY$> = Delete(WOLogRecord<WO_LOG_WO_MAT_KEY$>, 1, CassPos, 0)
|
|
Database_Services('WriteDataRow', 'WO_LOG', WoNo, WoLogRecord)
|
|
If Error_Services('NoError') then
|
|
Work_Order_Services('UpdateReceivedQty', WONo)
|
|
Work_Order_Services('UpdateReleasedQty', WONo)
|
|
Work_Order_Services('UpdateUnscheduledQuantities')
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = "Unable to locate cass no " : WoMatKey : ' in the WO_LOG ' : WoNo : ' Record.'
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Invalid WoMat Key ' : WoMatKey : ' passed to RemoveWoMatCassetteFromWO routine.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignVoidNonEpp(WOMatKey, Username)
|
|
|
|
ErrorMessage = ''
|
|
WONo = Field(WOMatKey, '*', 1)
|
|
CassNo = Field(WoMatKey, '*', 2)
|
|
ReactType = XLATE('WO_LOG', WONo, WO_LOG_REACT_TYPE$, 'X')
|
|
If ReactType EQ 'ASM' OR ReactType EQ 'ASM+' OR ReactType EQ 'HTR' then
|
|
RDSNo = Database_Services('ReadDataColumn', 'WO_MAT', WoMatKey, WO_MAT_RDS_NO$, True$, 0, False$)
|
|
If Error_Services('NoError') then
|
|
WoMatRec = Database_Services('ReadDataRow', 'WO_MAT', WoMatKey, True$, 0, False$)
|
|
IsVoided = WoMatRec<WO_MAT_VOID$>
|
|
If Not(IsVoided) then
|
|
IsOnHold = Hold_Services('CheckForHold', WoMatKey)
|
|
If Not(IsOnHold) then
|
|
Service_Services('PostProcedure', 'WORK_ORDER_SERVICES', 'RemoveWoMatCassetteFromWO':@vm:WOMatKey:@vm:Username)
|
|
If Error_Services('NoError') then
|
|
Service_Services('PostProcedure', 'WO_MAT_SERVICES', 'SetWoMatVoidFlag':@vm:WOMatKey:@VM:Username)
|
|
if Error_Services('NoError') then
|
|
Service_Services('PostProcedure', 'RDS_SERVICES', 'DetachRDSFromWO':@vm:RDSNo)
|
|
If Error_Services('NoError') then
|
|
LotEventParams = ''
|
|
LotEventParams<1,1> = 'CreateLotEvent' ; //Service Module
|
|
LotEventParams<1,2> = ''; //Legacy Lot Id, set below
|
|
LotEventParams<1,3> = DateTime(); //Datetime
|
|
LotEventParams<1,4> = 'VOID'; //Event Type
|
|
LotEventParams<1,5> = 'Lot voided by ' : Username; //Event Note
|
|
LotEventParams<1,6> = ''; //Equipment id
|
|
LotEventParams<1,7> = Username ;//User Id
|
|
LotEventParams<1,8> = True$; //IsLegacyLotId
|
|
LotEventParams<1,9> = ''; //Legacy Lot Type, set below
|
|
If RDSNo NE '' then
|
|
LotEventParams<1,2> = RDSNo
|
|
LotEventParams<1,9> = 'RDS'; //Legacy Lot Type
|
|
Service_Services('PostProcedure', 'LOT_EVENT_SERVICES', LotEventParams)
|
|
end else
|
|
LotEventParams<1,2> = WoMatKey
|
|
LotEventParams<1,9> = 'WO_MAT'
|
|
Service_Services('PostProcedure', 'LOT_EVENT_SERVICES', LotEventParams)
|
|
end
|
|
If Error_Services('NoError') then
|
|
//Add inventory transaction
|
|
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Unable to void lot as it is already voided.'
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = 'Cannot use this routine to void EpiPro lots.'
|
|
end
|
|
|
|
If ErrorMessage NE '' then
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = Username
|
|
LogData<3> = WOMatKey
|
|
LogData<4> = ErrorMessage
|
|
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
|
|
Error_Services('Add', ErrorMessage)
|
|
end else
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = Username
|
|
LogData<3> = WOMatKey
|
|
LogData<4> = 'Void queued successfully.'
|
|
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignVoidWMI(WMInKey, Username)
|
|
|
|
ErrorMessage = ''
|
|
WONo = Field(WMInKey, '*', 1)
|
|
CassNo = Field(WMInKey, '*', 3)
|
|
WoStepKey = Xlate('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
|
|
WoMatKey = WONo : '*' : CassNo
|
|
ReactType = XLATE('WO_LOG', WONo, WO_LOG_REACT_TYPE$, 'X')
|
|
If ReactType EQ 'EPP' then
|
|
WMInRec = Database_Services('ReadDataRow', 'WM_IN', WMInKey, True$, 0, False$)
|
|
IsVoided = WMInRec<WM_IN_VOID$>
|
|
If Not(IsVoided) then
|
|
IsOnHold = Hold_Services('CheckForHold', WoMatKey)
|
|
If Not(IsOnHold) then
|
|
Service_Services('PostProcedure', 'WM_IN_SERVICES', 'SetVoidFlag':@vm:WMInKey:@VM:Username)
|
|
If Error_Services('NoError') then
|
|
LotEventParams = ''
|
|
LotEventParams<1,1> = 'CreateLotEvent'
|
|
LotEventParams<1,2> = WMInKey
|
|
LotEventParams<1,3> = DateTime()
|
|
LotEventParams<1,4> = 'VOID'
|
|
LotEventParams<1,5> = 'Lot voided by ' : Username
|
|
LotEventParams<1,6> = ''
|
|
LotEventParams<1,7> = Username
|
|
LotEventParams<1,8> = True$
|
|
LotEventParams<1,9> = 'WM_IN'
|
|
Service_Services('PostProcedure', 'LOT_EVENT_SERVICES', LotEventParams)
|
|
If Error_Services('NoError') then
|
|
//Check if WMO is also voided. If it is, remove it from the WO_MAT_KEY field in WO_LOG, and void the WO_MAT record
|
|
WMOKey = WMInKey; //the paired WMO key is the same as the WMIKey
|
|
IsWMOVoided = Database_Services('ReadDataColumn', 'WM_OUT', WMOKey, WM_OUT_VOID$)
|
|
If IsWMOVoided then
|
|
Service_Services('PostProcedure', 'WO_MAT_SERVICES', 'SetWoMatVoidFlag':@VM:WoMatKey:@VM:Username)
|
|
If Error_Services('NoError') then
|
|
Service_Services('PostProcedure', 'WORK_ORDER_SERVICES','RemoveWoMatCassetteFromWO':@VM:WoMatKey:@VM:Username)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Unable to void lot as it is already voided.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Cannot use this routine to void EpiPro lots.'
|
|
end
|
|
|
|
If ErrorMessage NE '' then
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = Username
|
|
LogData<3> = WMInKey
|
|
LogData<4> = ErrorMessage
|
|
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
|
|
Error_Services('Add', ErrorMessage)
|
|
end else
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = Username
|
|
LogData<3> = WMInKey
|
|
LogData<4> = 'Void queued successfully.'
|
|
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
Service SignVoidWMO(WMOutKey, Username)
|
|
|
|
ErrorMessage = ''
|
|
WONo = Field(WMOutKey, '*', 1)
|
|
CassNo = Field(WMOutKey, '*', 3)
|
|
WoStepKey = Xlate('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
|
|
WoMatKey = WONo : '*' : CassNo
|
|
ReactType = XLATE('WO_LOG', WONo, WO_LOG_REACT_TYPE$, 'X')
|
|
If ReactType EQ 'EPP' then
|
|
WMOutRec = Database_Services('ReadDataRow', 'WM_OUT', WMOutKey, True$, 0, False$)
|
|
IsVoided = WMOutRec<WM_OUT_VOID$>
|
|
If Not(IsVoided) then
|
|
IsOnHold = Hold_Services('CheckForHold', WoMatKey)
|
|
If Not(IsOnHold) then
|
|
Service_Services('PostProcedure', 'WM_OUT_SERVICES', 'SetVoidFlag':@vm:WMOutKey:@VM:Username)
|
|
If Error_Services('NoError') then
|
|
LotEventParams = ''
|
|
LotEventParams<1,1> = 'CreateLotEvent'
|
|
LotEventParams<1,2> = WMOutKey
|
|
LotEventParams<1,3> = DateTime()
|
|
LotEventParams<1,4> = 'VOID'
|
|
LotEventParams<1,5> = 'Lot voided by ' : Username
|
|
LotEventParams<1,6> = ''
|
|
LotEventParams<1,7> = Username
|
|
LotEventParams<1,8> = True$
|
|
LotEventParams<1,9> = 'WM_OUT'
|
|
Service_Services('PostProcedure', 'LOT_EVENT_SERVICES', LotEventParams)
|
|
If Error_Services('NoError') then
|
|
//Check if WMI is also voided. If it is, remove it from the WO_MAT_KEY field in WO_LOG, and void the WO_MAT record
|
|
WMIKey = WMOutKey; //the paired WMO key is the same as the WMIKey
|
|
IsWMIVoided = Database_Services('ReadDataColumn', 'WM_IN', WMIKey, WM_IN_VOID$)
|
|
If IsWMIVoided then
|
|
Service_Services('PostProcedure', 'WO_MAT_SERVICES', 'SetWoMatVoidFlag':@VM:WoMatKey:@VM:Username)
|
|
If Error_Services('NoError') then
|
|
Service_Services('PostProcedure', 'WORK_ORDER_SERVICES','RemoveWoMatCassetteFromWO':@VM:WoMatKey:@VM:Username)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Unable to void lot as it is already voided.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Cannot use this routine to void EpiPro lots.'
|
|
end
|
|
|
|
If ErrorMessage NE '' then
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = Username
|
|
LogData<3> = WMOutKey
|
|
LogData<4> = ErrorMessage
|
|
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
|
|
Error_Services('Add', ErrorMessage)
|
|
end else
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = Username
|
|
LogData<3> = WMOutKey
|
|
LogData<4> = 'Void queued successfully.'
|
|
Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$)
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
Service GetEligiblePeelOffLotsByWOAndEntityType(WONo, EntityType)
|
|
|
|
ErrorMessage = ''
|
|
EligibleCassIds = ''
|
|
|
|
If RowExists('WO_LOG', WONo) then
|
|
Begin Case
|
|
Case EntityType EQ 'RDS'
|
|
CassIds = Database_Services('ReadDataColumn', 'WO_LOG', WONo, WO_LOG_WO_MAT_KEY$, True$, 0, False$)
|
|
for each CassId in CassIds using @VM
|
|
RDSNo = XLATE('WO_MAT', CassId, WO_MAT_RDS_NO$, 'X')
|
|
Signatures = Signature_Services('GetSigProfile', CassId, 0, RDSNo)
|
|
Eligible = True$
|
|
for each Signature in Signatures<1> using @VM setting SigPos
|
|
SignatureDtm = Signatures<3, SigPos>
|
|
If SignatureDtm NE '' then
|
|
Eligible = False$
|
|
end
|
|
Until Eligible EQ False$
|
|
Next Signature
|
|
If Eligible then EligibleCassIds<1, -1> = CassId
|
|
Next CassId
|
|
Case EntityType EQ 'WM_OUT'
|
|
//WM_OUTS can be voided when
|
|
//1. There are no RDS Nos associated
|
|
//2. There have never been any wafers in them
|
|
WOStepKey = XLATE('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
|
|
CassIds = Database_Services('ReadDataColumn', 'WO_STEP', WOStepKey, WO_STEP_WM_OUT_KEYS$, True$, 0, False$)
|
|
for each CassId in CassIds using @VM
|
|
WMORec = Database_Services('ReadDataRow', 'WM_OUT', CassId, True$, 0, False);//XLATE('WM_OUT',WMOutKeys<1,I>,'','X')
|
|
WMO_RdsNos = WMORec<WM_OUT_RDS$>
|
|
WMO_NCRNos = WMORec<WM_OUT_SLOT_NCR$>
|
|
WMO_UMWCassIDs = WMORec<WM_OUT_UMW_CASS_ID$>
|
|
Eligible = True$
|
|
//Loop through RDS list to see if there is an RDS attached. If there are any RDS No's attached it is not eligible.
|
|
for each RDSNo in WMO_RDSNos using @VM
|
|
If RDSNo NE '' then
|
|
Eligible = False$
|
|
end
|
|
Until Eligible EQ False$
|
|
Next RDSNo
|
|
//Loop through NCR list to see if there are any NCR's associated. If there are any NCR No's attached it is not eligible.
|
|
If Eligible then
|
|
For Each NCRNo in WMO_NCRNos using @VM
|
|
If NCRNo NE '' then
|
|
Eligible = False$
|
|
end
|
|
Until Eligible EQ False$
|
|
Next NCR
|
|
end
|
|
//Loop through MU Wafer Usage list to see if there are any MU wafer's taken from this lot. If there are any Makeup Wafers attached it is not eligible.
|
|
If Eligible then
|
|
For Each UMWCass in WMO_UMWCassIDs using @VM
|
|
If UMWCass NE '' then
|
|
Eligible = False$
|
|
end
|
|
Until Eligible EQ False$
|
|
Next UMWCass
|
|
end
|
|
If Eligible then EligibleCassIds<1, -1> = CassId
|
|
Next CassId
|
|
Case EntityType EQ 'WM_IN'
|
|
WOStepKey = XLATE('WO_LOG', WONo, WO_LOG_WO_STEP_KEY$, 'X')
|
|
CassIds = Database_Services('ReadDataColumn', 'WO_STEP', WOStepKey, WO_STEP_WM_IN_KEYS$, True$, 0, False$)
|
|
for each CassId in CassIds using @VM
|
|
Eligible = True$
|
|
WMIRec = Database_Services('ReadDataRow', 'WM_IN', CassId, True$, 0, False);//XLATE('WM_OUT',WMOutKeys<1,I>,'','X')
|
|
WMI_RdsNos = WMIRec<WM_IN_RDS_NO$>
|
|
WMI_NCRNos = WMIRec<WM_IN_NCR_NO$>
|
|
Eligible = True$
|
|
//Loop through RDS list to see if there is an RDS attached. If there are any RDS No's attached it is not eligible.
|
|
for each RDSNo in WMI_RDSNos using @VM
|
|
If RDSNo NE '' then
|
|
Eligible = False$
|
|
end
|
|
Until Eligible EQ False$
|
|
Next RDSNo
|
|
//Loop through NCR list to see if there are any NCR's associated. If there are any NCR No's attached it is not eligible.
|
|
If Eligible then
|
|
For Each NCRNo in WMI_NCRNos using @VM
|
|
If NCRNo NE '' then
|
|
Eligible = False$
|
|
end
|
|
Until Eligible EQ False$
|
|
Next NCR
|
|
end
|
|
If Eligible then EligibleCassIds<1, -1> = CassId
|
|
Next CassId
|
|
Case EntityType EQ ''
|
|
ErrorMessage = 'Entity type parameter was invalid.'
|
|
Case Otherwise$
|
|
ErrorMessage = 'Entity type parameter was null.'
|
|
End Case
|
|
end else
|
|
ErrorMessage = 'WO# ' : WONo : ' not found in WO_LOG table.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', 'Error in ' : Service : '. ' : ErrorMessage)
|
|
end
|
|
|
|
Response = EligibleCassIds
|
|
end service
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Internal GoSubs
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ClearCursors:
|
|
|
|
For counter = 0 to 8
|
|
ClearSelect counter
|
|
Next counter
|
|
|
|
return
|
|
|