package hu.user.lis.workflow;
-import hu.gov.nav.schemas.osa._3_0.api.InvoiceDirectionType;
-import hu.gov.nav.schemas.osa._3_0.api.QueryInvoiceDigestRequest;
-import hu.gov.nav.schemas.osa._3_0.api.QueryInvoiceDigestResponse;
+import hu.gov.nav.schemas.ntca._1_0.common.BasicResultType;
+import hu.gov.nav.schemas.ntca._1_0.common.FunctionCodeType;
+import hu.gov.nav.schemas.osa._3_0.api.*;
+import hu.gov.nav.schemas.osa._3_0.data.InvoiceData;
import hu.user.lis.service.nav.TaxOfficeInvoiceService;
import hu.user.lis.service.nav.TaxOfficeRequestBuilder;
import hu.user.lis.service.nav.TaxOfficeXmlConverter;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Collections;
+import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@Test
public void testWithConnector() throws Exception {
- Optional<QueryInvoiceDigestResponse> response = taxOfficeInvoiceService.queryInboundInvoices(1);
- response.ifPresent(queryInvoiceDigestResponse -> log.info("Response: {}", taxOfficeXmlConverter.toXml(queryInvoiceDigestResponse)));
+ int availablePages = 1;
+ int currentPage = 1;
+ while (currentPage <= availablePages) {
+ Optional<QueryInvoiceDigestResponse> response = taxOfficeInvoiceService.queryInboundInvoices(currentPage);
+ if (!response.isPresent()) {
+ break;
+ }
+
+ Optional<FunctionCodeType> functionCode = response
+ .map(QueryInvoiceDigestResponse::getResult)
+ .map(BasicResultType::getFuncCode);
+
+ if (functionCode.isPresent() && FunctionCodeType.OK.equals(functionCode.get())) {
+ if (currentPage == 1) {
+ availablePages = response
+ .map(QueryInvoiceDigestResponse::getInvoiceDigestResult)
+ .map(InvoiceDigestResultType::getAvailablePage).orElse(0);
+ }
+
+ Optional<List<InvoiceDigestType>> invoiceList = response
+ .map(QueryInvoiceDigestResponse::getInvoiceDigestResult)
+ .map(InvoiceDigestResultType::getInvoiceDigest);
+
+ if (invoiceList.isPresent()) {
+ for (InvoiceDigestType invoiceDigest : invoiceList.get()) {
+ String invoiceNumber = invoiceDigest.getInvoiceNumber();
+ String supplierTaxNumber = invoiceDigest.getSupplierTaxNumber();
+ Optional<InvoiceData> invoiceData = taxOfficeInvoiceService.queryInboundInvoiceData(invoiceNumber, supplierTaxNumber);
+ invoiceData.ifPresent(invoice -> log.info("Found invoice: {}", taxOfficeXmlConverter.toXml(invoice)));
+ }
+ }
+ }
+ currentPage++;
+ }
}
}
\ No newline at end of file
import java.security.cert.CertificateException;
@Configuration
-public class CustomRestTemplateConfiguration {
+public class RestTemplateSSLConfiguration {
@Value("${service.nav.trust.store}")
private Resource trustStore;
package hu.user.lis.service.nav;
-import hu.gov.nav.schemas.osa._3_0.api.InvoiceDirectionType;
-import hu.gov.nav.schemas.osa._3_0.api.QueryInvoiceDigestRequest;
-import hu.gov.nav.schemas.osa._3_0.api.QueryInvoiceDigestResponse;
+import hu.gov.nav.schemas.osa._3_0.api.*;
+import hu.gov.nav.schemas.osa._3_0.data.InvoiceData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
import java.util.Optional;
+import java.util.zip.GZIPInputStream;
@Service
public class TaxOfficeInvoiceService {
-
@Autowired
TaxOfficeRequestBuilder taxOfficeRequestBuilder;
@Autowired
TaxOfficeConnector taxOfficeConnector;
+ private String decompress(byte[] bytes) throws Exception {
+ final StringBuilder builder = new StringBuilder();
+ try (GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes));
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8))) {
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ builder.append(line);
+ }
+ }
+ return builder.toString();
+ }
+
public Optional<QueryInvoiceDigestResponse> queryInboundInvoices(int page) throws Exception {
- QueryInvoiceDigestRequest queryRequest = taxOfficeRequestBuilder.requestInvoiceDigest();
- queryRequest.setPage(page);
- queryRequest.setInvoiceDirection(InvoiceDirectionType.INBOUND);
- queryRequest.setInvoiceQueryParams(taxOfficeRequestBuilder.params());
+ QueryInvoiceDigestRequest request = taxOfficeRequestBuilder.requestInvoiceDigest();
+ request.setPage(page);
+ request.setInvoiceDirection(InvoiceDirectionType.INBOUND);
+ request.setInvoiceQueryParams(taxOfficeRequestBuilder.params());
WebClient.RequestBodySpec bodySpec = taxOfficeConnector.getClient().post().uri("/queryInvoiceDigest");
- WebClient.RequestHeadersSpec<?> headersSpec = bodySpec.bodyValue(taxOfficeXmlConverter.toXml(queryRequest));
+ WebClient.RequestHeadersSpec<?> headersSpec = bodySpec.bodyValue(taxOfficeXmlConverter.toXml(request));
Mono<String> responseMono = headersSpec.retrieve().bodyToMono(String.class);
return taxOfficeXmlConverter.fromXml(responseMono.block(), QueryInvoiceDigestResponse.class);
}
+ public Optional<InvoiceData> queryInboundInvoiceData(String invoiceNumber, String supplierTaxNumber) throws Exception {
+ InvoiceNumberQueryType query = new InvoiceNumberQueryType();
+ query.setInvoiceDirection(InvoiceDirectionType.INBOUND);
+ query.setInvoiceNumber(invoiceNumber);
+ query.setSupplierTaxNumber(supplierTaxNumber);
+
+ QueryInvoiceDataRequest queryRequest = taxOfficeRequestBuilder.requestInvoiceData();
+ queryRequest.setInvoiceNumberQuery(query);
+
+ WebClient.RequestBodySpec bodySpec = taxOfficeConnector.getClient().post().uri("/queryInvoiceData");
+ WebClient.RequestHeadersSpec<?> headersSpec = bodySpec.bodyValue(taxOfficeXmlConverter.toXml(queryRequest));
+ Mono<String> responseMono = headersSpec.retrieve().bodyToMono(String.class);
+ Optional<QueryInvoiceDataResponse> response = taxOfficeXmlConverter.fromXml(responseMono.block(), QueryInvoiceDataResponse.class);
+// invoiceData: A számla adatai BASE64 kódolásban
+// compressedContentIndicator: Jelöli, ha az invoiceData tartalmát a BASE64 dekódolást követően még ki kell tömöríteni az olvasáshoz
+// Base64 base64 = new Base64();
+// String decodedString = new String(base64.decode(invoiceBytes));
+ byte[] invoiceBytes = response
+ .map(QueryInvoiceDataResponse::getInvoiceDataResult)
+ .map(InvoiceDataResultType::getInvoiceData)
+ .orElseThrow(NullPointerException::new);
+
+ boolean isDataCompressed = response
+ .map(QueryInvoiceDataResponse::getInvoiceDataResult)
+ .map(InvoiceDataResultType::isCompressedContentIndicator)
+ .orElse(false);
+
+ String invoiceData;
+ if (isDataCompressed) {
+ invoiceData = decompress(invoiceBytes);
+ } else {
+ invoiceData = new String(invoiceBytes);
+ }
+ return taxOfficeXmlConverter.fromXml(invoiceData, InvoiceData.class);
+ }
+
}
Az így és sorrendben konkatenált string nagybetűs SHA3-512 hash eredménye lesz a requestSignature
értéke.
*/
- private void calculateSimpleRequestSignature(QueryInvoiceDigestRequest request) {
- ZonedDateTime zdt = request.getHeader().getTimestamp().toGregorianCalendar().toZonedDateTime();
+ private void calculateSimpleRequestSignature(BasicHeaderType header, UserHeaderType user) {
+ ZonedDateTime zdt = header.getTimestamp().toGregorianCalendar().toZonedDateTime();
ZonedDateTime zdtUTC = zdt.withZoneSameInstant(ZoneOffset.UTC);
- String rsSignature = request.getHeader().getRequestId() +
+ String rsSignature = header.getRequestId() +
DATE_TIME_FORMATTER.format(zdtUTC) +
signKey;
CryptoType reqCryptoType = new CryptoType();
reqCryptoType.setCryptoType("SHA3-512");
reqCryptoType.setValue(sha3_512Hex(rsSignature).toUpperCase());
- request.getUser().setRequestSignature(reqCryptoType);
+ user.setRequestSignature(reqCryptoType);
}
/* Java 9 fölött már támogatott 3rd party nélkül is*/
result.setHeader(header());
result.setUser(user());
result.setSoftware(software());
- calculateSimpleRequestSignature(result);
+ calculateSimpleRequestSignature(result.getHeader(), result.getUser());
return result;
}
+ public QueryInvoiceDataRequest requestInvoiceData() throws DatatypeConfigurationException {
+ QueryInvoiceDataRequest result = new QueryInvoiceDataRequest();
+ result.setHeader(header());
+ result.setUser(user());
+ result.setSoftware(software());
+ calculateSimpleRequestSignature(result.getHeader(), result.getUser());
+ return result;
+ }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-import java.nio.file.Paths;
import java.util.Optional;
@Log4j2
public class DownloadInvoiceData implements JavaDelegate {
@Autowired
- PartnerRepository partnerRepository;
+ private PartnerRepository partnerRepository;
@Autowired
- IncomingInvoiceFetcherService incomingInvoiceFetcherService;
+ private IncomingInvoiceFetcherService incomingInvoiceFetcherService;
+
+// @Override
+// public void execute(DelegateExecution delegateExecution) throws Exception {
+// String invoiceId = (String) delegateExecution.getVariable("invoice");
+// log.info("Processing invoice {}", invoiceId);
+// IncomingInvoice invoice = incomingInvoiceFetcherService.getInvoiceFromPath(Paths.get(invoiceId));
+// Optional<Partner> partnerEntity = partnerRepository.findByVatNr(invoice.getPartner().getVatNr());
+// partnerEntity.ifPresent(invoice::setPartner);
+// delegateExecution.setVariableLocal("invoiceEntity", invoice);
+// log.info("Invoice {} processed", invoiceId);
+// }
@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
- String invoiceId = (String) delegateExecution.getVariable("invoice");
- log.info("Processing invoice {}", invoiceId);
- IncomingInvoice invoice = incomingInvoiceFetcherService.getInvoiceFromPath(Paths.get(invoiceId));
+ String invoiceXml = (String) delegateExecution.getVariable("invoice");
+ log.info("Processing invoice {}", invoiceXml);
+ IncomingInvoice invoice = incomingInvoiceFetcherService.getInvoiceDataOnline(invoiceXml);
Optional<Partner> partnerEntity = partnerRepository.findByVatNr(invoice.getPartner().getVatNr());
partnerEntity.ifPresent(invoice::setPartner);
delegateExecution.setVariableLocal("invoiceEntity", invoice);
- log.info("Invoice {} processed", invoiceId);
+ log.info("Invoice {} processed", invoiceXml);
}
-
}
package hu.user.lis.workflow.invoice;
import hu.user.lis.workflow.invoice.service.IncomingInvoiceFetcherService;
-import hu.user.lis.workflow.properties.WorkflowProperties;
import lombok.extern.log4j.Log4j2;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.List;
@Log4j2
@Component
public class ListNewInvoices implements JavaDelegate {
- @Autowired
- WorkflowProperties workflowProperties;
+// @Autowired
+// private WorkflowProperties workflowProperties;
@Autowired
- IncomingInvoiceFetcherService incomingInvoiceFetcherService;
+ private IncomingInvoiceFetcherService incomingInvoiceFetcherService;
+
+// @Override
+// public void execute(DelegateExecution delegateExecution) throws Exception {
+// log.info("Executing");
+// Path inputPath = Paths.get(workflowProperties.getImportInvoice().getInputPath());
+// List<String> invoices = incomingInvoiceFetcherService.getNewInvoicesFromPath(inputPath);
+//
+// delegateExecution.setVariableLocal("invoices", invoices);
+// }
@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
log.info("Executing");
- Path inputPath = Paths.get(workflowProperties.getImportInvoice().getInputPath());
- List<String> invoices = incomingInvoiceFetcherService.getNewInvoicesFromPath(inputPath);
+ List<String> invoices = incomingInvoiceFetcherService.getNewInvoicesOnline();
delegateExecution.setVariableLocal("invoices", invoices);
}
+
}
package hu.user.lis.workflow.invoice.service;
+import hu.gov.nav.schemas.ntca._1_0.common.BasicResultType;
+import hu.gov.nav.schemas.ntca._1_0.common.FunctionCodeType;
+import hu.gov.nav.schemas.osa._3_0.api.InvoiceDigestResultType;
+import hu.gov.nav.schemas.osa._3_0.api.InvoiceDigestType;
+import hu.gov.nav.schemas.osa._3_0.api.QueryInvoiceDigestResponse;
+import hu.gov.nav.schemas.osa._3_0.data.InvoiceData;
import hu.user.lis.db.Currency;
import hu.user.lis.db.IncomingInvoice;
import hu.user.lis.db.Partner;
import hu.user.lis.db.repository.PartnerRepository;
import hu.user.lis.service.data.DataGeneratorService;
import hu.user.lis.service.nav.TaxOfficeDataConverter;
+import hu.user.lis.service.nav.TaxOfficeInvoiceService;
+import hu.user.lis.service.nav.TaxOfficeXmlConverter;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Autowired
private TaxOfficeDataConverter taxOfficeDataConverter;
+ @Autowired
+ private TaxOfficeInvoiceService taxOfficeInvoiceService;
+
+ @Autowired
+ private TaxOfficeXmlConverter taxOfficeXmlConverter;
+
public List<String> getNewInvoices() {
return Arrays.asList("Invoice-test-1", "Invoice-test-2", "Invoice-test-3");
}
List<Partner> partners = partnerRepository.findAll();
return partners.get(RandomUtils.nextInt(0, partners.size()));
}
+
+ public IncomingInvoice getInvoiceDataOnline(String invoiceDigestInfo) throws Exception {
+ String[] tokens = invoiceDigestInfo.split(",");
+ String invoiceNumber = tokens[0];
+ String supplierTaxNumber = tokens[1];
+ InvoiceData invoiceData = taxOfficeInvoiceService.queryInboundInvoiceData(invoiceNumber, supplierTaxNumber).orElseThrow(NullPointerException::new);
+ String invoiceXml = taxOfficeXmlConverter.toXml(invoiceData);
+ IncomingInvoice result = taxOfficeDataConverter.getIncomingInvoice(invoiceXml);
+ Partner partner = taxOfficeDataConverter.getPartner(invoiceXml);
+ result.setPartner(partner);
+ return result;
+ }
+
+ public List<String> getNewInvoicesOnline() throws Exception {
+ List<String> result = new ArrayList<>();
+ int availablePages = 1;
+ int currentPage = 1;
+ while (currentPage <= availablePages) {
+ Optional<QueryInvoiceDigestResponse> response = taxOfficeInvoiceService.queryInboundInvoices(currentPage);
+ if (!response.isPresent()) {
+ break;
+ }
+
+ Optional<FunctionCodeType> functionCode = response
+ .map(QueryInvoiceDigestResponse::getResult)
+ .map(BasicResultType::getFuncCode);
+
+ if (functionCode.isPresent() && FunctionCodeType.OK.equals(functionCode.get())) {
+ if (currentPage == 1) {
+ availablePages = response
+ .map(QueryInvoiceDigestResponse::getInvoiceDigestResult)
+ .map(InvoiceDigestResultType::getAvailablePage).orElse(0);
+ }
+
+ Optional<List<InvoiceDigestType>> invoiceList = response
+ .map(QueryInvoiceDigestResponse::getInvoiceDigestResult)
+ .map(InvoiceDigestResultType::getInvoiceDigest);
+
+ if (invoiceList.isPresent()) {
+ for (InvoiceDigestType invoiceDigest : invoiceList.get()) {
+ String invoiceNumber = invoiceDigest.getInvoiceNumber();
+ String supplierTaxNumber = invoiceDigest.getSupplierTaxNumber();
+ result.add(String.format("%s,%s", invoiceNumber, supplierTaxNumber));
+ }
+ }
+ }
+ currentPage++;
+ }
+ return result;
+ }
}