OBJECT Codeunit 50007 Expensify Integration Function { OBJECT-PROPERTIES { Date=12/27/19; Time=[ 2:09:44 PM]; Modified=Yes; Version List=ENI18.11.01; } PROPERTIES { OnRun=BEGIN CreateReimburseRecords; END; } CODE { VAR ExpensifyConfig@1102615000 : Record 50004; ExpensifyCommands@1102615001 : Record 50005; ExpensifyUsers@1102615011 : Record 50001; ExpensifyPolicies@1102615015 : Record 50006; HTTPMgmt@1102615010 : Codeunit 1297; ResponseTempBlob@1102615009 : Record 99008535; ResponseInStream@1102615008 : InStream; ResponseOutStream@1102615007 : OutStream; HttpStatusCode@1102615006 : DotNet "'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Net.HttpStatusCode"; ResponseHeaders@1102615005 : DotNet "'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Collections.Specialized.NameValueCollection"; HTTPResponseText@1102615004 : Text[1024]; HTTPResponseLength@1102615003 : Integer; HTTPRequestParameters@1102615002 : Text[1024]; RequestDescription@1102615012 : TextConst 'ENU="?requestJobDescription="'; ExpensifyUserID@1102615013 : Text[250]; ExpensifyUserEmail@1102615014 : Text[250]; RequestDescriptionCURL@1170000000 : TextConst 'ENU="-d requestJobDescription="'; CURL@1170000001 : TextConst 'ENU=C:\\Expensify\\curl-7.54.0-win64-mingw\\bin\\curl.exe'; ExpensifyNAVFunctions@1170000002 : Codeunit 50008; Window@1102615016 : Dialog; FetchReport@1102615017 : TextConst 'ENU=Fetching Reports....'; Text001@1102615018 : TextConst 'ENU=Please check the user credentials/ connection details.'; Err001@1102615019 : TextConst 'ENU=Authentication URI not defined. Please check configuration.'; PROCEDURE AuthenticateUser@1102615001(iUserName@1102615000 : Text[50];iCommand@1102615001 : Text[250]) AuthenticationStatus : Boolean; BEGIN iUserName := LOWERCASE(COPYSTR(iUserName,2,STRLEN(iUserName)-2)); ExpensifyConfig.RESET; IF ExpensifyConfig.FINDFIRST THEN BEGIN ExpensifyCommands.RESET; ExpensifyCommands.SETRANGE("Expensify API Command Name",iCommand); IF ExpensifyCommands.FINDFIRST THEN BEGIN CLEAR(HTTPMgmt); IF iCommand = 'Authenticate' THEN HTTPRequestParameters := CreateAuthenticationRequest(ExpensifyCommands."Expensify API Command Type", ExpensifyCommands."Expensify API Command Setting", iUserName); HTTPMgmt.Initialize(ExpensifyConfig."Expensify API URL" + HTTPRequestParameters); HTTPMgmt.SetMethod('POST'); HTTPMgmt.SetContentLength(0); CLEAR(ResponseInStream); CLEAR(ResponseTempBlob); ResponseTempBlob.Blob.CREATEINSTREAM(ResponseInStream); HTTPMgmt.GetResponse(ResponseInStream,HttpStatusCode,ResponseHeaders); IF NOT(ISNULL(HttpStatusCode)) THEN IF (HttpStatusCode.Equals(HttpStatusCode.OK)) THEN AuthenticationStatus := TRUE ELSE AuthenticationStatus := FALSE; IF NOT(AuthenticationStatus) THEN HTTPMgmt.ProcessFaultResponse(Text001); END ELSE ERROR(Err001); END; EXIT(AuthenticationStatus); END; LOCAL PROCEDURE CreateAccessKey@1102615004(iUserName@1102615000 : Text[50]) UserAccessKey : Text[500]; BEGIN IF ExpensifyConfig.FINDFIRST THEN BEGIN ExpensifyUsers.RESET; ExpensifyUsers.SETRANGE(USERID,iUserName); IF ExpensifyUsers.FINDFIRST THEN BEGIN ExpensifyUserID := ExpensifyUsers."Expensify User ID"; ExpensifyUserEmail := ExpensifyUsers."Expensify User Email"; UserAccessKey := '"credentials":' + '{"partnerUserID":"' + ExpensifyUserID + '",' + '"partnerUserSecret":"' + ExpensifyUsers."Expensify User Secret" + '"' + '}'; END; END; END; LOCAL PROCEDURE CreateAccessKeyCURL@1170000005(iUserName@1102615000 : Text[50]) UserAccessKey : Text[500]; BEGIN IF ExpensifyConfig.FINDFIRST THEN BEGIN ExpensifyUsers.RESET; ExpensifyUsers.SETRANGE(USERID,iUserName); IF ExpensifyUsers.FINDFIRST THEN BEGIN ExpensifyUserID := ExpensifyUsers."Expensify User ID"; ExpensifyUserEmail := ExpensifyUsers."Expensify User Email"; UserAccessKey := '"credentials":' + '{"partnerUserID":"' + ExpensifyUserID + '",' + '"partnerUserSecret":"' + ExpensifyUsers."Expensify User Secret" + '"' + '}'; END; END; END; PROCEDURE GetAdminPolicyList@1102615003(iUserName@1102615000 : Text[50]) AuthenticationStatus : Boolean; VAR JSON@1102615006 : Codeunit 50006; JSONString@1102615005 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.String"; TempPostingExchField@1102615004 : TEMPORARY Record 50003; JSONtringBuilder@1102615003 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Text.StringBuilder"; JSONMgmt@1102615002 : Codeunit 50006; RecordCounter@1102615001 : Integer; ChkExpensifyPolicies@1102615007 : Record 50006; BEGIN iUserName := LOWERCASE(COPYSTR(iUserName,2,STRLEN(iUserName)-2)); ExpensifyConfig.RESET; IF ExpensifyConfig.FINDFIRST THEN BEGIN ExpensifyCommands.RESET; ExpensifyCommands.SETRANGE("Expensify API Command Name",'Policy List'); IF ExpensifyCommands.FINDFIRST THEN HTTPRequestParameters := CreatePolicyListRequest(ExpensifyCommands."Expensify API Command Type", ExpensifyCommands."Expensify API Command Setting", iUserName); END; IF AuthenticateUser(iUserName,'Policy List') THEN BEGIN HTTPResponseLength := 0; HTTPResponseText := ''; JSONtringBuilder := JSONtringBuilder.StringBuilder; REPEAT ResponseInStream.READTEXT(HTTPResponseText); HTTPResponseLength += STRLEN(HTTPResponseText); JSONtringBuilder.Append(HTTPResponseText); UNTIL STRLEN(HTTPResponseText) = 0; JSONString := JSONtringBuilder.ToString(0,HTTPResponseLength); JSONMgmt.StartJSon; CLEAR(TempPostingExchField); JSONMgmt.ReadJSon(JSONString,TempPostingExchField); IF TempPostingExchField.FINDFIRST THEN BEGIN ExpensifyPolicies.RESET; IF ExpensifyPolicies.FINDFIRST THEN ExpensifyPolicies.DELETEALL; REPEAT ExpensifyPolicies.INIT; FOR RecordCounter := 1 TO 6 DO BEGIN IF TempPostingExchField."Node ID" = 'policyList..outputcurrency' THEN BEGIN ExpensifyPolicies."Expensify Policy Currency" := TempPostingExchField.Value; TempPostingExchField.NEXT; END ELSE IF TempPostingExchField."Node ID" = 'policyList..owner' THEN BEGIN ExpensifyPolicies."Expensify Policy Owner" := TempPostingExchField.Value; TempPostingExchField.NEXT; END ELSE IF TempPostingExchField."Node ID" = 'policyList..role' THEN BEGIN IF TempPostingExchField.Value = 'admin' THEN ExpensifyPolicies."Expensify Policy Role" := ExpensifyPolicies."Expensify Policy Role"::admin ELSE IF TempPostingExchField.Value = 'auditor' THEN ExpensifyPolicies."Expensify Policy Role" := ExpensifyPolicies."Expensify Policy Role"::auditor ELSE IF TempPostingExchField.Value = 'user' THEN ExpensifyPolicies."Expensify Policy Role" := ExpensifyPolicies."Expensify Policy Role"::user ELSE ExpensifyPolicies."Expensify Policy Role" := ExpensifyPolicies."Expensify Policy Role"::others; TempPostingExchField.NEXT; END ELSE IF TempPostingExchField."Node ID" = 'policyList..name' THEN BEGIN ExpensifyPolicies."Expensify Policy Name" := TempPostingExchField.Value; TempPostingExchField.NEXT; END ELSE IF TempPostingExchField."Node ID" = 'policyList..id' THEN BEGIN ExpensifyPolicies."Expensify Policy ID" := TempPostingExchField.Value; TempPostingExchField.NEXT; END ELSE IF TempPostingExchField."Node ID" = 'policyList..type' THEN BEGIN IF TempPostingExchField.Value = 'corporate' THEN ExpensifyPolicies."Expensify Policy Type" := ExpensifyPolicies."Expensify Policy Type"::corporate ELSE IF TempPostingExchField.Value = 'team' THEN ExpensifyPolicies."Expensify Policy Type" := ExpensifyPolicies."Expensify Policy Type"::team ELSE ExpensifyPolicies."Expensify Policy Type" := ExpensifyPolicies."Expensify Policy Type"::others; TempPostingExchField.NEXT; END; END; CLEAR(ChkExpensifyPolicies); IF ExpensifyPolicies."Expensify Policy ID" <> '' THEN IF NOT(ChkExpensifyPolicies.GET(ExpensifyPolicies."Expensify Policy ID")) THEN ExpensifyPolicies.INSERT; CLEAR(ExpensifyPolicies); UNTIL TempPostingExchField.NEXT = 0; END; END; END; PROCEDURE GetExpReportsList@1102615000(iUserName@1102615000 : Text[50]) AuthenticationStatus : Boolean; VAR JSON@1102615006 : Codeunit 50006; JSONString@1102615005 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.String"; TempPostingExchField@1102615004 : TEMPORARY Record 50003; JSONtringBuilder@1102615003 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Text.StringBuilder"; JSONMgmt@1102615002 : Codeunit 50006; RecordCounter@1102615001 : Integer; ChkExpensifyPolicies@1102615007 : Record 50006; FileNameStringBuilder@1102615009 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Text.StringBuilder"; FileNameString@1102615008 : Text[1024]; BEGIN iUserName := LOWERCASE(COPYSTR(iUserName,2,STRLEN(iUserName)-2)); ExpensifyConfig.RESET; IF ExpensifyConfig.FINDFIRST THEN BEGIN ExpensifyCommands.RESET; ExpensifyCommands.SETRANGE("Expensify API Command Name",'Expense Reports'); IF ExpensifyCommands.FINDFIRST THEN BEGIN HTTPRequestParameters := CreateExpRepsRequest(ExpensifyCommands."Expensify API Command Type", ExpensifyCommands."Expensify API Command Setting", iUserName); IF AuthenticateUser(iUserName,'Expense Reports') THEN BEGIN HTTPResponseLength := 0; HTTPResponseText := ''; FileNameStringBuilder := FileNameStringBuilder.StringBuilder; REPEAT ResponseInStream.READTEXT(HTTPResponseText); HTTPResponseLength += STRLEN(HTTPResponseText); FileNameStringBuilder.Append(HTTPResponseText); UNTIL STRLEN(HTTPResponseText) = 0; FileNameString := FileNameStringBuilder.ToString(0,HTTPResponseLength); END; END; END; IF (FileNameString <> '') AND ExpensifyConfig.FINDFIRST THEN BEGIN ExpensifyCommands.RESET; ExpensifyCommands.SETRANGE("Expensify API Command Name",'Download Reports'); IF ExpensifyCommands.FINDFIRST THEN BEGIN HTTPRequestParameters := CreateDownloadRequest(ExpensifyCommands."Expensify API Command Type", ExpensifyCommands."Expensify API Command Setting", iUserName,FileNameString); IF AuthenticateUser(iUserName,'Download Reports') THEN BEGIN HTTPResponseLength := 0; HTTPResponseText := ''; JSONtringBuilder := JSONtringBuilder.StringBuilder; REPEAT ResponseInStream.READTEXT(HTTPResponseText); HTTPResponseLength += STRLEN(HTTPResponseText); JSONtringBuilder.Append(HTTPResponseText); UNTIL STRLEN(HTTPResponseText) = 0; JSONString := JSONtringBuilder.ToString(0,HTTPResponseLength); JSONMgmt.StartJSon; CLEAR(TempPostingExchField); JSONMgmt.ReadJSon(JSONString,TempPostingExchField); END; END; END; END; PROCEDURE GetExpReportsListCURL@1170000000(iUserName@1102615000 : Text[50]) AuthenticationStatus : Boolean; VAR JSON@1102615006 : Codeunit 50006; JSONString@1102615005 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.String"; TempPostingExchField@1102615004 : TEMPORARY Record 50003; JSONtringBuilder@1102615003 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Text.StringBuilder"; JSONMgmt@1102615002 : Codeunit 50006; RecordCounter@1102615001 : Integer; ChkExpensifyPolicies@1102615007 : Record 50006; FileNameStringBuilder@1102615009 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Text.StringBuilder"; FileNameString@1102615008 : Text[1024]; ProcessCtrl@1170000000 : DotNet "'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Diagnostics.Process"; Command@1170000001 : DotNet "'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Diagnostics.ProcessStartInfo"; ResultText@1170000002 : Text[1024]; FileMgmt@1170000003 : Codeunit 419; ResultFile@1170000004 : File; ResultFileStream@1170000005 : OutStream; LineFeed@1170000006 : ARRAY [2] OF Char; CSVUpload@1170000007 : XMLport 50001; ImportFileStream@1170000008 : InStream; ReimburseSheet@1170000009 : Record 50000; BEGIN Window.OPEN(FetchReport); iUserName := LOWERCASE(COPYSTR(iUserName,2,STRLEN(iUserName)-2)); ExpensifyConfig.RESET; IF ExpensifyConfig.FINDFIRST THEN BEGIN ExpensifyCommands.RESET; ExpensifyCommands.SETRANGE("Expensify API Command Name",'Expense Reports'); IF ExpensifyCommands.FINDFIRST THEN BEGIN HTTPRequestParameters := CreateExpRepsRequestCURL(ExpensifyCommands."Expensify API Command Type", ExpensifyCommands."Expensify API Command Setting", iUserName); MESSAGE(HTTPRequestParameters); Command := Command.ProcessStartInfo(CURL,HTTPRequestParameters); Command.CreateNoWindow := TRUE; Command.UseShellExecute := FALSE; Command.RedirectStandardOutput := TRUE; ProcessCtrl := ProcessCtrl.Process; ProcessCtrl.StartInfo(Command); ProcessCtrl.Start(); ResultText := ProcessCtrl.StandardOutput.ReadToEnd(); CLEAR(ProcessCtrl); IF ResultText <> '' THEN FileNameString := ResultText; END; END; IF (FileNameString <> '') AND ExpensifyConfig.FINDFIRST THEN BEGIN ExpensifyCommands.RESET; ExpensifyCommands.SETRANGE("Expensify API Command Name",'Download Reports'); IF ExpensifyCommands.FINDFIRST THEN BEGIN HTTPRequestParameters := CreateDownloadRequestCURL(ExpensifyCommands."Expensify API Command Type", ExpensifyCommands."Expensify API Command Setting", iUserName,FileNameString); Command := Command.ProcessStartInfo(CURL,HTTPRequestParameters); Command.CreateNoWindow := TRUE; Command.UseShellExecute := FALSE; Command.RedirectStandardOutput := TRUE; ProcessCtrl := ProcessCtrl.Process; ProcessCtrl.StartInfo(Command); ProcessCtrl.Start(); ResultFile.CREATE(TEMPORARYPATH + 'expenseReport.csv'); ResultFile.TEXTMODE(TRUE); LineFeed[1] := 10; LineFeed[2] := 13; REPEAT ResultText := ProcessCtrl.StandardOutput.ReadLine(); ResultFile.WRITE(ResultText); AddToImportTable(ResultText); UNTIL ResultText = ''; ResultFile.CLOSE; AuthenticationStatus := TRUE; CLEAR(ProcessCtrl); ReimburseSheet.RESET; IF ReimburseSheet.FINDFIRST THEN BEGIN REPEAT ExpensifyNAVFunctions.CreateReimburseReqsts(ReimburseSheet."Expense Spender Code",ReimburseSheet."Expense Tag"); UNTIL ReimburseSheet.NEXT = 0; END; END; END; Window.CLOSE; END; LOCAL PROCEDURE CreateAuthenticationRequest@1102615002(iCommandType@1102615000 : Text[100];iCommandInputSetting@1102615001 : Text[250];iUserName@1102615002 : Text[250]) RequestText : Text[1024]; BEGIN RequestText := RequestDescription; RequestText += '{"type":"' + iCommandType +'",'; RequestText += CreateAccessKey(iUserName) + ','; RequestText += '"inputSettings":{' + '"type":"' + iCommandInputSetting + '",' + '"adminOnly":true,' + '"userEmail":"' + ExpensifyUserEmail + '"'; RequestText += '}'; RequestText += '}'; END; LOCAL PROCEDURE CreatePolicyListRequest@1102615005(iCommandType@1102615000 : Text[100];iCommandInputSetting@1102615001 : Text[250];iUserName@1102615002 : Text[250]) RequestText : Text[1024]; BEGIN RequestText := RequestDescription; RequestText += '{"type":"' + iCommandType +'",'; RequestText += CreateAccessKey(iUserName) + ','; RequestText += '"inputSettings":{' + '"type":"' + iCommandInputSetting + '",' + '"adminOnly":true,' + '"userEmail":"' + ExpensifyUserEmail + '"'; RequestText += '}'; RequestText += '}'; END; LOCAL PROCEDURE CreateExpRepsRequest@1102615006(iCommandType@1102615000 : Text[100];iCommandInputSetting@1102615001 : Text[250];iUserName@1102615002 : Text[250]) RequestText : Text[1024]; BEGIN RequestText := RequestDescription; RequestText += '{"type":"' + iCommandType +'",'; RequestText += CreateAccessKey(iUserName) + ','; RequestText += '"onReceive":{ "immediateResponse":["returnRandomFileName"] },'; RequestText += '"inputSettings":{' + '"type":"' + iCommandInputSetting + '",' + //'"reportState":"SUBMITTED","limit":"10",' + '"filters":{"startDate":"2016-01-01","endDate":"2019-12-31"}},'; //'"filters":{"reportIDList":"19778497"}},'; RequestText += '"outputSettings":{ "fileExtension":"txt", "fileBasename":"allExpReps" },'; RequestText += '"onFinish":[{ "actionName":"markAsExported", "label":"Expensify Export" },{"actionName":"email",' + '"recipients":"rajat@inecta.com", "message":"Your report is ready."}]'; RequestText += '}'; RequestText += '&template=${expense.merchant},{report.reportName}'; END; LOCAL PROCEDURE CreateDownloadRequest@1102615010(iCommandType@1102615000 : Text[100];iCommandInputSetting@1102615001 : Text[250];iUserName@1102615002 : Text[250];iFileName@1102615003 : Text[1024]) RequestText : Text[1024]; BEGIN RequestText := RequestDescription; RequestText += '{"type":"' + iCommandType +'",'; RequestText += CreateAccessKey(iUserName) + ','; RequestText += '"filename":"' + iFileName +'","fileSystem":"integrationServer"'; RequestText += '}'; END; LOCAL PROCEDURE CreateExpRepsRequestCURL@1170000001(iCommandType@1102615000 : Text[100];iCommandInputSetting@1102615001 : Text[250];iUserName@1102615002 : Text[250]) RequestText : Text[1024]; BEGIN RequestText := ' '; { RequestText += ExpensifyConfig."Expensify API URL" + ' '; RequestText += RequestDescriptionCURL; RequestText += '"{type:' + iCommandType +','; RequestText += CreateAccessKeyCURL(iUserName) + ','; RequestText += 'onReceive:{ immediateResponse:[returnRandomFileName] },'; RequestText += 'inputSettings:{' + 'type:' + iCommandInputSetting + ',' + 'filters:{startDate:2016-01-01,endDate:2019-12-31}},'; RequestText += 'outputSettings:{ fileExtension:csv, fileBasename:allExpReps },'; RequestText += 'onFinish:[{ actionName:markAsExported, label:Expensify Export }]'; RequestText += '}"'; RequestText += ' --data-urlencode "template@C:\\Expensify\\curl-7.54.0-win64-mingw\\bin\\expensify_template.ftl" -H Expect:'; } RequestText += ExpensifyConfig."Expensify API URL" + ' '; RequestText += RequestDescriptionCURL; RequestText += '{"type":"' + iCommandType +'",'; RequestText += CreateAccessKeyCURL(iUserName) + ','; RequestText += '"onReceive":{"immediateResponse":["returnRandomFileName"]},'; RequestText += '"inputSettings":{' + '"type":"' + iCommandInputSetting + '",' + '"filters":{"startDate":"2016-01-01","endDate":"2019-12-31"}},'; RequestText += '"outputSettings":{"fileExtension":"csv", "fileBasename":"allExpReps" },'; RequestText += '"onFinish":[{"actionName":"markAsExported", "label":"Expensify Export"}]'; RequestText += '}'; RequestText += ' --data-urlencode "template@C:\\Expensify\\curl-7.54.0-win64-mingw\\bin\\expensify_template.ftl" -H Expect:'; END; LOCAL PROCEDURE CreateDownloadRequestCURL@1170000002(iCommandType@1102615000 : Text[100];iCommandInputSetting@1102615001 : Text[250];iUserName@1102615002 : Text[250];iFileName@1102615003 : Text[1024]) RequestText : Text[1024]; BEGIN RequestText := ' '; RequestText += ExpensifyConfig."Expensify API URL" + ' '; RequestText += RequestDescriptionCURL; RequestText += '{"type":"' + iCommandType +'",'; RequestText += CreateAccessKey(iUserName) + ','; RequestText += '"filename":"' + iFileName +'"'; RequestText += '}'; END; LOCAL PROCEDURE AddToImportTable@1170000004(InputLine@1170000000 : Text[1024]); VAR lImportStore@1170000001 : Record 50000; SplitChar@1170000002 : Text[1]; SplitCharPos@1170000003 : Integer; LastCharPos@1170000004 : Integer; TempLine@1170000005 : Text[1024]; Category@1170000006 : Text; RecipientRec@1170000007 : Record 23; ReportExists@1170000008 : Boolean; OldImportStore@1170000009 : Record 50000; BEGIN SplitChar := '|'; LastCharPos := 1; IF InputLine <> '' THEN BEGIN lImportStore.INIT; SplitCharPos := STRPOS(InputLine,SplitChar); lImportStore."Expense Time" := ReturnTextValue(InputLine,LastCharPos,SplitCharPos); InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); lImportStore."Expense Merchant" := ReturnTextValue(InputLine,LastCharPos,SplitCharPos); InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); IF (ReturnTextValue(InputLine,LastCharPos,SplitCharPos) <>'') AND (ReturnTextValue(InputLine,LastCharPos,SplitCharPos) <>'Amount') THEN EVALUATE(lImportStore."Expense Amount",ReturnTextValue(InputLine,LastCharPos,SplitCharPos)) ELSE lImportStore."Expense Amount" := 0; lImportStore."Expense Amount" /= 100; InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); IF Category = 'Food' THEN lImportStore."Expense Category" := lImportStore."Expense Category" ::Food ELSE IF Category = 'Transportation' THEN lImportStore."Expense Category" := lImportStore."Expense Category" ::Travel ELSE IF Category = 'Entertainment' THEN lImportStore."Expense Category" := lImportStore."Expense Category" ::Entertainment ELSE lImportStore."Expense Category" := lImportStore."Expense Category" ::Other; InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); lImportStore."Expense Tag" := ReturnTextValue(InputLine,LastCharPos,SplitCharPos); InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); lImportStore."Expense Comment" := ReturnTextValue(InputLine,LastCharPos,SplitCharPos); InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); IF ReturnTextValue(InputLine,LastCharPos,SplitCharPos) = 'YES' THEN lImportStore."Expense Reimbursable" := TRUE ELSE lImportStore."Expense Reimbursable" := FALSE; InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); IF ReturnTextValue(InputLine,LastCharPos,SplitCharPos) = 'YES' THEN lImportStore."Expense Billable" := TRUE ELSE lImportStore."Expense Billable" := FALSE; InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); lImportStore."Expense Currency" := ReturnTextValue(InputLine,LastCharPos,SplitCharPos); InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); lImportStore."Expense Receipt Link" := ReturnTextValue(InputLine,LastCharPos,SplitCharPos); InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); lImportStore."Expense Spender Contact" := ReturnTextValue(InputLine,LastCharPos,SplitCharPos); InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); RecipientRec.RESET; RecipientRec.SETRANGE("E-Mail",lImportStore."Expense Spender Contact"); IF RecipientRec.FINDFIRST THEN lImportStore."Expense Spender Code" := RecipientRec."No."; InputLine := COPYSTR(InputLine,SplitCharPos+1); SplitCharPos := STRPOS(InputLine,SplitChar); lImportStore."Expense Report ID" := ReturnTextValue(InputLine,LastCharPos,SplitCharPos); lImportStore."Expense Transaction ID" := InputLine; OldImportStore.RESET; OldImportStore.SETRANGE("Expense Report ID",lImportStore."Expense Report ID"); OldImportStore.SETRANGE("Expense Transaction ID",lImportStore."Expense Transaction ID"); IF OldImportStore.FINDFIRST THEN ReportExists := TRUE ELSE ReportExists := FALSE; IF NOT(lImportStore."Expense Time" = 'Timestamp') AND NOT(ReportExists) THEN lImportStore.INSERT; END END; LOCAL PROCEDURE ReturnTextValue@1170000009(InputLine@1170000000 : Text[1024];StartVal@1170000001 : Integer;EndVal@1170000002 : Integer) Value : Text; BEGIN IF StartVal >= EndVal THEN Value := '' ELSE Value := COPYSTR(InputLine,StartVal,EndVal-1); EXIT(Value); END; LOCAL PROCEDURE CreateReimburseRecords@1170000003(); VAR ReimburseSheet@1170000000 : Record 50000; NAVFunctions@1170000001 : Codeunit 50008; BEGIN ReimburseSheet.RESET; ReimburseSheet.SETRANGE("Expense Status",ReimburseSheet."Expense Status"::New); IF ReimburseSheet.FINDFIRST THEN BEGIN REPEAT NAVFunctions.CreateReimburseReqsts(ReimburseSheet."Expense Spender Code",ReimburseSheet."Expense Tag"); UNTIL ReimburseSheet.NEXT = 0; END; END; BEGIN { ENI18.11.01 EXPENSIFY } END. } }