Compile function Shipment_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        :   Shipment_Services

    Description :   Handler program for all Shipment services.


    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)
        11/13/24    djm     Original programmer.
        1/8/2025    djm     Added parsing for connection errors and logging for loop resets. Removed emails for COC_AVAILABILITY.

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
$insert LOGICAL
$Insert SERVICE_SETUP
$Insert COC_EQUATES
$Insert COMPANY_EQUATES

Declare function Error_Services, Company_Services, FTP_Services, Environment_Services, Logging_Services, Shipment_Services
Declare function Database_Services
Declare subroutine Error_Services, Mona_Services, Rlist, SRP_Stopwatch, Logging_Services, Database_Services
Declare subroutine Shipment_Services, OBJ_Notes

Equ     CRLF$ to \0D0A\

LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\COC_Availability'
LogDate      = Oconv(Date(), 'D4/')
LogTime      = Oconv(Time(), 'MTS')
LogFileName  = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_NETWORK.log'
Headers      = 'Logging DTM' : @FM : 'Message'
ColumnWidths = 30 : @FM : 300
objLogNetwork       = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)	
LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM

GoToService

Return Response or ""

Options MonaResources = 'FILE_GENERATION', 'FILE_TRANSMISSION', 'FILE_AVAILABILITY', 'FTP_SERVER_REACHABLE'

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SERVICES
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------------------------------------------------
// CycleRetentionDates
//
//
// Cycles the APP_INFO*COC_AVAILABILITY record dates to check a portion of the retention period at a time.
// Intended to be run by the Service Manager.
// 
//----------------------------------------------------------------------------------------------------------------------
Service CycleRetentionDates()

    hSysLists       = Database_Services('GetTableHandle', 'SYSLISTS')
    Lock hSysLists, ServiceKeyID then
        CycleRec = Xlate('APP_INFO', 'COC_AVAILABILITY', '', 'X')
        TodayDate = Date()
        EarliestDate = Shipment_Services('GetEarliestDate')
        If CycleRec<1> EQ TodayDate then
            CurrStartDate = CycleRec<2>
            CurrEndDate = CycleRec<3>
            PotentialStartDate = CurrStartDate - 10
            PotentialEndDate = CurrEndDate - 10
            Begin Case
                Case CurrStartDate EQ EarliestDate
                    gosub LogLoopReset
                    StartDate = TodayDate - 10
                    EndDate = TodayDate
                Case PotentialStartDate LT EarliestDate
                    StartDate = EarliestDate
                    EndDate = EarliestDate + 10
                Case Otherwise$
                    StartDate = PotentialStartDate
                    EndDate = PotentialEndDate
            End Case
            
            NewRec = CycleRec
            NewRec<2> = StartDate
            NewRec<3> = EndDate
            Database_Services('WriteDataRow', 'APP_INFO', 'COC_AVAILABILITY', NewRec, True$, False$, False$)
            StartDate = Oconv(StartDate, 'D4-')
            EndDate = Oconv(EndDate, 'D4-')
            Shipment_Services('CheckFileAvailability', StartDate, EndDate)
        end else
            gosub LogLoopReset
            StartDate = TodayDate - 10
            EndDate = TodayDate
            NewRec = ''
            NewRec<1> = TodayDate
            NewRec<2> = StartDate
            NewRec<3> = EndDate
            Database_Services('WriteDataRow', 'APP_INFO', 'COC_AVAILABILITY', NewRec, True$, False$, False$)
            
            StartDate = Oconv(StartDate, 'D4-')
            EndDate = Oconv(EndDate, 'D4-')
            Shipment_Services('CheckFileAvailability', StartDate, EndDate)
        end
        Unlock hSysLists, ServiceKeyID else null
    end
    
end service


