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) + +![Screenshot](./screenshot.png) 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
+ +
+
+

+ Select a file : +

+ + +
+
+ + + 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
+ +
+
+

+ Select a file : +

+ + +
+
+ + + 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 + +