# EDIFACT_ORDERS_16033

This library has been written in order to parse the edifact message ORDERS according to the specification of [ISO_16033](http://www.edi-optique.org/standards_opto/Documents%20partages/ISO_16033-5_CD%20ORDERS%20(contact%20lens).pdf)

The current implemenetation is limited to contact lens, but can easily be extended.

The library can also be used to interpret any edifact Message if you derive the message class

## Install

simply `npm install editfact_orders_16033`

It uses the `edifact` library

## how to use this library

### Orders16003

If you just need ORDERS for contact lense, Bingo most of the job is done.

Let start with a [simple example](example/simple_order.js):

```js
const Order16033 = require('edifact_orders_iso_16033/order16033');
const Edi = require('edifact_orders_iso_16033/edi');
const _ = require('lodash');

let edifact = Edi.compact(`
      UNA:+.? '
      UNB+UNOC:1+WS-ESTORE+NOV+20181001:1255+253006++ESTORE'
      UNH+137+ORDERS:D:96B:UN:INFO32'
      BGM+105+1231614'
      DTM+4:201810011221:203'
      NAD+BY+26336:100++WIN OPTIC+31 RUE LOUISE MICHEL+LEVALLOIS-PERRET++92300+FR'
      CTA+OC+LEVY MICHAEL'
      COM+0147574678:TE'
      NAD+SU+NOV:100'
      NAD+ST+00000:174++HERRERO UMBERTO+2024 AVENUE DE SOISSONS:+CHATEAU-THIERRY++02400+FR'
      CTA+GR'
      COM+0660066099:TE'
      COM+umberto.herrero@gmail.com:EM'
      NAD+AA+26336:100'
      LIN+2++1231614+0'
      PIA+1+0+0+0'
      LIN+1'
      PIA+5+MEL013:SA'
      IMD+F+8+:::MENICON PREMIO TORIC'
      QTY+21:1:CU'
      CCI+++ABO:::ABG'
      MEA+AAE++MM:14.00'
      CCI+++ABO:::RAY'
      MEA+AAE++MM:08.60'
      CCI+++ABO:::SPH'
      MEA+AAE++DP:-0.75'
      CCI+++ABO:::CYL'
      MEA+AAE++DP:-0.75'
      CCI+++ABO:::CLX'
      MEA+AAE++°:090'
      RFF+FI:3'
      RFF+AEG:1231614'
      NAD+UD+++HERRERO'
      LIN+2'
      PIA+5+MEL013:SA'
      IMD+F+8+:::MENICON PREMIO TORIC'
      QTY+21:1:CU'
      CCI+++ABO:::ABG'
      MEA+AAE++MM:14.00'
      CCI+++ABO:::RAY'
      MEA+AAE++MM:08.60'
      CCI+++ABO:::SPH'
      MEA+AAE++DP:-0.75'
      CCI+++ABO:::CYL'
      MEA+AAE++DP:-0.75'
      CCI+++ABO:::CLX'
      MEA+AAE++°:090'
      RFF+FI:3'
      RFF+AEG:1231614'
      NAD+UD+++HERRERO'
      UNS+S'
      UNT+50+137'
      UNZ+1+253006'
   `);

const order = new Order16033();
order.interpret(edifact);

// the property data of order contains all data of the order
// please note that most properties are a camelCase of the Edifact norm definition for the element / component
// some like SPH are shortcuts
// some like party embed objects discribe by the Qualifier code (ex BY)

assert(_.isEqual(order.data,
{
  messages: [
    {
      lines: [
        {
          ItemNumber: 'MEL013',
          ItemNumberType: "SA",
          itemDescription1: 'MENICON PREMIO TORIC',
          itemDescription2: undefined,
          lineItemNumber: 1,
          quantity: '1',
          ABG: '14.00',
          RAY: '08.60',
          SPH: '-0.75',
          CYL: '-0.75',
          CLX: '090',
          typeOfLine: '3',
          opticianReferenceNumber: '1231614',
          party: { UD: { nameAndAddress: [ '' ], partyName: [ 'HERRERO' ] } }
        },
        {
          ItemNumber: 'MEL013',
          ItemNumberType: "SA",
          itemDescription1: 'MENICON PREMIO TORIC',
          itemDescription2: undefined,
          lineItemNumber: 2,
          quantity: '1',
          ABG: '14.00',
          RAY: '08.60',
          SPH: '-0.75',
          CYL: '-0.75',
          CLX: '090',
          typeOfLine: '3',
          opticianReferenceNumber: '1231614',
          party: { UD: { nameAndAddress: [ '' ], partyName: [ 'HERRERO' ] } }
        }
      ],
      party: {
        BY: {
          partyId: '26336',
          codeListQualifier: '100',
          nameAndAddress: [ '' ],
          partyName: [ 'WIN OPTIC' ],
          street: [ '31 RUE LOUISE MICHEL' ],
          cityName: 'LEVALLOIS-PERRET',
          countrySubEntityDetails: [ '' ],
          postalIdentificationCode: '92300',
          countryNameCode: 'FR',
          CTA: {
            OC: {
              departmentOrEmployeeIdentification: 'LEVY MICHAEL',
              COM: { TE: '0147574678' }
            }
          }
        },
        SU: { partyId: 'NOV', codeListQualifier: '100' },
        ST: {
          partyId: '00000',
          codeListQualifier: '174',
          nameAndAddress: [ '' ],
          partyName: [ 'HERRERO UMBERTO' ],
          street: [ '2024 AVENUE DE SOISSONS', '' ],
          cityName: 'CHATEAU-THIERRY',
          countrySubEntityDetails: [ '' ],
          postalIdentificationCode: '02400',
          countryNameCode: 'FR',
          CTA: {
            GR: {
              COM: { TE: '0660066099', EM: 'umberto.herrero@gmail.com' }
            }
          }
        },
        AA: { partyId: '26336', codeListQualifier: '100' }
      },
      messageReferenceNumber: '137',
      documentNumber: '1231614',
      dateOfOrder: '2018-10-01 12:21:00'
    }
  ],
  senderIdentification: 'WS-ESTORE',
  recipientIdentification: 'NOV',
  dateOfPreparation: '2018-10-01 12:55:00',
  interchangeReference: '253006',
  applicationReference: 'ESTORE',
  testIndicator: '0'
}
));

/***** be careful about where is found some data ****

According to the norm, some segment can be set at the message level (=order)
or at the line level.

For example `NAD+UD` (= end user) can be found before the first `LIN` or inside a line.

Currently, the library set the corresponding attributes at the level it found the segment.

If you need to accept for example `NAD+UD` at any level, please use the following code: (continuing the example above)
*/

// end user for line 1
const message0 = order.data.messages[0];
let endUser = _.get(message0,'lines[0].party.UD') ||
              _.get(message0,'lines[0].party.UD');
assert(endUser.partyName[0] === 'HERRERO');
```

## structure of the library

```plantuml
@startuml
agent YourApplication
agent Order16033
agent Message
Order16033 -|> Message

agent Parser
agent Validator

YourApplication --> Order16033: interpret(edifact)
YourApplication <-- Order16033: .data
Order16033 --> Parser: new
Order16033 --> Validator: new
Order16033 <-- Parser: on..
Parser o- Validator
@enduml
```

### Order16033

[reference](docs/index.html#order16033)

This class interpret ORDERS according to 16033 (currently limited to contact lenses).

### Message

Message is the super class of Order16033 and implement all the mechanic about segment interpretation.

for each segment found in the edifact message a `segmentXXX` method ( where XXX is the segment code) is called. If no method is found an error is thrown.

This mean that the class that extends Message (like Order16033) must implement all segment that can be found in the message.

Message constructor needs 3 parameters:

-   the encoding (`UNOC` in the case of Order16033),
-   the segments definition
-   the elements as defined by edifact library.

each `segmentXXX(s)` methods will receive the current segment as parameter, so you can easily access any value of the segment with `s.val(elementNumber, componentNumber)` or alternatively call `this.expectVal(elementNumber, componentNumber,acceptedValues)` that both check that the value of the element/component in the current segment is one of the given values and returns this value. if this is not the case an error will be throw with an adequate message error.

Most `segmentXXX` method will just set some property of the data property of the class extending Message, but sometimes, it will also change the state of the interpretation. For more example see `segmentLIN` of `Order16033` that creates a new `._currentLine`, and adds it to the `.data.lines` array.

Methods like `segmentPIA` will set properties of the `._currentLines`.

### Edi

[reference](docs/api.md#edi)

the Edi class implement some basic helpers in order to convert dates,
and also implements a writer (see below).

One usefull static function for test and example is `compact` that allow to write your edifact examples on multiple lines, with indentation spaces for the purpose of readability and compact this into a valid edifact string.

## EDIFACT première approche

[structure de base](https://ecosio.com/en/blog/edi-standards-overview-structure-of-an-edifact-file/):

### Messages

le texte complet de notre échange. en l'occurence il s'agit d'un message ORDERS [norme UN pour ORDERS](http://www.unece.org/fileadmin/DAM/trade/untdid/d01a/trmd/orders_c.htm)

#### segment

le message est composé de segments.
le segment débute avec un code (de 3 lettres) suivi d'un `+` et se termine par `'`.
le segment est composé de `data element`qui sont séparés par des `+`

##### data element

un élement est lui même composé de `component` qui sont séparés (si il y a lieu) par des `:`

## sémentique de l'EDIFACT

comme la norme est touffue juste quelles indications pour mieux aborder celle-ci:

### lignes de commande

une ligne de commande est représentée par un goupe de segments [group 29](https://service.unece.org/trade/untdid/d11a/trmd/orders_c.htm#1100_X)

les lignes de commandes sont dans ce qui s'appelle `DETAIL SECTION` qui débute par le premier segment `LIN` et se termine implicitement lorsque la `SUMMARY SECTION` débute par le segment `UMS`