//----------------------------------------------------------------------------------------------------------------------
// CheckFileAvailability
//
//
// Confirms the availabiliy of generated files on the FTP serve, otherwise sets a MONA critical status for COC
// FILE_AVAILABILITY. Intended to be run by the Service Manager.
// 
//----------------------------------------------------------------------------------------------------------------------
Service CheckFileAvailability(StartDate, EndDate)
    Error_Services('Clear')
    NetworkError = False$
    OPEN 'COC' TO COCTable ELSE
        Error_Services('Add', 'Unable to open COC Table')
        Return
    END
    
    SelectQuery = 'SELECT COC BY ENTRY_DATE WITH ENTRY_DATE GE ' : Quote(StartDate) : ' AND WITH ENTRY_DATE LE ' : Quote(EndDate)
    Clearselect
    RList(SelectQuery, 5, '', '', '')
    
    If @List_Active EQ 3 AND @RecCount NE 0 then
        Done = 0
        LOOP
            READNEXT COCNo ELSE Done = 1
        UNTIL Done OR NetworkError
            READ COCRec FROM COCTable, COCNo THEN
                WONo          = COCRec<COC_WO_NO$>
                CustNo        = XLATE('COC', COCNo, 'WO_CUST_NO_EX', 'X')
                If CustNo EQ '' then CustNo = XLATE('WO_LOG',WONo,'CUST_NO','X')						
                AutoDataFlag  = XLATE('COMPANY',CustNo,COMPANY_AUTO_FTP_FLAG$,'X')
                If AutoDataFlag then
                    NewCOC = COCRec
                    NewCOC<COC_FTP_SHOULD_EXIST$> = True$
                    Gosub CompanyExceptionCheck
                    DeleteScript    = True$
                    
                    Query = '*' : COCNo : '*'
                    QueryResult = FTP_Services('ListDirectory', FTPHost, Username, Password, RemoteDirectory, Query, '', DeleteScript, SSH, '')
                    ErrTest = Error_Services('GetMessage')
                    If ErrTest EQ '' then
                        If QueryResult NE '' then
                            NewCOC<COC_FTP_EXISTS$> = True$
                            Database_Services('WriteDataRow', 'COC', COCNo, NewCOC, True$, False$, False$)
                        end
                    end else
                    	// Ignore ssh_init and network errors
                        If ( (IndexC(ErrTest, 'ssh_init', 1) EQ 0) and (IndexC(ErrTest, 'Network error', 1) EQ 0 ) and (IndexC(ErrTest, 'Access Denied', 1) EQ 0)) then
                             Error_Services('Add', 'Expected file for shipment ' : COCNo : ' missing.')
                             NewCOC<COC_FTP_EXISTS$> = False$
                             Database_Services('WriteDataRow', 'COC', COCNo, NewCOC, True$, False$, False$)
                             Gosub LogMissingFile
                        End else
                        	NetworkError = True$
                        end
                    end
                end
            END
        REPEAT
    end
    // Code to run COC SELECT and change MONA Status
    If NetworkError EQ False$ then
        //Log that there were no network errors detected.
        NetworkLogMessage = 'No network errors detected.'
        GoSub LogNetworkStatus
    	Shipment_Services('ClearMONACritical', 'FTP_SERVER_REACHABLE')
		
		EarliestDate = Shipment_Services('GetEarliestDate')
		EarliestDate = OConv(EarliestDate, 'D4-')
		SelectQuery = 'SELECT COC BY ENTRY_DATE WITH ENTRY_DATE GE ' : Quote(EarliestDate) : ' AND WITH FTP_SHOULD_EXIST EQ 1 AND WITH FTP_EXISTS EQ 0'
		Clearselect
		RList(SelectQuery, 5, '', '', '')
		MissingCOCs = ''
		Done = False$
		LOOP
            READNEXT MissingCOCNo ELSE Done = 1
        UNTIL Done
        	MissingCOCs<-1> = MissingCOCNo
        REPEAT
		If @List_Active EQ 3 AND @RecCount NE 0 then
			swap @FM with ',' in MissingCOCs
			Shipment_Services('SetMONACritical', 'FILE_AVAILABILITY', 'Error locating expected COC file(s). Please review the logs and correct. ' : MissingCOCs)
		end else
			Shipment_Services('ClearMONACritical', 'FILE_AVAILABILITY')
		end
    end else
        //Log that there were network errors detected.
        If Assigned(ErrTest) then
            NetworkLogMessage = ErrTest
            swap CRLF$ with ' , ' in NetworkLogMessage
            GoSub LogNetworkStatus
        end
    	Shipment_Services('SetMONAWarning', 'FTP_SERVER_REACHABLE')
    	Error_Services('Add', Service : 'service failed. ''An issue connecting to the FTP server has occured.')
    end
end service


//----------------------------------------------------------------------------------------------------------------------
// GetEarliestDate
//
//
// Returns the earliest date that the service should check for.
// 
// 
//----------------------------------------------------------------------------------------------------------------------
Service GetEarliestDate()
    
    TodayDate = Date()
    /////// Earliest Date where all documents to date are accounted for. To be used until 3-2-25, after which the earliest date should always just be 1 year before the current date.////////////////////////////////////
    TempEarliestDate = '4-14-24'
    TempEarliestDate = Iconv(TempEarliestDate, 'D')
    LastYearDate = TodayDate - 365
    If LastYearDate LT TempEarliestDate then
        EarliestDate = TempEarliestDate
    end else
        EarliestDate = LastYearDate
    end
    
    Response = EarliestDate
    
End Service


//----------------------------------------------------------------------------------------------------------------------
// SetMONACritical
//
//
// Sets a MONA Critical Status for the specified COC monitoring resource.
// Sends a notification to the FI_SUPPORT notification group with the specified message.
// 
// 
//----------------------------------------------------------------------------------------------------------------------
Service SetMONACritical(MONAResource=MONAResources, ErrorMessage)
    
    IF MONAResource = 'FILE_GENERATION' OR MONAResource = 'FILE_TRANSMISSION' OR MONAResource = 'FILE_AVAILABILITY' OR MONAResource = 'FTP_SERVER_REACHABLE' then
        Mona_Services('PostStatus', 'GRP_OPENINSIGHT_MES_OP_FE_COC', MONAResource, 'CRITICAL')
        If ErrorMessage NE '' then
        	// Log error
			LogDate      = Oconv(Date(), 'D4/')
			LogTime      = Oconv(Time(), 'MTS')
			LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\Shipment'
			LogFileName  = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_MonA_Critical.log'
			Headers      = 'Logging DTM' : @FM : 'Error' 
			ColumnWidths = 30 : @FM : 300
			objMonaLog   = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)
			LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM
			LogData      = ''
			LogData<1>   = LoggingDtm
			LogData<2>   = ErrorMessage
			Logging_Services('AppendLog', objMonaLog, LogData, @RM, @FM)
            // Send an internal OI message to FI Support
            Recipients   = Xlate('NOTIFICATION', 'FI_SUPPORT', 'USER_ID', 'X')
            SentFrom     = 'SYSTEM'
            Subject      = 'COC ' : MONAResource : ' Error!'
            Message      = ErrorMessage
            AttachWindow = ''
            AttachKey    = ''
            SendToGroup  = ''
            Parms        = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
            obj_Notes('Create',Parms)
        End
    end else
        Error_Services('Add', 'Invalid COC MONA resource.')
    end
    
End Service

Service SetMONAWarning(MONAResource=MONAResources, ErrorMessage)
    
    IF MONAResource = 'FILE_GENERATION' OR MONAResource = 'FILE_TRANSMISSION' OR MONAResource = 'FILE_AVAILABILITY' OR MONAResource = 'FTP_SERVER_REACHABLE' then
        Mona_Services('PostStatus', 'GRP_OPENINSIGHT_MES_OP_FE_COC', MONAResource, 'WARNING')
        If ErrorMessage NE '' then
        	// Log error
			LogDate      = Oconv(Date(), 'D4/')
			LogTime      = Oconv(Time(), 'MTS')
			LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\Shipment'
			LogFileName  = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_MonA_Warning.log'
			Headers      = 'Logging DTM' : @FM : 'Error' 
			ColumnWidths = 30 : @FM : 300
			objMonaLog   = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)
			LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM
			LogData      = ''
			LogData<1>   = LoggingDtm
			LogData<2>   = ErrorMessage
			Logging_Services('AppendLog', objMonaLog, LogData, @RM, @FM)
        End
    end else
        Error_Services('Add', 'Invalid COC MONA resource.')
    end
    
End Service
//----------------------------------------------------------------------------------------------------------------------
// ClearMONACritical
//
//
// Sets a MONA OK Status for the specified COC monitoring resource.
// 
// 
//----------------------------------------------------------------------------------------------------------------------
Service ClearMONACritical(MONAResource=MONAResources)
    
    IF MONAResource = 'FILE_GENERATION' OR MONAResource = 'FILE_TRANSMISSION' OR MONAResource = 'FILE_AVAILABILITY' OR MONAResource = 'FTP_SERVER_REACHABLE' then
        Mona_Services('PostStatus', 'GRP_OPENINSIGHT_MES_OP_FE_COC', MONAResource, 'OK')
    end else
        Error_Services('Add', 'Invalid COC MONA resource.')
    end
    
