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.