Rotina Automática Purchase Order (EICPO400)


A idéia deste artigo é apenas para exemplificar como efetuar a rotina automática para a rotina Purchase Order (EICPO400). Para quem conhece Purchase Order, sabe o quanto é difícil inserir invoice uma a uma, e porque não utilizar uma rotina automática para importar várias invoices numa mesma Purchase Order? Primeiramente é necessário saber quais são os parâmetros do MsExecAuto do EICPO400 (PO)

MSExecAuto({|a,b,c,d| EICPO400(a,b,c,d)},Nil,aCab,aItens,3)
Onde: a = Deixaremos como Nil, pois no fonte padrão, ele entenderá que será uma PO b = Cabeçalho da PO (Tabela SW2) c = Itens da PO (Tabela SW3) d = Como é uma inclusão, utilizaremos a opção 3, se fosse uma alteração usa-se a opção 4 ou 5 para exclusão. Campos que irei utilizar no meu exemplo: Estrutura do cabeçalho
//Abaixo informo na variavel aCab os campos que julgo necessário no meu ambiente
AAdd(aCab,  {'W2_FILIAL'  	, xFilial("SW2"), Nil})
AAdd(aCab,  {'W2_PO_DT'   	, dDatabase	    , Nil})
AAdd(aCab,  {'W2_IMPCO'   	, '2'	        , Nil})
AAdd(aCab,  {'W2_FORN'   	, '000015'	    , Nil})
AAdd(aCab,  {'W2_FORLOJ'   	, '01'	        , Nil})
AAdd(aCab,  {'W2_FOB_TOT'   , 0				, Nil})
AAdd(aCab,  {'W2_AGENTE'   	, '001'			, Nil})
AAdd(aCab,  {'W2_TIPO_EM'   , 'MA'			, Nil})
AAdd(aCab,  {'W2_ORIGEM'   	, 'AMS'			, Nil})
AAdd(aCab,  {'W2_DEST'  	, 'VIR'			, Nil})
AAdd(aCab,  {'W2_FREINC'   	, '2'			, Nil})
AAdd(aCab,  {'W2_FREPPCC'   , 'CC'			, Nil})
AAdd(aCab,  {'W2_COND_PA'   , '00001'		, Nil}) 
AAdd(aCab,  {'W2_DIAS_PA'   , 180 			, Nil})
AAdd(aCab,  {'W2_COMPRA'   	, '000001' 		, Nil})
AAdd(aCab,  {'W2_MOEDA'   	, 'USD' 		, Nil})
AAdd(aCab,  {'W2_DT_PAR'    , dDatabase 	, Nil})
AAdd(aCab,  {'W2_PARID_U'   , 1 			, Nil})
AAdd(aCab,  {'W2_INCOTER'   , 'FCA' 		, Nil})
AAdd(aCab,  {'W2_IMPORT'   	, '1' 			, Nil})
AAdd(aCab,  {'W2_EMITIDO'  	, 'S' 			, Nil})
AAdd(aCab,  {'W2_DT_PC'   	, dDatabase 	, Nil})
AAdd(aCab,  {'W2_STAT_PC'   , '' 			, Nil})
AAdd(aCab,  {'W2_E_LC'   	, '2' 			, Nil})
AAdd(aCab,  {'W2_POSICAO'   , '1' 			, Nil})
AAdd(aCab,  {'W2_IMPENC'   	, '2' 			, Nil})
AAdd(aCab,  {'W2_CONTR'   	, '2' 			, Nil})
AAdd(aCab,  {'W2_RAT_POR'  	, '1' 			, Nil})
Estrutura para incluir os Itens
//Abaixo informo na variavel aItens os campos que julgo necessário no meu ambiente	
aAdd(aItens,{;  
{'W3_FILIAL'  	,  aDados[i,1]  , Nil},;
{'W3_CC'   		,  aDados[i,2]  , Nil},;
{'W3_SI_NUM'  	,  aDados[i,3]  , Nil},;
{'W3_COD_I'   	,  aDados[i,4]  , Nil},;
{'W3_FORN'   	,  aDados[i,5]  , Nil},;
{'W3_FORLOJ'  	,  aDados[i,6]  , Nil},;
{'W3_FLUXO'   	,  iif(aDados[i,7] == "2","7",aDados[i,7])  , Nil},;
{'W3_QTDE'   	,  aDados[i,8]  , Nil},;
{'W3_SALDO_Q'	,  aDados[i,8]  , Nil},;
{'W3_PRECO'   	,  aDados[i,9]  , Nil},;
{'W3_DT_EMB'  	,  aDados[i,10] , Nil},;
{'W3_DT_ENTR' 	,  aDados[i,11] , Nil},;
{'W3_TEC'   	,  aDados[i,12] , Nil},;
{'W3_POSICAO' 	,  aDados[i,13] , Nil},;
{'W3_PGI_NUM' 	,  aDados[i,14] , Nil},;
{'W3_SEQ'   	,  aDados[i,15] , Nil},;
{'W3_REG'   	,  aDados[i,16] , Nil},;
{'W3_NR_CONT' 	,  aDados[i,17] , Nil},;
{'W3_PESOL'   	,  aDados[i,18] , Nil},;
{'W3_FABR'   	,  aDados[i,19] , Nil},;
{'W3_FABLOJ'  	,  aDados[i,20] , Nil};
})
Exemplo do fonte:
User Function ExAutoPO()
	Local aCab      := {}	//aCab Array contendo os campos do cabeçalho (SW2)
	Local aItens    := {}	//aItens Array contendo os campos dos itens (SW3).
	Local cNumPO    := ""
	Local nOpc		:= 3	//3- Inclusão
					//4- Alteração é necessário o uso do campo LINPOS para localizar o bem
					//5- Exclusão é necessário o uso do campo LINPOS para localizar o bem e o 
					//AUTDELETA para que seja deletado
							
	Private lMsErroAuto := .F. 	//Determina se houve alguma inconsistência na execução da rotina 
	Private lMsHelpAuto := .T.	//Determina se as mensagens de help devem ser direcionadas para o arq. de log

	//Abaixo informo na variavel aCab os campos que julgo necessário no meu ambiente
	AAdd(aCab,  {'W2_FILIAL'  	, xFilial("SW2"), Nil})
	AAdd(aCab,  {'W2_PO_DT'   	, dDatabase	    , Nil})
	AAdd(aCab,  {'W2_IMPCO'   	, '2'	        , Nil})
	AAdd(aCab,  {'W2_FORN'   	, '000015'	    , Nil})
	AAdd(aCab,  {'W2_FORLOJ'   	, '01'	        , Nil})
	AAdd(aCab,  {'W2_FOB_TOT'   , 0				, Nil})
	AAdd(aCab,  {'W2_AGENTE'   	, '001'			, Nil})
	AAdd(aCab,  {'W2_TIPO_EM'   , 'MA'			, Nil})
	AAdd(aCab,  {'W2_ORIGEM'   	, 'AMS'			, Nil})
	AAdd(aCab,  {'W2_DEST'  	, 'VIR'			, Nil})
	AAdd(aCab,  {'W2_FREINC'   	, '2'			, Nil})
	AAdd(aCab,  {'W2_FREPPCC'   , 'CC'			, Nil})
	AAdd(aCab,  {'W2_COND_PA'   , '00001'		, Nil}) 
	AAdd(aCab,  {'W2_DIAS_PA'   , 180 			, Nil})
	AAdd(aCab,  {'W2_COMPRA'   	, '000001' 		, Nil})
	AAdd(aCab,  {'W2_MOEDA'   	, 'USD' 		, Nil})
	AAdd(aCab,  {'W2_DT_PAR'    , dDatabase 	, Nil})
	AAdd(aCab,  {'W2_PARID_U'   , 1 			, Nil})
	AAdd(aCab,  {'W2_INCOTER'   , 'FCA' 		, Nil})
	AAdd(aCab,  {'W2_IMPORT'   	, '1' 			, Nil})
	AAdd(aCab,  {'W2_EMITIDO'  	, 'S' 			, Nil})
	AAdd(aCab,  {'W2_DT_PC'   	, dDatabase 	, Nil})
	AAdd(aCab,  {'W2_STAT_PC'   , '' 			, Nil})
	AAdd(aCab,  {'W2_E_LC'   	, '2' 			, Nil})
	AAdd(aCab,  {'W2_POSICAO'   , '1' 			, Nil})
	AAdd(aCab,  {'W2_IMPENC'   	, '2' 			, Nil})
	AAdd(aCab,  {'W2_CONTR'   	, '2' 			, Nil})
	AAdd(aCab,  {'W2_RAT_POR'  	, '1' 			, Nil})


    aadd(aDados, {xFilial("SW3"), '01', '159000', 'PRODUTO0001' , '000001', '01', '2', 1000, 1000, 1.00, CTOD('10/10/2018'), CTOD('11/11/2018'), '84389000', '1', '', 0, 1, 1, 0.100, '000001', '01'} )
    aadd(aDados, {xFilial("SW3"), '01', '159000', 'PRODUTO0002' , '000001', '01', '1', 2000, 2000, 0.28, CTOD('10/10/2018'), CTOD('12/11/2018'), '84389000', '2', '', 0, 1, 2, 1.000, '000002', '01'} )
    aadd(aDados, {xFilial("SW3"), '01', '159000', 'PRODUTO0003' , '000001', '01', '1', 1000, 1000, 0.31, CTOD('10/10/2018'), CTOD('14/11/2018'), '84389000', '3', '', 0, 1, 3, 0.400, '000001', '01'} )
    
    For i := 1 to Len(aDados)
    	
        //Abaixo informo na variavel aItens os campos que julgo necessário no meu ambiente	
		aAdd(aItens,{;  
		{'W3_FILIAL'  	,  aDados[i,1]  , Nil},;
		{'W3_CC'   		,  aDados[i,2]  , Nil},;
		{'W3_SI_NUM'  	,  aDados[i,3]  , Nil},;
		{'W3_COD_I'   	,  aDados[i,4]  , Nil},;
		{'W3_FORN'   	,  aDados[i,5]  , Nil},;
		{'W3_FORLOJ'  	,  aDados[i,6]  , Nil},;
		{'W3_FLUXO'   	,  iif(aDados[i,7] == "2","7",aDados[i,7])  , Nil},;
		{'W3_QTDE'   	,  aDados[i,8]  , Nil},;
		{'W3_SALDO_Q'	,  aDados[i,8]  , Nil},;
		{'W3_PRECO'   	,  aDados[i,9]  , Nil},;
		{'W3_DT_EMB'  	,  aDados[i,10] , Nil},;
		{'W3_DT_ENTR' 	,  aDados[i,11] , Nil},;
		{'W3_TEC'   	,  aDados[i,12] , Nil},;
		{'W3_POSICAO' 	,  aDados[i,13] , Nil},;
		{'W3_PGI_NUM' 	,  aDados[i,14] , Nil},;
		{'W3_SEQ'   	,  aDados[i,15] , Nil},;
		{'W3_REG'   	,  aDados[i,16] , Nil},;
		{'W3_NR_CONT' 	,  aDados[i,17] , Nil},;
		{'W3_PESOL'   	,  aDados[i,18] , Nil},;
		{'W3_FABR'   	,  aDados[i,19] , Nil},;
		{'W3_FABLOJ'  	,  aDados[i,20] , Nil};
		}) 
           
    Next

	MSExecAuto({|a,b,c,d| EICPO400(a,b,c,d)},Nil,aCab,aItens,nOpc)
	If lMsErroAuto
		MostraErro() //função padrão para exibir o erro encontrado (http://tdn.totvs.com/pages/releaseview.action?pageId=6815088)
	Else
		//Irei capturar o número da PO que o sistema gerou
		cNumPO := IIF(ValType(SW2->W2_PO_NUM)=="U","",SW2->W2_PO_NUM)
		
		MsgInfo("A P.O. " + Alltrim(cNumPO) + " foi incluida com sucesso!","Sucesso")
	EndIf

Return
Abaixo, uma demonstração da rotina sendo executada no Protheus. No meu caso, eu criei uma rotina no qual irá importar diversos arquivos textos no formato CSV, e cada arquivo corresponderá em uma Purchase Order (PO). A rotina irá preencher um grid e irá fazer um salto de linha (pintei em vermelho), para cada arquivo. Ao confirmar, o sistema irá criar minhas PO's automaticamente. Caso exista algum erro, a função MostraErro() irá exibir em tela para que meu usuário possa analisar depois.