End Service


//----------------------------------------------------------------------------------------------------------------------
// ResetAllCOCMonaStatus
//
//
// Resets MONA critical status for COC FILE_GENERATION, FILE_TRANSMISSION, and FILE_AVAILABILITY.
// 
// 
//----------------------------------------------------------------------------------------------------------------------
Service ResetAllCOCMonaStatus()
    
    Mona_Services('PostStatus', 'GRP_OPENINSIGHT_MES_OP_FE_COC', 'FILE_GENERATION', 'OK')
    Mona_Services('PostStatus', 'GRP_OPENINSIGHT_MES_OP_FE_COC', 'FILE_TRANSMISSION', 'OK')
    Mona_Services('PostStatus', 'GRP_OPENINSIGHT_MES_OP_FE_COC', 'FILE_AVAILABILITY', 'OK')
    
End Service


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


InitCocLog:
	
	LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\COC_Availability'
	LogDate      = Oconv(Date(), 'D4/')
	LogTime      = Oconv(Time(), 'MTS')
	LogFileName  = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_Error.log'
	Headers      = 'Logging DTM' : @FM : 'Shipment ID' : @FM : 'Expected Remote Directory' :@FM: 'Customer/COMPANY Number' :@FM: 'Error Output'
	ColumnWidths = 30 : @FM : 20 : @FM : 50 :@FM: 50 :@FM: 300
	objLog       = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)	
	LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM
	
return

InitNetworkLog:
   
    LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\COC_Availability'
    LogDate      = Oconv(Date(), 'D4/')
    LogTime      = Oconv(Time(), 'MTS')
    LogFileName  = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_NETWORK.log'
    Headers      = 'Logging DTM' : @FM : 'Message'
    ColumnWidths = 30 : @FM : 300
    objLogNetwork       = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)	
    LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM
   
return

LogNetworkStatus:
    
    If Assigned(NetworkLogMessage) then
        ErrorLogMessage = NetworkLogMessage
    end else
        ErrorLogMessage = 'Unspecified network error'
    end
    GoSub InitNetworkLog
    LogData = ''
    LogData<1> = LoggingDTM
    LogData<2> = ErrorLogMessage
    Logging_Services('AppendLog', objLogNetwork, LogData, @RM, @FM) 
    
return

LogMissingFile:
    
    GoSub InitCocLog
    LogData = ''
    LogData<1>      = LoggingDTM
    LogData<2>      = COCNo
    LogData<3>      = RemoteDirectory
    LogData<4>      = CustNo
    LogData<5>      = ErrTest
    Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
    
return


LogLoopReset:
	
	GoSub InitCocLog
    LogData = ''
    LogData<1>      = LoggingDTM
    LogData<2>      = ''
    LogData<3>      = 'Loop Restart'
    LogData<4>      = ''
    Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
    
return


CompanyExceptionCheck:
    
    Begin Case
        Case CustNo EQ '6593' OR CustNo EQ '408' OR CustNo EQ '7076'
            FTPHost            = '10.72.176.48'
            Username        = 'Infineon\TEMFTPEPIMesa'
            Password        = 'fW&EHJhKWg!skUKV4_34'
            RemoteDirectory = '\TEMFTP_EPIMesa\Archive'
            SSH             = False$
        Case CustNo EQ '6775'
            FTPHost            = 'sFTPNA.extra.infineon.com'
            Username        = 'DNAMesaFI-FTP'
            Password        = 'OpenInsight2018....!'
            RemoteDirectory = '/Tower'
            SSH             = True$
        Case CustNo EQ '7053' OR CustNo EQ '7092'
            FTPHost            = 'sFTPNA.extra.infineon.com'
            Username        = 'DNAMesaFI-FTP'
            Password        = 'OpenInsight2018....!'
            RemoteDirectory = '/Tower'
            SSH             = True$
        Case Otherwise$
            FTPSettings     = Company_Services('GetFTPServer', CustNo)
            FTPHost         = FTPSettings<1>;//this is new
            Username        = FTPSettings<2>;//this is new
            Password        = FTPSettings<3>;//this is new
            RemoteDirectory = '/' : FTPSettings<5>;//this is new
            SSH             = FTPSettings<6>;//this is new
    End Case
    
return

