diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d5c66ec1..b46c6f14 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -29,7 +29,7 @@ jobs:
java-version: ${{ matrix.java-version }}
cache: maven
- name: Maven tests
- run: mvn verify
+ run: mvn verify -Pexamples
- name: Upload XBuilder e2e Yaml files
uses: actions/upload-artifact@v4
with:
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..c5f3f6b9
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "interactive"
+}
\ No newline at end of file
diff --git a/examples/pom.xml b/examples/pom.xml
new file mode 100644
index 00000000..9d62956b
--- /dev/null
+++ b/examples/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+
+
+ io.github.project-openubl
+ xhandler-parent
+ 5.0.3-SNAPSHOT
+ ../pom.xml
+
+
+ examples-parent
+ Examples - Parent
+ Examples parent
+ pom
+
+
+ xbuilder
+ xsender
+ wildfly
+ tomcat
+ springbot
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 3.4.0
+
+ false
+
+
+
+
+
+
diff --git a/examples/springbot/README.md b/examples/springbot/README.md
new file mode 100644
index 00000000..ad8f2b14
--- /dev/null
+++ b/examples/springbot/README.md
@@ -0,0 +1,13 @@
+## Demo XBuilder and XSender using Spring Boot
+
+Download this repository and execute
+
+```shell
+mvn spring-boot:run
+```
+
+### Use the demo
+
+Open [http://localhost:8080](http://localhost:8080)
+
+
diff --git a/examples/springbot/pom.xml b/examples/springbot/pom.xml
new file mode 100644
index 00000000..b19cc731
--- /dev/null
+++ b/examples/springbot/pom.xml
@@ -0,0 +1,102 @@
+
+
+ 4.0.0
+
+
+ io.github.project-openubl
+ examples-parent
+ 5.0.3-SNAPSHOT
+ ../pom.xml
+
+
+ examples-springbot
+ Examples - Springbot
+
+
+ UTF-8
+ 3.0.0-M4
+ UTF-8
+ 2.7.8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring.boot-version}
+ pom
+ import
+
+
+ org.apache.camel.springboot
+ camel-spring-boot-bom
+ 3.20.3
+ pom
+ import
+
+
+
+
+
+
+ io.github.project-openubl
+ xbuilder
+
+
+ io.github.project-openubl
+ spring-boot-xsender
+ 4.1.4
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.apache.camel
+ camel-test-spring-junit5
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring.boot-version}
+
+
+
+ repackage
+
+
+
+
+
+ maven-surefire-plugin
+ ${surefire.plugin.version}
+
+
+ maven-compiler-plugin
+ 3.11.0
+
+ 11
+ 11
+ 11
+
+
+
+
+
+
diff --git a/examples/springbot/screenshot.png b/examples/springbot/screenshot.png
new file mode 100644
index 00000000..f8320874
Binary files /dev/null and b/examples/springbot/screenshot.png differ
diff --git a/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/Application.java b/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/Application.java
new file mode 100644
index 00000000..a18f2124
--- /dev/null
+++ b/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/Application.java
@@ -0,0 +1,16 @@
+package io.github.project.openubl.quickstart.xbuilder.springboot;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@ComponentScan
+@ComponentScan("io.github.project.openubl.spring.xsender.runtime")
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderController.java b/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderController.java
new file mode 100644
index 00000000..626fdae0
--- /dev/null
+++ b/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderController.java
@@ -0,0 +1,99 @@
+package io.github.project.openubl.quickstart.xbuilder.springboot;
+
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
+import io.github.project.openubl.xbuilder.content.models.common.Cliente;
+import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
+import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
+import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
+import io.github.project.openubl.xbuilder.enricher.ContentEnricher;
+import io.github.project.openubl.xbuilder.enricher.config.DateProvider;
+import io.github.project.openubl.xbuilder.enricher.config.Defaults;
+import io.github.project.openubl.xbuilder.renderer.TemplateProducer;
+import io.github.project.openubl.xbuilder.signature.CertificateDetails;
+import io.github.project.openubl.xbuilder.signature.CertificateDetailsFactory;
+import io.github.project.openubl.xbuilder.signature.XMLSigner;
+import io.github.project.openubl.xbuilder.signature.XmlSignatureHelper;
+import io.quarkus.qute.Template;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import org.w3c.dom.Document;
+
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.time.LocalDate;
+
+@RestController
+public class XBuilderController {
+
+ Defaults defaults = Defaults.builder()
+ .icbTasa(new BigDecimal("0.2"))
+ .igvTasa(new BigDecimal("0.18"))
+ .build();
+
+ DateProvider dateProvider = LocalDate::now;
+
+ @RequestMapping(
+ method = RequestMethod.POST,
+ value = "/api/create-xml",
+ produces = "text/plain"
+ )
+ public String createXML(@RequestBody String clientName) throws Exception {
+ Invoice invoice = createInvoice(clientName);
+
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(invoice);
+
+ Template template = TemplateProducer.getInstance().getInvoice();
+ String xml = template.data(invoice).render();
+
+ // Sign XML
+ InputStream ksInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx");
+ CertificateDetails certificate = CertificateDetailsFactory.create(ksInputStream, "password");
+
+ X509Certificate x509Certificate = certificate.getX509Certificate();
+ PrivateKey privateKey = certificate.getPrivateKey();
+ Document signedXML = XMLSigner.signXML(xml, "Project OpenUBL", x509Certificate, privateKey);
+
+ // Return
+ byte[] bytesFromDocument = XmlSignatureHelper.getBytesFromDocument(signedXML);
+ return new String(bytesFromDocument, StandardCharsets.ISO_8859_1);
+ }
+
+ private Invoice createInvoice(String clientName) {
+ return Invoice.builder()
+ .serie("F001")
+ .numero(1)
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build()
+ )
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build()
+ )
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build()
+ )
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item2")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build()
+ )
+ .build();
+ }
+
+}
diff --git a/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XSenderController.java b/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XSenderController.java
new file mode 100644
index 00000000..263e2955
--- /dev/null
+++ b/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XSenderController.java
@@ -0,0 +1,65 @@
+package io.github.project.openubl.quickstart.xbuilder.springboot;
+
+import io.github.project.openubl.xsender.Constants;
+import io.github.project.openubl.xsender.camel.utils.CamelData;
+import io.github.project.openubl.xsender.camel.utils.CamelUtils;
+import io.github.project.openubl.xsender.company.CompanyCredentials;
+import io.github.project.openubl.xsender.company.CompanyURLs;
+import io.github.project.openubl.xsender.files.BillServiceFileAnalyzer;
+import io.github.project.openubl.xsender.files.BillServiceXMLFileAnalyzer;
+import io.github.project.openubl.xsender.files.ZipFile;
+import io.github.project.openubl.xsender.models.SunatResponse;
+import io.github.project.openubl.xsender.sunat.BillServiceDestination;
+import org.apache.camel.CamelContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+@RestController
+public class XSenderController {
+
+ @Autowired
+ private CamelContext camelContext;
+
+ CompanyURLs companyURLs = CompanyURLs.builder()
+ .invoice("https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService")
+ .perceptionRetention("https://e-beta.sunat.gob.pe/ol-ti-itemision-otroscpe-gem-beta/billService")
+ .despatch("https://api-cpe.sunat.gob.pe/v1/contribuyente/gem")
+ .build();
+
+ CompanyCredentials credentials = CompanyCredentials.builder()
+ .username("12345678959MODDATOS")
+ .password("MODDATOS")
+ .token("accessTokenParaGuiasDeRemision")
+ .build();
+
+ @PostMapping("/api/file/upload")
+ public String uploadFile(@RequestParam("file") MultipartFile file) throws Exception {
+ byte[] bytes = file.getBytes();
+
+ BillServiceFileAnalyzer fileAnalyzer = new BillServiceXMLFileAnalyzer(bytes, companyURLs);
+
+ // Archivo ZIP
+ ZipFile zipFile = fileAnalyzer.getZipFile();
+
+ // Configuración para enviar xml y Configuración para consultar ticket
+ BillServiceDestination fileDestination = fileAnalyzer.getSendFileDestination();
+ BillServiceDestination ticketDestination = fileAnalyzer.getVerifyTicketDestination();
+
+ // Send file
+ CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, fileDestination, credentials);
+
+ SunatResponse sendFileSunatResponse = camelContext.createProducerTemplate()
+ .requestBodyAndHeaders(
+ Constants.XSENDER_BILL_SERVICE_URI,
+ camelData.getBody(),
+ camelData.getHeaders(),
+ SunatResponse.class
+ );
+
+ return fileAnalyzer.getXmlContent().getDocumentType() + " " + sendFileSunatResponse.getStatus();
+ }
+
+}
diff --git a/examples/springbot/src/main/resources/CERTIFICADO CLAVE PRIVADA.key b/examples/springbot/src/main/resources/CERTIFICADO CLAVE PRIVADA.key
new file mode 100644
index 00000000..1d4416e6
--- /dev/null
+++ b/examples/springbot/src/main/resources/CERTIFICADO CLAVE PRIVADA.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAt1IT3CtWuVOP03CFd3jSl4wTOXm8TRPhOyDNsPQU5A+eJWJ5
+7v5HY/AE9aLaBQxl/UV0Qr/yMyHUgj1ZOyRsYuC4e8XzPiVpHqPjZonARi3bT+ry
+/1f4lBmDrLZdsJLGG9xnFoCv2XEC3FtCln1AUXMGmChJziNnmhpvtQwB6SPIKZSt
+eVU1sEUDdC91MdYwZxEojYzfW5m1sd/owL/slRb3qegH2YPjLWx2dOZRWU3L5TOv
+50dSzZOsP6B1kDesJpB7iKkUJRoq3icmxQE1AjComIPKuoPKwwZUuzeUkkgoTbBN
+Lpc2kMDu1M2X3m3lF8Ca7qwhvK5qzKfU+YWAnwIDAQABAoIBAFCX2PtWYk4fmn+O
+XF7l00+k2V7PUiVgtAhWp5c/9188Ln6pCIo1aBVblBKZgdfuV3g9bJtb35LzMIYB
+ipUhsjTWLsTbhdCwicJassKFlO5FgsFjvWjcuAAEJ4tqsU3LeSUOhJO0B5tEv8k4
+pdGbRweH1kJWk/v4PLfXH30sxjpELcEwyGjFUuKGKVFliwuLXVKlBijgrq2M+GCG
+1A7vO9O0JR3yGq4r8ERzJI0zNy62RzjLPF2bes0168ovcJ3Kidt2gYVVf+2kGTvc
+skBWdIVWFgVYtNKNoy+5Y8qPMH+7QmuDA0gMt6mXdRJHL6p0Yy+yZLCZqeDoGjgU
+WvsrjeECgYEA6xxwS4w3qp2H8Fn1WmLOJo1EOieqRCvJLc/srHbmYxKOqEdzp/Lt
+uheZ1XpzsgLSPIaD3JnEj+8a7n7J0B6ZKkyoPBUTLLilm/qPe/+C7WKWaidhXVXJ
+q9Dmoyo9zLBSKqm0QJBCNEvZ7DT4RtyFL0Y0HWntIeBcrXAdfBss4NUCgYEAx5us
+axT6CoYPGqQZgorg3WgxAcA0WpbiyBdpFVsOycbpwWqQlqGLDNOvyjzyUSGMrGo3
+ObAsW6cOpKkapXfq2hTCbHupecm/4QYoDOPo7hAHwCuy/ODHJhzo5OM53n8EggFW
+XnomzvadKyAY9/+0fH2WZxns3EwKs5YO2fTtdaMCgYAWhaTkN8xlVa3eAmAUhn6F
+BudQQth2q1McRly/sKwlNXPg/uc/YXAQcY5U+uP2W3rUPXaIPVqtBxSnYBHpE+VM
+PgenqcUqdY23wWrZUAK0xsrt5FPZYwxsnxhY7QT6hLF6UMNpo+gTpmh7zh8yepFv
+k+QOJUWIBzwZiTHp35iO+QKBgHnzelvR7RIQ5Zl5OLyw7MFYrthK/bF7DgMBioop
+n9dXV+l7mertt26WxofgxIsc3D1ah3MPV4qHfkLLriP6J9olZMOyqdBmmnx4rm9x
+rxYDZTjbefdVvVZjw0ZULT7qi26CMqp2Js+7jDqU2axq5XJJqGJFTJkrPD6MJ3ay
+VYHRAoGAGG+rgP44tjwu0qmmUDfdp1tlMzUwVmM3pvjw1+RKYQprt+K3cUlBliPf
+VKMs9aQ0J6VrjrkNHTL85VzeOK6QYnsKZuski3GD0hA3XVE3u4SuMCb3Rmt6eLVr
+f9UGabwN9n5il3ZV7+qCmvpYGZzQ1A8+jZgbFWW3bp4BuIiwbbg=
+-----END RSA PRIVATE KEY-----
diff --git a/examples/springbot/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer b/examples/springbot/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer
new file mode 100644
index 00000000..8c9ce325
--- /dev/null
+++ b/examples/springbot/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE9zCCA9+gAwIBAgIIVziKPglBFFAwDQYJKoZIhvcNAQEFBQAwggENMRswGQYK
+CZImiZPyLGQBGRYLTExBTUEuUEUgU0ExCzAJBgNVBAYTAlBFMQ0wCwYDVQQIDARM
+SU1BMQ0wCwYDVQQHDARMSU1BMRgwFgYDVQQKDA9UVSBFTVBSRVNBIFMuQS4xRTBD
+BgNVBAsMPEROSSA5OTk5OTk5IFJVQyAxMjM0NTY3ODkxMiAtIENFUlRJRklDQURP
+IFBBUkEgREVNT1NUUkFDScOTTjFEMEIGA1UEAww7Tk9NQlJFIFJFUFJFU0VOVEFO
+VEUgTEVHQUwgLSBDRVJUSUZJQ0FETyBQQVJBIERFTU9TVFJBQ0nDk04xHDAaBgkq
+hkiG9w0BCQEWDWRlbW9AbGxhbWEucGUwHhcNMjAxMTA0MjAyNTU1WhcNMjIxMTA0
+MjAyNTU1WjCCAQ0xGzAZBgoJkiaJk/IsZAEZFgtMTEFNQS5QRSBTQTELMAkGA1UE
+BhMCUEUxDTALBgNVBAgMBExJTUExDTALBgNVBAcMBExJTUExGDAWBgNVBAoMD1RV
+IEVNUFJFU0EgUy5BLjFFMEMGA1UECww8RE5JIDk5OTk5OTkgUlVDIDEyMzQ1Njc4
+OTEyIC0gQ0VSVElGSUNBRE8gUEFSQSBERU1PU1RSQUNJw5NOMUQwQgYDVQQDDDtO
+T01CUkUgUkVQUkVTRU5UQU5URSBMRUdBTCAtIENFUlRJRklDQURPIFBBUkEgREVN
+T1NUUkFDScOTTjEcMBoGCSqGSIb3DQEJARYNZGVtb0BsbGFtYS5wZTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALdSE9wrVrlTj9NwhXd40peMEzl5vE0T
+4TsgzbD0FOQPniViee7+R2PwBPWi2gUMZf1FdEK/8jMh1II9WTskbGLguHvF8z4l
+aR6j42aJwEYt20/q8v9X+JQZg6y2XbCSxhvcZxaAr9lxAtxbQpZ9QFFzBpgoSc4j
+Z5oab7UMAekjyCmUrXlVNbBFA3QvdTHWMGcRKI2M31uZtbHf6MC/7JUW96noB9mD
+4y1sdnTmUVlNy+Uzr+dHUs2TrD+gdZA3rCaQe4ipFCUaKt4nJsUBNQIwqJiDyrqD
+ysMGVLs3lJJIKE2wTS6XNpDA7tTNl95t5RfAmu6sIbyuasyn1PmFgJ8CAwEAAaNX
+MFUwHQYDVR0OBBYEFPxbUIr45L+Z3UITV2cp3yNjkm6qMB8GA1UdIwQYMBaAFPxb
+UIr45L+Z3UITV2cp3yNjkm6qMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3
+DQEBBQUAA4IBAQBIRHrTbqwpvdlohUzbuyMt/OOQMqhL7fQjML8zYVbP9YuSFSws
+qvYaA30WRRqEf1kvYdyc6E0zzV36EgegtHOBHQq3N+JX+VtLnLROB/O3YKnwqufn
+5BRMPG9WRgsLBVC1NybycCqTEJHyQn1d3oJ1U8c1NKx7CMez5/2h+NaPThBmjcwM
+NOTuJVzIOcDpEmSq4ZUDf29k1JZTh4AMtzn94+4usqVm0KGrlJ4Kiyp6NyTjCSJC
+KMPScfBdmvpkkvW+FM1InfXfrcmG6ImUKUfVT5FasuDKb0eQR5OouMCpHFEIULOp
+KccMCjEGHuTUKmLVKSXpt5y3dxH+hEBRaW2J
+-----END CERTIFICATE-----
diff --git a/examples/springbot/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx b/examples/springbot/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx
new file mode 100644
index 00000000..797e5433
Binary files /dev/null and b/examples/springbot/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx differ
diff --git a/examples/springbot/src/main/webapp/css/styles.css b/examples/springbot/src/main/webapp/css/styles.css
new file mode 100644
index 00000000..151a9f36
--- /dev/null
+++ b/examples/springbot/src/main/webapp/css/styles.css
@@ -0,0 +1,3 @@
+.invalid {
+ color: red;
+}
diff --git a/examples/springbot/src/main/webapp/index.html b/examples/springbot/src/main/webapp/index.html
new file mode 100644
index 00000000..66db2eff
--- /dev/null
+++ b/examples/springbot/src/main/webapp/index.html
@@ -0,0 +1,71 @@
+
+
+
+ HTML5 + REST Hello World
+
+
+
+
+
+XBuilder + REST create xml
+
+
+
+
+
+XSender + send XML
+
+
+
+
+
diff --git a/examples/tomcat/.gitignore b/examples/tomcat/.gitignore
new file mode 100644
index 00000000..e67567eb
--- /dev/null
+++ b/examples/tomcat/.gitignore
@@ -0,0 +1,37 @@
+# Eclipse
+.project
+.classpath
+.settings/
+bin/
+
+# IntelliJ
+.idea
+*.ipr
+*.iml
+*.iws
+
+# NetBeans
+nb-configuration.xml
+
+# Visual Studio Code
+.vscode
+
+# OSX
+.DS_Store
+
+# Vim
+*.swp
+*.swo
+
+# patch
+*.orig
+*.rej
+
+# Maven
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+release.properties
+
+workspace/
\ No newline at end of file
diff --git a/examples/tomcat/README.md b/examples/tomcat/README.md
new file mode 100644
index 00000000..458f4642
--- /dev/null
+++ b/examples/tomcat/README.md
@@ -0,0 +1,16 @@
+## Deploy
+
+- Compile the application
+
+```shell
+mvn clean package
+```
+
+- Use Cargo to download and deploy it to Tomcat
+
+```shell
+mvn cargo:run
+```
+
+- Open http://localhost:8080/tomcat-xbuilder-xsender/
+
diff --git a/examples/tomcat/pom.xml b/examples/tomcat/pom.xml
new file mode 100644
index 00000000..d98509f1
--- /dev/null
+++ b/examples/tomcat/pom.xml
@@ -0,0 +1,97 @@
+
+
+ 4.0.0
+
+
+ io.github.project-openubl
+ examples-parent
+ 5.0.3-SNAPSHOT
+ ../pom.xml
+
+
+ tomcat-example
+
+ Examples - Tomcat
+ war
+
+
+ UTF-8
+ 3.0.0
+ UTF-8
+
+ 9x
+ 9.0.46
+
+
+
+
+
+ io.github.project-openubl
+ xbuilder
+
+
+ io.github.project-openubl
+ xsender
+
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+ ${tomcat.version}
+ provided
+
+
+
+
+
+
+ org.codehaus.cargo
+ cargo-maven3-plugin
+ 1.9.10
+
+
+ tomcat${tomcat.id}
+ installed
+
+ https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/${tomcat.version}/tomcat-${tomcat.version}.zip
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ false
+
+
+
+
+ maven-surefire-plugin
+ ${surefire.plugin.version}
+
+
+ maven-compiler-plugin
+ 3.11.0
+
+ 11
+ 11
+ 11
+
+
+
+
+
+
+
+ tomcat10
+
+ 10x
+ 10.1.8
+
+
+
+
+
diff --git a/examples/tomcat/quickstart.sh b/examples/tomcat/quickstart.sh
new file mode 100755
index 00000000..adcaeb05
--- /dev/null
+++ b/examples/tomcat/quickstart.sh
@@ -0,0 +1,21 @@
+# Generate .war
+mvn clean package
+
+# Download Tomcat
+rm -rf workspace/
+#wget https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/9.0.46/tomcat-9.0.46.zip -P workspace/
+wget https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/10.1.8/tomcat-10.1.8.zip -P workspace/
+#unzip workspace/tomcat-9.0.46.zip -d workspace/
+unzip workspace/tomcat-10.1.8.zip -d workspace/
+#chmod +x -R ./workspace/apache-tomcat-9.0.46/bin
+chmod +x -R ./workspace/apache-tomcat-10.1.8/bin
+
+# Copy .war to Tomcat
+#cp target/tomcat-xbuilder-xsender-0.0.1-SNAPSHOT.war workspace/apache-tomcat-9.0.46/webapps/demo.war
+cp target/tomcat-xbuilder-xsender-0.0.1-SNAPSHOT.war workspace/apache-tomcat-10.1.8/webapps/demo.war
+
+# Start Tomcat
+#./workspace/apache-tomcat-9.0.46/bin/startup.sh
+./workspace/apache-tomcat-10.1.8/bin/startup.sh
+
+sleep 10s
diff --git a/examples/tomcat/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderServlet.java b/examples/tomcat/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderServlet.java
new file mode 100644
index 00000000..519ca602
--- /dev/null
+++ b/examples/tomcat/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderServlet.java
@@ -0,0 +1,112 @@
+package io.github.project.openubl.quickstart.xbuilder.springboot;
+
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
+import io.github.project.openubl.xbuilder.content.models.common.Cliente;
+import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
+import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
+import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
+import io.github.project.openubl.xbuilder.enricher.ContentEnricher;
+import io.github.project.openubl.xbuilder.enricher.config.DateProvider;
+import io.github.project.openubl.xbuilder.enricher.config.Defaults;
+import io.github.project.openubl.xbuilder.renderer.TemplateProducer;
+import io.github.project.openubl.xbuilder.signature.CertificateDetails;
+import io.github.project.openubl.xbuilder.signature.CertificateDetailsFactory;
+import io.github.project.openubl.xbuilder.signature.XMLSigner;
+import io.github.project.openubl.xbuilder.signature.XmlSignatureHelper;
+import io.quarkus.qute.Template;
+import org.w3c.dom.Document;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.time.LocalDate;
+
+@WebServlet("/api/create-xml/")
+public class XBuilderServlet extends HttpServlet {
+
+ Defaults defaults = Defaults.builder()
+ .icbTasa(new BigDecimal("0.2"))
+ .igvTasa(new BigDecimal("0.18"))
+ .build();
+
+ DateProvider dateProvider = LocalDate::now;
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String clientName = req.getReader().readLine();
+
+ try {
+ Invoice invoice = createInvoice(clientName);
+
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(invoice);
+
+ Template template = TemplateProducer.getInstance().getInvoice();
+ String xml = template.data(invoice).render();
+
+ // Sign XML
+ InputStream ksInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx");
+
+ CertificateDetails certificate = CertificateDetailsFactory.create(ksInputStream, "password");
+
+
+ X509Certificate x509Certificate = certificate.getX509Certificate();
+ PrivateKey privateKey = certificate.getPrivateKey();
+ Document signedXML = XMLSigner.signXML(xml, "Project OpenUBL", x509Certificate, privateKey);
+
+ // Return
+ byte[] bytesFromDocument = XmlSignatureHelper.getBytesFromDocument(signedXML);
+
+ String xmlString = new String(bytesFromDocument, StandardCharsets.ISO_8859_1);
+
+ // Response
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("text/plain");
+ resp.getWriter().write(xmlString);
+ resp.getWriter().flush();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Invoice createInvoice(String clientName) {
+ return Invoice.builder()
+ .serie("F001")
+ .numero(1)
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build()
+ )
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build()
+ )
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build()
+ )
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item2")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build()
+ )
+ .build();
+ }
+
+}
diff --git a/examples/tomcat/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XSenderServlet.java b/examples/tomcat/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XSenderServlet.java
new file mode 100644
index 00000000..59f6365f
--- /dev/null
+++ b/examples/tomcat/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XSenderServlet.java
@@ -0,0 +1,85 @@
+package io.github.project.openubl.quickstart.xbuilder.springboot;
+
+import io.github.project.openubl.xsender.Constants;
+import io.github.project.openubl.xsender.camel.StandaloneCamel;
+import io.github.project.openubl.xsender.camel.utils.CamelData;
+import io.github.project.openubl.xsender.camel.utils.CamelUtils;
+import io.github.project.openubl.xsender.company.CompanyCredentials;
+import io.github.project.openubl.xsender.company.CompanyURLs;
+import io.github.project.openubl.xsender.files.BillServiceFileAnalyzer;
+import io.github.project.openubl.xsender.files.BillServiceXMLFileAnalyzer;
+import io.github.project.openubl.xsender.files.ZipFile;
+import io.github.project.openubl.xsender.models.SunatResponse;
+import io.github.project.openubl.xsender.sunat.BillServiceDestination;
+import org.apache.camel.CamelContext;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@WebServlet("/api/file/upload")
+public class XSenderServlet extends HttpServlet {
+
+ CompanyURLs companyURLs = CompanyURLs.builder()
+ .invoice("https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService")
+ .perceptionRetention("https://e-beta.sunat.gob.pe/ol-ti-itemision-otroscpe-gem-beta/billService")
+ .despatch("https://api-cpe.sunat.gob.pe/v1/contribuyente/gem")
+ .build();
+
+ CompanyCredentials credentials = CompanyCredentials.builder()
+ .username("12345678959MODDATOS")
+ .password("MODDATOS")
+ .token("accessTokenParaGuiasDeRemision")
+ .build();
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ byte[] bytes = this.getClass()
+ .getClassLoader()
+ .getResourceAsStream("invoice.xml").readAllBytes();
+
+ BillServiceFileAnalyzer fileAnalyzer = null;
+
+ fileAnalyzer = new BillServiceXMLFileAnalyzer(bytes, companyURLs);
+
+
+ // Archivo ZIP
+ ZipFile zipFile = fileAnalyzer.getZipFile();
+
+ // Configuración para enviar xml y Configuración para consultar ticket
+ BillServiceDestination fileDestination = fileAnalyzer.getSendFileDestination();
+ BillServiceDestination ticketDestination = fileAnalyzer.getVerifyTicketDestination();
+
+ // Send file
+ CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, fileDestination, credentials);
+
+ CamelContext camelContext = StandaloneCamel.getInstance()
+ .getMainCamel()
+ .getCamelContext();
+
+ SunatResponse sendFileSunatResponse = camelContext.createProducerTemplate()
+ .requestBodyAndHeaders(
+ Constants.XSENDER_BILL_SERVICE_URI,
+ camelData.getBody(),
+ camelData.getHeaders(),
+ SunatResponse.class
+ );
+
+ String response = fileAnalyzer.getXmlContent().getDocumentType() + " " + sendFileSunatResponse.getStatus();
+
+ // Response
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("text/plain");
+ resp.getWriter().write(response);
+ resp.getWriter().flush();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+}
diff --git a/examples/tomcat/src/main/resources/CERTIFICADO CLAVE PRIVADA.key b/examples/tomcat/src/main/resources/CERTIFICADO CLAVE PRIVADA.key
new file mode 100644
index 00000000..1d4416e6
--- /dev/null
+++ b/examples/tomcat/src/main/resources/CERTIFICADO CLAVE PRIVADA.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAt1IT3CtWuVOP03CFd3jSl4wTOXm8TRPhOyDNsPQU5A+eJWJ5
+7v5HY/AE9aLaBQxl/UV0Qr/yMyHUgj1ZOyRsYuC4e8XzPiVpHqPjZonARi3bT+ry
+/1f4lBmDrLZdsJLGG9xnFoCv2XEC3FtCln1AUXMGmChJziNnmhpvtQwB6SPIKZSt
+eVU1sEUDdC91MdYwZxEojYzfW5m1sd/owL/slRb3qegH2YPjLWx2dOZRWU3L5TOv
+50dSzZOsP6B1kDesJpB7iKkUJRoq3icmxQE1AjComIPKuoPKwwZUuzeUkkgoTbBN
+Lpc2kMDu1M2X3m3lF8Ca7qwhvK5qzKfU+YWAnwIDAQABAoIBAFCX2PtWYk4fmn+O
+XF7l00+k2V7PUiVgtAhWp5c/9188Ln6pCIo1aBVblBKZgdfuV3g9bJtb35LzMIYB
+ipUhsjTWLsTbhdCwicJassKFlO5FgsFjvWjcuAAEJ4tqsU3LeSUOhJO0B5tEv8k4
+pdGbRweH1kJWk/v4PLfXH30sxjpELcEwyGjFUuKGKVFliwuLXVKlBijgrq2M+GCG
+1A7vO9O0JR3yGq4r8ERzJI0zNy62RzjLPF2bes0168ovcJ3Kidt2gYVVf+2kGTvc
+skBWdIVWFgVYtNKNoy+5Y8qPMH+7QmuDA0gMt6mXdRJHL6p0Yy+yZLCZqeDoGjgU
+WvsrjeECgYEA6xxwS4w3qp2H8Fn1WmLOJo1EOieqRCvJLc/srHbmYxKOqEdzp/Lt
+uheZ1XpzsgLSPIaD3JnEj+8a7n7J0B6ZKkyoPBUTLLilm/qPe/+C7WKWaidhXVXJ
+q9Dmoyo9zLBSKqm0QJBCNEvZ7DT4RtyFL0Y0HWntIeBcrXAdfBss4NUCgYEAx5us
+axT6CoYPGqQZgorg3WgxAcA0WpbiyBdpFVsOycbpwWqQlqGLDNOvyjzyUSGMrGo3
+ObAsW6cOpKkapXfq2hTCbHupecm/4QYoDOPo7hAHwCuy/ODHJhzo5OM53n8EggFW
+XnomzvadKyAY9/+0fH2WZxns3EwKs5YO2fTtdaMCgYAWhaTkN8xlVa3eAmAUhn6F
+BudQQth2q1McRly/sKwlNXPg/uc/YXAQcY5U+uP2W3rUPXaIPVqtBxSnYBHpE+VM
+PgenqcUqdY23wWrZUAK0xsrt5FPZYwxsnxhY7QT6hLF6UMNpo+gTpmh7zh8yepFv
+k+QOJUWIBzwZiTHp35iO+QKBgHnzelvR7RIQ5Zl5OLyw7MFYrthK/bF7DgMBioop
+n9dXV+l7mertt26WxofgxIsc3D1ah3MPV4qHfkLLriP6J9olZMOyqdBmmnx4rm9x
+rxYDZTjbefdVvVZjw0ZULT7qi26CMqp2Js+7jDqU2axq5XJJqGJFTJkrPD6MJ3ay
+VYHRAoGAGG+rgP44tjwu0qmmUDfdp1tlMzUwVmM3pvjw1+RKYQprt+K3cUlBliPf
+VKMs9aQ0J6VrjrkNHTL85VzeOK6QYnsKZuski3GD0hA3XVE3u4SuMCb3Rmt6eLVr
+f9UGabwN9n5il3ZV7+qCmvpYGZzQ1A8+jZgbFWW3bp4BuIiwbbg=
+-----END RSA PRIVATE KEY-----
diff --git a/examples/tomcat/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer b/examples/tomcat/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer
new file mode 100644
index 00000000..8c9ce325
--- /dev/null
+++ b/examples/tomcat/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE9zCCA9+gAwIBAgIIVziKPglBFFAwDQYJKoZIhvcNAQEFBQAwggENMRswGQYK
+CZImiZPyLGQBGRYLTExBTUEuUEUgU0ExCzAJBgNVBAYTAlBFMQ0wCwYDVQQIDARM
+SU1BMQ0wCwYDVQQHDARMSU1BMRgwFgYDVQQKDA9UVSBFTVBSRVNBIFMuQS4xRTBD
+BgNVBAsMPEROSSA5OTk5OTk5IFJVQyAxMjM0NTY3ODkxMiAtIENFUlRJRklDQURP
+IFBBUkEgREVNT1NUUkFDScOTTjFEMEIGA1UEAww7Tk9NQlJFIFJFUFJFU0VOVEFO
+VEUgTEVHQUwgLSBDRVJUSUZJQ0FETyBQQVJBIERFTU9TVFJBQ0nDk04xHDAaBgkq
+hkiG9w0BCQEWDWRlbW9AbGxhbWEucGUwHhcNMjAxMTA0MjAyNTU1WhcNMjIxMTA0
+MjAyNTU1WjCCAQ0xGzAZBgoJkiaJk/IsZAEZFgtMTEFNQS5QRSBTQTELMAkGA1UE
+BhMCUEUxDTALBgNVBAgMBExJTUExDTALBgNVBAcMBExJTUExGDAWBgNVBAoMD1RV
+IEVNUFJFU0EgUy5BLjFFMEMGA1UECww8RE5JIDk5OTk5OTkgUlVDIDEyMzQ1Njc4
+OTEyIC0gQ0VSVElGSUNBRE8gUEFSQSBERU1PU1RSQUNJw5NOMUQwQgYDVQQDDDtO
+T01CUkUgUkVQUkVTRU5UQU5URSBMRUdBTCAtIENFUlRJRklDQURPIFBBUkEgREVN
+T1NUUkFDScOTTjEcMBoGCSqGSIb3DQEJARYNZGVtb0BsbGFtYS5wZTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALdSE9wrVrlTj9NwhXd40peMEzl5vE0T
+4TsgzbD0FOQPniViee7+R2PwBPWi2gUMZf1FdEK/8jMh1II9WTskbGLguHvF8z4l
+aR6j42aJwEYt20/q8v9X+JQZg6y2XbCSxhvcZxaAr9lxAtxbQpZ9QFFzBpgoSc4j
+Z5oab7UMAekjyCmUrXlVNbBFA3QvdTHWMGcRKI2M31uZtbHf6MC/7JUW96noB9mD
+4y1sdnTmUVlNy+Uzr+dHUs2TrD+gdZA3rCaQe4ipFCUaKt4nJsUBNQIwqJiDyrqD
+ysMGVLs3lJJIKE2wTS6XNpDA7tTNl95t5RfAmu6sIbyuasyn1PmFgJ8CAwEAAaNX
+MFUwHQYDVR0OBBYEFPxbUIr45L+Z3UITV2cp3yNjkm6qMB8GA1UdIwQYMBaAFPxb
+UIr45L+Z3UITV2cp3yNjkm6qMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3
+DQEBBQUAA4IBAQBIRHrTbqwpvdlohUzbuyMt/OOQMqhL7fQjML8zYVbP9YuSFSws
+qvYaA30WRRqEf1kvYdyc6E0zzV36EgegtHOBHQq3N+JX+VtLnLROB/O3YKnwqufn
+5BRMPG9WRgsLBVC1NybycCqTEJHyQn1d3oJ1U8c1NKx7CMez5/2h+NaPThBmjcwM
+NOTuJVzIOcDpEmSq4ZUDf29k1JZTh4AMtzn94+4usqVm0KGrlJ4Kiyp6NyTjCSJC
+KMPScfBdmvpkkvW+FM1InfXfrcmG6ImUKUfVT5FasuDKb0eQR5OouMCpHFEIULOp
+KccMCjEGHuTUKmLVKSXpt5y3dxH+hEBRaW2J
+-----END CERTIFICATE-----
diff --git a/examples/tomcat/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx b/examples/tomcat/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx
new file mode 100644
index 00000000..797e5433
Binary files /dev/null and b/examples/tomcat/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx differ
diff --git a/examples/tomcat/src/main/resources/invoice.xml b/examples/tomcat/src/main/resources/invoice.xml
new file mode 100644
index 00000000..25bcb678
--- /dev/null
+++ b/examples/tomcat/src/main/resources/invoice.xml
@@ -0,0 +1,159 @@
+
+
+
+
+ nGXHhWrjhVfXVnm1i1RRP7c6mUY=aUHCPyZLFnKtA3vDBbVVoPcbtW/Dgj8xDza4m0Uu+3pgPWgkaqWTfM7RSH91i9kHlT5Ou88pAeU1
+mv5pFayEoH/gVImxyc6OKDMRmVf0FKVf9xZzOkuXYT2TZmXC8FgJGegOUum+sgdMB6VM66TEDXOy
+qhr6qOC8HqZIbRDacArClg5g4GtWBCXL6Mdt15/6I+JvzNb7/7xcaRrh+E2JyZcAGcB1knKwkZd4
+AMpMuCsXaWfDdTssOPcT+CpqNb93eW/6q88ZxQh+D057uBMaAf9EhOzM6QQkirVygrgnJuMaE6JF
+/gSbXYtqRGH3vszSljqWothGfd0GCKYBmE/SXg==MIICmzCCAYMCBgFxQLzLUjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjAw
+NDAzMTU0OTA2WhcNMzAwNDAzMTU1MDQ2WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCBFvkmIdnA8xd4LlEPigj/bcSYJg1KKgARd/QmTlcW80TLuYJ0
+FZuvXpf26iIT9HbkKTEkbaCqA+vCz5gIXhSiKaKuwy8FE0sagxVr93mfT/MK0x4yxijE4gyhQcY5
+4n9wQ0XaEygZT3tSm5iEgZQrcjWHAxYvfS9zGJcdumU2Q3A/wvdjiBQtMyRdYnH9bZje6EIlES/M
+SK/GwHEGNgi4j0rkpVFRSGxlYYlAj97DrX681eg6FzADWsVfFwgmHFAO4uDuT1E1SbHay3yC7d6f
+tWhD0BCe8ZC6XikVVgdcLRn8oIYNjIv9QxmnbbP0OsKUHTonj/5trxWezhwQIPuHAgMBAAEwDQYJ
+KoZIhvcNAQELBQADggEBACnf3I29sFwIV5xpxOvDNYHDapvH366kX1yBGKqnTIyWvz0bEeRuYmOa
+v0UN8gCJg+pJxoYc5NXURxTlqsj3XLirRTBW3rZJZWoING3RthU+lAMyC5Ao9rJEhNftxgSAc+DW
+5T31JR+Du6V8BnFjyTML3ZPz3QtJwC2IpaFExqjrxodWuiC6c8FtHoPZRp5QfBjdVbDN9kC9YzrP
+UkvotM3GiZNB1XrAsvxYmDa3J8ASCRJ11aGMoGkoGYQ4hGfCQBG7DDkq1REbetwE9oqUaHuTTPGi
+z3QCqD69SPpu1QuTS86iQ5dYxK70uE47yH0erb0UQ5+dNH5OMSjO8mQdGtw=
+
+
+ 2.1
+ 2.0
+ B001-1
+ 2020-03-28
+ 12:21:49
+ 03
+ PEN
+
+ 12312312312
+
+
+ 12312312312
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+
+
+ 12345678912
+
+
+ mi nombre comercial
+
+
+
+
+ 050101
+ 123456
+ Las Flores
+ Huamanga
+ Ayacucho
+ Mariscal Caceres
+
+
+
+
+ PE
+
+
+
+
+ +051 123 456 789
+ email@gmail.com
+
+
+
+
+
+
+ 12345678
+
+
+
+
+ 050101
+ 123456
+ Las Flores
+ Huamanga
+ Ayacucho
+ Mariscal Caceres
+
+
+
+
+ PE
+
+
+
+
+ +051 123 456 789
+ email@gmail.com
+
+
+
+
+ 1.8
+
+ 10
+ 1.8
+
+ S
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+ 10
+ 11.8
+ 11.8
+
+
+ 1
+ 1
+ 10
+
+
+ 11.8
+ 01
+
+
+
+ 1.8
+
+ 10
+ 1.8
+
+ S
+ 18
+ 10
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+
+
+
+ 10
+
+
+
\ No newline at end of file
diff --git a/examples/tomcat/src/main/webapp/WEB-INF /web.xml b/examples/tomcat/src/main/webapp/WEB-INF /web.xml
new file mode 100644
index 00000000..bc7c1f0c
--- /dev/null
+++ b/examples/tomcat/src/main/webapp/WEB-INF /web.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/examples/tomcat/src/main/webapp/css/styles.css b/examples/tomcat/src/main/webapp/css/styles.css
new file mode 100644
index 00000000..151a9f36
--- /dev/null
+++ b/examples/tomcat/src/main/webapp/css/styles.css
@@ -0,0 +1,3 @@
+.invalid {
+ color: red;
+}
diff --git a/examples/tomcat/src/main/webapp/index.html b/examples/tomcat/src/main/webapp/index.html
new file mode 100644
index 00000000..66db2eff
--- /dev/null
+++ b/examples/tomcat/src/main/webapp/index.html
@@ -0,0 +1,71 @@
+
+
+
+ HTML5 + REST Hello World
+
+
+
+
+
+XBuilder + REST create xml
+
+
+
+
+
+XSender + send XML
+
+
+
+
+
diff --git a/examples/wildfly/README.md b/examples/wildfly/README.md
new file mode 100644
index 00000000..a641b0ab
--- /dev/null
+++ b/examples/wildfly/README.md
@@ -0,0 +1,17 @@
+Steps:
+
+## Init Wildfly
+
+```shell
+mvn wildfly:start -f xbuilder-jee-vanilla/
+```
+
+## Deploy your app
+
+```shell
+mvn wildfly:deploy -f xbuilder-jee-vanilla/
+```
+
+## Open browser
+
+- Open [http://localhost:8080/xbuilder-jee-vanilla](http://localhost:8080/xbuilder-jee-vanilla)
diff --git a/examples/wildfly/pom.xml b/examples/wildfly/pom.xml
new file mode 100644
index 00000000..20e9ca83
--- /dev/null
+++ b/examples/wildfly/pom.xml
@@ -0,0 +1,88 @@
+
+
+ 4.0.0
+
+ io.github.project-openubl
+ examples-parent
+ 5.0.3-SNAPSHOT
+ ../pom.xml
+
+
+ wildlfy-example
+ Examples - Wildfly
+ war
+
+
+
+ 26.1.1.Final
+ 2.0.2.Final
+
+
+
+
+
+
+ org.wildfly.bom
+ wildfly-jakartaee8-with-tools
+ ${version.server.bom}
+ pom
+ import
+
+
+
+
+
+
+ io.github.project-openubl
+ xbuilder
+
+
+
+
+ jakarta.enterprise
+ jakarta.enterprise.cdi-api
+ provided
+
+
+
+
+ org.jboss.spec.javax.annotation
+ jboss-annotations-api_1.3_spec
+ provided
+
+
+
+
+ org.jboss.spec.javax.ws.rs
+ jboss-jaxrs-api_2.1_spec
+ provided
+
+
+
+
+ ${project.artifactId}
+
+
+
+ org.wildfly.plugins
+ wildfly-maven-plugin
+ ${version.wildfly.maven.plugin}
+
+ ${version.server.bom}
+
+
+
+
+
+
+ org.wildfly.plugins
+ wildfly-maven-plugin
+
+
+
+
\ No newline at end of file
diff --git a/examples/wildfly/src/main/java/io/github/project/openubl/quickstart/xbuilder/jee/UBLResource.java b/examples/wildfly/src/main/java/io/github/project/openubl/quickstart/xbuilder/jee/UBLResource.java
new file mode 100644
index 00000000..c9e3abdb
--- /dev/null
+++ b/examples/wildfly/src/main/java/io/github/project/openubl/quickstart/xbuilder/jee/UBLResource.java
@@ -0,0 +1,50 @@
+package io.github.project.openubl.quickstart.xbuilder.jee;
+
+import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
+import io.github.project.openubl.xbuilder.enricher.ContentEnricher;
+import io.github.project.openubl.xbuilder.enricher.config.DateProvider;
+import io.github.project.openubl.xbuilder.enricher.config.Defaults;
+import io.github.project.openubl.xbuilder.renderer.TemplateProducer;
+import io.quarkus.qute.Template;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@ApplicationScoped
+@Path("/")
+public class UBLResource {
+
+ Defaults defaults = Defaults.builder()
+ .icbTasa(new BigDecimal("0.2"))
+ .igvTasa(new BigDecimal("0.18"))
+ .build();
+
+ DateProvider dateProvider = LocalDate::now;
+
+ @Inject
+ UBLService ublService;
+
+ @POST
+ @Path("/create-xml")
+ @Produces("text/plain")
+ public String createInvoice(String client) {
+ // Invoice generation
+ Invoice invoice = ublService.createInvoice(client);
+
+ // Enrich data
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(invoice);
+
+ // Generate XML
+ Template template = TemplateProducer.getInstance().getInvoice();
+ String xml = template.data(invoice).render();
+
+ return xml;
+ }
+
+}
diff --git a/examples/wildfly/src/main/java/io/github/project/openubl/quickstart/xbuilder/jee/UBLService.java b/examples/wildfly/src/main/java/io/github/project/openubl/quickstart/xbuilder/jee/UBLService.java
new file mode 100644
index 00000000..53d3bc19
--- /dev/null
+++ b/examples/wildfly/src/main/java/io/github/project/openubl/quickstart/xbuilder/jee/UBLService.java
@@ -0,0 +1,45 @@
+package io.github.project.openubl.quickstart.xbuilder.jee;
+
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
+import io.github.project.openubl.xbuilder.content.models.common.Cliente;
+import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
+import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
+import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
+
+import java.math.BigDecimal;
+
+public class UBLService {
+
+ public Invoice createInvoice(String clientName) {
+ return Invoice.builder()
+ .serie("F001")
+ .numero(1)
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build()
+ )
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build()
+ )
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build()
+ )
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item2")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build()
+ )
+ .build();
+ }
+
+}
diff --git a/examples/wildfly/src/main/resources/CERTIFICADO CLAVE PRIVADA.key b/examples/wildfly/src/main/resources/CERTIFICADO CLAVE PRIVADA.key
new file mode 100644
index 00000000..1d4416e6
--- /dev/null
+++ b/examples/wildfly/src/main/resources/CERTIFICADO CLAVE PRIVADA.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAt1IT3CtWuVOP03CFd3jSl4wTOXm8TRPhOyDNsPQU5A+eJWJ5
+7v5HY/AE9aLaBQxl/UV0Qr/yMyHUgj1ZOyRsYuC4e8XzPiVpHqPjZonARi3bT+ry
+/1f4lBmDrLZdsJLGG9xnFoCv2XEC3FtCln1AUXMGmChJziNnmhpvtQwB6SPIKZSt
+eVU1sEUDdC91MdYwZxEojYzfW5m1sd/owL/slRb3qegH2YPjLWx2dOZRWU3L5TOv
+50dSzZOsP6B1kDesJpB7iKkUJRoq3icmxQE1AjComIPKuoPKwwZUuzeUkkgoTbBN
+Lpc2kMDu1M2X3m3lF8Ca7qwhvK5qzKfU+YWAnwIDAQABAoIBAFCX2PtWYk4fmn+O
+XF7l00+k2V7PUiVgtAhWp5c/9188Ln6pCIo1aBVblBKZgdfuV3g9bJtb35LzMIYB
+ipUhsjTWLsTbhdCwicJassKFlO5FgsFjvWjcuAAEJ4tqsU3LeSUOhJO0B5tEv8k4
+pdGbRweH1kJWk/v4PLfXH30sxjpELcEwyGjFUuKGKVFliwuLXVKlBijgrq2M+GCG
+1A7vO9O0JR3yGq4r8ERzJI0zNy62RzjLPF2bes0168ovcJ3Kidt2gYVVf+2kGTvc
+skBWdIVWFgVYtNKNoy+5Y8qPMH+7QmuDA0gMt6mXdRJHL6p0Yy+yZLCZqeDoGjgU
+WvsrjeECgYEA6xxwS4w3qp2H8Fn1WmLOJo1EOieqRCvJLc/srHbmYxKOqEdzp/Lt
+uheZ1XpzsgLSPIaD3JnEj+8a7n7J0B6ZKkyoPBUTLLilm/qPe/+C7WKWaidhXVXJ
+q9Dmoyo9zLBSKqm0QJBCNEvZ7DT4RtyFL0Y0HWntIeBcrXAdfBss4NUCgYEAx5us
+axT6CoYPGqQZgorg3WgxAcA0WpbiyBdpFVsOycbpwWqQlqGLDNOvyjzyUSGMrGo3
+ObAsW6cOpKkapXfq2hTCbHupecm/4QYoDOPo7hAHwCuy/ODHJhzo5OM53n8EggFW
+XnomzvadKyAY9/+0fH2WZxns3EwKs5YO2fTtdaMCgYAWhaTkN8xlVa3eAmAUhn6F
+BudQQth2q1McRly/sKwlNXPg/uc/YXAQcY5U+uP2W3rUPXaIPVqtBxSnYBHpE+VM
+PgenqcUqdY23wWrZUAK0xsrt5FPZYwxsnxhY7QT6hLF6UMNpo+gTpmh7zh8yepFv
+k+QOJUWIBzwZiTHp35iO+QKBgHnzelvR7RIQ5Zl5OLyw7MFYrthK/bF7DgMBioop
+n9dXV+l7mertt26WxofgxIsc3D1ah3MPV4qHfkLLriP6J9olZMOyqdBmmnx4rm9x
+rxYDZTjbefdVvVZjw0ZULT7qi26CMqp2Js+7jDqU2axq5XJJqGJFTJkrPD6MJ3ay
+VYHRAoGAGG+rgP44tjwu0qmmUDfdp1tlMzUwVmM3pvjw1+RKYQprt+K3cUlBliPf
+VKMs9aQ0J6VrjrkNHTL85VzeOK6QYnsKZuski3GD0hA3XVE3u4SuMCb3Rmt6eLVr
+f9UGabwN9n5il3ZV7+qCmvpYGZzQ1A8+jZgbFWW3bp4BuIiwbbg=
+-----END RSA PRIVATE KEY-----
diff --git a/examples/wildfly/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer b/examples/wildfly/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer
new file mode 100644
index 00000000..8c9ce325
--- /dev/null
+++ b/examples/wildfly/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE9zCCA9+gAwIBAgIIVziKPglBFFAwDQYJKoZIhvcNAQEFBQAwggENMRswGQYK
+CZImiZPyLGQBGRYLTExBTUEuUEUgU0ExCzAJBgNVBAYTAlBFMQ0wCwYDVQQIDARM
+SU1BMQ0wCwYDVQQHDARMSU1BMRgwFgYDVQQKDA9UVSBFTVBSRVNBIFMuQS4xRTBD
+BgNVBAsMPEROSSA5OTk5OTk5IFJVQyAxMjM0NTY3ODkxMiAtIENFUlRJRklDQURP
+IFBBUkEgREVNT1NUUkFDScOTTjFEMEIGA1UEAww7Tk9NQlJFIFJFUFJFU0VOVEFO
+VEUgTEVHQUwgLSBDRVJUSUZJQ0FETyBQQVJBIERFTU9TVFJBQ0nDk04xHDAaBgkq
+hkiG9w0BCQEWDWRlbW9AbGxhbWEucGUwHhcNMjAxMTA0MjAyNTU1WhcNMjIxMTA0
+MjAyNTU1WjCCAQ0xGzAZBgoJkiaJk/IsZAEZFgtMTEFNQS5QRSBTQTELMAkGA1UE
+BhMCUEUxDTALBgNVBAgMBExJTUExDTALBgNVBAcMBExJTUExGDAWBgNVBAoMD1RV
+IEVNUFJFU0EgUy5BLjFFMEMGA1UECww8RE5JIDk5OTk5OTkgUlVDIDEyMzQ1Njc4
+OTEyIC0gQ0VSVElGSUNBRE8gUEFSQSBERU1PU1RSQUNJw5NOMUQwQgYDVQQDDDtO
+T01CUkUgUkVQUkVTRU5UQU5URSBMRUdBTCAtIENFUlRJRklDQURPIFBBUkEgREVN
+T1NUUkFDScOTTjEcMBoGCSqGSIb3DQEJARYNZGVtb0BsbGFtYS5wZTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALdSE9wrVrlTj9NwhXd40peMEzl5vE0T
+4TsgzbD0FOQPniViee7+R2PwBPWi2gUMZf1FdEK/8jMh1II9WTskbGLguHvF8z4l
+aR6j42aJwEYt20/q8v9X+JQZg6y2XbCSxhvcZxaAr9lxAtxbQpZ9QFFzBpgoSc4j
+Z5oab7UMAekjyCmUrXlVNbBFA3QvdTHWMGcRKI2M31uZtbHf6MC/7JUW96noB9mD
+4y1sdnTmUVlNy+Uzr+dHUs2TrD+gdZA3rCaQe4ipFCUaKt4nJsUBNQIwqJiDyrqD
+ysMGVLs3lJJIKE2wTS6XNpDA7tTNl95t5RfAmu6sIbyuasyn1PmFgJ8CAwEAAaNX
+MFUwHQYDVR0OBBYEFPxbUIr45L+Z3UITV2cp3yNjkm6qMB8GA1UdIwQYMBaAFPxb
+UIr45L+Z3UITV2cp3yNjkm6qMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3
+DQEBBQUAA4IBAQBIRHrTbqwpvdlohUzbuyMt/OOQMqhL7fQjML8zYVbP9YuSFSws
+qvYaA30WRRqEf1kvYdyc6E0zzV36EgegtHOBHQq3N+JX+VtLnLROB/O3YKnwqufn
+5BRMPG9WRgsLBVC1NybycCqTEJHyQn1d3oJ1U8c1NKx7CMez5/2h+NaPThBmjcwM
+NOTuJVzIOcDpEmSq4ZUDf29k1JZTh4AMtzn94+4usqVm0KGrlJ4Kiyp6NyTjCSJC
+KMPScfBdmvpkkvW+FM1InfXfrcmG6ImUKUfVT5FasuDKb0eQR5OouMCpHFEIULOp
+KccMCjEGHuTUKmLVKSXpt5y3dxH+hEBRaW2J
+-----END CERTIFICATE-----
diff --git a/examples/wildfly/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx b/examples/wildfly/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx
new file mode 100644
index 00000000..797e5433
Binary files /dev/null and b/examples/wildfly/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx differ
diff --git a/examples/wildfly/src/main/webapp/WEB-INF/beans.xml b/examples/wildfly/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 00000000..42454a1a
--- /dev/null
+++ b/examples/wildfly/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/wildfly/src/main/webapp/WEB-INF/web.xml b/examples/wildfly/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000..bee222cf
--- /dev/null
+++ b/examples/wildfly/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,12 @@
+
+
+
+ javax.ws.rs.core.Application
+ /api/*
+
+
diff --git a/examples/wildfly/src/main/webapp/css/styles.css b/examples/wildfly/src/main/webapp/css/styles.css
new file mode 100644
index 00000000..151a9f36
--- /dev/null
+++ b/examples/wildfly/src/main/webapp/css/styles.css
@@ -0,0 +1,3 @@
+.invalid {
+ color: red;
+}
diff --git a/examples/wildfly/src/main/webapp/index.html b/examples/wildfly/src/main/webapp/index.html
new file mode 100644
index 00000000..094efc2e
--- /dev/null
+++ b/examples/wildfly/src/main/webapp/index.html
@@ -0,0 +1,57 @@
+
+
+
+ HTML5 + REST Hello World
+
+
+
+
+
+XBuilder + REST create xml
+
+
+
+
+
diff --git a/examples/xbuilder/pom.xml b/examples/xbuilder/pom.xml
new file mode 100644
index 00000000..a0a32a4b
--- /dev/null
+++ b/examples/xbuilder/pom.xml
@@ -0,0 +1,22 @@
+
+
+ 4.0.0
+
+ io.github.project-openubl
+ examples-parent
+ 5.0.3-SNAPSHOT
+ ../pom.xml
+
+
+ xbuilder-example
+ Examples - XBuilder
+
+
+
+ io.github.project-openubl
+ xbuilder
+
+
+
diff --git a/examples/xbuilder/src/main/java/io/github/project/openubl/quickstart/xbuilder/Main.java b/examples/xbuilder/src/main/java/io/github/project/openubl/quickstart/xbuilder/Main.java
new file mode 100644
index 00000000..5bb032f2
--- /dev/null
+++ b/examples/xbuilder/src/main/java/io/github/project/openubl/quickstart/xbuilder/Main.java
@@ -0,0 +1,110 @@
+package io.github.project.openubl.quickstart.xbuilder;
+
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
+import io.github.project.openubl.xbuilder.content.models.common.Cliente;
+import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
+import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
+import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
+import io.github.project.openubl.xbuilder.enricher.ContentEnricher;
+import io.github.project.openubl.xbuilder.enricher.config.DateProvider;
+import io.github.project.openubl.xbuilder.enricher.config.Defaults;
+import io.github.project.openubl.xbuilder.renderer.TemplateProducer;
+import io.github.project.openubl.xbuilder.signature.CertificateDetails;
+import io.github.project.openubl.xbuilder.signature.CertificateDetailsFactory;
+import io.github.project.openubl.xbuilder.signature.XMLSigner;
+import io.github.project.openubl.xbuilder.signature.XmlSignatureHelper;
+import io.quarkus.qute.Template;
+import org.w3c.dom.Document;
+
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.time.LocalDate;
+
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+ // Create XML
+ String xml = createUnsignedXML();
+
+ System.out.println("Your XML is:");
+ System.out.println(xml);
+
+ // Sign XML
+ Document signedXML = signXML(xml);
+
+ byte[] bytesFromDocument = XmlSignatureHelper.getBytesFromDocument(signedXML);
+ String signedXMLString = new String(bytesFromDocument, StandardCharsets.ISO_8859_1);
+
+ System.out.println("\n Your signed XML is:");
+ System.out.println(signedXMLString);
+ }
+
+ public static String createUnsignedXML() {
+ // General config
+ Defaults defaults = Defaults.builder()
+ .icbTasa(new BigDecimal("0.2"))
+ .igvTasa(new BigDecimal("0.18"))
+ .build();
+
+ DateProvider dateProvider = () -> LocalDate.of(2019, 12, 24);
+
+ // Invoice generation
+ Invoice invoice = invoiceFactory();
+
+ // Enrich data
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(invoice);
+
+ // Generate XML
+ Template template = TemplateProducer.getInstance().getInvoice();
+ String xml = template.data(invoice).render();
+
+ return xml;
+ }
+
+ public static Document signXML(String xml) throws Exception {
+ InputStream ksInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx");
+ CertificateDetails certificate = CertificateDetailsFactory.create(ksInputStream, "password");
+
+ X509Certificate x509Certificate = certificate.getX509Certificate();
+ PrivateKey privateKey = certificate.getPrivateKey();
+ return XMLSigner.signXML(xml, "Project OpenUBL", x509Certificate, privateKey);
+ }
+
+ public static Invoice invoiceFactory() {
+ return Invoice
+ .builder()
+ .serie("F001")
+ .numero(1)
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build()
+ )
+ .cliente(Cliente.builder()
+ .nombre("Carlos Feria")
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build()
+ )
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build()
+ )
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item2")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build()
+ )
+ .build();
+ }
+
+}
diff --git a/examples/xbuilder/src/main/resources/CERTIFICADO CLAVE PRIVADA.key b/examples/xbuilder/src/main/resources/CERTIFICADO CLAVE PRIVADA.key
new file mode 100644
index 00000000..1d4416e6
--- /dev/null
+++ b/examples/xbuilder/src/main/resources/CERTIFICADO CLAVE PRIVADA.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAt1IT3CtWuVOP03CFd3jSl4wTOXm8TRPhOyDNsPQU5A+eJWJ5
+7v5HY/AE9aLaBQxl/UV0Qr/yMyHUgj1ZOyRsYuC4e8XzPiVpHqPjZonARi3bT+ry
+/1f4lBmDrLZdsJLGG9xnFoCv2XEC3FtCln1AUXMGmChJziNnmhpvtQwB6SPIKZSt
+eVU1sEUDdC91MdYwZxEojYzfW5m1sd/owL/slRb3qegH2YPjLWx2dOZRWU3L5TOv
+50dSzZOsP6B1kDesJpB7iKkUJRoq3icmxQE1AjComIPKuoPKwwZUuzeUkkgoTbBN
+Lpc2kMDu1M2X3m3lF8Ca7qwhvK5qzKfU+YWAnwIDAQABAoIBAFCX2PtWYk4fmn+O
+XF7l00+k2V7PUiVgtAhWp5c/9188Ln6pCIo1aBVblBKZgdfuV3g9bJtb35LzMIYB
+ipUhsjTWLsTbhdCwicJassKFlO5FgsFjvWjcuAAEJ4tqsU3LeSUOhJO0B5tEv8k4
+pdGbRweH1kJWk/v4PLfXH30sxjpELcEwyGjFUuKGKVFliwuLXVKlBijgrq2M+GCG
+1A7vO9O0JR3yGq4r8ERzJI0zNy62RzjLPF2bes0168ovcJ3Kidt2gYVVf+2kGTvc
+skBWdIVWFgVYtNKNoy+5Y8qPMH+7QmuDA0gMt6mXdRJHL6p0Yy+yZLCZqeDoGjgU
+WvsrjeECgYEA6xxwS4w3qp2H8Fn1WmLOJo1EOieqRCvJLc/srHbmYxKOqEdzp/Lt
+uheZ1XpzsgLSPIaD3JnEj+8a7n7J0B6ZKkyoPBUTLLilm/qPe/+C7WKWaidhXVXJ
+q9Dmoyo9zLBSKqm0QJBCNEvZ7DT4RtyFL0Y0HWntIeBcrXAdfBss4NUCgYEAx5us
+axT6CoYPGqQZgorg3WgxAcA0WpbiyBdpFVsOycbpwWqQlqGLDNOvyjzyUSGMrGo3
+ObAsW6cOpKkapXfq2hTCbHupecm/4QYoDOPo7hAHwCuy/ODHJhzo5OM53n8EggFW
+XnomzvadKyAY9/+0fH2WZxns3EwKs5YO2fTtdaMCgYAWhaTkN8xlVa3eAmAUhn6F
+BudQQth2q1McRly/sKwlNXPg/uc/YXAQcY5U+uP2W3rUPXaIPVqtBxSnYBHpE+VM
+PgenqcUqdY23wWrZUAK0xsrt5FPZYwxsnxhY7QT6hLF6UMNpo+gTpmh7zh8yepFv
+k+QOJUWIBzwZiTHp35iO+QKBgHnzelvR7RIQ5Zl5OLyw7MFYrthK/bF7DgMBioop
+n9dXV+l7mertt26WxofgxIsc3D1ah3MPV4qHfkLLriP6J9olZMOyqdBmmnx4rm9x
+rxYDZTjbefdVvVZjw0ZULT7qi26CMqp2Js+7jDqU2axq5XJJqGJFTJkrPD6MJ3ay
+VYHRAoGAGG+rgP44tjwu0qmmUDfdp1tlMzUwVmM3pvjw1+RKYQprt+K3cUlBliPf
+VKMs9aQ0J6VrjrkNHTL85VzeOK6QYnsKZuski3GD0hA3XVE3u4SuMCb3Rmt6eLVr
+f9UGabwN9n5il3ZV7+qCmvpYGZzQ1A8+jZgbFWW3bp4BuIiwbbg=
+-----END RSA PRIVATE KEY-----
diff --git a/examples/xbuilder/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer b/examples/xbuilder/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer
new file mode 100644
index 00000000..8c9ce325
--- /dev/null
+++ b/examples/xbuilder/src/main/resources/CERTIFICADO CLAVE PUBLICA SUNAT.cer
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE9zCCA9+gAwIBAgIIVziKPglBFFAwDQYJKoZIhvcNAQEFBQAwggENMRswGQYK
+CZImiZPyLGQBGRYLTExBTUEuUEUgU0ExCzAJBgNVBAYTAlBFMQ0wCwYDVQQIDARM
+SU1BMQ0wCwYDVQQHDARMSU1BMRgwFgYDVQQKDA9UVSBFTVBSRVNBIFMuQS4xRTBD
+BgNVBAsMPEROSSA5OTk5OTk5IFJVQyAxMjM0NTY3ODkxMiAtIENFUlRJRklDQURP
+IFBBUkEgREVNT1NUUkFDScOTTjFEMEIGA1UEAww7Tk9NQlJFIFJFUFJFU0VOVEFO
+VEUgTEVHQUwgLSBDRVJUSUZJQ0FETyBQQVJBIERFTU9TVFJBQ0nDk04xHDAaBgkq
+hkiG9w0BCQEWDWRlbW9AbGxhbWEucGUwHhcNMjAxMTA0MjAyNTU1WhcNMjIxMTA0
+MjAyNTU1WjCCAQ0xGzAZBgoJkiaJk/IsZAEZFgtMTEFNQS5QRSBTQTELMAkGA1UE
+BhMCUEUxDTALBgNVBAgMBExJTUExDTALBgNVBAcMBExJTUExGDAWBgNVBAoMD1RV
+IEVNUFJFU0EgUy5BLjFFMEMGA1UECww8RE5JIDk5OTk5OTkgUlVDIDEyMzQ1Njc4
+OTEyIC0gQ0VSVElGSUNBRE8gUEFSQSBERU1PU1RSQUNJw5NOMUQwQgYDVQQDDDtO
+T01CUkUgUkVQUkVTRU5UQU5URSBMRUdBTCAtIENFUlRJRklDQURPIFBBUkEgREVN
+T1NUUkFDScOTTjEcMBoGCSqGSIb3DQEJARYNZGVtb0BsbGFtYS5wZTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALdSE9wrVrlTj9NwhXd40peMEzl5vE0T
+4TsgzbD0FOQPniViee7+R2PwBPWi2gUMZf1FdEK/8jMh1II9WTskbGLguHvF8z4l
+aR6j42aJwEYt20/q8v9X+JQZg6y2XbCSxhvcZxaAr9lxAtxbQpZ9QFFzBpgoSc4j
+Z5oab7UMAekjyCmUrXlVNbBFA3QvdTHWMGcRKI2M31uZtbHf6MC/7JUW96noB9mD
+4y1sdnTmUVlNy+Uzr+dHUs2TrD+gdZA3rCaQe4ipFCUaKt4nJsUBNQIwqJiDyrqD
+ysMGVLs3lJJIKE2wTS6XNpDA7tTNl95t5RfAmu6sIbyuasyn1PmFgJ8CAwEAAaNX
+MFUwHQYDVR0OBBYEFPxbUIr45L+Z3UITV2cp3yNjkm6qMB8GA1UdIwQYMBaAFPxb
+UIr45L+Z3UITV2cp3yNjkm6qMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3
+DQEBBQUAA4IBAQBIRHrTbqwpvdlohUzbuyMt/OOQMqhL7fQjML8zYVbP9YuSFSws
+qvYaA30WRRqEf1kvYdyc6E0zzV36EgegtHOBHQq3N+JX+VtLnLROB/O3YKnwqufn
+5BRMPG9WRgsLBVC1NybycCqTEJHyQn1d3oJ1U8c1NKx7CMez5/2h+NaPThBmjcwM
+NOTuJVzIOcDpEmSq4ZUDf29k1JZTh4AMtzn94+4usqVm0KGrlJ4Kiyp6NyTjCSJC
+KMPScfBdmvpkkvW+FM1InfXfrcmG6ImUKUfVT5FasuDKb0eQR5OouMCpHFEIULOp
+KccMCjEGHuTUKmLVKSXpt5y3dxH+hEBRaW2J
+-----END CERTIFICATE-----
diff --git a/examples/xbuilder/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx b/examples/xbuilder/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx
new file mode 100644
index 00000000..797e5433
Binary files /dev/null and b/examples/xbuilder/src/main/resources/LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx differ
diff --git a/examples/xsender/pom.xml b/examples/xsender/pom.xml
new file mode 100644
index 00000000..e67936a8
--- /dev/null
+++ b/examples/xsender/pom.xml
@@ -0,0 +1,22 @@
+
+
+ 4.0.0
+
+ io.github.project-openubl
+ examples-parent
+ 5.0.3-SNAPSHOT
+ ../pom.xml
+
+
+ xsender-example
+ Examples - XSender
+
+
+
+ io.github.project-openubl
+ xsender
+
+
+
diff --git a/examples/xsender/src/main/java/io/github/project/openubl/quickstart/xsender/Main.java b/examples/xsender/src/main/java/io/github/project/openubl/quickstart/xsender/Main.java
new file mode 100644
index 00000000..b2dca27e
--- /dev/null
+++ b/examples/xsender/src/main/java/io/github/project/openubl/quickstart/xsender/Main.java
@@ -0,0 +1,59 @@
+package io.github.project.openubl.quickstart.xsender;
+
+import io.github.project.openubl.xsender.Constants;
+import io.github.project.openubl.xsender.camel.StandaloneCamel;
+import io.github.project.openubl.xsender.camel.utils.CamelData;
+import io.github.project.openubl.xsender.camel.utils.CamelUtils;
+import io.github.project.openubl.xsender.company.CompanyCredentials;
+import io.github.project.openubl.xsender.company.CompanyURLs;
+import io.github.project.openubl.xsender.files.BillServiceFileAnalyzer;
+import io.github.project.openubl.xsender.files.BillServiceXMLFileAnalyzer;
+import io.github.project.openubl.xsender.files.ZipFile;
+import io.github.project.openubl.xsender.models.SunatResponse;
+import io.github.project.openubl.xsender.sunat.BillServiceDestination;
+import org.apache.camel.CamelContext;
+
+import java.io.File;
+import java.nio.file.Paths;
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ CompanyURLs companyURLs = CompanyURLs.builder()
+ .invoice("https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService")
+ .perceptionRetention("https://e-beta.sunat.gob.pe/ol-ti-itemision-otroscpe-gem-beta/billService")
+ .despatch("https://api-cpe.sunat.gob.pe/v1/contribuyente/gem")
+ .build();
+
+ CompanyCredentials credentials = CompanyCredentials.builder()
+ .username("12345678959MODDATOS")
+ .password("MODDATOS")
+ .build();
+
+ File xml = Paths.get(Main.class.getClassLoader().getResource("invoice.xml").toURI()).toFile();
+ BillServiceFileAnalyzer fileAnalyzer = new BillServiceXMLFileAnalyzer(xml, companyURLs);
+
+ // Archivo ZIP
+ ZipFile zipFile = fileAnalyzer.getZipFile();
+
+ // Configuración para enviar xml y Configuración para consultar ticket
+ BillServiceDestination fileDestination = fileAnalyzer.getSendFileDestination();
+ BillServiceDestination ticketDestination = fileAnalyzer.getVerifyTicketDestination();
+
+ // Send file
+ CamelContext camelContext = StandaloneCamel.getInstance()
+ .getMainCamel()
+ .getCamelContext();
+
+ CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, fileDestination, credentials);
+
+ SunatResponse sendFileSunatResponse = camelContext.createProducerTemplate()
+ .requestBodyAndHeaders(
+ Constants.XSENDER_BILL_SERVICE_URI,
+ camelData.getBody(),
+ camelData.getHeaders(),
+ SunatResponse.class
+ );
+
+ System.out.println("SUNAT status: " + sendFileSunatResponse.getStatus());
+ }
+}
diff --git a/examples/xsender/src/main/resources/invoice.xml b/examples/xsender/src/main/resources/invoice.xml
new file mode 100644
index 00000000..25bcb678
--- /dev/null
+++ b/examples/xsender/src/main/resources/invoice.xml
@@ -0,0 +1,159 @@
+
+
+
+
+ nGXHhWrjhVfXVnm1i1RRP7c6mUY=aUHCPyZLFnKtA3vDBbVVoPcbtW/Dgj8xDza4m0Uu+3pgPWgkaqWTfM7RSH91i9kHlT5Ou88pAeU1
+mv5pFayEoH/gVImxyc6OKDMRmVf0FKVf9xZzOkuXYT2TZmXC8FgJGegOUum+sgdMB6VM66TEDXOy
+qhr6qOC8HqZIbRDacArClg5g4GtWBCXL6Mdt15/6I+JvzNb7/7xcaRrh+E2JyZcAGcB1knKwkZd4
+AMpMuCsXaWfDdTssOPcT+CpqNb93eW/6q88ZxQh+D057uBMaAf9EhOzM6QQkirVygrgnJuMaE6JF
+/gSbXYtqRGH3vszSljqWothGfd0GCKYBmE/SXg==MIICmzCCAYMCBgFxQLzLUjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjAw
+NDAzMTU0OTA2WhcNMzAwNDAzMTU1MDQ2WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCBFvkmIdnA8xd4LlEPigj/bcSYJg1KKgARd/QmTlcW80TLuYJ0
+FZuvXpf26iIT9HbkKTEkbaCqA+vCz5gIXhSiKaKuwy8FE0sagxVr93mfT/MK0x4yxijE4gyhQcY5
+4n9wQ0XaEygZT3tSm5iEgZQrcjWHAxYvfS9zGJcdumU2Q3A/wvdjiBQtMyRdYnH9bZje6EIlES/M
+SK/GwHEGNgi4j0rkpVFRSGxlYYlAj97DrX681eg6FzADWsVfFwgmHFAO4uDuT1E1SbHay3yC7d6f
+tWhD0BCe8ZC6XikVVgdcLRn8oIYNjIv9QxmnbbP0OsKUHTonj/5trxWezhwQIPuHAgMBAAEwDQYJ
+KoZIhvcNAQELBQADggEBACnf3I29sFwIV5xpxOvDNYHDapvH366kX1yBGKqnTIyWvz0bEeRuYmOa
+v0UN8gCJg+pJxoYc5NXURxTlqsj3XLirRTBW3rZJZWoING3RthU+lAMyC5Ao9rJEhNftxgSAc+DW
+5T31JR+Du6V8BnFjyTML3ZPz3QtJwC2IpaFExqjrxodWuiC6c8FtHoPZRp5QfBjdVbDN9kC9YzrP
+UkvotM3GiZNB1XrAsvxYmDa3J8ASCRJ11aGMoGkoGYQ4hGfCQBG7DDkq1REbetwE9oqUaHuTTPGi
+z3QCqD69SPpu1QuTS86iQ5dYxK70uE47yH0erb0UQ5+dNH5OMSjO8mQdGtw=
+
+
+ 2.1
+ 2.0
+ B001-1
+ 2020-03-28
+ 12:21:49
+ 03
+ PEN
+
+ 12312312312
+
+
+ 12312312312
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+
+
+ 12345678912
+
+
+ mi nombre comercial
+
+
+
+
+ 050101
+ 123456
+ Las Flores
+ Huamanga
+ Ayacucho
+ Mariscal Caceres
+
+
+
+
+ PE
+
+
+
+
+ +051 123 456 789
+ email@gmail.com
+
+
+
+
+
+
+ 12345678
+
+
+
+
+ 050101
+ 123456
+ Las Flores
+ Huamanga
+ Ayacucho
+ Mariscal Caceres
+
+
+
+
+ PE
+
+
+
+
+ +051 123 456 789
+ email@gmail.com
+
+
+
+
+ 1.8
+
+ 10
+ 1.8
+
+ S
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+ 10
+ 11.8
+ 11.8
+
+
+ 1
+ 1
+ 10
+
+
+ 11.8
+ 01
+
+
+
+ 1.8
+
+ 10
+ 1.8
+
+ S
+ 18
+ 10
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+
+
+
+ 10
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 5fe75d30..95abd883 100644
--- a/pom.xml
+++ b/pom.xml
@@ -145,6 +145,8 @@
projectopenubl+subscribe@googlegroups.com
**/*.java
+ **/*.xml
+ **/*.properties
@@ -281,6 +283,13 @@
+
+
+ examples
+
+ examples
+
+