...
Code Block |
---|
{
"schedule": {
"Item": {
"scheduleLineDate": "",
"salesDocumentItem": "000150",
"orderQuantityInSalesUnits": "10"
}
},
"rotationHeader": {
"yourReference": "SF",
"valueShipping": "0",
"valueAccessoryCosts": "0",
"termsOfPaymentKey": "B028",
"shippingConditions": "Standard",
"sdDocumentCurrency": "BRL",
"salesOrganization": "DC01",
"salesOffice": "DB03",
"salesGroup": "091",
"salesDocumentType": "ZDX - Venda Normal",
"salesDistrict": "Deca - MG Região 07",
"requestedDeliveryDate": "",
"priceListType": "Não",
"incotermsPart2": "CIF - Custo, seguro & frete",
"incotermsPart1": "CIF - Custo, seguro & frete",
"division": "MS",
"distributionChannel": "40",
"dateForPricingAndExchangeRate": None,
"customerPurchaseOrderNumber": "",
"customerPurchaseOrderDate": "2020-07-30",
"customerGroup": "false",
"cup": "Revenda",
"completeDeliveryDefinedForEachSalesOrder": ""
},
"quotePartners": {
"Item": {
"partnerFunction": "EmissorOrdem",
"customerNumber": "0000032611"
}
},
"quoteItems": {
"Item": {
"salesDocumentItem": "000150",
"rateConditionRound": "0",
"rateConditionAmountOrPercentage": "0.00",
"plant": "D085",
"materialNumber": "4688.931"
}
},
"guuid": None,
"extension": {
"Item": {
"dataPartOfBapiExtensionParameter3": None,
"dataPartOfBapiExtensionParameter2": "",
"dataPartOfBapiExtensionParameter1": None,
"dataPartOfBapiExtensionParameter": ""
}
}
} |
...
Os campos do payload podem ser especificados abaixo:
A Execução do Payload pode ser visto no comando abaixo. Para este caso, a chamada dos preços, vendas totais e impostos serão para o documento ZDX.
...
...
Campo do Payload | Descrição |
---|---|
| Data de Agendamento |
| Item do Documento de Vendas |
| Unidades de Quantidade De Vendas |
| Referência: SF ou HUB |
| Tipo de Documento |
| Valor de Expedição |
| Valor de Custos Acessórios |
| Chave de Termos de Pagamento |
| Condições de Expedição |
| Moeda de Documento SD |
| Organização de Vendas |
| Escritório de Vendas |
| Grupo de Vendas |
| Região de Vendas |
| Data de Entrega do Pedido |
| Typo de Lista de Preço |
| Incoterms 2 |
| Incoterms 1 |
| Divisão |
| Canal de Distribuição |
| Data para Taxa de Preço e Troca |
| Número de Ordem do Pedido do Cliente |
| Data de Ordem do Pedido do Cliente |
| Grupo do cliente |
| Cup |
| |
| Função Parceiro |
| Número do Cliente |
| Item do Documento de Vendas |
| |
| |
| Planta |
| Número do Material |
| |
| |
| |
|
A Execução do Payload pode ser visto no comando abaixo. Para este caso, a chamada dos preços, vendas totais e impostos serão para o documento ZDX.
Code Block |
---|
for row in df_payload.rdd.collect(): payload_retorno_s4_chamada_json["rotationHeader"]["shippingConditions"]hana_interno = row["SHIP_COND"]payload_retorno_s4_hana payload_chamada_json["rotationHeader"]["sdDocumentCurrency"] = if row["CURRENCYDOC_TYPE"] == 'ZDX - Venda Normal': payload_chamada_json["rotationHeaderschedule"]["Item"]["salesOrganizationsalesDocumentItem"] = row["SALESITM_ORGNUMBER"] payload_chamada_json["rotationHeaderschedule"]["salesOfficeItem"] = row["SALES_OFFscheduleLineDate"] = today payload_chamada_json["rotationHeader"]["salesGrouptermsOfPaymentKey"] = row["SALES_GRPPMNTTRMS"] payload_chamada_json["rotationHeader"]["salesDocumentTypeshippingConditions"] = row["DOCSHIP_TYPECOND"] payload_chamada_json["rotationHeader"]["salesDistrictsdDocumentCurrency"] = row["SALES_DISTCURRENCY"] payload_chamada_json["rotationHeader"]["priceListTypesalesOrganization"] = row["PRICESALES_LISTORG"] payload_chamada_json["rotationHeader"]["incotermsPart2salesOffice"] = row["INCOTERMS2SALES_OFF"] payload_chamada_json["rotationHeader"]["incotermsPart1salesGroup"] = row["INCOTERMS1SALES_GRP"] payload_chamada_json["rotationHeader"]["divisionsalesDocumentType"] = row["DIVISIONDOC_TYPE"] payload_chamada_json["rotationHeader"]["distributionChannelsalesDistrict"] = row["DISTRSALES_CHANDIST"] payload_chamada_json["rotationHeader"]["customerGrouppriceListType"] = row["CUSTPRICE_GROUPLIST"] payload_chamada_json["rotationHeader"]["cupincotermsPart2"] = row["cupINCOTERMS2"] payload_chamada_json["quotePartnersrotationHeader"]["Item"]["partnerFunctionincotermsPart1"] = row["INCOTERMS1"] payload_chamada_json["rotationHeader"]["division"] = row["PARTN_ROLEDIVISION"] payload_chamada_json["quotePartnersrotationHeader"]["ItemdistributionChannel"]["customerNumber"] = row["PARTNDISTR_NUMBCHAN"] payload_chamada_json["quoteItemsrotationHeader"]["ItemcustomerGroup"]["salesDocumentItem"] = row["ITMCUST_NUMBERGROUP"] payload_chamada_json["quoteItemsrotationHeader"]["Itemcup"]["plant"] = row["PLANTcup"] payload_chamada_json["quoteItemsquotePartners"]["Item"]["materialNumberpartnerFunction"] = row["MATERIALPARTN_ROLE"] payload_chamada_json["guuid"quotePartners"]["Item"]["customerNumber"] = row["uuidPARTN_NUMB"] payload_chamada_str = json.dumps(payload_chamada_json) json["quoteItems"]["Item"]["salesDocumentItem"] = row["ITM_NUMBER"] payload_saida = chamada_simulate_api(payload_chamada_str) json["quoteItems"]["Item"]["plant"] = row["PLANT"] payload_retorno_str = payload_saida.text chamada_json["quoteItems"]["Item"]["materialNumber"] = row["MATERIAL"] if (payload_retornochamada_str[:5json["guuid"] == row["<?xml"):uuid"] payload_retornochamada_str = json.dumps(payload_chamada_retornojson) payload_saida = chamada_simulate_api(payload_chamada_str) payload_retorno_str = payload_retorno_str.replace("Sem Erros!", "ERRO: Retorno enviado em XML!")saida.text if (payload_retorno_str[:5] = payload_retorno_str[:-1]= "<?xml"): payload_retorno_str = payload_retorno_str[1 payload_retorno_str = payload_retorno_str.replace("Sem Erros!", "ERRO: Retorno enviado em XML!") payload_retorno_str = payload_retorno_str[:-1] payload_retorno_str = payload_retorno_str[1:] payload_chamada_str = payload_chamada_str[:-1] else : payload_chamada_str = payload_chamada_str[:-1] payload_retorno_str = payload_retorno_str[:-2] payload_retorno_str = payload_retorno_str[2:] merge_json = payload_chamada_str +","+ payload_retorno_str + "}" print(merge_json) payload_gravar = json.loads(merge_json) print(payload_gravar) if (payload_gravar["quoteConditions"][0]["otherCosts"] == "NULL" or payload_gravar["quoteConditions"][0]["otherCosts"] == "null" or payload_gravar["quoteConditions"][0]["otherCosts"] == None ): payload_gravar["quoteConditions"][0]["otherCosts"] = 0.0 if (payload_gravar["quoteConditions"][0]["valueTaxSubstitutionTributary"] == "NULL" or payload_gravar["quoteConditions"][0]["valueTaxSubstitutionTributary"] == "null" or payload_gravar["quoteConditions"][0]["valueTaxSubstitutionTributary"] == None ): payload_gravar["quoteConditions"][0]["valueTaxSubstitutionTributary"] = 0.0 if (payload_gravar["quoteConditions"][0]["commercialCost"] == "NULL" or payload_gravar["quoteConditions"][0]["commercialCost"] == "null" or payload_gravar["quoteConditions"][0]["commercialCost"] == None ): payload_gravar["quoteConditions"][0]["commercialCost"] = 0.0 if (payload_gravar["quoteConditions"][0]["manufacturingCost"] == "NULL" or payload_gravar["quoteConditions"][0]["manufacturingCost"] == "null" or payload_gravar["quoteConditions"][0]["manufacturingCost"] == None ): payload_gravar["quoteConditions"][0]["manufacturingCost"] = 0.0 if (payload_gravar["quoteConditions"][0]["valueAdditionalSale"] == "NULL" or payload_gravar["quoteConditions"][0]["valueAdditionalSale"] == "null" or payload_gravar["quoteConditions"][0]["valueAdditionalSale"] == None ): payload_gravar["quoteConditions"][0]["valueAdditionalSale"] = 0.0 if (len(payload_gravar["quotationItems"]) != 0): payload_gravar["sapReturn"] = payload_retorno_json["sapReturn"] if (len(payload_gravar["quotationItems"]) == 0): payload_gravar["quotationItems"] = payload_retorno_json["quotationItems"] payload_gravar["quoteConditions"] = payload_retorno_json["quoteConditions"] jsonData = json.dumps(payload_gravar) print(jsonData) jsonDataList = [] jsonDataList.append(jsonData) jsonRDD = sc.parallelize(jsonDataList) df = spark.read.json(jsonRDD) df.write.format("delta").mode("append").saveAsTable(simulate_table_name) |
...
Code Block |
---|
if (payload_retorno_str[:5] == "<?xml"):
print("Verificado que o formato está em XML e dará problema")
payload_retorno_str = payload_retorno
payload_retorno_str = payload_retorno_str.replace("Sem Erros!", "ERRO: Retorno enviado em XML!")
payload_retorno_str = payload_retorno_str[:-1]
payload_retorno_str = payload_retorno_str[1:]
payload_chamada_str = payload_chamada_str[:-1]
else :
print("Comportamento esperado")
payload_chamada_str = payload_chamada_str[:-1]
payload_retorno_str = payload_retorno_str[:-2]
payload_retorno_str = payload_retorno_str[2:] |
De acordo com a Figura abaixo pode-se a validação do retorno que ocorreu em xml e que identificamos que havia um bug na API.
...
retorno_str[2:] |
De acordo com a Figura abaixo pode-se a validação do retorno que ocorreu em xml e que identificamos que havia um bug na API.
...
Payload SAP ECC para o S4
O mapeamento dos campos permite realizar o de-para do payload das informações obtidas do SAP ECC para o S4. Tal processo foi realizada com o auxílio de uma planilha secundária (Anexo abaixo) que contém a dicionarização dos campos de cada tabela. Esta dicionarização possibilita mapear os campos do S4 a partir do SAP ECC, permitindo que a adequação dos campos sejam iguais.
View file | ||
---|---|---|
|
Conforme o arquivo, a realização do mapeamento precisa do uso do notebook do databricks. O comando que cria o dataframe a partir dos campos do S4 está abaixo:
Code Block |
---|
dfvw= df.withColumn('customerNumber',get_json_object(to_json('d'),'$.results.Customer'))\
.withColumn('salesOrganization',get_json_object(to_json('d'),'$.salesOrganization'))\
.withColumn('division',get_json_object(to_json('A_SalesOrderSimulation'),'$.A_SalesOrderSimulationType.OrganizationDivision'))\
.withColumn('termsOfPaymentKey',get_json_object(to_json('A_SalesOrderSimulation'),'$.A_SalesOrderSimulationType.CustomerPaymentTerms'))\
.withColumn('salesDocumentType',get_json_object(to_json('A_SalesOrderSimulation'),'$.A_SalesOrderSimulationType.SalesGroup'))\
.withColumn('distributionChannel',get_json_object(to_json('A_SalesOrderSimulation'),'$.A_SalesOrderSimulationType.DistributionChannel'))\
.withColumn('shippingType',get_json_object(to_json('A_SalesOrderSimulation'),'$.A_SalesOrderSimulationType.IncotermsLocation1'))\
.withColumn('clienteDaEntrega',lit(''))\
.withColumn('materialNumber',get_json_object(to_json('d'),'$.results.Material'))\
.withColumn('embalaLouca', when(get_json_object(to_json('rotationheader'),'$.customerGroup').cast(IntegerType()) >0,lit('true')).otherwise(lit('false')))\
.withColumn('entregaPaletizada',lit('0').cast(BooleanType()))\
.withColumn('dataInicioVigencia',get_json_object(to_json('quotationItems'),'$[1].returnDateForReturnablePackaging')) \
.withColumn('cup',get_json_object(to_json('rotationheader'),'$.cup'))\
.withColumn('plant',get_json_object(to_json('quotationItems'),'$.results.Plant'))\
.withColumn('conditionUnit',get_json_object(to_json('quotationItems'),'$[1].conditionUnit'))\
.withColumn('conditionPricingUnit' ,get_json_object(to_json('quotationItems'),'$[1].conditionPricingUnit'))\
.withColumn('confirmedQuantity' ,get_json_object(to_json('quotationItems'),'$[1].confirmedQuantity'))\
.withColumn('conditionBaseValue',get_json_object(to_json('quotationItems'),'$[1].conditionBaseValue'))\
.withColumn('salePeriod' ,get_json_object(to_json('quoteConditions'),'$[0].salePeriod'))\
.withColumn('salePrice',get_json_object(to_json('quoteConditions'),'$[0].salePrice'))\
.withColumn('valueICMS',get_json_object(to_json('quoteConditions'),'$[0].valueICMS'))\
.withColumn('valueICMSST',get_json_object(to_json('quoteConditions'),'$[0].valueICMSST'))\
.withColumn('valueCofins',get_json_object(to_json('quoteConditions'),'$[0].valueCofins'))\
.withColumn('valueIPI',get_json_object(to_json('quoteConditions'),'$[0].valueIPI'))\
.withColumn('valuePIS',get_json_object(to_json('quoteConditions'),'$[0].valuePIS'))\
.withColumn('totalValueItem',get_json_object(to_json('quoteConditions'),'$[0].totalValueItem'))\
.withColumn('valueBonus',get_json_object(to_json('quoteConditions'),'$[0].valueBonus'))\
.withColumn('discountTotal',get_json_object(to_json('quoteConditions'),'$[0].discountTotal'))\
.withColumn('shippingPriceClosed',get_json_object(to_json('quoteConditions'),'$[0].shippingPriceClosed'))\
.withColumn('insurancePriceClosed',get_json_object(to_json('quoteConditions'),'$[0].insurancePriceClosed'))\
.withColumn('insurancePriceOpen',get_json_object(to_json('quoteConditions'),'$[0].insurancePriceOpen'))\
.withColumn('manufacturingCost',get_json_object(to_json('quoteConditions'),'$[0].manufacturingCost'))\
.withColumn('commercialCost',get_json_object(to_json('quoteConditions'),'$[0].commercialCost'))\
.withColumn('otherCosts',get_json_object(to_json('quoteConditions'),'$[0].otherCosts'))\
.withColumn('valueAdditionalSale',get_json_object(to_json('quoteConditions'),'$[0].valueAdditionalSale'))\
.withColumn('valueTaxSubstitutionTributary',get_json_object(to_json('quoteConditions'),'$[0].valueTaxSubstitutionTributary'))\
.withColumn('netValue',get_json_object(to_json('A_SalesOrderSimulation'),'$[0].A_SalesOrderSimulationType.NetAmount'))\
.withColumn('salePricePeriodUnit',get_json_object(to_json('quoteConditions'),'$[0].salePricePeriodUnit'))\
.withColumn('salePriceUnit',get_json_object(to_json('quoteConditions'),'$[0].salePriceUnit'))\
.withColumn('tag',current_timestamp())\
.withColumn('idsimulate',df.guuid)\
.withColumn('dataProcesso',current_date())\ |
A metodologia para realizar o de-para é a seguinte:
Visualiza o campo no notebook do databricks (código acima), por exemplo, o campo customerNumber
Abre o arquivo do mapeamento em excel, utiliza a aba SAP ECC, procura este campo na coluna chamada “Campo Payload” e verifica o nome do campo na coluna “Parâmetro/Estrutura”.
Utiliza a aba SAP S4 Hana, do mesmo arquivo, e verifica o mesmo nome de campo da coluna “Parâmetro/Estrutura”. Para este registro, obtém o campo correto na coluna “Campo do Payload”.
Alterar o código
A partir do arquivo, na aba do SAP ECC, utiliza-se o campo chamado “Parâmetro/Estrutura” para visualizar o campo origem do SAP.
No código acima, realiza a adequação do campo para o mesmo nome do campo payload na cláusula que obtem o objeto do json -
get_json_object(to_json('d'),'$.results.Customer')