Compile function Material_Movement_Services(@Service, @Params) /*********************************************************************************************************************** Name : Material_Movement_Services Description : Handler program for all material movement services. Notes : 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) 01/07/21 DPC Original programmer - built to support PTI movement on form NDW_PTI_MAT_SCAN 08/23/21 DPC Added code to support new PTO form (NDW_PTO_MAT_SCAN) 01/22/22 DPC Added code to support GaN and EPP processes 06/01/22 DPC Removed GAN references ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $insert SERVICE_SETUP $insert SCANS_EQUATES $insert APP_INSERTS $insert WO_MAT_EQUATES $insert RDS_EQUATES $insert NOTIFICATION_EQU $insert EPI_PART_EQUATES $Insert WO_LOG_EQUATES $Insert MSG_EQUATES Declare function Scan_Services, Memory_Services, Database_Services, SRP_JSON, RTI_CreateGUID, Memberof, obj_WO_Mat Declare function Get_Property, RDS_Services, EpiPro_Services, DateTime, Signature_Services, Material_Movement_Services Declare subroutine Scan_Services, Memory_Services, Database_Services, SRP_JSON, Security_Services, Hold_Services Declare subroutine obj_WO_Mat_Log, obj_WO_Mat, Set_Status, SAP_Services, Obj_Notes, Print_SAP_Cass_Ship_Label GoToService else Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' module.') end Return Response or "" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Service Parameter Options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Options SCAN_TYPES = 'CASSETTE1', 'CASSETTE2', 'SUPPLIER' Options SCAN_TYPES_PTO = 'LABEL1', 'LABEL2' //----------------------------------------------------------------------------- // SERVICES //----------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- // ProcessFQAScanData // // Processes new scan data and updates the SCANS database row for the indicated Scan ID. This service should parse the // scan data and identify its intended field and then evaluate if the scan data is valid. Note: just because the scan // resource is not ready to be accepted, it does not mean this scan data is invalid. Each scan data will have to be // evaluated on a case by case basis. //---------------------------------------------------------------------------------------------------------------------- Service ProcessFQAScanData(ScanData, ScanType = SCAN_TYPES, Param1, Param2, Param3) ErrorMsg = '' If (ScanData NE '') then ColumnIndex = '' ColumnValue = '' // Identify the scan data based on the data identifier prefix (if any). Otherwise, assume this is a // type of cassette ID (i.e., RDS or WMO). Begin Case Case ScanType EQ 'SUPPLIER' ValidLot = False$ If ScanData[1, 2] EQ '2T' OR ScanData[1,2] EQ '1T' then ScanData[1, 2] = '' ScanSubLot = ScanData CassetteID = Param1 If INDEX(CassetteID,'.',2) then RDSType = 'EPP' end else RDSType = 'SIC' end ValidLot = Rds_Services('IsValidSubLot', CassetteID, RDSType, ScanSubLot) If ValidLot NE True$ then // Add error to error stack ErrorMsg = 'Invalid Supplier Lot: ':ScanData end If ErrorMsg EQ '' then Response = ScanSubLot Case ScanType EQ 'CASSETTE1' DelimCount = DCount(ScanData, '|') Begin Case Case ( (ScanData[1, 2] EQ '1T') or (ScanData[1, 1] EQ 'O') ) ErrorMsg = '1D Lot Label Scanned. 2D Lot Label Required.' Case (DelimCount NE 8) ErrorMsg = 'Invalid Lot Label Scan.' Case Otherwise$ CassetteID = Field(ScanData, '|', 3) SeqNo = Field(ScanData, '|', 8) End Case If ErrorMsg EQ '' then If CassetteID[1, 2] EQ '1T' then CassetteID[1, 2] = '' end else If CassetteID[1,1] EQ 'I' OR CassetteID[1,1] EQ 'O' then CassetteID[1,1] = '' end If INDEX(CassetteID,'.',2) then RDSType = 'EPP' WOMatKey = Field(CassetteID, '.', 1):'*':Field(CassetteID, '.', 3) end else RDSType = 'SIC' WOMatKey = Xlate('RDS', CassetteID, 'WO_MAT_KEY', 'X') end ValidCassetteID = Rds_Services('IsValidRDS', CassetteID, RDSType ) If ValidCassetteID EQ True$ then If Param1 NE '' AND ScanData NE Param1 then ;*Cassette2 Scan ErrorMsg = 'Lot Label Mismatch: ':CassetteID: ' does not match ': Param1 end If ErrorMsg EQ '' then // Check if FQA is signed FQASigned = '' WorkOrdNo = Field(WOMatKey, '*', 1) ReactorType = XLATE('WO_LOG', WorkOrdNo, 'REACT_TYPE', 'X') QAStage = '' Begin Case Case RDSType EQ 'EPP' QAStage = 'MO_QA' Case Otherwise$ QAStage = 'QA' End Case FQASigned = Signature_Services('CheckSignature', WOMatKey, QAStage) If NOT(FQASigned) then ErrorMsg = 'FQA not signed for ':CassetteID:'!' end end else ErrorMsg = 'Invalid Lot ID ':CassetteID end If ErrorMsg EQ '' then Response = '' Response<1> = CassetteID Response<2> = SeqNo end end Case ScanType EQ 'CASSETTE2' // Assume this is intended to be a Cassette ID scan (either WMO or RDS). Only if this is a // non-existent carrier will the scan data be considered invalid. // Strip '1T', 'I', and 'O' prefixes. ValidCassetteID = False$ ; // Assume Cassette ID is not valid for now. Cassette1ID = Param1 Seq1No = Param2 DelimCount = DCount(ScanData, '|') Begin Case Case ( (ScanData[1, 2] EQ '1T') or (ScanData[1, 1] EQ 'O') ) ErrorMsg = '1D Lot Label Scanned. 2D Lot Label Required.' Case (DelimCount NE 8) ErrorMsg = 'Invalid Lot Label Scan.' Case Otherwise$ CassetteID = Field(ScanData, '|', 3) Seq2No = Field(ScanData, '|', 8) End Case If ErrorMsg EQ '' then If CassetteID[1, 2] EQ '1T' then CassetteID[1, 2] = '' end else If CassetteID[1,1] EQ 'I' OR CassetteID[1,1] EQ 'O' then CassetteID[1,1] = '' end If INDEX(CassetteID,'.',2) then RDSType = 'EPP' end else RDSType = 'SIC' end ValidCassetteID = Rds_Services('IsValidRDS', CassetteID, RDSType ) If ValidCassetteID EQ True$ then If Cassette1ID NE '' AND (CassetteID NE Cassette1ID) then ;*Cassette2 Scan ErrorMsg = 'Lot Label Mismatch: ':CassetteID: ' does not match ': Cassette1ID end If Seq1No EQ Seq2No then ErrorMsg = 'FQA Label verification failed due':CRLF$:'to operator double-scanning barcode.' end end else ErrorMsg = 'Invalid RDS Number: ':CassetteID end If ErrorMsg EQ '' then Response = CassetteID end End Case end else ErrorMsg = 'ScanData argument was missing in the ' : Service : ' service.' end If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) end service //---------------------------------------------------------------------------------------------------------------------- // ProcessPTIScanData // // Processes new scan data and updates the SCANS database row for the indicated Scan ID. This service should parse the // scan data and identify its intended field and then evaluate if the scan data is valid. Note: just because the scan // resource is not ready to be accepted, it does not mean this scan data is invalid. Each scan data will have to be // evaluated on a case by case basis. //---------------------------------------------------------------------------------------------------------------------- Service ProcessPTIScanData(ScanData, ScanType = SCAN_TYPES, Param1, Param2, Param3) ErrorMsg = '' If (ScanData NE '') then ColumnIndex = '' ColumnValue = '' // Identify the scan data based on the data identifier prefix (if any). Otherwise, assume this is a // type of cassette ID (i.e., RDS or WMO). Begin Case Case ScanType EQ 'SUPPLIER' ValidLot = False$ If ScanData[1, 2] EQ '2T' OR ScanData[1,2] EQ '1T' then ScanData[1, 2] = '' ScanSubLot = ScanData CassetteID = Param1 If INDEX(CassetteID,'.',2) then RDSType = 'EPP' end else RDSType = 'SIC' end ValidLot = Rds_Services('IsValidSubLot', CassetteID, RDSType, ScanSubLot) If ValidLot NE True$ then ErrorMsg = 'Invalid Supplier Lot: ':ScanData If ErrorMsg EQ '' then Response = ScanSubLot Case ScanType EQ 'CASSETTE1' debug // Assume this is intended to be a Cassette ID scan (either WMO or RDS). Only if this is a // non-existent carrier will the scan data be considered invalid. // Strip '1T', 'I', and 'O' prefixes. ValidCassetteID = False$ ; // Assume Cassette ID is not valid for now. DelimCount = DCount(ScanData, '|') Begin Case Case (ScanData[1, 1] EQ 'I') ! Temporary exception while we exhaust current WMI inventory on KIT racks that ! do not have a 2D barcode. CassetteID = ScanData SeqNo = 'SEQ1' Case ( (ScanData[1, 2] EQ '1T') or (ScanData[1, 1] EQ 'O') ) ErrorMsg = '1D Lot Label Scanned. 2D Lot Label Required.' Case (DelimCount NE 8) ErrorMsg = 'Invalid Lot Label Scan.' Case Otherwise$ CassetteID = Field(ScanData, '|', 3) SeqNo = Field(ScanData, '|', 8) End Case If ErrorMsg EQ '' then If CassetteID[1, 2] EQ '1T' then CassetteID[1, 2] = '' end else If CassetteID[1,1] EQ 'I' OR CassetteID[1,1] EQ 'O' then CassetteID[1,1] = '' end If INDEX(CassetteID,'.',2) then RDSType = 'EPP' end else RDSType = 'SIC' end ValidCassetteID = Rds_Services('IsValidRDS', CassetteID, RDSType) If ValidCassetteID EQ True$ then If Param1 NE '' AND (ScanData NE Param1) then ;*Cassette2 Scan ErrorMsg = 'Lot Label Mismatch: ':CassetteID: ' does not match ': Param1 end end else ErrorMsg = 'Invalid Cassette Number: ':CassetteID end If ErrorMsg EQ '' then Response = '' Response<1> = CassetteID Response<2> = SeqNo end end Case ScanType EQ 'CASSETTE2' // Assume this is intended to be a Cassette ID scan (either WMO or RDS). Only if this is a // non-existent carrier will the scan data be considered invalid. // Strip '1T', 'I', and 'O' prefixes. ValidCassetteID = False$ ; // Assume Cassette ID is not valid for now. Cassette1ID = Param1 Seq1No = Param2 DelimCount = DCount(ScanData, '|') Begin Case Case (ScanData[1, 1] EQ 'I') ! Temporary exception while we exhaust current WMI inventory on KIT racks that ! do not have a 2D barcode. CassetteID = ScanData Seq2No = 'SEQ2' Case ( (ScanData[1, 2] EQ '1T') or (ScanData[1, 1] EQ 'O') ) ErrorMsg = '1D Lot Label Scanned. 2D Lot Label Required.' Case (DelimCount NE 8) ErrorMsg = 'Invalid Lot Label Scan.' Case Otherwise$ CassetteID = Field(ScanData, '|', 3) Seq2No = Field(ScanData, '|', 8) End Case If ErrorMsg EQ '' then If CassetteID[1, 2] EQ '1T' then CassetteID[1, 2] = '' end else If CassetteID[1,1] EQ 'I' OR CassetteID[1,1] EQ 'O' then CassetteID[1,1] = '' end If INDEX(CassetteID,'.',2) then RDSType = 'EPP' end else RDSType = 'SIC' end ValidCassetteID = Rds_Services('IsValidRDS', CassetteID, RDSType) If ValidCassetteID EQ True$ then If Cassette1ID NE '' AND (CassetteID NE Cassette1ID) then ;*Cassette2 Scan ErrorMsg = 'Lot Label Mismatch: ':CassetteID: ' does not match ': Cassette1ID end If Seq1No EQ Seq2No then ErrorMsg = 'PTI Label verification failed due':CRLF$:'to operator double-scanning barcode.' end end else ErrorMsg = 'Invalid Cassette Number: ':CassetteID end If ErrorMsg EQ '' then Response = CassetteID end End Case end else ErrorMsg = 'ScanData argument was missing in the ' : Service : ' service.' end If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) end service //---------------------------------------------------------------------------------------------------------------------- // ProcessPTOScanData // // This service should parse the scan data and identify its intended field and then evaluate if the scan data is valid. // For PTO scan, we will first look at the 2D barcode from the 4x2 (RDS or cassette label). After parsing, we will take // the 3rd data point and try to validate that is in an RDS and that that RDS record is in the proper state to do the PTO // transaction. If so, it will automatically print the 4x4 (what OI refers to as Shipping label), from which the operator // will scan the 2D barcode. Parsing that barcode, we will attempt to bring back the RDS again and validate that it is the // same RDS we got from the first label. If so, then the 'Save' button is enabled and the operator is allowed to process the // transaction. //---------------------------------------------------------------------------------------------------------------------- Service ProcessPTOScanData(ScanData, ScanType = SCAN_TYPES_PTO, Param1, Param2) ErrorMsg = '' Location = 'PTO Mat' If (ScanData NE '') then ColumnIndex = '' ColumnValue = '' Cassette1 = '' Cassette2 = '' Begin Case Case ScanType EQ 'LABEL1' // Determine whether regular NEPP or EPP label scan // NEPP should be data matrix scan and have 7 parts, RDS_No is the 3rd // EPP is 1D scan and will have the WMO number (e.g. 170369*1*48) // This should be a multi-part 2D datamatrix scan, so there should be a long string separated by pipe symbols. // Validate the 1. it is multi-part string and 2. that the RDS number from the string is a) valid RDS number // and b) is currently is the proper state to do PTO transaction. // Strip any standardized prefixes (e.g. '1T', '2T', etc.) as necessary // Data from Label1 should have 8 parts (no matter type - Si or EPP), we're looking for the 3rd cnt = DCount(ScanData, '|') if cnt NE 8 then ErrorMsg = 'Invalid Lot Label Scan.' end else Cassette1 = Field(ScanData, '|', 3) end If ErrorMsg EQ '' then // Strip the prefix encoding If Cassette1[1, 2] EQ '1T' OR Cassette1[1, 2] EQ '2T' then Cassette1[1, 2] = '' end else If Cassette1[1,1] EQ 'I' OR ScanData[1,1] EQ 'O' then Cassette1[1,1] = '' end WOMatKey = '' RdsRec = '' WONo = '' CassNo = '' If INDEX(Cassette1,'.',2) then RDSType = 'EPP' WMOKey = Cassette1 Convert '.' to '*' in WMOKey If RowExists('WM_OUT', WMOKey) then WONo = Field(WMOKey, '*', 1, 1) CassNo = Field(WMOKey, '*', 3, 1) WOMatKey = WONo:'*':CassNo end end else RDSType = 'SIC' WOMatKey = XLATE('RDS', Cassette1, 'WO_MAT_KEY', 'X') RdsRec = Database_Services('ReadDataRow','RDS', Cassette1) WONo = RdsRec CassNo = RdsRec end ValidCassette1 = False$ ; // Assume Cassette ID is not valid for now. testCass1 = Cassette1 Convert '*' to '.' in testCass1 If Rds_Services('IsValidRDS', Cassette1, RDSType) then If Rds_Services('GetHoldStatus', Cassette1, RDSType) EQ False$ then If Rds_Services('IsPackaged', Cassette1, RDSType) EQ True$ then ValidCassette1 = True$ end else ErrorMsg = RDSType: ' RDS ':testCass1: ' has not completed packaging.' end end else ErrorMsg = RDSType: ' RDS ':testCass1: ' is currently on hold.' end end else ErrorMsg = RDSType: ' RDS ' : testCass1 : ' is an invalid RDS number.' end If ErrorMsg EQ '' then LastPTO = obj_WO_Mat('OutofPTO',WOMatKey) StepNo = 1 IF LastPTO THEN MsgHead = 'Cassette previously scanned through PTO' MsgText = 'Scanned at ':LastPTO<2>:' by ':LastPTO<1>:CRLF$ MsgText := 'Are you sure you wish to rescan and reprint the shipping label?' OK = Msg(@WINDOW, '','YESNO','',MsgHead:@FM:MsgText) IF NOT(OK) THEN ErrorMsg = 'Scan Cancelled' END else Print_SAP_Cass_Ship_Label(WONo,StepNo,CassNo,Cassette1, RDSType) end end else Print_SAP_Cass_Ship_Label(WONo,StepNo,CassNo,Cassette1, RDSType) end If ErrorMsg EQ '' then If ValidCassette1 EQ True$ then If Param1 NE '' AND ScanData NE Param1 then ;*Cassette2 Scan ErrorMsg = 'RDS Mismatch: ':Cassette1: ' does not match ': Param1 end end else ErrorMsg = 'Invalid RDS Number: ':Cassette1 end If ErrorMsg EQ '' then Response = Cassette1 end end end Case ScanType EQ 'LABEL2' cnt = DCount(ScanData, ';') if cnt EQ 9 then // Tower is customer and RDS should be 2nd position Cassette2 = Field(ScanData, ';', 2) end else if cnt EQ 10 then // All other customers and RDS should be 3rd position Cassette2 = Field(ScanData, ';', 3) end else ErrorMsg = 'Invalid Shipping Label Scan.' end If ErrorMsg EQ '' then // Strip the prefix encoding If Cassette2[1, 2] EQ '1T' OR Cassette2[1, 2] EQ '2T' then Cassette2[1, 2] = '' end else If Cassette2[1,1] EQ 'I' OR ScanData[1,1] EQ 'O' then Cassette2[1,1] = '' end testCass1 = Param3 testCass2 = Cassette2 convert '*' to '.' in testCass1 convert '*' to '.' in testCass2 If testCass1 NE testCass2 then ErrorMsg = 'Scan Mismatch - RDS values do not match. Both cassettes placed on hold - Supervisor, Lead, or Engineering disposition required.':CRLF$ | : 'RDS Label #1: ':testCass1:CRLF$ | : 'RDS Label #2: ':testCass2:CRLF$ ScanMismatch = True$ GoSub ToggleLotHold end If ErrorMsg EQ '' then Response = Cassette2 end End Case end else ErrorMsg = 'ScanData argument was missing in the ' : Service : ' service.' end If ErrorMsg NE '' then Error_Services('Add', ErrorMsg) end service Service SaveRecord(CassetteID, Warehouse, Location, OperatorID) // Write success record in Material Log RDSKey = CassetteID WMOKey = CassetteID Convert '.' to '*' in WMOKey Begin Case Case RowExists('RDS', RDSKey) EQ True$ // RDS number WOMatKey = Xlate('RDS', RDSKey, 'WO', 'X') WOMatKey = WoMatKey:'*':Xlate('RDS', RDSKey, 'CASS_NO', 'X') Case RowExists('WM_OUT', WMOKey) EQ True$ // WM_OUT key WOMatKey = Xlate('WM_OUT', WMOKey, 'WO_MAT_KEY', 'X') Case RowExists('WO_MAT', CassetteID) EQ True$ // WO_MAT key WOMatKey = CassetteID Case Otherwise$ ErrorMessage = 'Invalid cassette ID ':CassetteID Error_Services('Add', ErrorMessage) End Case If Error_Services('NoError') then LogFile = 'WO_MAT' Action = 'PLACE' WhCd = Warehouse LocCd = Location UserID = OperatorID Tag = CassetteID ToolID = '' errCode = '' WONo = Field(WOMatKey, '*', 1, 1) CassNo = Field(WOMatKey, '*', 2, 1) InvDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS') WOMLParms = LogFile:@RM WOMLParms := InvDTM:@RM WOMLParms := Action:@RM WOMLParms := WhCd:@RM WOMLParms := LocCd:@RM WOMLParms := WONo:@RM WOMLParms := CassNo:@RM WOMLParms := UserID:@RM WOMLParms := Tag:@RM WOMLParms := ToolID Set_Status(0) errCode = '' obj_WO_Mat_Log('Create',WOMLParms) If Get_Status(errCode) then Swap @SVM with CRLF$ in errCode ErrorMsg = 'Errors calling obj_WO_Mat_Log("Create"). Error code: ':errCode Error_Services('Add', ErrorMsg) Gosub SendErrorNotification end end end service SendErrorNotification: Recipients = '' SentFrom = 'MATERIAL_MOVEMENT_SERVICES' Subject = 'ERROR CALLING OBJ_WO_MAT ' Message = 'Error occured while attempting to write WO_MAT_LOG at ':Location:' Scan':CRLF$:ErrorMsg AttachKey = WoMatKey AttachWindow = '' SendToGroup = 'FI_SUPPORT' Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) return ToggleLotHold: If ScanMismatch EQ True$ then // Write fail packaging record in material log for first cassette ID LogFile = 'WO_MAT' LogDTM = DateTime() Action = 'PLACE' WhCd = '1K' LocCd = 'PTO' UserID = @User4 Tags = 'RDS Mismatch (':Cassette2:')' ToolID = '' OperatorID = @User4 If Cassette1 EQ '' then Cassette1 = Param1 end // Check if first cassette ID is a valid RDS or WM_OUT key Convert '.' to '*' in Cassette1 ValidCass = False$ Begin Case Case ( RowExists('RDS', Cassette1) EQ True$ ) WONo = Xlate('RDS', Cassette1, 'WO', 'X') CassNo = Xlate('RDS', Cassette1, 'CASS_NO', 'X') HoldEntity = 'RDS' Case ( RowExists('WM_OUT', Cassette1) EQ True$ ) WONo = Field(Cassette1, '*', 1, 1) CassNo = Field(Cassette1, '*', 3, 1) HoldEntity = 'WM_OUT' Case ( RowExists('WO_MAT', Cassette1) EQ True$ ) WONo = Field(Cassette1, '*', 1, 1) CassNo = Field(Cassette1, '*', 2, 1) HoldEntity = 'WO_MAT' Case Otherwise$ Null // To do: Throw Error End Case Convert '*' to '.' in Cassette1 HoldEntityID = Cassette1 WOMLParms = LogFile:@RM WOMLParms := LogDTM:@RM WOMLParms := Action:@RM WOMLParms := WhCd:@RM WOMLParms := LocCd:@RM WOMLParms := WONo:@RM WOMLParms := CassNo:@RM WOMLParms := UserID:@RM WOMLParms := Tags:@RM WOMLParms := ToolID Set_Status(0) errCode = '' obj_WO_Mat_Log('Create',WOMLParms) If Get_Status(errCode) then Swap @SVM with CRLF$ in errCode ErrorMsg = 'Error calling obj_WO_Mat_Log("Create"). Error code: ':errCode Gosub SendErrorNotification end // Place first cassette on hold WOMatKey = WONo:'*':CassNo CtrlEntID = False$ ;* Control checked/unchecked OriginFlag = 'PTO' ;* Flag to indicate a hold initiated from the packagaing form Hold_Services('ToggleHold', WOMatKey, HoldEntity, HoldEntityID, CtrlEntID, OriginFlag, '', OperatorID) // Check if second cassette ID is a valid RDS or WM_OUT key Convert '.' to '*' in Cassette2 ValidCass = False$ Begin Case Case ( RowExists('RDS', Cassette2) EQ True$ ) ValidCass = True$ WONo = Xlate('RDS', Cassette2, 'WO', 'X') CassNo = Xlate('RDS', Cassette2, 'CASS_NO', 'X') HoldEntity = 'RDS' Case ( RowExists('WM_OUT', Cassette2) EQ True$ ) ValidCass = True$ WONo = Field(Cassette2, '*', 1, 1) CassNo = Field(Cassette2, '*', 3, 1) HoldEntity = 'WM_OUT' Case ( RowExists('WO_MAT', Cassette2) EQ True$ ) ValidCass = True$ WONo = Field(Cassette2, '*', 1, 1) CassNo = Field(Cassette2, '*', 2, 1) HoldEntity = 'WO_MAT' Case Otherwise$ Null End Case // Write fail packaging record in material log for second cassette ID If ValidCass EQ True$ then LogFile = 'WO_MAT' LogDTM = DateTime() Action = 'PLACE' WhCd = '1K' LocCd = 'PTO' UserID = @User4 Tags = 'RDS Mismatch (':Cassette1:')' ToolID = '' HoldEntityID = Cassette2 WOMLParms = LogFile:@RM WOMLParms := LogDTM:@RM WOMLParms := Action:@RM WOMLParms := WhCd:@RM WOMLParms := LocCd:@RM WOMLParms := WONo:@RM WOMLParms := CassNo:@RM WOMLParms := UserID:@RM WOMLParms := Tags:@RM WOMLParms := ToolID Set_Status(0) errCode = '' obj_WO_Mat_Log('Create',WOMLParms) If Get_Status(errCode) then Swap @SVM with CRLF$ in errCode ErrorMsg = 'Error calling obj_WO_Mat_Log("Create"). Error code: ':errCode Gosub SendErrorNotification end // Place second cassette on hold WOMatKey = WONo:'*':CassNo CtrlEntID = False$ ;* Control checked/unchecked OriginFlag = 'PTO' ;* Flag to indicate a hold initiated from the packaging form Parms = WOMatKey:@RM:HoldEntity:@RM:HoldEntityID:@RM:CtrlEntID:@RM:OriginFlag:@RM:OperatorID Hold_Services('ToggleHold', WOMatKey, HoldEntity, HoldEntityID, CtrlEntID, OriginFlag, '', OperatorID) end GoSub SendPTOMismatchNotification errCode = '' IF Get_Status(errCode) THEN Error_Services('Add', 'Error code ':errCode:' in ':Service:' service.') Error_Services('Add', 'Cassette scans did not match! Both cassettes placed on hold - Supervisor, Lead, or Engineering disposition required.') end return SendPTOMismatchNotification: // Send scan mismatch notification Recipients = XLATE('NOTIFICATION','PTO_MISMATCH',NOTIFICATION_USER_ID$,'X') SentFrom = 'MATERIAL_MOVEMENT_SERVICES' Subject = 'PTO Mat Scan Verification Mismatch' Message = 'RDS label verification failed at PTO MatScan. Both cassettes placed on hold - Supervisor, Lead, or Engineering disposition required.':CRLF$ | : 'RDS Label #1: ':Cassette1:CRLF$ | : 'RDS Label #2: ':Cassette2:CRLF$ | : 'Operator: ':@User4 AttachWindow = '' AttachKey = '' SendToGroup = '' Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) return