impvore e-invoice format
This commit is contained in:
parent
2b997da394
commit
0d9c9d8615
6 changed files with 471 additions and 56 deletions
|
|
@ -33,6 +33,10 @@ import org.imixs.workflow.engine.WorkflowService;
|
||||||
import org.imixs.workflow.exceptions.AdapterException;
|
import org.imixs.workflow.exceptions.AdapterException;
|
||||||
import org.imixs.workflow.exceptions.PluginException;
|
import org.imixs.workflow.exceptions.PluginException;
|
||||||
import org.imixs.workflow.util.XMLParser;
|
import org.imixs.workflow.util.XMLParser;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
import com.alexanderlogistics.BusinessPartnerService;
|
import com.alexanderlogistics.BusinessPartnerService;
|
||||||
import com.alexanderlogistics.InvoiceUtil;
|
import com.alexanderlogistics.InvoiceUtil;
|
||||||
|
|
@ -143,51 +147,6 @@ public class EInvoiceAdapter implements SignalAdapter {
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * This helper method tries to find the pdf file matching the item
|
|
||||||
// * 'cargosoft.import.filename'. If not found the method returns the first .pdf
|
|
||||||
// * file form the list of attachments. The method returns null if no pdf file
|
|
||||||
// * exits
|
|
||||||
// *
|
|
||||||
// * @param workitem
|
|
||||||
// * @return the pdf FileData object
|
|
||||||
// * @throws PluginException if not pdf file was found
|
|
||||||
// */
|
|
||||||
// private FileData loadPDF(ItemCollection workitem) throws PluginException {
|
|
||||||
// FileData pdfFileData = null;
|
|
||||||
// String cargosoftFileName =
|
|
||||||
// workitem.getItemValueString("cargosoft.import.filename");
|
|
||||||
// if (!cargosoftFileName.isEmpty()) {
|
|
||||||
// cargosoftFileName = cargosoftFileName.replace(".xml", ".pdf");
|
|
||||||
|
|
||||||
// // try to load filedata....
|
|
||||||
// pdfFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(),
|
|
||||||
// cargosoftFileName);
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (pdfFileData == null) {
|
|
||||||
// // take first pdf file available
|
|
||||||
// List<String> fileNames = workitem.getFileNames();
|
|
||||||
// for (String filename : fileNames) {
|
|
||||||
|
|
||||||
// if (filename.toLowerCase().endsWith(".pdf")) {
|
|
||||||
// pdfFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(),
|
|
||||||
// filename);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (pdfFileData == null) {
|
|
||||||
// throw new PluginException(EInvoiceAdapter.class.getSimpleName(),
|
|
||||||
// DOCUMENT_ERROR,
|
|
||||||
// "DOCUMENT_ERROR: no pdf file found!");
|
|
||||||
// }
|
|
||||||
// return pdfFileData;
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
private FileData embeddXML(FileData pdfFileData, FileData xmlFileData) throws PluginException {
|
private FileData embeddXML(FileData pdfFileData, FileData xmlFileData) throws PluginException {
|
||||||
try {
|
try {
|
||||||
PDDocument document = PDDocument.load(pdfFileData.getContent());
|
PDDocument document = PDDocument.load(pdfFileData.getContent());
|
||||||
|
|
@ -250,13 +209,16 @@ public class EInvoiceAdapter implements SignalAdapter {
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
private void updateEInvoice(FileData fileDataXMLTemplate, ItemCollection workitem) throws PluginException {
|
public void updateEInvoice(FileData fileDataXMLTemplate, ItemCollection workitem) throws PluginException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
EInvoiceModel model = EInvoiceModelFactory.read(new ByteArrayInputStream(fileDataXMLTemplate.getContent()));
|
EInvoiceModel model = EInvoiceModelFactory.read(new ByteArrayInputStream(fileDataXMLTemplate.getContent()));
|
||||||
|
|
||||||
model.setId(workitem.getItemValueString("invoice.number"));
|
model.setId(workitem.getItemValueString("invoice.number"));
|
||||||
|
// Currency
|
||||||
|
model.setCurrency(workitem.getItemValueString("invoice.currency"));
|
||||||
|
// BR-DE-15: BuyerReference (BT-10) is mandatory, but we have no real reference
|
||||||
|
model.setBuyerReference("n/a");
|
||||||
// Update Rechnungssummen...
|
// Update Rechnungssummen...
|
||||||
if (workitem.getItemValueDouble("invoice.total.tax") > 0) {
|
if (workitem.getItemValueDouble("invoice.total.tax") > 0) {
|
||||||
// wir haben eine Steuer!
|
// wir haben eine Steuer!
|
||||||
|
|
@ -275,7 +237,7 @@ public class EInvoiceAdapter implements SignalAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Summenbildung
|
// // Summenbildung
|
||||||
model.setNetTotalAmount(workitem.getItemValueDouble("invoice.total"));
|
model.setNetTotalAmount(workitem.getItemValueDouble("invoice.total.net"));
|
||||||
model.setGrandTotalAmount(workitem.getItemValueDouble("invoice.total"));
|
model.setGrandTotalAmount(workitem.getItemValueDouble("invoice.total"));
|
||||||
|
|
||||||
// date
|
// date
|
||||||
|
|
@ -292,6 +254,13 @@ public class EInvoiceAdapter implements SignalAdapter {
|
||||||
// References><Reference type="cs">AB230321</Reference>
|
// References><Reference type="cs">AB230321</Reference>
|
||||||
// model.setOrderReferenceId(workitem.getItemValueString("order.number"));
|
// model.setOrderReferenceId(workitem.getItemValueString("order.number"));
|
||||||
|
|
||||||
|
// Strip all XML comments from the document...
|
||||||
|
stripComments(model.getRoot().getOwnerDocument());
|
||||||
|
|
||||||
|
// Remove empty template placeholder elements (e.g. <ram:PersonName/>)
|
||||||
|
// that were never populated by the adapter.
|
||||||
|
// stripEmptyElements(model.getRoot());
|
||||||
|
|
||||||
// finally update the template file
|
// finally update the template file
|
||||||
fileDataXMLTemplate.setContent(model.getContent());
|
fileDataXMLTemplate.setContent(model.getContent());
|
||||||
|
|
||||||
|
|
@ -327,6 +296,12 @@ public class EInvoiceAdapter implements SignalAdapter {
|
||||||
tradeParty.setPostcodeCode(businessPartner.getItemValueString("partner.zip"));
|
tradeParty.setPostcodeCode(businessPartner.getItemValueString("partner.zip"));
|
||||||
tradeParty.setStreetAddress(businessPartner.getItemValueString("partner.address"));
|
tradeParty.setStreetAddress(businessPartner.getItemValueString("partner.address"));
|
||||||
|
|
||||||
|
// CII-SR-314: SpecifiedTaxRegistration should not be present on
|
||||||
|
// ShipToTradeParty
|
||||||
|
if (!"ship_to".equals(type)) {
|
||||||
|
tradeParty.setVatNumber(businessPartner.getItemValueString("partner.vat"));
|
||||||
|
}
|
||||||
|
|
||||||
return tradeParty;
|
return tradeParty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,10 +319,95 @@ public class EInvoiceAdapter implements SignalAdapter {
|
||||||
tradeLineItem.setName(orderItem.getItemValueString("datev.text"));
|
tradeLineItem.setName(orderItem.getItemValueString("datev.text"));
|
||||||
tradeLineItem.setQuantity(1);
|
tradeLineItem.setQuantity(1);
|
||||||
tradeLineItem.setNetPrice(orderItem.getItemValueDouble("datev.umsatz"));
|
tradeLineItem.setNetPrice(orderItem.getItemValueDouble("datev.umsatz"));
|
||||||
|
tradeLineItem.setGrossPrice(orderItem.getItemValueDouble("datev.umsatz"));
|
||||||
tradeLineItem.setTotal(orderItem.getItemValueDouble("datev.umsatz"));
|
tradeLineItem.setTotal(orderItem.getItemValueDouble("datev.umsatz"));
|
||||||
// tradeLineItem.setTaxRate(orderItem.getItemValueDouble("vat"));
|
|
||||||
|
tradeLineItem.setTaxRate(orderItem.getItemValueDouble("datev.vatrate"));
|
||||||
|
|
||||||
return tradeLineItem;
|
return tradeLineItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively removes empty leaf elements from the document.
|
||||||
|
* <p>
|
||||||
|
* An element is considered "empty" if it has no text content, no
|
||||||
|
* attributes, and no child elements. Because removing a child can make
|
||||||
|
* its parent empty as well (e.g. an empty {@code DefinedTradeContact}
|
||||||
|
* once all of its empty grandchildren are gone), the method processes
|
||||||
|
* children first (bottom-up) and then re-checks the current node.
|
||||||
|
* <p>
|
||||||
|
* This is used to clean up template placeholder elements
|
||||||
|
* (e.g. {@code <ram:PersonName/>}) that were never populated by the
|
||||||
|
* adapter and should not appear in the final invoice.
|
||||||
|
*/
|
||||||
|
private void stripEmptyElements(Element element) {
|
||||||
|
// First, recurse into child elements (bottom-up)
|
||||||
|
NodeList children = element.getChildNodes();
|
||||||
|
for (int i = children.getLength() - 1; i >= 0; i--) {
|
||||||
|
Node child = children.item(i);
|
||||||
|
if (child.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
stripEmptyElements((Element) child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then remove this element itself if it is now empty
|
||||||
|
Node parent = element.getParentNode();
|
||||||
|
if (parent != null && isEmptyElement(element)) {
|
||||||
|
parent.removeChild(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given element has no text content, no attributes,
|
||||||
|
* and no remaining child elements.
|
||||||
|
*/
|
||||||
|
private boolean isEmptyElement(Element element) {
|
||||||
|
if (element.hasAttributes()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (element.getTextContent() != null && !element.getTextContent().trim().isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
NodeList children = element.getChildNodes();
|
||||||
|
for (int i = 0; i < children.getLength(); i++) {
|
||||||
|
if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all XML comment nodes from the given document.
|
||||||
|
* <p>
|
||||||
|
* The KSeF template carries comments to help template maintainers
|
||||||
|
* (field explanations, fixed-value markers, business rules). These
|
||||||
|
* comments must not appear in the final invoice that is submitted
|
||||||
|
* to KSeF or reviewed by the tax advisor - they only add noise.
|
||||||
|
*/
|
||||||
|
private void stripComments(Document doc) {
|
||||||
|
if (doc == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
removeCommentsRecursive(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively walks a node and removes every direct child that is an
|
||||||
|
* XML comment. Iterates from the last child backwards so that
|
||||||
|
* removing a node does not affect the index of the still-to-visit
|
||||||
|
* children.
|
||||||
|
*/
|
||||||
|
private void removeCommentsRecursive(Node node) {
|
||||||
|
Node child = node.getLastChild();
|
||||||
|
while (child != null) {
|
||||||
|
Node previous = child.getPreviousSibling();
|
||||||
|
if (child.getNodeType() == Node.COMMENT_NODE) {
|
||||||
|
node.removeChild(child);
|
||||||
|
} else if (child.hasChildNodes()) {
|
||||||
|
removeCommentsRecursive(child);
|
||||||
|
}
|
||||||
|
child = previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
package com.alexanderlogistics.einvoice;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.imixs.workflow.FileData;
|
||||||
|
import org.imixs.workflow.ItemCollection;
|
||||||
|
import org.imixs.workflow.engine.DocumentService;
|
||||||
|
import org.imixs.workflow.engine.WorkflowService;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import com.alexanderlogistics.BusinessPartnerService;
|
||||||
|
import com.alexanderlogistics.InvoiceService;
|
||||||
|
import com.alexanderlogistics.TestLoggerConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der AGLEInvoiceAdapterTest prüft die Umwandlung einer Cargosoft Rechnung in
|
||||||
|
* eine E-Rechnung
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class AGLEInvoiceAdapterTest {
|
||||||
|
|
||||||
|
private static Logger logger = Logger.getLogger(AGLEInvoiceAdapterTest.class.getName());
|
||||||
|
|
||||||
|
private static final String TEMPLATE_FILE = "pl/e-invoice/templates/factur-x.xml";
|
||||||
|
|
||||||
|
ItemCollection businessPartner;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BusinessPartnerService businessPartnerService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private DocumentService documentService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private WorkflowService workflowService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private InvoiceService invoiceService;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private EInvoiceAdapter adapter;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() throws Exception {
|
||||||
|
|
||||||
|
TestLoggerConfig.setupTestLogger();
|
||||||
|
|
||||||
|
// adapter = new EInvoiceAdapter();
|
||||||
|
|
||||||
|
// Prepare mock business partner
|
||||||
|
businessPartner = new ItemCollection();
|
||||||
|
businessPartner.setItemValue("partner.name", "Test Sp. z o.o.");
|
||||||
|
businessPartner.setItemValue("partner.country", "PL");
|
||||||
|
businessPartner.setItemValue("partner.city", "Warszawa");
|
||||||
|
businessPartner.setItemValue("partner.zip", "00-001");
|
||||||
|
businessPartner.setItemValue("partner.address", "ul. Testowa 1");
|
||||||
|
businessPartner.setItemValue("partner.vat", "PL1234567890");
|
||||||
|
businessPartner.setItemValue("dbtr.number", "D-12345");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple PLN invoice with one tax rate (23%).
|
||||||
|
* Expected: P_13_1, P_14_1, P_15.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test Simple Invoice (PLN, 23%)")
|
||||||
|
public void testSimpleInvoice() throws Exception {
|
||||||
|
logger.info("==> Test: Simple Invoice");
|
||||||
|
|
||||||
|
ItemCollection workitem = new ItemCollection();
|
||||||
|
workitem.setItemValue("invoice.number", "FV/2025/001");
|
||||||
|
workitem.setItemValue("invoice.date", LocalDate.of(2025, 2, 10));
|
||||||
|
workitem.setItemValue("invoice.duedate", LocalDate.of(2025, 3, 10));
|
||||||
|
workitem.setItemValue("invoice.currency", "PLN");
|
||||||
|
workitem.setItemValue("invoice.total.net", 10000.00);
|
||||||
|
workitem.setItemValue("invoice.total.tax", 23.0);
|
||||||
|
workitem.setItemValue("invoice.total", 12300.00);
|
||||||
|
workitem.setItemValue("invoice.correction", "false");
|
||||||
|
workitem.setItemValue("invoice.CorrectionInvoiceNumber", "");
|
||||||
|
workitem.setItemValue("partner.id", "BP-001");
|
||||||
|
workitem.setItemValue("partner.vat", "PL1234567890");
|
||||||
|
workitem.setItemValue("invoice.performancedate", new Date());
|
||||||
|
|
||||||
|
// Prepare child items (invoice line items)
|
||||||
|
List<Object> childItems = new ArrayList<>();
|
||||||
|
|
||||||
|
ItemCollection lineItem1 = new ItemCollection();
|
||||||
|
lineItem1.setItemValue("numpos", "1");
|
||||||
|
lineItem1.setItemValue("datev.text", "Transport Berlin - Warsaw");
|
||||||
|
lineItem1.setItemValue("billingtext", "Transport Berlin - Warsaw");
|
||||||
|
lineItem1.setItemValue("datev.umsatz", 6000.00);
|
||||||
|
lineItem1.setItemValue("datev.vatrate", 23.0);
|
||||||
|
lineItem1.setItemValue("cargosoft.vat.code", "23");
|
||||||
|
childItems.add(lineItem1.getAllItems());
|
||||||
|
|
||||||
|
ItemCollection lineItem2 = new ItemCollection();
|
||||||
|
lineItem2.setItemValue("numpos", "2");
|
||||||
|
lineItem2.setItemValue("datev.text", "Customs handling");
|
||||||
|
lineItem2.setItemValue("billingtext", "Customs handling");
|
||||||
|
lineItem2.setItemValue("datev.umsatz", 4000.00);
|
||||||
|
lineItem2.setItemValue("datev.vatrate", 23.0);
|
||||||
|
lineItem2.setItemValue("cargosoft.vat.code", "23");
|
||||||
|
childItems.add(lineItem2.getAllItems());
|
||||||
|
|
||||||
|
workitem.setItemValue("_childitems", childItems);
|
||||||
|
|
||||||
|
when(businessPartnerService.getBusinessPartnerByID("BP-001"))
|
||||||
|
.thenReturn(businessPartner);
|
||||||
|
|
||||||
|
FileData xmlTemplate = loadTemplateFromResources(TEMPLATE_FILE);
|
||||||
|
|
||||||
|
adapter.updateEInvoice(xmlTemplate, workitem);
|
||||||
|
|
||||||
|
assertNotNull(xmlTemplate.getContent(), "XML content should not be null after update");
|
||||||
|
assertTrue(xmlTemplate.getContent().length > 0, "XML content should not be empty");
|
||||||
|
|
||||||
|
writeOutputToResources(xmlTemplate, "einvoice-simple.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Helper methods ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the KSeF XML template from src/test/resources.
|
||||||
|
*/
|
||||||
|
private FileData loadTemplateFromResources(String filename) {
|
||||||
|
try (InputStream is = getClass().getClassLoader().getResourceAsStream(filename)) {
|
||||||
|
if (is == null) {
|
||||||
|
fail("Template file not found in test resources: " + filename
|
||||||
|
+ "\nPlease place your KSeF XML template at: src/test/resources/"
|
||||||
|
+ filename);
|
||||||
|
}
|
||||||
|
byte[] content = is.readAllBytes();
|
||||||
|
return new FileData(filename, content, "application/xml", null);
|
||||||
|
} catch (IOException e) {
|
||||||
|
fail("Failed to read template: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the resulting XML to src/test/resources/output/ for manual inspection.
|
||||||
|
*/
|
||||||
|
private void writeOutputToResources(FileData fileData, String filename) throws IOException {
|
||||||
|
Path outputDir = Paths.get("src", "test", "resources", "einvoice/output");
|
||||||
|
Files.createDirectories(outputDir);
|
||||||
|
Path outputPath = outputDir.resolve(filename);
|
||||||
|
Files.write(outputPath, fileData.getContent());
|
||||||
|
System.out.println("──────────────────────────────────────────────");
|
||||||
|
System.out.println("Output written to: " + outputPath.toAbsolutePath());
|
||||||
|
System.out.println("──────────────────────────────────────────────");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
|
||||||
|
xmlns:a="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
|
||||||
|
xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:10"
|
||||||
|
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
|
||||||
|
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
|
||||||
|
xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<rsm:ExchangedDocumentContext>
|
||||||
|
<ram:GuidelineSpecifiedDocumentContextParameter>
|
||||||
|
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
|
||||||
|
</ram:GuidelineSpecifiedDocumentContextParameter>
|
||||||
|
</rsm:ExchangedDocumentContext>
|
||||||
|
<rsm:ExchangedDocument>
|
||||||
|
<ram:ID>FV/2025/001</ram:ID>
|
||||||
|
<ram:TypeCode>380</ram:TypeCode>
|
||||||
|
<ram:IssueDateTime>
|
||||||
|
<udt:DateTimeString format="102">20250210</udt:DateTimeString>
|
||||||
|
</ram:IssueDateTime>
|
||||||
|
<ram:IncludedNote>
|
||||||
|
<ram:Content>Payment Instructions:</ram:Content>
|
||||||
|
</ram:IncludedNote>
|
||||||
|
<ram:IncludedNote>
|
||||||
|
<ram:Content>Please ensure that the payment reference includes the invoice number, BL or
|
||||||
|
AWB number, container or shipment number and place of loading and discharge.
|
||||||
|
The full invoice amount must be transferred without any deductions and all bank charges
|
||||||
|
must be covered by the sender.
|
||||||
|
Otherwise, the beneficiary’s bank will be unable to process the incoming payment.</ram:Content>
|
||||||
|
</ram:IncludedNote>
|
||||||
|
<ram:IncludedNote>
|
||||||
|
<ram:Content>Alexander Global Logistics</ram:Content>
|
||||||
|
</ram:IncludedNote>
|
||||||
|
<ram:IncludedNote>
|
||||||
|
<ram:Content>Numer NIP: PL9552521552</ram:Content>
|
||||||
|
</ram:IncludedNote>
|
||||||
|
</rsm:ExchangedDocument>
|
||||||
|
<rsm:SupplyChainTradeTransaction>
|
||||||
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
|
<ram:AssociatedDocumentLineDocument>
|
||||||
|
<ram:LineID>1</ram:LineID>
|
||||||
|
</ram:AssociatedDocumentLineDocument>
|
||||||
|
<ram:SpecifiedTradeProduct>
|
||||||
|
<ram:Name>Transport Berlin - Warsaw</ram:Name>
|
||||||
|
</ram:SpecifiedTradeProduct>
|
||||||
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
|
<ram:GrossPriceProductTradePrice>
|
||||||
|
<ram:ChargeAmount>6000.0</ram:ChargeAmount>
|
||||||
|
</ram:GrossPriceProductTradePrice>
|
||||||
|
<ram:NetPriceProductTradePrice>
|
||||||
|
<ram:ChargeAmount>6000.0</ram:ChargeAmount>
|
||||||
|
</ram:NetPriceProductTradePrice>
|
||||||
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
|
<ram:BilledQuantity unitCode="C62">1.0</ram:BilledQuantity>
|
||||||
|
</ram:SpecifiedLineTradeDelivery>
|
||||||
|
<ram:SpecifiedLineTradeSettlement>
|
||||||
|
<ram:ApplicableTradeTax>
|
||||||
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
|
<ram:RateApplicablePercent>23.0</ram:RateApplicablePercent>
|
||||||
|
</ram:ApplicableTradeTax>
|
||||||
|
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
|
<ram:LineTotalAmount>6000.0</ram:LineTotalAmount>
|
||||||
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
|
<ram:AssociatedDocumentLineDocument>
|
||||||
|
<ram:LineID>2</ram:LineID>
|
||||||
|
</ram:AssociatedDocumentLineDocument>
|
||||||
|
<ram:SpecifiedTradeProduct>
|
||||||
|
<ram:Name>Customs handling</ram:Name>
|
||||||
|
</ram:SpecifiedTradeProduct>
|
||||||
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
|
<ram:GrossPriceProductTradePrice>
|
||||||
|
<ram:ChargeAmount>4000.0</ram:ChargeAmount>
|
||||||
|
</ram:GrossPriceProductTradePrice>
|
||||||
|
<ram:NetPriceProductTradePrice>
|
||||||
|
<ram:ChargeAmount>4000.0</ram:ChargeAmount>
|
||||||
|
</ram:NetPriceProductTradePrice>
|
||||||
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
|
<ram:BilledQuantity unitCode="C62">1.0</ram:BilledQuantity>
|
||||||
|
</ram:SpecifiedLineTradeDelivery>
|
||||||
|
<ram:SpecifiedLineTradeSettlement>
|
||||||
|
<ram:ApplicableTradeTax>
|
||||||
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
|
<ram:RateApplicablePercent>23.0</ram:RateApplicablePercent>
|
||||||
|
</ram:ApplicableTradeTax>
|
||||||
|
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
|
<ram:LineTotalAmount>4000.0</ram:LineTotalAmount>
|
||||||
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
|
<ram:ApplicableHeaderTradeAgreement>
|
||||||
|
<ram:BuyerReference>n/a</ram:BuyerReference>
|
||||||
|
<ram:SellerTradeParty>
|
||||||
|
<ram:Name>Alexander Global Logistics</ram:Name>
|
||||||
|
<ram:DefinedTradeContact>
|
||||||
|
<ram:PersonName>n/a</ram:PersonName>
|
||||||
|
<ram:TelephoneUniversalCommunication>
|
||||||
|
<ram:CompleteNumber>+49 421 566 46 0</ram:CompleteNumber>
|
||||||
|
</ram:TelephoneUniversalCommunication>
|
||||||
|
<ram:EmailURIUniversalCommunication>
|
||||||
|
<ram:URIID>info@alexander-logistics.com</ram:URIID>
|
||||||
|
</ram:EmailURIUniversalCommunication>
|
||||||
|
</ram:DefinedTradeContact>
|
||||||
|
<ram:PostalTradeAddress>
|
||||||
|
<ram:PostcodeCode>70-660</ram:PostcodeCode>
|
||||||
|
<ram:LineOne>Gdanska 36</ram:LineOne>
|
||||||
|
<ram:CityName>Szczecin</ram:CityName>
|
||||||
|
<ram:CountryID>PL</ram:CountryID>
|
||||||
|
</ram:PostalTradeAddress>
|
||||||
|
<ram:URIUniversalCommunication>
|
||||||
|
<ram:URIID schemeID="EM">info@alexander-logistics.com</ram:URIID>
|
||||||
|
</ram:URIUniversalCommunication>
|
||||||
|
<ram:SpecifiedTaxRegistration>
|
||||||
|
<ram:ID schemeID="VA">PL9552521552</ram:ID>
|
||||||
|
</ram:SpecifiedTaxRegistration>
|
||||||
|
</ram:SellerTradeParty>
|
||||||
|
<ram:BuyerTradeParty>
|
||||||
|
<ram:Name>Test Sp. z o.o.</ram:Name>
|
||||||
|
<ram:PostalTradeAddress>
|
||||||
|
<ram:PostcodeCode>00-001</ram:PostcodeCode>
|
||||||
|
<ram:LineOne>ul. Testowa 1</ram:LineOne>
|
||||||
|
<ram:CityName>Warszawa</ram:CityName>
|
||||||
|
<ram:CountryID>PL</ram:CountryID>
|
||||||
|
</ram:PostalTradeAddress>
|
||||||
|
<ram:SpecifiedTaxRegistration>
|
||||||
|
<ram:ID schemeID="VA">PL1234567890</ram:ID>
|
||||||
|
</ram:SpecifiedTaxRegistration>
|
||||||
|
</ram:BuyerTradeParty>
|
||||||
|
</ram:ApplicableHeaderTradeAgreement>
|
||||||
|
<ram:ApplicableHeaderTradeDelivery>
|
||||||
|
<ram:ShipToTradeParty>
|
||||||
|
<ram:Name>Test Sp. z o.o.</ram:Name>
|
||||||
|
<ram:PostalTradeAddress>
|
||||||
|
<ram:PostcodeCode>00-001</ram:PostcodeCode>
|
||||||
|
<ram:LineOne>ul. Testowa 1</ram:LineOne>
|
||||||
|
<ram:CityName>Warszawa</ram:CityName>
|
||||||
|
<ram:CountryID>PL</ram:CountryID>
|
||||||
|
</ram:PostalTradeAddress>
|
||||||
|
</ram:ShipToTradeParty>
|
||||||
|
</ram:ApplicableHeaderTradeDelivery>
|
||||||
|
<ram:ApplicableHeaderTradeSettlement>
|
||||||
|
<ram:InvoiceCurrencyCode>PLN</ram:InvoiceCurrencyCode>
|
||||||
|
<ram:SpecifiedTradeSettlementPaymentMeans>
|
||||||
|
<ram:TypeCode>30</ram:TypeCode>
|
||||||
|
<ram:PayeePartyCreditorFinancialAccount>
|
||||||
|
<ram:IBANID>PL79116022020000000654306674</ram:IBANID>
|
||||||
|
</ram:PayeePartyCreditorFinancialAccount>
|
||||||
|
<ram:PayeeSpecifiedCreditorFinancialInstitution>
|
||||||
|
<ram:BICID>BIGBPLPWXXX</ram:BICID>
|
||||||
|
</ram:PayeeSpecifiedCreditorFinancialInstitution>
|
||||||
|
</ram:SpecifiedTradeSettlementPaymentMeans>
|
||||||
|
<ram:ApplicableTradeTax>
|
||||||
|
<ram:CalculatedAmount>2300.0</ram:CalculatedAmount>
|
||||||
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
|
<ram:BasisAmount>10000.0</ram:BasisAmount>
|
||||||
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
|
<ram:RateApplicablePercent>23.0</ram:RateApplicablePercent>
|
||||||
|
</ram:ApplicableTradeTax>
|
||||||
|
<ram:SpecifiedTradePaymentTerms>
|
||||||
|
<ram:Description/>
|
||||||
|
<ram:DueDateDateTime>
|
||||||
|
<udt:DateTimeString format="102">20250310</udt:DateTimeString>
|
||||||
|
</ram:DueDateDateTime>
|
||||||
|
</ram:SpecifiedTradePaymentTerms>
|
||||||
|
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
|
<ram:LineTotalAmount>10000.0</ram:LineTotalAmount>
|
||||||
|
<ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>
|
||||||
|
<ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>
|
||||||
|
<ram:TaxBasisTotalAmount>10000.0</ram:TaxBasisTotalAmount>
|
||||||
|
<ram:TaxTotalAmount currencyID="PLN">2300.0</ram:TaxTotalAmount>
|
||||||
|
<ram:GrandTotalAmount>12300.0</ram:GrandTotalAmount>
|
||||||
|
<ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
|
||||||
|
<ram:DuePayableAmount>12300.0</ram:DuePayableAmount>
|
||||||
|
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
|
</ram:ApplicableHeaderTradeSettlement>
|
||||||
|
</rsm:SupplyChainTradeTransaction>
|
||||||
|
</rsm:CrossIndustryInvoice>
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<Naglowek>
|
<Naglowek>
|
||||||
<KodFormularza kodSystemowy="FA (3)" wersjaSchemy="1-0E">FA</KodFormularza>
|
<KodFormularza kodSystemowy="FA (3)" wersjaSchemy="1-0E">FA</KodFormularza>
|
||||||
<WariantFormularza>3</WariantFormularza>
|
<WariantFormularza>3</WariantFormularza>
|
||||||
<DataWytworzeniaFa>2026-05-28T19:18:53.850338633Z</DataWytworzeniaFa>
|
<DataWytworzeniaFa>2026-07-23T14:06:32.328007Z</DataWytworzeniaFa>
|
||||||
<SystemInfo>Imixs eInvoice</SystemInfo>
|
<SystemInfo>Imixs eInvoice</SystemInfo>
|
||||||
</Naglowek>
|
</Naglowek>
|
||||||
<Podmiot1>
|
<Podmiot1>
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
<P_1>2025-02-10</P_1>
|
<P_1>2025-02-10</P_1>
|
||||||
<P_1M>Szczecin</P_1M>
|
<P_1M>Szczecin</P_1M>
|
||||||
<P_2>FV/2025/001</P_2>
|
<P_2>FV/2025/001</P_2>
|
||||||
<P_6>2026-05-28</P_6>
|
<P_6>2026-07-23</P_6>
|
||||||
<P_13_8>10000.00</P_13_8>
|
<P_13_8>10000.00</P_13_8>
|
||||||
<P_15>10000.00</P_15>
|
<P_15>10000.00</P_15>
|
||||||
<Adnotacje>
|
<Adnotacje>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<Naglowek>
|
<Naglowek>
|
||||||
<KodFormularza kodSystemowy="FA (3)" wersjaSchemy="1-0E">FA</KodFormularza>
|
<KodFormularza kodSystemowy="FA (3)" wersjaSchemy="1-0E">FA</KodFormularza>
|
||||||
<WariantFormularza>3</WariantFormularza>
|
<WariantFormularza>3</WariantFormularza>
|
||||||
<DataWytworzeniaFa>2026-05-28T19:18:53.948427821Z</DataWytworzeniaFa>
|
<DataWytworzeniaFa>2026-07-23T15:09:14.896034Z</DataWytworzeniaFa>
|
||||||
<SystemInfo>Imixs eInvoice</SystemInfo>
|
<SystemInfo>Imixs eInvoice</SystemInfo>
|
||||||
</Naglowek>
|
</Naglowek>
|
||||||
<Podmiot1>
|
<Podmiot1>
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
<P_1>2025-02-10</P_1>
|
<P_1>2025-02-10</P_1>
|
||||||
<P_1M>Szczecin</P_1M>
|
<P_1M>Szczecin</P_1M>
|
||||||
<P_2>FV/2025/001</P_2>
|
<P_2>FV/2025/001</P_2>
|
||||||
<P_6>2026-05-28</P_6>
|
<P_6>2026-07-23</P_6>
|
||||||
<P_13_1>10000.00</P_13_1>
|
<P_13_1>10000.00</P_13_1>
|
||||||
<P_14_1>2300.00</P_14_1>
|
<P_14_1>2300.00</P_14_1>
|
||||||
<P_15>12300.00</P_15>
|
<P_15>12300.00</P_15>
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,12 @@
|
||||||
<ram:SellerTradeParty>
|
<ram:SellerTradeParty>
|
||||||
<ram:Name>Alexander Global Logistics</ram:Name>
|
<ram:Name>Alexander Global Logistics</ram:Name>
|
||||||
<ram:DefinedTradeContact>
|
<ram:DefinedTradeContact>
|
||||||
<ram:PersonName></ram:PersonName>
|
<ram:PersonName>n/a</ram:PersonName>
|
||||||
<ram:TelephoneUniversalCommunication>
|
<ram:TelephoneUniversalCommunication>
|
||||||
<ram:CompleteNumber></ram:CompleteNumber>
|
<ram:CompleteNumber>+49 421 566 46 0</ram:CompleteNumber>
|
||||||
</ram:TelephoneUniversalCommunication>
|
</ram:TelephoneUniversalCommunication>
|
||||||
<ram:EmailURIUniversalCommunication>
|
<ram:EmailURIUniversalCommunication>
|
||||||
<ram:URIID></ram:URIID>
|
<ram:URIID>info@alexander-logistics.com</ram:URIID>
|
||||||
</ram:EmailURIUniversalCommunication>
|
</ram:EmailURIUniversalCommunication>
|
||||||
</ram:DefinedTradeContact>
|
</ram:DefinedTradeContact>
|
||||||
<ram:PostalTradeAddress>
|
<ram:PostalTradeAddress>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue