Skip to content

Commit

Permalink
Added support for Peppol Business Message Envelope v2.0.1 and eDEC Co…
Browse files Browse the repository at this point in the history
…de Lists v8.6
  • Loading branch information
aaron-kumar committed Aug 26, 2023
1 parent d4d7726 commit 56d02a4
Show file tree
Hide file tree
Showing 15 changed files with 227 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package network.oxalis.vefa.peppol.common.model;

import java.io.Serializable;

public class C1CountryIdentifier extends AbstractSimpleIdentifier implements Serializable {

private static final long serialVersionUID = -3492824463587521885L;

public static C1CountryIdentifier of(String value) {
return new C1CountryIdentifier(value);
}

public C1CountryIdentifier(String value) {
super(value);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class Header implements Serializable {

private DocumentTypeIdentifier documentType;

private C1CountryIdentifier c1CountryIdentifier;

private InstanceIdentifier identifier;

private InstanceType instanceType;
Expand All @@ -53,34 +55,35 @@ public static Header newInstance() {
}

public static Header of(ParticipantIdentifier sender, ParticipantIdentifier receiver, List<ParticipantIdentifier> cc,
ProcessIdentifier process, DocumentTypeIdentifier documentType, InstanceIdentifier identifier,
InstanceType instanceType, Date creationTimestamp) {
return new Header(sender, receiver, cc, process, documentType, identifier, instanceType, creationTimestamp, null);
ProcessIdentifier process, DocumentTypeIdentifier documentType, C1CountryIdentifier c1CountryIdentifier,
InstanceIdentifier identifier, InstanceType instanceType, Date creationTimestamp) {
return new Header(sender, receiver, cc, process, documentType, c1CountryIdentifier, identifier, instanceType, creationTimestamp, null);
}

public static Header of(ParticipantIdentifier sender, ParticipantIdentifier receiver,
ProcessIdentifier process, DocumentTypeIdentifier documentType, InstanceIdentifier identifier,
InstanceType instanceType, Date creationTimestamp) {
return new Header(sender, receiver, new ArrayList<>(), process, documentType, identifier, instanceType, creationTimestamp, null);
ProcessIdentifier process, DocumentTypeIdentifier documentType, C1CountryIdentifier c1CountryIdentifier,
InstanceIdentifier identifier, InstanceType instanceType, Date creationTimestamp) {
return new Header(sender, receiver, new ArrayList<>(), process, documentType, c1CountryIdentifier, identifier, instanceType, creationTimestamp, null);
}

public static Header of(ParticipantIdentifier sender, ParticipantIdentifier receiver, ProcessIdentifier process,
DocumentTypeIdentifier documentType) {
return new Header(sender, receiver, new ArrayList<>(), process, documentType, null, null, null, null);
DocumentTypeIdentifier documentType ) {
return new Header(sender, receiver, new ArrayList<>(), process, documentType, null, null, null, null, null);
}

public Header() {
// No action.
}

private Header(ParticipantIdentifier sender, ParticipantIdentifier receiver, List<ParticipantIdentifier> copyReceiver,
ProcessIdentifier process, DocumentTypeIdentifier documentType, InstanceIdentifier identifier,
InstanceType instanceType, Date creationTimestamp, Map<String, ArgumentIdentifier> arguments) {
ProcessIdentifier process, DocumentTypeIdentifier documentType, C1CountryIdentifier c1CountryIdentifier,
InstanceIdentifier identifier, InstanceType instanceType, Date creationTimestamp, Map<String, ArgumentIdentifier> arguments) {
this.sender = sender;
this.receiver = receiver;
this.copyReceiver = copyReceiver;
this.process = process;
this.documentType = documentType;
this.c1CountryIdentifier = c1CountryIdentifier;
this.identifier = identifier;
this.instanceType = instanceType;
this.creationTimestamp = creationTimestamp;
Expand All @@ -107,6 +110,10 @@ public Header documentType(DocumentTypeIdentifier documentType) {
return copy(h -> h.documentType = documentType);
}

public Header c1CountryIdentifier(C1CountryIdentifier c1CountryIdentifier) {
return copy(h -> h.c1CountryIdentifier = c1CountryIdentifier);
}

public Header identifier(InstanceIdentifier identifier) {
return copy(h -> h.identifier = identifier);
}
Expand Down Expand Up @@ -144,6 +151,7 @@ public boolean equals(Object o) {
Objects.equals(receiver, header.receiver) &&
Objects.equals(process, header.process) &&
Objects.equals(documentType, header.documentType) &&
Objects.equals(c1CountryIdentifier, header.c1CountryIdentifier) &&
Objects.equals(identifier, header.identifier) &&
Objects.equals(instanceType, header.instanceType) &&
Objects.equals(creationTimestamp, header.creationTimestamp) &&
Expand All @@ -152,7 +160,7 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hash(sender, receiver, process, documentType, identifier, instanceType, creationTimestamp, arguments);
return Objects.hash(sender, receiver, process, documentType, c1CountryIdentifier, identifier, instanceType, creationTimestamp, arguments);
}

@Override
Expand All @@ -163,6 +171,7 @@ public String toString() {
", copyReceiver=" + copyReceiver +
", process=" + process +
", documentType=" + documentType +
", c1CountryIdentifier=" + c1CountryIdentifier +
", identifier=" + identifier +
", instanceType=" + instanceType +
", creationTimestamp=" + creationTimestamp +
Expand All @@ -171,8 +180,8 @@ public String toString() {
}

private Header copy(Consumer<Header> consumer) {
Header header = new Header(sender, receiver, new ArrayList<>(copyReceiver), process, documentType, identifier,
instanceType, creationTimestamp, new HashMap<>(arguments));
Header header = new Header(sender, receiver, new ArrayList<>(copyReceiver), process, documentType, c1CountryIdentifier,
identifier, instanceType, creationTimestamp, new HashMap<>(arguments));
consumer.accept(header);
return header;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package network.oxalis.vefa.peppol.common.model;

import org.testng.Assert;
import org.testng.annotations.Test;

public class C1CountryIdentifierTest {

@Test
public void simple() {
Assert.assertNotNull(InstanceIdentifier.generateUUID().getIdentifier());

C1CountryIdentifier c1CountryIdentifier = C1CountryIdentifier.of("IN");

Assert.assertEquals(c1CountryIdentifier.getIdentifier(), "IN");
Assert.assertEquals(c1CountryIdentifier.toString(), "IN");

Assert.assertTrue(c1CountryIdentifier.equals(c1CountryIdentifier));
Assert.assertFalse(c1CountryIdentifier.equals("IN"));
Assert.assertFalse(c1CountryIdentifier.equals(null));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public void simple() {
.process(ProcessIdentifier.of("urn:www.cenbii.eu:profile:bii05:ver2.0"))
.documentType(DocumentTypeIdentifier.of("urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2::CreditNote" +
"##urn:www.cenbii.eu:transaction:biitrns014:ver2.0:extended:urn:www.peppol.eu:bis:peppol5a:ver2.0::2.1", DocumentTypeIdentifier.BUSDOX_DOCID_QNS_SCHEME))
.c1CountryIdentifier(C1CountryIdentifier.of("IN"))
.instanceType(InstanceType.of("urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2", "CreditNote", "2.1"))
.creationTimestamp(new Date())
.identifier(InstanceIdentifier.generateUUID());
Expand All @@ -44,6 +45,7 @@ public void simple() {
.process(ProcessIdentifier.of("urn:www.cenbii.eu:profile:bii05:ver2.0", Scheme.of("cenbii-procid-ubl")))
.documentType(DocumentTypeIdentifier.of("urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2::CreditNote" +
"##urn:www.cenbii.eu:transaction:biitrns014:ver2.0:extended:urn:www.peppol.eu:bis:peppol5a:ver2.0::2.1"))
.c1CountryIdentifier(C1CountryIdentifier.of("IN"))
.instanceType(InstanceType.of("urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2", "CreditNote", "2.1"))
.creationTimestamp(header.getCreationTimestamp())
.identifier(InstanceIdentifier.of(header.getIdentifier().getIdentifier()));
Expand All @@ -60,6 +62,7 @@ public void simple() {
Assert.assertEquals(header.getReceiver(), header2.getReceiver());
Assert.assertEquals(header.getProcess(), header2.getProcess());
Assert.assertEquals(header.getDocumentType(), header2.getDocumentType());
Assert.assertEquals(header.getC1CountryIdentifier(), header2.getC1CountryIdentifier());
Assert.assertEquals(header.getInstanceType(), header2.getInstanceType());
Assert.assertEquals(header.getCreationTimestamp(), header2.getCreationTimestamp());
Assert.assertEquals(header.getIdentifier(), header2.getIdentifier());
Expand All @@ -85,7 +88,7 @@ public void shortOfMethod() {
ParticipantIdentifier.of("9908123456785"),
ProcessIdentifier.of("Some:Process"),
DocumentTypeIdentifier.of("Some:Document"),
null, null, null
null,null, null, null
)));
Assert.assertFalse(header.equals(Header.of(
ParticipantIdentifier.of("9908:98764321"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,14 @@ public enum PeppolIcd implements Icd {
JP_IIN("JP:IIN", "0221", "National Tax Agency Japan"),
MY_EIF("MY:EIF", "0230", "Malaysia Digital Economy Corporation Sdn Bhd (MDEC)"),

// ICDs created and maintained by OpenPEPPOL
// ICDs created and maintained by OpenPEPPOL
@Deprecated // Will be "REMOVED" after 30.11.2023 release
DK_CPR("DK:CPR", "9901", "Danish Ministry of the Interior and Health"),
@Deprecated // Will be "REMOVED" after 30.11.2023 release
DK_CVR("DK:CVR", "9902", "The Danish Commerce and Companies Agency"),
@Deprecated // Will be "REMOVED" after 30.11.2023 release
DK_SE("DK:SE", "9904", "Danish Ministry of Taxation, Central Customs and Tax Administration"),
@Deprecated // Will be "REMOVED" after 30.11.2023 release
DK_VANS("DK:VANS", "9905", "Danish VANS providers"),

@Deprecated
Expand All @@ -98,7 +102,7 @@ public enum PeppolIcd implements Icd {
AT_KUR("AT:KUR", "9919", "Kennziffer des Unternehmensregisters"),
ES_VAT("ES:VAT", "9920", "Agencia Española de Administración Tributaria"),

@Deprecated
@Deprecated //Will be "REMOVED" after 30.11.2023 release
IT_IPA("IT:IPA", "9921", "Indice delle Pubbliche Amministrazioni"),

AD_VAT("AD:VAT", "9922", "Andorra VAT number"),
Expand Down Expand Up @@ -137,7 +141,7 @@ public enum PeppolIcd implements Icd {
@Deprecated
NL_ION("NL:OIN", "9954", "Dutch Originator's Identification Number"),

@Deprecated
@Deprecated // Will be "REMOVED" after 2023-10-31 release
BE_CBE("BE:CBE", "9956", "Belgian Crossroad Bank of Enterprises"),

FR_VAT("FR:VAT", "9957", "French VAT number"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@

import network.oxalis.peppol.sbdh.jaxb.*;
import network.oxalis.vefa.peppol.common.lang.PeppolRuntimeException;
import network.oxalis.vefa.peppol.common.model.ArgumentIdentifier;
import network.oxalis.vefa.peppol.common.model.DocumentTypeIdentifier;
import network.oxalis.vefa.peppol.common.model.ParticipantIdentifier;
import network.oxalis.vefa.peppol.common.model.ProcessIdentifier;
import network.oxalis.vefa.peppol.common.model.*;
import network.oxalis.vefa.peppol.common.util.ExceptionUtil;

import javax.xml.bind.JAXBContext;
Expand Down Expand Up @@ -83,6 +80,13 @@ static Scope createScope(ProcessIdentifier processIdentifier) {
return scope;
}

static Scope createScope(C1CountryIdentifier c1CountryIdentifier) {
Scope scope = new Scope();
scope.setType("COUNTRY_C1");
scope.setInstanceIdentifier(c1CountryIdentifier.getIdentifier());
return scope;
}

static Scope createScope(DocumentTypeIdentifier documentTypeIdentifier) {
Scope scope = new Scope();
scope.setType("DOCUMENTID");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ static Header read(StandardBusinessDocumentHeader sbdh) throws SbdhException {
SbdhException.notNull("Sender is not provided in SBDH.",
sbdh.getSender());
SbdhException.notNull("Sender identifier is not provided in SBDH.",
sbdh.getSender().get(0).getIdentifier());
sbdh.getSender().getIdentifier());

PartnerIdentification senderIdentifier = sbdh.getSender().get(0).getIdentifier();
PartnerIdentification senderIdentifier = sbdh.getSender().getIdentifier();
header = header.sender(
ParticipantIdentifier.of(senderIdentifier.getValue(), Scheme.of(senderIdentifier.getAuthority())));

// Receiver
SbdhException.notNull("Receiver is not provided in SBDH.",
sbdh.getReceiver());
SbdhException.notNull("Receiver identifier is not provided in SBDH.",
sbdh.getReceiver().get(0).getIdentifier());
sbdh.getReceiver().getIdentifier());

PartnerIdentification receiverIdentifier = sbdh.getReceiver().get(0).getIdentifier();
PartnerIdentification receiverIdentifier = sbdh.getReceiver().getIdentifier();
header = header.receiver(
ParticipantIdentifier.of(receiverIdentifier.getValue(), Scheme.of(receiverIdentifier.getAuthority())));

Expand Down Expand Up @@ -124,6 +124,10 @@ static Header read(StandardBusinessDocumentHeader sbdh) throws SbdhException {
header = header.process(ProcessIdentifier.of(scope.getInstanceIdentifier(), scheme));
break;
}
case "COUNTRY_C1": {
header = header.c1CountryIdentifier(C1CountryIdentifier.of(scope.getInstanceIdentifier()));
break;
}
default: {
header = header.argument(ArgumentIdentifier.of(type, scope.getInstanceIdentifier()));
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ static void write(XMLStreamWriter streamWriter, Header header) throws SbdhExcept
sbdh.setHeaderVersion("1.0");

// Sender
sbdh.getSender().add(SbdhHelper.createPartner(header.getSender()));
sbdh.setSender(SbdhHelper.createPartner(header.getSender()));

// Receiver
sbdh.getReceiver().add(SbdhHelper.createPartner(header.getReceiver()));
sbdh.setReceiver(SbdhHelper.createPartner(header.getReceiver()));

sbdh.setDocumentIdentification(new DocumentIdentification());
// Standard
Expand All @@ -74,6 +74,11 @@ static void write(XMLStreamWriter streamWriter, Header header) throws SbdhExcept
scopes.add(SbdhHelper.createScope(header.getDocumentType()));
// ProcessID
scopes.add(SbdhHelper.createScope(header.getProcess()));
// C1CountryIdentifier
// C1 Country is Not mandatory yet
if(null != header.getC1CountryIdentifier()){
scopes.add(SbdhHelper.createScope(header.getC1CountryIdentifier()));
}
// Extras
header.getArguments().forEach(ai -> scopes.add(SbdhHelper.createScope(ai)));

Expand All @@ -85,6 +90,7 @@ static void write(XMLStreamWriter streamWriter, Header header) throws SbdhExcept
marshaller.marshal(SbdhHelper.OBJECT_FACTORY.createStandardBusinessDocumentHeader(sbdh), streamWriter);
} catch (Exception e) {
throw new SbdhException("Unable to write SBDH.", e);
//e.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,59 @@ public void version103() throws IOException, SbdhException {
);
}
}

@Test
public void version200() throws IOException, SbdhException {
try (InputStream inputStream = getClass().getResourceAsStream("/peppol-sbdh-2.00.xml")) {
Header header = SbdhReader.read(inputStream);

Assert.assertEquals(
header.getSender(),
ParticipantIdentifier.of(
"0088:7315458756324",
ParticipantIdentifier.DEFAULT_SCHEME
));
Assert.assertEquals(
header.getReceiver(),
ParticipantIdentifier.of(
"0088:4562458856624",
ParticipantIdentifier.DEFAULT_SCHEME
));
Assert.assertEquals(
header.getDocumentType(),
DocumentTypeIdentifier.of(
"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
DocumentTypeIdentifier.BUSDOX_DOCID_QNS_SCHEME
));
Assert.assertEquals(
header.getProcess(),
ProcessIdentifier.of(
"urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
ProcessIdentifier.DEFAULT_SCHEME
));
Assert.assertEquals(
header.getC1CountryIdentifier(),
C1CountryIdentifier.of("IN"));
Assert.assertEquals(
header.getCreationTimestamp(),
new Date(1512551825734L)
);
Assert.assertEquals(
header.getIdentifier(),
InstanceIdentifier.of("123123")
);
Assert.assertEquals(
header.getInstanceType().getStandard(),
"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
);
Assert.assertEquals(
header.getInstanceType().getType(),
"Invoice"
);
Assert.assertEquals(
header.getInstanceType().getVersion(),
"2.1"
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@
public class SbdWriterTest {

public static final Header header = Header.newInstance()
.sender(ParticipantIdentifier.of("9908:987654325"))
.receiver(ParticipantIdentifier.of("9908:123456785"))
.process(ProcessIdentifier.of("urn:www.cenbii.eu:profile:bii04:ver1.0"))
.documentType(DocumentTypeIdentifier.of(
"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice" +
"##urn:www.cenbii.eu:transaction:biicoretrdm010:ver1.0" +
":#urn:www.peppol.eu:bis:peppol4a:ver1.0::2.0", DocumentTypeIdentifier.BUSDOX_DOCID_QNS_SCHEME ))
.instanceType(InstanceType.of("urn:oasis:names:specification:ubl:schema:xsd:Invoice-2", "Invoice", "2.0"))
.sender(ParticipantIdentifier.of("0088:7315458756324"))
.receiver(ParticipantIdentifier.of("0088:4562458856624"))
.process(ProcessIdentifier.of(">urn:fdc:peppol.eu:2017:poacc:billing:01:1.0", Scheme.of("cenbii-procid-ubl")))
.documentType(DocumentTypeIdentifier.of("urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice" +
"##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1"))
.c1CountryIdentifier(C1CountryIdentifier.of("IN"))
.instanceType(InstanceType.of("urn:oasis:names:specification:ubl:schema:xsd:Invoice-2", "Invoice", "2.1"))
.creationTimestamp(new Date())
.identifier(InstanceIdentifier.generateUUID());

Expand Down
Loading

0 comments on commit 56d02a4

Please sign in to comment.