No artigo de hoje, vou mostrar como copiar arquivos gerados via AdvPL (ou até mesmo arquivos que ficam no servidor na Protheus Data) para uma pasta compartilhada do OneDrive.
Antes de começarmos pessoal, vou detalhar abaixo o cenário do cliente:
- O cliente não possuía a integração paga com a API da Microsoft
- Então foi preparado uma máquina com uma conta do OneDrive configurada
- Nesse computador, foi compartilhado uma pasta na rede, dentro da pasta do OneDrive
Agora com esse cenário, vamos a lógica que foi desenvolvida:
- Nos jobs que geram os relatórios em PDF na Protheus Data, é acionado a função zOneDrive
- Essa função, cria 2 arquivos .bat dentro da Protheus Data, um é para criar uma pasta dentro da pasta compartilhada na rede e o outro é para copiar o relatório, mudando de nome
- Todas as tentativas de realizar a cópia via rede (seja com WaitRunSrv, com XCOPY, etc), falharam (talvez devido ao Firewall do cliente). Então ao invés de acionar a cópia via AdvPL, foi criado um código em Java que aciona os dois arquivos bat criados no passo 2
- Via Agendador do Windows, foi agendado para rodar esse .jar duas vezes ao dia
Abaixo o código fonte em AdvPL:
//Bibliotecas
#Include "TOTVS.ch"
/*/{Protheus.doc} User Function zOneDrive
Função que copia um relatório local da Protheus Data para uma pasta no OneDrive
@type Function
@author Atilio
@since 02/05/2022
/*/
User Function zOneDrive(dDataRef, cDirOrig, cArqOrig, cArqDest)
Local aArea := FWGetArea()
Local cPastaOne := SuperGetMV("MV_X_ONEDR", .F., "\\192.168.70.209\relatorios\")
Local cDirTmp := "\x_temp\onedrive\"
Local cArqBat := "1_" + dToS(Date()) + "_" + StrTran(Time(), ":", "-") + "_pasta_onedrive.bat"
Local cArqBat2 := "2_" + dToS(Date()) + "_" + StrTran(Time(), ":", "-") + "_copia_onedrive.bat"
Local cComandos := ""
Local cDirBase := GetSrvProfString("RootPath", "")
Default dDataRef := DaySub(Date(), 1)
Default cDirOrig := ""
Default cArqOrig := ""
Default cArqDest := ""
//Somente se tiver as quatro pastas
If ! Empty(cDirOrig) .And. ! Empty(cArqOrig) .And. ! Empty(cArqDest)
//Somente se o arquivo existir na origem
If File(cDirOrig + cArqOrig)
cArqDest := FWNoAccent(cArqDest)
//Monta o diretório de destino - 202205 (Maio de 2022)\
cDirDest := SubStr(dToS(dDataRef), 1, 6) + " (" + MesExtenso(dDataRef) + " de " + cValToChar(Year(dDataRef)) + ")\"
If ! ExistDir(cPastaOne + cDirDest)
cComandos := 'mkdir "' + cPastaOne + cDirDest + '"' + CRLF
EndIf
//Dia 01\
cDirDest += "Dia " + StrZero(Day(dDataRef), 2) + "\"
If ! ExistDir(cPastaOne + cDirDest)
cComandos := 'mkdir "' + cPastaOne + cDirDest + '"' + CRLF
EndIf
//Se houver comandos, cria o bat
If ! Empty(cComandos)
//Caso o arquivo ja exista, será excluido
If File(cDirTmp + cArqBat)
FErase(cDirTmp + cArqBat)
EndIf
MemoWrite(cDirTmp + cArqBat, cComandos)
EndIf
//Bat que copia o arquivo e renomeia
cComandos := ''
cComandos += 'XCOPY "' + cDirBase + cDirOrig + cArqOrig+ '" "' + cPastaOne + cDirDest + '" /y' + CRLF
cComandos += 'RENAME "' + cPastaOne + cDirDest + cArqOrig + '" "' + cArqDest + '"' + CRLF
cComandos += 'timeout 2' + CRLF
MemoWrite(cDirTmp + cArqBat2, cComandos)
Sleep(5000)
EndIf
EndIf
FWRestArea(aArea)
Return
E abaixo o código fonte em Java:
import java.io.File;
import java.io.IOException;
public class PExecCopy {
/*
* Author: Daniel Atilio
* References:
* Get Files - https://www.tutorialspoint.com/how-to-get-list-of-all-files-folders-from-a-folder-in-java
* File Contains ".bat" - https://stackoverflow.com/questions/17134773/to-check-if-string-contains-particular-word
* Run Batch - https://stackoverflow.com/questions/615948/how-do-i-run-a-batch-file-from-my-java-application
* Delete Files - https://www.geeksforgeeks.org/delete-file-using-java/
*/
public static void main(String[] args) {
String folder = "D:\\TOTVS\\Protheus_Data\\x_temp\\onedrive\\";
String fullFile = "";
String search = ".bat";
//Creating a File object for directory
File directoryPath = new File(folder);
//List of all files and directories
String contents[] = directoryPath.list();
System.out.println("List of files and directories in the specified directory:");
for(int i=0; i<contents.length; i++) {
fullFile = folder + contents[i];
System.out.println(fullFile);
//Validate file is .bat
if ( fullFile.toLowerCase().indexOf(search.toLowerCase()) != -1 ) {
try{
Process p = Runtime.getRuntime().exec(fullFile);
p.waitFor();
}catch( IOException ex ){
//Validate the case the file can't be accesed (not enought permissions)
System.out.println("Failed to run batch #1");
}catch( InterruptedException ex ){
//Validate the case the process is being stopped by some external situation
System.out.println("Failed to run batch #2");
}
//Delete file
File file = new File(fullFile);
if (file.delete()) {
System.out.println("File deleted successfully");
}
else {
System.out.println("Failed to delete the file");
}
}
}
}
}
Bom pessoal, por hoje é só.
Abraços e até a próxima.