Created
January 15, 2016 02:47
-
-
Save jrnunes/fc398b70a0f265bcde05 to your computer and use it in GitHub Desktop.
Report to test the NFC-e on SAP NF-e (GRC), generating the infNFeSupl and qrCode tags, based on a enhancement on
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
REPORT Z_NFCE_QRCODE_POC. | |
DATA: | |
lv_ssfappl type ssfappl, | |
ls_nfehd TYPE /xnfe/outnfehd, | |
ls_xml_nfe TYPE /xnfe/outnfexml, | |
ls_xml_skip TYPE /xnfe/outnfexml. | |
DATA: lv_unsigned_xml TYPE /xnfe/xmlstring, | |
lv_signed_xml TYPE /xnfe/xmlstring, | |
lv_cnpj TYPE /xnfe/cnpj, | |
lv_id TYPE string, | |
lv_dummy TYPE string, "#EC NEEDED | |
lv_xmlversion TYPE /xnfe/xml_version_nfe. | |
PARAMETERS: p_guid TYPE /xnfe/guid_16 DEFAULT '56615121F0E321E0E10080000A14E248'. | |
START-OF-SELECTION. | |
*--------------------------------------------------------------------* | |
* Read NF-e from database | |
*--------------------------------------------------------------------* | |
CALL FUNCTION '/XNFE/OUTNFE_READ_NFE_FOR_UPD' | |
EXPORTING | |
iv_guid = p_guid | |
IMPORTING | |
es_nfehd = ls_nfehd | |
es_xml_nfe = ls_xml_nfe | |
es_xml_skip = ls_xml_skip | |
EXCEPTIONS | |
nfe_does_not_exist = 1 | |
nfe_locked = 2 | |
technical_error = 3 | |
OTHERS = 4. | |
IF sy-subrc NE 0. | |
WRITE 'Erro ao ler NF-e' COLOR COL_NEGATIVE. | |
STOP. | |
ENDIF. | |
*--------------------------------------------------------------------* | |
* If already signed, remove the Signature tag | |
*--------------------------------------------------------------------* | |
data: lo_ixml type ref to if_ixml, | |
lo_stream_factory type ref to if_ixml_stream_factory, | |
lo_stream type ref to if_ixml_stream, | |
lo_doc TYPE REF TO if_ixml_document, | |
lo_node_col TYPE REF TO if_ixml_node_collection, | |
lo_node TYPE REF TO if_ixml_node, | |
lo_node_parent TYPE REF TO if_ixml_node, | |
lo_iterator TYPE REF TO if_ixml_node_iterator, | |
lv_xml TYPE xstring. | |
lv_xml = ls_xml_nfe-xmlstring. | |
lo_ixml = cl_ixml=>create( ). | |
lo_stream_factory = lo_ixml->create_stream_factory( ). | |
lo_doc = lo_ixml->create_document( ). | |
IF lo_ixml->create_parser( | |
document = lo_doc | |
stream_factory = lo_stream_factory | |
istream = lo_stream_factory->create_istream_xstring( string = lv_xml ) | |
)->parse( ) <> 0. | |
RETURN. | |
ENDIF. | |
lo_node_col = lo_doc->get_elements_by_tag_name( | |
name = 'Signature'). | |
IF lo_node_col->get_length( ) > 0. | |
DATA: lv_ret TYPE i. | |
lo_node = lo_node_col->get_item( 0 ). | |
lo_node_parent = lo_node->get_parent( ). | |
lo_node_parent->remove_child( lo_node ). | |
ENDIF. | |
CLEAR lv_xml. | |
lo_doc->render( | |
ostream = lo_ixml->create_stream_factory( | |
)->create_ostream_xstring( | |
string = lv_xml ) ). | |
*--------------------------------------------------------------------* | |
* Fill lv_id and lv_cnpj from XML | |
*--------------------------------------------------------------------* | |
CLEAR: lo_node, lo_node_parent, lo_node_col. | |
DATA: lo_nnm TYPE REF TO if_ixml_named_node_map. | |
lo_node_col = lo_doc->get_elements_by_tag_name( name = 'infNFe' ). | |
IF lo_node_col->get_length( ) > 0. | |
lo_node_parent = lo_node_col->get_item( 0 ). | |
lo_nnm = lo_node_parent->get_attributes( ). | |
lo_node = lo_nnm->get_named_item( name = 'Id' ). | |
lv_id = lo_node->get_value( ). | |
ENDIF. | |
CLEAR: lo_node, lo_node_parent, lo_node_col. | |
lo_node_col = lo_doc->get_elements_by_tag_name( name = 'CNPJ' ). | |
lo_iterator = lo_node_col->create_iterator( ). | |
DO. | |
lo_node = lo_iterator->get_next( ). | |
IF lo_node->get_parent( )->get_name( ) = 'emit'. | |
lv_cnpj = lo_node->get_value( ). | |
EXIT. | |
ENDIF. | |
IF lo_node IS INITIAL. | |
EXIT. | |
ENDIF. | |
ENDDO. | |
*--------------------------------------------------------------------* | |
* Sign it again, now adding the NFC-e tag infSupl & QRCode | |
*--------------------------------------------------------------------* | |
PERFORM core_signature_create_2 USING lv_xml lv_id lv_cnpj | |
CHANGING lv_signed_xml lv_ssfappl. | |
BREAK-POINT. | |
*--------------------------------------------------------------------* | |
* This FORM is a copy of Function Module /XNFE/CORE_SIGNATURE_CREATE_2 | |
* The idea here is to show what could be done to enhance this FM in | |
* order to issue NFC-e with the correct qrCode tag | |
*--------------------------------------------------------------------* | |
FORM core_signature_create_2 USING iv_unsigned_xml TYPE /xnfe/xmlstring | |
iv_id TYPE string | |
iv_cnpj TYPE /xnfe/cnpj | |
CHANGING ev_signed_xml TYPE /xnfe/xmlstring | |
ev_ssfapplic TYPE ssfappl. | |
CONSTANTS lc_signature_ns_prefix TYPE string VALUE ''. | |
CONSTANTS lc_c14n_attribute TYPE string VALUE 'Id'. | |
DATA: | |
ls_tcnpj TYPE /xnfe/tcnpj, | |
lo_sign TYPE REF TO cl_sec_sxml_dsignature, | |
lo_error TYPE REF TO cx_root, | |
lv_txterror TYPE string, | |
lf_signature TYPE xstring, | |
lro_sign_badi TYPE REF TO /xnfe/sign_create. | |
SELECT SINGLE * FROM /xnfe/tcnpj INTO ls_tcnpj WHERE cnpj = iv_cnpj. | |
IF sy-subrc <> 0. | |
MESSAGE e100(/xnfe/app) WITH iv_cnpj RAISING cnpj_not_maintained. | |
ENDIF. | |
TRY. | |
* check if BADI is implemented | |
GET BADI lro_sign_badi. | |
* execute BADI if it is implemented | |
CALL BADI lro_sign_badi->sign_xml | |
EXPORTING | |
unsigned_xml = iv_unsigned_xml | |
id = iv_id | |
keystore_view = ls_tcnpj-kstview | |
keystore_elem = ls_tcnpj-kstelem | |
CHANGING | |
signed_xml = ev_signed_xml | |
EXCEPTIONS | |
invalid_call = 1 | |
internal_error = 2 | |
sign_xml_error = 3 | |
OTHERS = 4. | |
IF sy-subrc <> 0. | |
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno | |
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 RAISING badi_error. | |
ENDIF. | |
CATCH cx_badi_not_implemented. | |
* execute standard signature service | |
IF ls_tcnpj-ssfapplic IS INITIAL. | |
MESSAGE e102(/xnfe/app) WITH iv_cnpj RAISING cnpj_not_maintained. | |
ENDIF. | |
* create instance | |
TRY. | |
lo_sign = cl_sec_sxml_dsignature=>create_reader_instance( if_input = iv_unsigned_xml ). | |
* set attribtue for C14n | |
lo_sign->m_canonicalization = cl_sec_sxml_dsignature=>co_c14n_inclusive. | |
* set attribtue for NameSpace prefix lc_signature_ns_prefix | |
lo_sign->m_signature_ns_prefix = lc_signature_ns_prefix. | |
* set attribute for C14n , means first element with Attribute | |
* lc_c14n_attribute will be used to create a XML signature | |
lo_sign->set_attributes( if_attribute_name = lc_c14n_attribute ). | |
* sign XML data and get signature | |
lo_sign->sign_xml( | |
EXPORTING | |
if_ssf_app = ls_tcnpj-ssfapplic | |
if_add_keyinfo = abap_true | |
IMPORTING | |
ef_signature_xml = lf_signature ). | |
*--------------------------------------------------------------------* | |
* --- Begin of Modification --- | |
*--------------------------------------------------------------------* | |
DATA: lv_base_url TYPE string VALUE | |
'https://www.dfeportal.fazenda.pr.gov.br/dfe-portal/rest/servico/consultaNFCe?', | |
lv_digval TYPE string, | |
lv_digval_x TYPE xstring, | |
lv_hashqrcode TYPE hash160, | |
lv_url TYPE string. | |
*--------------------------------------------------------------------* | |
* Get DigestValue from lf_signature XML | |
*---------|----------------------------------------------------------* | |
lo_ixml = cl_ixml=>create( ). | |
lo_stream_factory = lo_ixml->create_stream_factory( ). | |
lo_doc = lo_ixml->create_document( ). | |
IF lo_ixml->create_parser( | |
document = lo_doc | |
stream_factory = lo_stream_factory | |
istream = lo_stream_factory->create_istream_xstring( string = lf_signature ) | |
)->parse( ) <> 0. | |
RETURN. | |
ENDIF. | |
lo_node_col = lo_doc->get_elements_by_tag_name( name = 'DigestValue' ). | |
IF lo_node_col->get_length( ) > 0. | |
lo_node = lo_node_col->get_item( 0 ). | |
lv_digval = lo_node->get_value( ). | |
ENDIF. | |
"Convert it into Hexadecimal as required by SEFAZ | |
CALL FUNCTION 'SCMS_STRING_TO_XSTRING' | |
EXPORTING | |
text = lv_digval | |
IMPORTING | |
buffer = lv_digval_x. | |
lv_digval = lv_digval_x. | |
*--------------------------------------------------------------------* | |
* Generate URL and QRCode Hash | |
*--------------------------------------------------------------------* | |
lv_url = |{ lv_base_url }chNFe=41160107796000000199650010000003641889057624&nVersao=100&tpAmb=1| && | |
|&dhEmi=323031362d30312d30345431323a31343a34322d30323a3030&vNF=12.90&vICMS=0.00&digVal={ lv_digval }| && | |
|&cIdToken=000001|. | |
CALL FUNCTION 'CALCULATE_HASH_FOR_CHAR' | |
exporting | |
ALG = 'SHA1' | |
DATA = lv_url | |
importing | |
HASH = lv_hashQRcode | |
exceptions | |
UNKNOWN_ALG = 1 | |
PARAM_ERROR = 2 | |
INTERNAL_ERROR = 3 | |
OTHERS = 4. | |
if sy-subrc EQ 0. | |
lv_url = lv_url && |&cHashQRCode={ lv_hashQRcode }|. | |
endif. | |
*--------------------------------------------------------------------* | |
* Add infNFeSupl and qrCode tags to the XML | |
*--------------------------------------------------------------------* | |
DATA: lo_cdata TYPE REF TO if_ixml_cdata_section, | |
lo_node_qrcode TYPE REF TO if_ixml_element. | |
CLEAR: lo_ixml, lo_stream_factory, lo_doc, lo_node, lo_node_col. | |
lo_ixml = cl_ixml=>create( ). | |
lo_stream_factory = lo_ixml->create_stream_factory( ). | |
lo_doc = lo_ixml->create_document( ). | |
IF lo_ixml->create_parser( | |
document = lo_doc | |
stream_factory = lo_stream_factory | |
istream = lo_stream_factory->create_istream_xstring( string = iv_unsigned_xml ) | |
)->parse( ) <> 0. | |
RETURN. | |
ENDIF. | |
lo_node_col = lo_doc->get_elements_by_tag_name( name = 'NFe' ). | |
IF lo_node_col->get_length( ) > 0. | |
lo_node = lo_node_col->get_item( 0 ). | |
lo_node_parent = lo_doc->create_simple_element( | |
name = 'infNFeSupl' | |
parent = lo_node | |
). | |
"Use CDATA to avoid issues with special chars | |
lo_cdata = lo_doc->create_cdata_section( lv_url ). | |
lo_node_qrcode = lo_doc->create_element( name = 'qrCode' ). | |
lo_node_qrcode->append_child( lo_cdata ). | |
lo_node_parent->append_child( lo_node_qrcode ). | |
ENDIF. | |
CLEAR iv_unsigned_xml. | |
lo_ixml->create_renderer( document = lo_doc | |
ostream = lo_ixml->create_stream_factory( | |
)->create_ostream_xstring( | |
string = iv_unsigned_xml ) | |
)->render( ). | |
*--------------------------------------------------------------------* | |
* --- End of Modification --- | |
*--------------------------------------------------------------------* | |
* embed signature in unsigned xml | |
lo_sign->embed_signature( | |
EXPORTING | |
if_xml = iv_unsigned_xml | |
if_signature = lf_signature | |
IMPORTING | |
ef_result = ev_signed_xml ). | |
CATCH cx_sec_sxml_error INTO lo_error. | |
lv_txterror = lo_error->if_message~get_text( ). | |
MESSAGE lv_txterror TYPE 'E' RAISING sign_xml_error. | |
CATCH cx_root INTO lo_error. | |
lv_txterror = lo_error->if_message~get_text( ). | |
MESSAGE lv_txterror TYPE 'E' RAISING sign_xml_error. | |
ENDTRY. | |
ENDTRY. | |
ENDFORM. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment