Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Facturacion Electronica PERU (https://www.clubdelphi.com/foros/showthread.php?t=93939)

oscarac 18-05-2019 00:51:04

Facturacion Electronica PERU
 
Estimados....
nuevamente yo molestando

este tema de la facturación electrónica me parece que ya esta globalizado, en muchos países se esta utilizando y "creo" que la metodología y proceso es bastante similar

el tema es que la SUNAT PERU (administración tributaria) permite la recepción de facturas via un webservice
lo primero que hay que hacer es generar los archivos XML, para esto tienen una "plantilla" (el menos es lo que he entendido), estas son las guias para el armado de los XML:

http://orientacion.sunat.gob.pe/inde...-contribuyente

en este enlace también podrán encontrar los esquemas para cada tipo de documento

http://orientacion.sunat.gob.pe/inde...lectronicos-bv

he bajado los esquemas, y via XML Data Binding he creado las unidades correspondientes en Delphi

la pregunta del millón (y espero que si llegamos a un buen resultado le sirva a todos los demás que tienen el mismo problema que yo)

como genero el XML ???

pseudocódigo :

Código Delphi [-]
Select Documento, Fecha, Cliente, Importes, artículos, cantidades from Facturas  -- Tengo la información de mi documento

... aquí imagino que debo declarar alguna unidad para crear el XML
Código Delphi [-]
while not facturas.eof Do
Begin
...
...
aquí imagino voy pasando "el cuerpo" del xml

End

libero el XML

... firmo

... certificado digital
.. envio

.. respuesta


mis conocimientos de Delphi en este tema no son tan avanzados como para poder entenderlo, pero si alguien me da una guía, creo poder resolver este tema


ya posteriormente los molestare para el envio via webservice y la analizar la respuesta

dec 18-05-2019 14:03:25

Hola a todos,

Lo de que preparases las correspondientes clases a partir de ciertos XML me confunde un poco, puesto que, si hablamos de crear un documento XML, propiamente, podriámos hablar de crearlo "a mano" (al fin y al cabo se trata de un archivo de texto), utilizar la clase TXMLDocument de Delphi, o, utilizar alguna solución como OmniXML, un conjunto de clases y funciones que pueden ayudarnos. Pero, como digo, tal vez me esté perdiendo algo, y, quieras generar un documento XML partiendo de las clases que has creado a partir de los XML de referencia o algo así...

oscarac 19-05-2019 00:34:59

exacto
hay una estructura ya definida para los XML, que estan en la pagina web que coloque

entonces necesirot una mano para poder entender el proceso

manelb 19-05-2019 08:45:46

Saludos a todos…

Hola oscarac, intentaré explicar nuestra experiencia sobre el tema por si te puede orientar…

Cuando en nuestro ERP desarrollamos la generación de facturas en formato xml, optamos por la generación “a pelo”, en formato texto, tal y como comenta el compañero dec.
Y así lo tenemos en la actualidad.

De todas formas, más tarde, investigamos sobre de qué forma los ficheros xsd que definen la estructura del xml podían utilizarse para simplificar el proceso y descubrimos el XML Data Binding.
Utilizando esta herramienta conseguimos generar una interface que permite generar y guardar de una forma más encapsulada la factura en formato xml.

En nuestro caso, la unidad que contiene la interface creada por el XML Data Binding a partir del xsd , contiene más de 6 mil líneas y esta es una muestra del código generado
Código Delphi [-]
{****************************************************************************************}
{                                                                                        }
{                                    XML Data Binding                                    }
{                                                                                        }
{         Generated on: 25/02/2017 16:38:47                                              }
{       Generated from: G:\DropBoxMBel\Dropbox\Facturacio Electronica\Facturaev3_2.xsd   }
{   Settings stored in: G:\DropBoxMBel\Dropbox\Facturacio Electronica\Facturaev3_2.xdb   }
{                                                                                        }
{****************************************************************************************}

unit Facturaev3_2;

interface

uses xmldom, XMLDoc, XMLIntf;

type

{ Forward Decls }

  IXMLFacturae = interface;
  IXMLFileHeaderType = interface;
  IXMLThirdPartyType = interface;
  IXMLTaxIdentificationType = interface;
  IXMLLegalEntityType = interface;
.
.
.
.
.
{ IXMLFacturae }

  IXMLFacturae = interface(IXMLNode)
    ['{4180325F-7A60-46DE-9C54-055114275527}']
    { Property Accessors }
    function Get_FileHeader: IXMLFileHeaderType;
    function Get_Parties: IXMLPartiesType;
    function Get_Invoices: IXMLInvoicesType;
    function Get_Extensions: IXMLExtensionsType;
    function Get_Signature: IXMLSignatureType_ds;
    { Methods & Properties }
    property FileHeader: IXMLFileHeaderType read Get_FileHeader;
    property Parties: IXMLPartiesType read Get_Parties;
    property Invoices: IXMLInvoicesType read Get_Invoices;
    property Extensions: IXMLExtensionsType read Get_Extensions;
    property Signature: IXMLSignatureType_ds read Get_Signature;
  end;
.
.
.
{ Global Functions }

function GetFacturae(Doc: IXMLDocument): IXMLFacturae;
function LoadFacturae(const FileName: string): IXMLFacturae;
function NewFacturae: IXMLFacturae;
.
.
.


Y un ejemplo de su llamada e inicio de construcción del xml
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  Factura: IXMLFacturae;
begin
  Factura:= GetFacturae(xml); {xml es un TXMLDocument}
  Factura.FileHeader.SchemaVersion:='3.2';
  Factura.FileHeader.Modality:='I';
  Factura.FileHeader.InvoiceIssuerType:='EM';
.
.
.
end;

Saludos

oscarac 20-05-2019 17:19:51

es exactamente lo que estoy haciendo
tambien investigue y llegue a la conclusion que los xsd son cono "una base"

asi que estoy en pleno analisis para generar el XML

quiza podamos apoyarnos mutuamente...

saludos

manelb 20-05-2019 19:03:17

Pero que problema tienes exactamente??

wilcg 20-05-2019 20:51:27

No soy experto en delphi, pero empiricamente he estado trabajando en un proyecto.
El XML lo he estado resolviendo de este modo, a ver si te es útil. OJO que la extructura del xml aún falta corregir.

Código Delphi [-]
Var
  FirmarXML: TCFXML;
  Zip: TZipFile;
  tDocXmlNombre: string;
  Xml: IXMLDOCUMENT;
  nMaster, nPrimero, nSegundo, nTercero, nCuarto, nQuinto, nAtributo, nItem,
    nItemSub, nCDATA: IXMLNODE;
begin
  Xml := NewXMLDocument;
  Xml.Version := '1.0';
  Xml.Encoding := 'UTF-8';
  // XML.StandAlone := 'yes';
  Xml.Options := [doNodeAutoIndent];

  nMaster := Xml.AddChild('Invoice');
  nMaster.Attributes['xmlns'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2';
  nMaster.Attributes['xmlns:cac'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2';
  nMaster.Attributes['xmlns:cbc'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2';
  nMaster.Attributes['xmlns:ccts'] := 'urn:un:unece:uncefact:documentation:2';
  nMaster.Attributes['xmlns:ds'] := 'http://www.w3.org/2000/09/xmldsig#';
  nMaster.Attributes['xmlns:ext'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2';
  nMaster.Attributes['xmlns:qdt'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2';
  nMaster.Attributes['xmlns:udt'] :=
    'urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2';
  nMaster.Attributes['xmlns:xsi'] :=
    'http://www.w3.org/2001/XMLSchema-instance';

  { Encabezado de Firma digital }
  nPrimero := nMaster.AddChild('ext:UBLExtensions');

  { Firma DIGITAL }
  nSegundo := nPrimero.AddChild('ext:UBLExtension');
  nSegundo.AddChild('ext:ExtensionContent').Text := '';

  { Ubl versión }
  nPrimero := nMaster.AddChild('cbc:UBLVersionID');
  nPrimero.Text := '2.1';
  { Cuztom }
  nPrimero := nMaster.AddChild('cbc:CustomizationID');
  nPrimero.Text := '2.0';

  // Información de COMPROBANTE
  { numeracion de factura }
  nPrimero := nMaster.AddChild('cbc:ID');
  nPrimero.Text := edtSerie.Text + '-' +
    FEnumCBT(FloatToStr(edtNumeracion.Value), 7, '0', False);

  { fecha y hora de emisión }
  nPrimero := nMaster.AddChild('cbc:IssueDate');
  nPrimero.Text := FormatDateTime('yyyy-mm-dd', edtFechaEmision.Date);

  { Código del comprobante }
  nPrimero := nMaster.AddChild('cbc:InvoiceTypeCode');
  nPrimero.Attributes['listID'] := '0101';
  nPrimero.Attributes['listAgencyName'] := 'PE:SUNAT';
  nPrimero.Attributes['listName'] := 'SUNAT:Identificador de Tipo de Documento';
  nPrimero.Attributes['listURI'] :=
    'urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo01';
  nPrimero.Text := FEObCodCBT(FEObIntLookup(edtComprobante));

  { Leyendo a letras el valor }
  nPrimero := nMaster.AddChild('cbc:Note');
  nPrimero.Attributes['languageLocaleID'] := '1000';
  nPrimero.Text := 'SON: ' + UpperCase(FELeyendoNUM(txtTotal.Value)) +
    ' Y 00/100 ' + ObDatoStrInt('monedas', 'id_moneda', 'descripcion',
    FEObIntLookup(edtMoneda));

  { Obteniendo el código de MONEDA }
  nPrimero := nMaster.AddChild('cbc:DocumentCurrencyCode');
  nPrimero.Attributes['listID'] := 'ISO 4217 Alpha';
  nPrimero.Attributes['listName'] := 'Currency';
  nPrimero.Attributes['listAgencyName'] :=
    'United Nations Economic Commission for Europe';
  nPrimero.Text := ObDatoStrInt('monedas', 'id_moneda', 'codigo',
    FEObIntLookup(edtMoneda));

  { Información de EMPRESA remitente }
  nPrimero := nMaster.AddChild('cac:Signature');
  nPrimero.AddChild('cbc:ID').Text := tRucEmisor;
  nSegundo := nPrimero.AddChild('cac:SignatoryParty');
  nTercero := nSegundo.AddChild('cac:PartyIdentification');
  nTercero.AddChild('cbc:ID').Text := tRucEmisor;
  nCuarto := nSegundo.AddChild('cac:PartyName');
  nCuarto.AddChild('cbc:Name').DOMNode.appendChild
    (Xml.DOMDocument.createCDATASection(tRazonEmisor));
  nSegundo := nPrimero.AddChild('cac:DigitalSignatureAttachment');
  nTercero := nSegundo.AddChild('cac:ExternalReference');
  nTercero.AddChild('cbc:URI').Text := tRucEmisor;

  { Datos del EMISOR }
  nPrimero := nMaster.AddChild('cac:AccountingSupplierParty');
  nItem := nPrimero.AddChild('cbc:CustomerAssignedAccountID');
  nItem.Text := tRucEmisor; // NUMERO DOC del Emisor
  nItem := nPrimero.AddChild('cbc:AdditionalAccountID');
  nItem.Text := FE_CodigoTipoDoc(tRucEmisor);
  // ID del DOC del Receptor     ( 1 = DNI; 6 = RUC )   Códigos de Tipos de Documentos de Identidad

  nSegundo := nPrimero.AddChild('cac:Party');
  nTercero := nSegundo.AddChild('cac:PartyIdentification');
  nAtributo := nTercero.AddChild('cbc:ID');
  nAtributo.Attributes['schemeID'] := '6';
  nAtributo.Attributes['schemeName'] :=
    'SUNAT:Identificador de Documento de Identidad';
  nAtributo.Attributes['schemeAgencyName'] := 'PE:SUNAT';
  nAtributo.Attributes['schemeURI'] :=
    'urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06';
  nAtributo.Text := tRucEmisor;
  nTercero := nSegundo.AddChild('cac:PartyName');
  nTercero.AddChild('cbc:Name').DOMNode.appendChild
    (Xml.DOMDocument.createCDATASection(tRazonEmisor));
  nTercero := nSegundo.AddChild('cac:PartyLegalEntity');
  nTercero.AddChild('cbc:RegistrationName').DOMNode.appendChild
    (Xml.DOMDocument.createCDATASection(tRazonEmisor));
  nItem := nTercero.AddChild('cac:RegistrationAddress');
  nItem.AddChild('cbc:AddressTypeCode').Text := IntToStr(tUbiGeoEmisor);
  // Código del domicilio fiscal o de local anexo del emisor

  { Datos del RECEPTOR }
  nPrimero := nMaster.AddChild('cac:AccountingCustomerParty');
  nItem := nPrimero.AddChild('cbc:CustomerAssignedAccountID');
  nItem.Text := edtDni.Text; // NUMERO DOC del Receptor
  nItem := nPrimero.AddChild('cbc:AdditionalAccountID');
  nItem.Text := FE_CodigoTipoDoc(edtDni.Text);
  // ID del DOC del Receptor     ( 1 = DNI; 6 = RUC ) Códigos de Tipos de Documentos de Identidad

  nSegundo := nPrimero.AddChild('cac:Party');
  nTercero := nSegundo.AddChild('cac:PartyIdentification');
  nAtributo := nTercero.AddChild('cbc:ID');
  nAtributo.Attributes['schemeID'] := FE_CodigoTipoDoc(edtDni.Text);
  nAtributo.Attributes['schemeName'] :=
    'SUNAT:Identificador de Documento de Identidad';
  nAtributo.Attributes['schemeAgencyName'] := 'PE:SUNAT';
  nAtributo.Attributes['schemeURI'] :=
    'urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06';
  nAtributo.Text := edtDni.Text;
  nTercero := nSegundo.AddChild('cac:PartyLegalEntity');
  nTercero.AddChild('cbc:RegistrationName').DOMNode.appendChild
    (Xml.DOMDocument.createCDATASection(edtNombre.Text));

  nPrimero := nMaster.AddChild('cac:TaxTotal');
  nSegundo := nPrimero.AddChild('cbc:TaxAmount');
  nSegundo.Attributes['currencyID'] := ObDatoStrInt('monedas', 'id_moneda',
    'codigo', FEObIntLookup(edtMoneda));
  nSegundo.Text := FormatFloat('0.00', txtIgv.Value); // corregir
  nSegundo := nPrimero.AddChild('cac:TaxSubtotal');
  nItem := nSegundo.AddChild('cbc:TaxableAmount');
  nItem.Attributes['currencyID'] := ObDatoStrInt('monedas', 'id_moneda',
    'codigo', FEObIntLookup(edtMoneda));
  nItem.Text := FormatFloat('0.00', txtTotal.Value);
  nTercero := nSegundo.AddChild('cbc:TaxAmount');
  nTercero.Attributes['currencyID'] := ObDatoStrInt('monedas', 'id_moneda',
    'codigo', FEObIntLookup(edtMoneda));
  nTercero.Text := FormatFloat('0.00', txtSubTotal.Value); // corregir
  nTercero := nSegundo.AddChild('cac:TaxCategory');
  nItem := nTercero.AddChild('cbc:ID');
  nItem.Attributes['schemeID'] := 'UN/ECE 5305';
  nItem.Attributes['schemeName'] := 'Tax Category Identifier';
  nItem.Attributes['schemeAgencyName'] :=
    'United Nations Economic Commission for Europe';
  nItem.Text := 'S';

  nCuarto := nTercero.AddChild('cac:TaxScheme');
  nQuinto := nCuarto.AddChild('cbc:ID');
  nQuinto.Attributes['schemeID'] := 'UN/ECE 5153';
  nQuinto.Attributes['schemeAgencyID'] := '6';
  nQuinto.Text := IntToStr(IgvObCodigoIntInt(ObIntLookup(edtImpuesto)));
  // Codigo Internacional del IGV

  nQuinto := nCuarto.AddChild('cbc:Name');
  nQuinto.Text := 'IGV'; // Corregir  ---- OJO ---- PENDIENTE
  nQuinto := nCuarto.AddChild('cbc:TaxTypeCode');
  nQuinto.Text := IgvObCntitStrInt(ObIntLookup(edtImpuesto));
  // CODIGO DEL TRIBUTO valor 3 igv (VAT, EXC, OTH)

  nPrimero := nMaster.AddChild('cac:LegalMonetaryTotal');
  nSegundo := nPrimero.AddChild('cbc:AllowanceTotalAmount');
  nSegundo.Attributes['currencyID'] := ObDatoStrInt('monedas', 'id_moneda',
    'codigo', FEObIntLookup(edtMoneda));
  nSegundo.Text := FloatToStr(txtDescuento.Value);
  nSegundo := nPrimero.AddChild('cbc:PayableAmount');
  nSegundo.Attributes['currencyID'] := ObDatoStrInt('monedas', 'id_moneda',
    'codigo', FEObIntLookup(edtMoneda));
  nSegundo.Text := FloatToStr(txtTotal.Value);

oscarac 21-05-2019 01:11:33

Cita:

Empezado por manelb (Mensaje 532082)
Pero que problema tienes exactamente??

que no se como empezar a crear el XML

oscarac 21-05-2019 06:46:29

wilcg estoy tomando como ejemplo tu codigo y me esta fucionando bien, pero me sale error en este codigo

Código Delphi [-]
nCuarto.AddChild('cbc:Name').DOMNode.appendChild (Xml.DOMDocument.createCDATASection(tRazonEmisor));

error : [dcc32 Error] frmEmisionFactura_f.pas(933): E2242 'DOMDocument' is not the name of a unit
acaso se encuentra en alguna otra unidad?

wilcg 21-05-2019 07:28:18

Un poco mas resumido para poder analizar el código y la informacion que se crea en el xml.
Código Delphi [-]
Var
  tDocXmlNombre: string;
  Xml: IXMLDOCUMENT;
  nMaster, nPrimero, nSegundo, nTercero, nCuarto, nQuinto, nAtributo, nItem,
    nItemSub, nCDATA: IXMLNODE;
begin
  Xml := NewXMLDocument;
  Xml.Version := '1.0';
  Xml.Encoding := 'UTF-8';
  // XML.StandAlone := 'yes';
  Xml.Options := [doNodeAutoIndent];

  nMaster := Xml.AddChild('Invoice');
  nMaster.Attributes['xmlns'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2';
  nMaster.Attributes['xmlns:cac'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2';
  nMaster.Attributes['xmlns:cbc'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2';
  nMaster.Attributes['xmlns:ccts'] := 'urn:un:unece:uncefact:documentation:2';
  nMaster.Attributes['xmlns:ds'] := 'http://www.w3.org/2000/09/xmldsig#';
  nMaster.Attributes['xmlns:ext'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2';
  nMaster.Attributes['xmlns:qdt'] :=
    'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2';
  nMaster.Attributes['xmlns:udt'] :=
    'urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2';
  nMaster.Attributes['xmlns:xsi'] :=
    'http://www.w3.org/2001/XMLSchema-instance';

  { Encabezado de Firma digital }
  nPrimero := nMaster.AddChild('ext:UBLExtensions');

  { Firma DIGITAL }
  nSegundo := nPrimero.AddChild('ext:UBLExtension');
  nSegundo.AddChild('ext:ExtensionContent').Text := '';

  { Ubl versión }
  nPrimero := nMaster.AddChild('cbc:UBLVersionID');
  nPrimero.Text := '2.1';
  { Cuztom }
  nPrimero := nMaster.AddChild('cbc:CustomizationID');
  nPrimero.Text := '2.0';

  // Información de COMPROBANTE
  { numeracion de factura }
  nPrimero := nMaster.AddChild('cbc:ID');
  nPrimero.Text := '12345678900-01-F001-0000001';

  { fecha y hora de emisión }
  nPrimero := nMaster.AddChild('cbc:IssueDate');
  nPrimero.Text := FormatDateTime('yyyy-mm-dd', Date);
   nPrimero     := nMaster.AddChild('cbc:IssueTime');
    nPrimero.Text := FormatDateTime('hh-mm-ss',Time);

   { fecha de vencimiento }
    nPrimero     := nMaster.AddChild('cbc:DueDate');
    nPrimero.Text := FormatDateTime('yyyy-mm-dd',Date);


  { Información de EMPRESA remitente }
  nPrimero := nMaster.AddChild('cac:Signature');
  nPrimero.AddChild('cbc:ID').Text := 'tRucEmisor';
  nSegundo := nPrimero.AddChild('cac:SignatoryParty');
  nTercero := nSegundo.AddChild('cac:PartyIdentification');
  nTercero.AddChild('cbc:ID').Text := 'tRucEmisor';
  nCuarto := nSegundo.AddChild('cac:PartyName');
  nCuarto.AddChild('cbc:Name').DOMNode.appendChild
    (Xml.DOMDocument.createCDATASection('tRazonEmisor'));
  nSegundo := nPrimero.AddChild('cac:DigitalSignatureAttachment');
  nTercero := nSegundo.AddChild('cac:ExternalReference');
  nTercero.AddChild('cbc:URI').Text := 'tRucEmisor';

  { Datos del EMISOR }
  nPrimero := nMaster.AddChild('cac:AccountingSupplierParty');
  nItem := nPrimero.AddChild('cbc:CustomerAssignedAccountID');
  nItem.Text := 'tRucEmisor'; // NUMERO DOC del Emisor
  nItem := nPrimero.AddChild('cbc:AdditionalAccountID');
  nItem.Text := 'FE_CodigoTipoDoc(tRucEmisor)';
  // ID del DOC del Receptor     ( 1 = DNI; 6 = RUC )   Códigos de Tipos de Documentos de Identidad

  Xml.SaveToFile(ExtractFilePath(Application.ExeName) + '12345678900-01-F001-0000001.xml');

oscarac 06-03-2020 00:22:45

Cita:

Empezado por manelb (Mensaje 532070)
Saludos a todos…

Hola oscarac, intentaré explicar nuestra experiencia sobre el tema por si te puede orientar…

Cuando en nuestro ERP desarrollamos la generación de facturas en formato xml, optamos por la generación “a pelo”, en formato texto, tal y como comenta el compañero dec.
Y así lo tenemos en la actualidad.

De todas formas, más tarde, investigamos sobre de qué forma los ficheros xsd que definen la estructura del xml podían utilizarse para simplificar el proceso y descubrimos el XML Data Binding.
Utilizando esta herramienta conseguimos generar una interface que permite generar y guardar de una forma más encapsulada la factura en formato xml.

En nuestro caso, la unidad que contiene la interface creada por el XML Data Binding a partir del xsd , contiene más de 6 mil líneas y esta es una muestra del código generado
Código Delphi [-]
{****************************************************************************************}
{                                                                                        }
{                                    XML Data Binding                                    }
{                                                                                        }
{         Generated on: 25/02/2017 16:38:47                                              }
{       Generated from: G:\DropBoxMBel\Dropbox\Facturacio Electronica\Facturaev3_2.xsd   }
{   Settings stored in: G:\DropBoxMBel\Dropbox\Facturacio Electronica\Facturaev3_2.xdb   }
{                                                                                        }
{****************************************************************************************}

unit Facturaev3_2;

interface

uses xmldom, XMLDoc, XMLIntf;

type

{ Forward Decls }

  IXMLFacturae = interface;
  IXMLFileHeaderType = interface;
  IXMLThirdPartyType = interface;
  IXMLTaxIdentificationType = interface;
  IXMLLegalEntityType = interface;
.
.
.
.
.
{ IXMLFacturae }

  IXMLFacturae = interface(IXMLNode)
    ['{4180325F-7A60-46DE-9C54-055114275527}']
    { Property Accessors }
    function Get_FileHeader: IXMLFileHeaderType;
    function Get_Parties: IXMLPartiesType;
    function Get_Invoices: IXMLInvoicesType;
    function Get_Extensions: IXMLExtensionsType;
    function Get_Signature: IXMLSignatureType_ds;
    { Methods & Properties }
    property FileHeader: IXMLFileHeaderType read Get_FileHeader;
    property Parties: IXMLPartiesType read Get_Parties;
    property Invoices: IXMLInvoicesType read Get_Invoices;
    property Extensions: IXMLExtensionsType read Get_Extensions;
    property Signature: IXMLSignatureType_ds read Get_Signature;
  end;
.
.
.
{ Global Functions }

function GetFacturae(Doc: IXMLDocument): IXMLFacturae;
function LoadFacturae(const FileName: string): IXMLFacturae;
function NewFacturae: IXMLFacturae;
.
.
.


Y un ejemplo de su llamada e inicio de construcción del xml
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  Factura: IXMLFacturae;
begin
  Factura:= GetFacturae(xml); {xml es un TXMLDocument}
  Factura.FileHeader.SchemaVersion:='3.2';
  Factura.FileHeader.Modality:='I';
  Factura.FileHeader.InvoiceIssuerType:='EM';
.
.
.
end;

Saludos

estoy retomando este tema de nuevo, voy a probar este metodo, me parece mas simple, si tu lo has probado, genera tambien los subniveles en el armado del XML?

manelb 06-03-2020 07:24:17

Si, este proceso genera la estructura completa de la factura.

Si lo necesitas, este fin de semana te puedo preparar un pequeño ejemplo con el xsd de la factura electrónica de España y te lo mando...

Saludos

manelb 06-03-2020 09:21:10

De forma muy rápida...

Me he descargado la documentación des de los enlaces que has puesto, he importado el xsd y he generado este pequeño ejemplo:

Metes un memo, un botón y un XMLDocument en un formulario, y en el botón pones lo siguiente:

Código Delphi [-]
var
  factura: IXMLInvoiceType;
  AccountID: IXMLAdditionalAccountIDType_cbc;
  PartyName: IXMLPartyNameType_cac;
begin
  factura:= GetInvoice(XMLDocument1);
  factura.IssueDate.NodeValue:='2011-06-28';
  factura.AccountingSupplierParty.CustomerAssignedAccountID.NodeValue:= '20100113612';

  AccountID:= factura.AccountingSupplierParty.AdditionalAccountID.Add;
  AccountID.nodevalue:='6';

  PartyName:= factura.AccountingSupplierParty.Party.PartyName.Add;
  PartyName.Name.NodeValue:='K&G Laboratorios';


  memoxml.lines.Text:= XMLDocument1.XML.Text;

end;

He cogido como ejemplo la factura que incluye en el documento
"Guia+XML+Boleta+version+2+0.pdf" que he descargado con la documentación.

Espero te sirva para comenzar....

Saludos

manelb 06-03-2020 09:48:04

Ah!!

Al componente XMLDocument le pones la propiedad Options.doNodeAutoIndent a true para que el texto quede mas estructurado

oscarac 08-03-2020 01:45:09

ok voy entediendo mas

pero hay algo que me tiene en duda

para que instancias

Código Delphi [-]
  AccountID: IXMLAdditionalAccountIDType_cbc;
  PartyName: IXMLPartyNameType_cac;

todo no se podria hacer desde

Código Delphi [-]
factura: IXMLInvoiceType;
???

oscarac 08-03-2020 02:04:46

o al menos explicame por favor como identifico

Raíz, Nodo, Atributo, DATO y asi sucesivamente

manelb 08-03-2020 14:27:07

Pues supongo que alguien habrá que pueda contestarte con más criterio que yo, o por lo menos constatar que mis argumentos son correctos, pero intentaré razonarte mi código.

El caso es que si te fijas como están declaradas las dos variables del ejemplo:
Código Delphi [-]
AccountID: IXMLAdditionalAccountIDType_cbc;
PartyName: IXMLPartyNameType_cac;

y te fijas en el tipo de la propiedad que queremos asignar:
Código Delphi [-]
property AdditionalAccountID: IXMLAdditionalAccountIDType_cbcList read Get_AdditionalAccountID;
property PartyName: IXMLPartyNameType_cacList read Get_PartyName;

pues te das cuenta que son propiedades tipo lista:
Código Delphi [-]
IXMLAdditionalAccountIDType_cbcList = interface(IXMLNodeCollection)
IXMLPartyNameType_cacList = interface(IXMLNodeCollection)

Por lo tanto, tenemos que crear una instancia de la clase que se espera en esa lista para poder asignarla a la propiedad.

En cuanto a lo de identificar Raíz, Nodo, Atributo…, etc., con este sistema, a mi entender, no lo necesitas.
Tu trabajas con la estructura del xml como si se tratara de cualquier otra clase, y te olvidas de los nombres de cada nodo, ya que la interface creada te permite trabajar con los nombres como propiedades.

Imagina la de errores sintácticos que se pueden cometer creando un xml complejo a pelo…
o incluso creando los nodos a mano, tipo AddChild('cac:DigitalSignatureAttachment'),
i lo que puede costar después depurar y encontrar un fallo de este tipo.

Supongo que, como todo, es cuestión de gustos, pero creo que las ventajas de hacerlo así son considerables.


Par cualquier cosa que necesites, pongo mis modestos conocimientos a tu disposición :)

Saludos

oscarac 08-03-2020 15:21:42

1 Archivos Adjunto(s)
hola buenos dias

yo estoy aprendiendo Delphi de manera autodidacta y hay temas que aun son desconocidos para mi
sobre todo esta parte de utilizar librerias externas y/o creacion lectura de XML

agradezco la paciencia

pero crees que podrias generarme un ejemplo?


de otro lado estuve "generando" un xml con el xsd, lo que no estoy entendiendo bien es que en los archivos XML de ejemplo (adjunto)
existen "claves" que cuando se generan con xl XSD no aparecen

[TEXT] <cbc:PriceAmount currencyID="PEN">38.00</cbc:PriceAmount>[/TEXT]
O TAMBIEN

<cbc:PriceTypeCode listName="SUNAT:Indicador de Tipo de Precio"
listAgencyName="PE:SUNAT"
listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo16">01</cbc:PriceTypeCode>

creo que con un ejemplo lo entenderia mejor

gracias

manelb 14-03-2020 11:19:56

Buenos días a todos…

Hola Oscarrac, perdona el retraso en contestar….

No comprendo a que te refieres cuando dices que
Cita:

en los archivos XML de ejemplo (adjunto)
existen "claves" que cuando se generan con xl XSD no aparecen
El fixhero xml resultante contendrá todas y cada una de las líneas que tú le añadas.
Es verdad que estas líneas que me muestras de ejemplo, las cuales hacen referencia a precios, además del propio valor de la etiqueta tienen atributos.
Para asignarlos, deberás conocer los diferentes valores que pueden tomar, y la forma de asignarlos a cada etiqueta.
No recuerdo yo ahora que el formato Facturae en España tenga etiquetas con atributos, pero buscando un poco he encontrado que probablemente se pueda hacer de la siguiente e forma.
He ampliado un poco el ejemplo anterior que puse para insertar un nodo con algunas etiquetas de una línea de factura

Código Delphi [-]
var
  factura: IXMLInvoiceType;
  AccountID: IXMLAdditionalAccountIDType_cbc;
  PartyName: IXMLPartyNameType_cac;
  unaLinea: IXMLInvoiceLineType_cac;
begin
  factura:= GetInvoice(XMLDocument1);
  factura.IssueDate.NodeValue:='2011-06-28';
  factura.AccountingSupplierParty.CustomerAssignedAccountID.NodeValue:= '20100113612';

  AccountID:= factura.AccountingSupplierParty.AdditionalAccountID.Add;
  AccountID.nodevalue:='6';

  PartyName:= factura.AccountingSupplierParty.Party.PartyName.Add;
  PartyName.Name.NodeValue:='K&G Laboratorios';

  //******

  unaLinea:= factura.InvoiceLine.Add;
  unalinea.id.NodeValue:=1;

  unaLinea.InvoicedQuantity.SetAttributeNS('unitCode','', 'BX');
  unaLinea.InvoicedQuantity.SetAttributeNS('unitCodeListID','', 'UN/ECE rec 20');
  unaLinea.InvoicedQuantity.SetAttributeNS('unitCodeListAgencyName','', 'United Nations Economic Commission forEurope');
  unaLinea.InvoicedQuantity.NodeValue:=2000;

  unaLinea.LineExtensionAmount.SetAttributeNS('currencyID','','PEN');
  unaLinea.LineExtensionAmount.NodeValue:= '43840.00';


  //*****

  memoxml.lines.Text:= XMLDocument1.XML.Text;

end;

Espero te sirva...

Saludos

oscarac 23-03-2020 04:45:24

estoy avanzando con esto

pero se me han presentado algunos problemas

como generar los nodos internos

por ejemplo los que estan dentro de

SIGNATURE

Código:

<cac:Signature>
    <cbc:ID>IDSignCF</cbc:ID>
    <cac:SignatoyParty>    <---------
      <cac:PartyIdentification>  <---------
        <cbd:ID>RUC del Emisor</cbd:ID> <-------
      </cac:PartyIdentification>
      <cac:PartyName>
        <cbd:Name>Nombre del Emisor</cbd:Name>
      </cac:PartyName>
    </cac:SignatoyParty>
    <cac:DigitalSignatureAttachment>
      <cac:ExternalReference>
        <cbc:URI>#SignatureCF</cbc:URI>
      </cac:ExternalReference>
    </cac:DigitalSignatureAttachment>
  </cac:Signature>

alguien tiene una idea

OJO estoy usando el archivo importado por el XML Data Binding UBLPEInvoice10


La franja horaria es GMT +2. Ahora son las 10:41:48.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi