774 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			774 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 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'
 | |
| 				// 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, 2] EQ '1T') or (ScanData[1, 1] EQ 'O') or (ScanData[1, 1] EQ 'I') )
 | |
| 						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, 2] EQ '1T') or (ScanData[1, 1] EQ 'O') or (ScanData[1, 1] EQ 'I') )
 | |
| 						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<RDS_WO$>
 | |
| 						CassNo   = RdsRec<RDS_CASS_NO$>
 | |
| 					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
 | |
| 
 |