Skip to content

Instantly share code, notes, and snippets.

@jrnunes
Created January 15, 2016 02:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrnunes/fc398b70a0f265bcde05 to your computer and use it in GitHub Desktop.
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
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