indice-co / EDI.Net

EDI Serializer/Deserializer. Supports EDIFact, X12 and TRADACOMS formats
MIT License
453 stars 169 forks source link

Possibility to add multiple values for SequenceEnd #201

Open Marmotor opened 3 years ago

Marmotor commented 3 years ago

Hello!

I have encountered a situation where I might have to use multiple value for the SequenceEnd field for the EdiSegmentGroupAttribute.

This is a part of the EDI DELFOR D96A standard structure: image

Underlined with red are the starting segments for two consecutive segment groups in the parent segment group. The blue circle says that Segment Group 22 can be absent.

Here are some of the classes I defined in my Model:

//[EdiSegmentGroup("QTY", SequenceEnd = "PAC")]
[EdiSegmentGroup("QTY", SequenceEnd = "NAD")]
public class Sg20:Qty
{
    public Scc SchedulingConditions { get; set; }

    public List<Dtm> SomeDateTime { get; set; }

    public List<Sg21> SegmentGroup21 { get; set; }
}

[EdiSegmentGroup("RFF", SequenceEnd = "PAC")]
public class Sg21:Rff
{
    public Dtm SomeDateTime { get; set; }
}

[EdiSegmentGroup("PAC", SequenceEnd = "NAD")]
public class Sg22:Pac
{
    public List<Mea >Measurements { get; set; }

    public List<Qty >Quantity { get; set; }

    public List<Dtm >SomeDateTime { get; set; }

    public List<Sg23> SegmentGroup23 { get; set; }
}

[EdiSegmentGroup("PCI", SequenceEnd = "NAD")]
public class Sg23:Pci
{
    public List<Gin >GoodsIdentityNumber { get; set; }
}

[EdiSegmentGroup("NAD", SequenceEnd = "UNS")]
public class Sg24:Nad
{
    public List<Loc >LocationIdentification { get; set; }

    public List<Ftx >FreeText { get; set; }

    public List<Sg25> SegmentGroup25 { get; set; }

    public List<Sg26> SegmentGroup26 { get; set; }

    public List<Sg27> SegmentGroup27 { get; set; }

    public List<Sg29> SegmentGroup29 { get; set; }

    public List<Sg31> SegmentGroup31 { get; set; }
}

Here is the actual issue: If Seg 22 is present in the EDIFACT message, then the SequenceEnd value for Seg 20 will have to be "PAC". If it is missing, the value should be "NAD". I will not know from the start how the message is constructed, so I need to have a possibility to set the SequenceEnd field in such a way to support both situations. Maybe there's some other way I'm missing to achieve what I wish? I searched the issues on SequenceEnd on this page and nothing stood up to help me out...

Thank you for your help!

GingerNinjaa commented 3 years ago

Hi, I have similar issue. Could you please show class "Qty"?

Marmotor commented 3 years ago

Hi, I have similar issue. Could you please show class "Qty"?

[EdiSegment, EdiPath("QTY")]
public class Qty
{
    [EdiValue("X(3)", Path = "QTY/0/0", Mandatory = true)]
    public string QuantityQualifier { get; set; }

    [EdiValue("9(15)", Path = "QTY/0/1", Mandatory = true)]
    public long Quantity { get; set; }

    [EdiValue("X(3)", Path = "QTY/0/2")]
    public string MeasureUnitQualifier { get; set; }
}
GingerNinjaa commented 3 years ago

So you dont create a object for "C186 QUANTITY DETAILS" ? image

You dont have a problem with serialization and deserialization ?

Marmotor commented 3 years ago

My class maps a generic QTY segment, and supports all its elements and element components according to the standard. If I understand your question correctly, the object you're asking about is exactly an instance of the Qty class, and that information should be denoted in the EDI file via a QTY segment combined with the specified SCC segment mentioned in the "Segment notes" part of your picture. For your second question, I have not encountered any serialization or deserialization errors with the approach I'm using, albeit I don't have a complete EDI file to test every component of my class structure.

cleftheris commented 3 years ago

Hi @Marmotor and thanks for your interest in Edi.Net

Regarding your question about escaping a sequence loop (SegmentGroup) using the "SequenceEnd" property I have to say that SequenceEnd is obsolete. It was my first attempt to tackle the problem of escaping a loop. The robust and complete way of doing this is by defining all the possible elements inside the loop instead in the SegmentGroupAttribute constructor. Take note that you only need to define the elements that take part in the same level of nesting. For example in your case segment group 20 would consist of [SegmentGroup("QTY", "SCC", "DTM", "RFF")] while group 21 would consist of [SegmentGroup("RFF", "DTM")]. Checkout this example https://github.com/indice-co/EDI.Net/blob/2b2d86e345a11106b7674384fb9b283f33ce3a3c/test/indice.Edi.Tests/Models/EDIFact_D01B_IFCSUM.cs#L318