shogg / edifact

Read edifact into your Go data structures.
MIT License
18 stars 7 forks source link

Support the same key at 2 places within the same segment group for BAPLIE #5

Closed nOBITa3001 closed 2 years ago

nOBITa3001 commented 2 years ago

Hello @shogg

Thank you for creating this package. I use this one in my project to read data from BAPLIE file

I have a situation that I have the same key, "LOC", at 2 places within the same segment group, "SG2" for my BAPLIE specification Unfortunately, I could not read the value using the duplicated key. I debugged and found my case that there is no "path" for the "specNode" value that use for looking up value from h.decodeTree in "handler.go" file

I have tried many setups, but they didn't work So, could you please help to verify my specification is correct or the package requires to add some logic to support this case

baplie-specification

var BAPLIE = spec.Msg("BAPLIE",
    spec.S("UNB", spec.C, 1),
    spec.S("UNH", spec.M, 1),
    spec.S("BGM", spec.M, 1),
    spec.S("DTM", spec.M, 1),
    spec.S("RFF", spec.C, 1),
    spec.S("NAD", spec.C, 9),
    spec.SG("SG1", spec.C, 1,
        spec.S("TDT", spec.M, 1),
        spec.S("LOC", spec.M, 9),
        spec.S("DTM", spec.M, 99),
        spec.S("RFF", spec.C, 1),
        spec.S("FTX", spec.C, 1),
    ),
    spec.SG("SG2", spec.C, 9999,
        spec.S("LOC", spec.M, 1),
        spec.S("GID", spec.C, 1),
        spec.S("GDS", spec.C, 9),
        spec.S("FTX", spec.C, 9),
        spec.S("MEA", spec.M, 9),
        spec.S("DIM", spec.C, 9),
        spec.S("TMP", spec.C, 1),
        spec.S("RNG", spec.C, 1),
        spec.S("LOC", spec.C, 9),
        spec.S("RFF", spec.M, 9),
        spec.SG("SG3", spec.C, 9,
            spec.S("EQD", spec.M, 1),
            spec.S("EQA", spec.C, 9),
            spec.S("NAD", spec.C, 1),
        ),
        spec.SG("SG4", spec.C, 9999,
            spec.S("DGS", spec.M, 1),
            spec.S("FTX", spec.C, 1),
        ),
    ),
    spec.S("UNT", spec.M, 1),
    spec.S("UNZ", spec.M, 1),
)

structs

type VesselDetails struct {
    TransportDet     string      `edifact:"SG1/TDT+20+065E+++COS:172:ZZZ+++VRIV3:103:ZZZ:?"`
    PlaceOfDeparture string      `edifact:"SG1/LOC+5+?"`
    NextPortOfCall   string      `edifact:"SG1/LOC+61+?"`
    Containers       []Container `edifact:"SG2"`
}

type Container struct {
    ISO             string `edifact:"SG2/SG3/EQD+CN+?+?"`
    ContainerName   string `edifact:"SG2/SG3/EQD+CN+?"`
    PortOfLoading   string `edifact:"SG2/LOC+9+?"`
    PortOfDischarge string `edifact:"SG2/LOC+11+?"`
    Stowage         string `edifact:"SG2/LOC+147+?"`
    WeightInKg      string `edifact:"SG2/MEA+WT++KGM:?"`
    SlotOperator    string `edifact:"SG2/SG3/NAD+CA+?"`
    IMDGCode        string `edifact:"SG2/SG4/DGS+IMD+?"`
    Description     string `edifact:"SG2/SG4/FTX+AAD+++?"`

function

func ParseEdifactFile(baplieMsg string) dtos.VesselDetails {
    document := strings.NewReader(baplieMsg)
    var vesselDetails dtos.VesselDetails
    if err := edifact.Unmarshal(document, &vesselDetails); err != nil {
        panic(err)
    }

    return VesselDetails
}

testing

var testMsgWith1Container = `
    UNB+UNOA:2+SEACOS+PUBLIC+210118:1038+31033627+++++UNKNOWN'
    UNH+SEACOSA3627+BAPLIE:D:95B:UN:SMDG22'
    BGM++R0C55E2211C418+9'
    DTM+137:2101181038:201'
    TDT+20+010E+++:172:20+++A8VP5:103:ZZZ:'
    LOC+5+GBLGP:139:6'
    LOC+61+DEHAM:139:6'
    DTM+133+test'
    LOC+147+0050106::5'
    MEA+VGM++KGM:24600'
    LOC+9+AAAA'
    LOC+11+BBBB'
    RFF+BM:1'
    EQD+CN+GRMU9201350+22T6+++5'
    UNT+18142+SEACOSA3627'
    UNZ+1+31033627'`

func TestParseEdifactFile(t *testing.T) {
    spec.Add("BAPLIE", BAPLIE)
    result := ParseEdifactFile(testMsgWith1Container)
    assert.Equal(t, "AAAA", result.Containers[0].PortOfLoading)
    assert.Equal(t, "BBBB", result.Containers[0].PortOfDischarge)
}

The above test will fail because "PortOfLoading" and "PortOfDischarge" are empty

shogg commented 2 years ago

I relaxed the lookup where to set a value in the target data structure. More than one segment with identical tag in a segment group works now.

nOBITa3001 commented 2 years ago

Hello @shogg

Thank you for the update!

Confirm it works as expected!