Under construction
Documentation
- Library book (one-time) supply: https://www.editeur.org/31/Library-Book-Supply/
- Library serials and subscriptions (ongoing) supply: https://www.editeur.org/48/Serials-and-Subscription-Products/ Question: does any library send EDIFACT orders to their vendors for ongoing? May only be needed for one-time orders. From A-M: Dennis Bridges should doublecheck with the Acq SIG. In my experience, EDIFACT orders are used mainly for one-time orders, not ongoing. If there are any libraries that need EDIFACT for ongoing orders, that will be MUCH less frequent than one-time orders.
- 11 Jan 2022: The response from the group so far has been that no one uses EDIFACT for ongoing. Though it is possible in theory to do so, this would make it very difficult to get examples of how it should be done. GBV has said that as long as the note to Vendor is included in the EDI details there is no need to exclude them.
- This example does not account for POLs with multiple locations/funds, but that is supported by the EDIFACT format. Will need to find an example From A-M: Checking with SMEs in the Consortial and Acq Slack channels. Will add examples when/if supplied by any libraries. So far (since 4 Jan), no examples supplied by libraries. A-M will dig up examples from previous notes. Best to account for these from the start. In a future iteration, consider adding a configuration field that allows libraries to drop these types of POLs out of the EDIFACT
Monographic Order (complete message, followed by a table explaining each field)
These samples may not have every field that FOLIO may want to support. Should review/confirm with the SMEs, for one-time/ongoing and physical/E/mixed
UNA:+.? '
UNB+UNOC:3+901494200:31B+0142948:31B+130620:0315+1001'
UNH+1001+ORDERS:D:96A:UN:EAN008'
BGM+220+2808+9'
DTM+137:20130620:102'
NAD+BY+901494200::31B'
NAD+SU+0142948::31B'
RFF+API:854674:91'
CUX+2:GBP:9'
LIN+1++9780393966510:EN'
PIA+5+0393966518:IB'
IMD+L+009+:::Stiglitz, Joseph E.'
IMD+L+050+:::Economics of the public sector / Jo:seph E. Stiglitz.'
IMD+L+109+:::W W Norton'
IMD+L+110+:::New York ?:'
IMD+L+170+:::c2000.'
IMD+L+180+:::Book'
QTY+21:1'
PRI+AAB:49.99'
RFF+LI:2808-1'
RFF+BFN:LIBRARY'
RFF+SLI:99932156716'
LOC+20+::92'
LIN+2++9781849207812:EN'
PIA+5+184920781X:IB'
IMD+L+009+:::Flick, Uwe, 1956-'
IMD+L+050+:::Introducing research methodology ?::a beginner?'s guide to doing a resea'
IMD+L+050+:::rch project / Uwe Flick.'
IMD+L+109+:::Sage Publications'
IMD+L+110+:::London ;'
IMD+L+170+:::c2011.'
IMD+L+180+:::Book'
QTY+21:1'
PRI+AAB:24.99'
RFF+LI:2808-2'
RFF+BFN:LIBRARY'
LOC+20+::92'
LIN+3++9781846144172:EN'
PIA+5+1846144175:IB'
IMD+L+009+:::Ovenden, Mark, 1963-'
IMD+L+050+:::London Underground by design / Mark: Ovenden.'
IMD+L+109+:::Particular'
IMD+L+110+:::London ?:'
IMD+L+170+:::2013.'
IMD+L+180+:::Book'
QTY+21:1'
PRI+AAB:20.0'
RFF+LI:2808-3'
RFF+BFN:LIBRARY'
LOC+20+::92'
LIN+4++9780230390584:EN'
PIA+5+0230390587:IB'
IMD+L+050+:::Total sustainability in the built e:nvironment / edited by Alison Cotgr'
IMD+L+050+:::ave and Mike Riley.'
IMD+L+109+:::Palgrave Macmillan'
IMD+L+110+:::Basingstoke ?:'
IMD+L+170+:::2013.'
IMD+L+180+:::Book'
QTY+21:1'
FTX+LIN++::intentional duplicate'
PRI+AAB:36.99'
RFF+LI:2808-4'
RFF+BFN:LIBRARY'
RFF+SLI:
LOC+20+::92'
UNS+S'
CNT+1:00004'
CNT+2:4'
UNT+000070+2808'
UNZ+1+1001'
Field Mapping Table
EDIFACT Field (example) | FOLIO field mapping | Open questions | Omit? (always/ if null/ never) | Description | Comments |
---|---|---|---|---|---|
UNA:+.? ' | never | Start of file | Can contain multiple order messages | ||
UNB+UNOC:3+901494200:31B+0142948:31B+130620:0315+1001' | UNOC:3 -> constant value vendorEdiOrdersExportConfig. vendorEdiOrdersExportConfig. vendorEdiOrdersExportConfig. vendorEdiOrdersExportConfig. current date:time Job ID | never | Interchange header Library EDI code:Library EDI type; Vendor EDI code:VendorEDI type + datetime + file ID | seller first, recipient second, date-time of preparation, file ID (starts with 1 and can go up to 14 digits) | |
UNH+1001+ORDERS:D:96A:UN:EAN008' | Job ID ORDERS:D:96A:UN:EAN008 → constant values | never | Order header = Start of order; EDIFACT message type | There would be a new UNH for each FOLIO PO in the file | |
BGM+220+2808+9' | compositePurchaseOrder. poNumber | never | FOLIO PO | 220 = order If at least one of the lines is rush, it's a rush order 9 = original 7 = duplicate (ie retransmission) = resend With current implementation orders are exported only once, so qualifier is always 9. | |
DTM+137:20130620:102' | 137 -> constant value compositePurchaseOrder. dateOrdered | never | Order date:Date format | Use dateOrdered or use file construction date? DB: Use the date ordered. the vendor will probably ignore this date as they assigned their own order date when the file is processed on their end. | |
NAD+BY+901494200::31B' | vendorEdiOrdersExportConfig. vendorEdiOrdersExportConfig. | never | Library EDI code and Library EDI type | "buyer name" (according to this doc) Can it vary within an order? DB: No, if there is a line with a different account that is for a different EDI configuration it will be added to a different file. It think we need to ignore the Library EDI code data point that exists in the account schema. | |
NAD+SU+0142948::31B' | vendorEdiOrdersExportConfig. vendorEdiOrdersExportConfig. | never | Vendor ID and ID type | "supplier name" | |
RFF+API:854674:91' | compositePurchaseOrder. compositePoLines.[first]. vendorDetail. vendorAccount 91 → constant value | if null | "buyer ID number" What do we do if there are different account numbers assigned to different lines in this PO? DB: I propose we do not allow this for the initial version of the integration. Meaning that if one of the POLs on a PO is flagged for export all flagged POLs on that PO must have the same account number. Ideally this validation can be done when opening POL. If not we will need to throw an error when building the file. The error message should include all PO numbers that could not be exported.
DB: Note it's possible that the order will have no account number. If the EDI configuration is the "Default integration" there will be no account number. From docs: RFF REFERENCE One or two optional occurrences per segment group SG02, giving the VAT or other | ||
CUX+2:GBP:9' | 2 and 9 -> constant values system currency from configuration module | never | Order currency | If FOLIO default currency and vendor currency are not the same, this may include info about both currencies, with different qualifiers 9 = order currency 10 = pricing currency Prevent mixed currency within an order by skipping such orders, and let the user know about an error!!! Do we still want to prevent anything? From the example below it looks like it's fine to have different currencies. DB: Send system currency at this level and POL currencies at the line level. GOBI shared an example of this A recent example from an Australian customers who's default currency is AUD but item currency is USD: UNA:+.? ‘ | |
LIN+1++9780393966510:EN' | compositePurchaseOrder. compositePoLines.[first]. details. productIds.[?]. productId check the productIdType to be one of the following (include the first one): ISBN, ISSN, ISMN qualifier: IB, IM or IS based on type | never | Order line 1 | May or may not be the same number as the POL line number, since the POLs may skip numbers, and the EDI order does not. From A-M: Keep in mind that the product ID is not always an ISBN. I think it's important to include the qualifier, which we should be able to identify based on the Product ID type. And if the Product ID type is not recognized, have a backstop of "other" or "unknown". DB: "The LIN segment carries the line number within the message, and may carry an EAN-13 article number (barcode number). The PIA segment carries any other product identifiers." Documentation identifies this as the General Trade Item Number (GTIN) which for library purchases may be accepted as 13 digit ISBN as AM stated above. | |
PIA+5+9780393966510:EN' | compositePurchaseOrder. compositePoLines.[first]. details. productIds.[n]. productId qualifier: IB, IM, IS or MF based on type PIA+5+ for product ID from previous field PIA+1+ for all other product IDs | if null | Product ID:ID type | ISBN-10 is no longer necessary 5 is a constant value? DB: One or more occurrences are used in this application to send an ISBN and/or a supplier’s own product code, either as the main product identifier (where no EAN number was given in LIN segment 39, or as an additional identifier. If no product code is available, the PIA segment is omitted, and the product must be fully identified by description in IMD segment 41. An additional occurrence may be used to identify an acceptable substitute for the product ordered. 1 = additional identification: use when the PIA segment carries an identifier which is additional to the main product identifier (eg a supplier’s own code sent in addition to the ISBN or EAN number) 1S = additional identification: an identification number for a multi-volume or multipart set to which the product belongs 2 = identification of an acceptable substitute 5 = main product identification: use when the PIA segment carries the main product code (normally the ISBN) EN = EAN-13 article number IB = ISBN (International Standard Book Number) | |
IMD+L+009+:::Stiglitz, Joseph E.' | L+009+::: → constant compositePurchaseOrder. compositePoLines.[first]. contributors.[n]. contributor repeat for each PO line | if null | Author (Contributor) | Optional: up to 99 repeats of IMD segment 41 may be used to give bibliographic details of the item to which the order line refers. This is mandatory if the item is not identified by a code or codes in LIN segment 39 and/or PIA segment 40. Where the text of a bibliographic data element exceeds 70 characters, additional repeats of the segment, carrying the same code in DE 7081, may be used as “continuation” segments. Multiples would be IMD+L+009+::: IMD+L+009+::: | |
IMD+L+050+:::Economics of the public sector / Jo:seph E. Stiglitz.' | L+050+::: → constant compositePurchaseOrder. compositePoLines.[first]. titleOrPackage wrap if it's longer than 70 characters | never | Title | From docs: Where the text of a bibliographic data element exceeds 70 characters, additional repeats of the segment, carrying the same code in DE 7081, may be used as “continuation” segments. | |
IMD+L+109+:::W W Norton' | L+109+::: → constant compositePurchaseOrder. compositePoLines.[first]. publisher | if null | Publisher | ||
always | Place of publication | Not available from FOLIO POL should we use a default value for this field? From A-M: No, omit the field. Do not use a default. Since it's not a required field, that will be OK. | |||
IMD+L+170+:::c2000.' | L+170+::: → constant compositePurchaseOrder. compositePoLines.[first]. publicationDate | if null | Publication date | ||
IMD+L+180+:::Book' | L+180+::: → constant materialTypeService.getMaterialTypeName for compositePurchaseOrder. compositePoLines.[first]. physical. materialType or compositePurchaseOrder. compositePoLines.[first]. eresource. materialType repeat the field for each type specified | if null | Material type | which material type should we use for mixed orders? From A-M: If no Inventory created, material type is optional. I would use the following (but doublecheck with Dennis Bridges )
| |
QTY+21:1' | 21 -> constant value compositePurchaseOrder. compositePoLines.[first]. cost. quantityPhysical or compositePurchaseOrder. compositePoLines.[first]. cost. quantityElectronic whichever is higher | never | Quantity ordered | should we count the sum of electronic and physical copies? or should we create a separate field for each type? From A-M and Acq SIG:
| |
PRI+AAB:49.99' | AAF → constant value compositePurchaseOrder. compositePoLines.[first]. cost. poLineEstimatedPrice | if null | Price | Several different kinds of qualifiers may be used; see documentation From the documentation: Price qualifier M an..3 AAA = calculation price net (the unit price which will actually be charged by the
| |
CUX+2:GBP:9' | 2 and 9 → constant values compositePurchaseOrder. compositePoLines.[first]. cost. currency | if null | |||
FTX+LIN++::intentional duplicate' | compositePurchaseOrder. compositePoLines.[first]. vendorDetail. instructions | if null or empty | POL: Instructions to vendor | ||
RFF+LI:2808-1' | compositePurchaseOrder. compositePoLines.[first]. poLineNumber | never | FOLIO POL | ||
RFF+BFN:LIBRARY' | compositePoLines.[first]. fundDistribution.[?]. code depending on the configuration, this should be either replaced or followed by ?: and by expense class that we would get by calling a service and providing expense class ID found here: compositePurchaseOrder. compositePoLines.[first]. fundDistribution.[?]. expenseClass repeat for each fund distribution up to 9 (10 total RFF fields) | if null | FOLIO fund code Example: RFF+BFN:HIST?:Elec' | Also expense class? Colon has special meaning in EDIFACT; will it be an issue that FOLIO uses colon between fund and expense class? (use ?as an escape?) From A-M and Acq SIG: Yes it will definitely be an issue. Is it possible to use an escape so the colon can be treated as a separator properly? We also will need to explain this convention to the vendors who will be receiving these orders. Dung Lan: MONO:HIST: expense class is more important than the fund; FOLIO outputs both; check with vendor on whether they could only pull the expense class from the fund Lisa S: Is it possible to only send Fund and not expense class? Peter S: Definitely need to send fund + expense class Maybe have as part of config. F+E, F only, E only. Dennis will review Libraries: if questions about fund:expense class handling, check with your vendor(s) show warning if we couldn't include some of them because of 10 RFF fields limit | |
RFF+SLI:99932156716' | compositePurchaseOrder. compositePoLines.[first]. vendorDetail. referenceNumbers.[n]. refNumber repeat the field for each reference number up to 10 total RFF fields | if null | Vendor reference number | (repeat if multiples) show warning if we couldn't include some of them because of 10 RFF fields limit | |
LOC+20+::92' | 20 → constant value Make a call to get location code for the ID found here (for holding we still need to get location code, not the holding code): compositePurchaseOrder. compositePoLines.[first]. locations.[?]. locationId repeat for each location and/or holding | if null | Delivery location | From A-M: Not the delivery location - actually the FOLIO location code. Populate if it's in the POL; omit if it's not in the POL. Note for the future - we could add a row to match locations with funds: GIR+L01+1:LQT+263364:LLO+Ask Library Helpdesk staff for assistance:LSQ+LIB48_3509_AMA:LFN’ | |
LIN+2++9781849207812:EN' | compositePurchaseOrder. compositePoLines.[second]. details. productIds.[?]. productId | From LIN to LOC we just repeat the same for each line in the order | |||
PIA+5+184920781X:IB' | |||||
IMD+L+009+:::Flick, Uwe, 1956-' | |||||
IMD+L+050+:::Introducing research methodology ?::a beginner?'s guide to doing a resea' | |||||
IMD+L+050+:::rch project / Uwe Flick.' | |||||
IMD+L+109+:::Sage Publications' | |||||
IMD+L+110+:::London ;' | |||||
IMD+L+170+:::c2011.' | |||||
IMD+L+180+:::Book' | |||||
QTY+21:1' | |||||
PRI+AAB:24.99' | |||||
RFF+LI:2808-2' | From A-M: We'll also need an optional, repeatable RFF field for vendor reference number, e.g. RFF+SLI:99932156716' | ||||
RFF+BFN:LIBRARY' | |||||
LOC+20+::92' | |||||
LIN+3++9781846144172:EN' | compositePurchaseOrder. compositePoLines.[third]. details. productIds.[?]. productId | ||||
PIA+5+1846144175:IB' | |||||
IMD+L+009+:::Ovenden, Mark, 1963-' | |||||
IMD+L+050+:::London Underground by design / Mark: Ovenden.' | |||||
IMD+L+109+:::Particular' | |||||
IMD+L+110+:::London ?:' | |||||
IMD+L+170+:::2013.' | |||||
IMD+L+180+:::Book' | |||||
QTY+21:1' | |||||
PRI+AAB:20.0' | |||||
RFF+LI:2808-3' | |||||
RFF+BFN:LIBRARY' | |||||
LOC+20+::92' | |||||
LIN+4++9780230390584:EN' | compositePurchaseOrder. compositePoLines.[fourth]. details. productIds.[?]. productId | ||||
PIA+5+0230390587:IB' | |||||
IMD+L+050+:::Total sustainability in the built e:nvironment / edited by Alison Cotgr' | |||||
IMD+L+050+:::ave and Mike Riley.' | |||||
IMD+L+109+:::Palgrave Macmillan' | |||||
IMD+L+110+:::Basingstoke ?:' | |||||
IMD+L+170+:::2013.' | |||||
IMD+L+180+:::Book' | |||||
QTY+21:2' | |||||
PRI+AAB:36.99' | |||||
RFF+LI:2808-4' | |||||
RFF+BFN:LIBRARY' | |||||
LOC+20+::92' | |||||
UNS+S' | constant | never | Summary (footer) separator | Indicates that all the line items of the PO are above, and next will be the summary of the PO | |
CNT+1:5' | 1 → constant Sum of quantities of each POLine in this PO Quantity for each POLine is calculated like this: compositePurchaseOrder. compositePoLines.[n]. cost. quantityPhysical or compositePurchaseOrder. compositePoLines.[n]. cost. quantityElectronic whichever is higher | never | Total quantity | Calculated by adding all the QTY in the individual line items | |
CNT+2:4' | 2 → constant count of POLines in this PO | never | Total number of line items | If any line has QTY >1, then CNT+1 ≠ CNT+2 | |
UNT+000070+2808' | number of lines in this segment (without zeros at the beginning) compositePurchaseOrder. poNumber | never | Message trailer (aka footer) | Signals the end of this PO; may be followed by a UNH segment starting the next FOLIO PO in the file | |
UNZ+1+1001' | message count Job ID | never | Interchange trailer (aka end of file) | file ID - same as at the beginning of the file |
Comp PO example:
{
"id": "2885c9f7-ea6b-492c-bbf3-f735aa1b3991",
"approved": true,
"billTo": "5f8a321e-6b38-4d90-92d4-bf08f91a2242",
"manualPo": false,
"notes": [
"Check credit card statement to make sure payment shows up"
],
"poNumber": "10016",
"orderType": "One-Time",
"reEncumber": false,
"shipTo": "f7c36792-05f7-4c8c-969d-103ac6763187",
"template": "4dee318b-f5b3-40dc-be93-cc89b8c45b6f",
"totalEstimatedPrice": 6,
"totalEncumbered": 0,
"totalExpended": 0,
"totalItems": 3,
"vendor": "e0fb5df2-cdf1-11e8-a8d5-f2801f1b9fd1",
"workflowStatus": "Pending",
"compositePoLines": [
{
"id": "a0cb094d-9edb-4578-b8b4-b45f20e9f29f",
"edition": "",
"checkinItems": false,
"instanceId": "e54b1f4d-7d05-4b1a-9368-3c36b75d8ac6",
"acquisitionMethod": "306489dd-0053-49ee-a068-c316444a8f55",
"automaticExport": false,
"alerts": [],
"cancellationRestriction": true,
"claims": [],
"collection": false,
"contributors": [
{
"contributor": "Sosa, Omar",
"contributorNameTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2a"
},
{
"contributor": "Keita, Seckou, 1977-",
"contributorNameTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2b"
}
],
"cost": {
"listUnitPrice": 2,
"currency": "USD",
"discountType": "percentage",
"quantityPhysical": 3,
"poLineEstimatedPrice": 6
},
"details": {
"productIds": [
{
"productId": "9786316800312",
"productIdType": "8261054f-be78-422d-bd51-4ed9f33c3422",
"qualifier": ""
},
{
"productId": "OTA-1031 Otá Records",
"productIdType": "b5d8cdc4-9441-487c-90cf-0c7ec97728eb"
}
],
"subscriptionInterval": 0
},
"fundDistribution": [
{
"code": "AFRICAHIST",
"fundId": "7fbd5d84-62d1-44c6-9c45-6cb173998bbd",
"expenseClassId": "1bcc3247-99bf-4dca-9b0f-7bc51a2998c2",
"distributionType": "percentage",
"value": 80
},
{
"code": "ASIAHIST",
"fundId": "55f48dc6-efa7-4cfe-bc7c-4786efe493e3",
"distributionType": "percentage",
"value": 20
}
],
"isPackage": false,
"locations": [
{
"locationId": "fcd64ce1-6995-48f0-840e-89ffa2288371",
"quantity": 1,
"quantityPhysical": 1
},
{
"holdingId": "e9285a1c-1dfc-4380-868c-e74073003f43",
"quantity": 2,
"quantityPhysical": 2
}
],
"orderFormat": "Physical Resource",
"paymentStatus": "Pending",
"physical": {
"createInventory": "Instance, Holding, Item",
"materialType": "1a54b431-2e4f-452d-9cae-9cee66c9a892",
"materialSupplier": "e0fb5df2-cdf1-11e8-a8d5-f2801f1b9fd1",
"volumes": []
},
"poLineNumber": "10016-1",
"publicationDate": "[2017]",
"publisher": "Otá Records, ",
"purchaseOrderId": "2885c9f7-ea6b-492c-bbf3-f735aa1b3991",
"receiptStatus": "Pending",
"reportingCodes": [],
"rush": false,
"source": "User",
"titleOrPackage": "Transparent water",
"vendorDetail": {
"instructions": "",
"vendorAccount": "1234",
"referenceNumbers": []
},
"metadata": {
"createdDate": "2022-01-26T14:06:10.681+00:00",
"createdByUserId": "07845848-84b7-52a6-a26b-96c88dd4a203",
"updatedDate": "2022-01-26T14:06:10.681+00:00",
"updatedByUserId": "07845848-84b7-52a6-a26b-96c88dd4a203"
}
}
],
"acqUnitIds": [],
"tags": {
"tagList": [
"amazon"
]
},
"metadata": {
"createdDate": "2022-01-26T14:01:16.706+00:00",
"createdByUserId": "07845848-84b7-52a6-a26b-96c88dd4a203",
"updatedDate": "2022-01-26T14:01:16.706+00:00",
"updatedByUserId": "07845848-84b7-52a6-a26b-96c88dd4a203"
},
"needReEncumber": false
}
Vendor EDI orders export config example:
{
"configName": "testConfigName",
"configDescription": "testConfigDescription",
"vendorId": "146b6c7f-0b8a-43b9-b35d-6489e6daee11",
"exportConfigId": "246b6c7f-0b8a-43b9-b35d-6489e6daee22",
"ediConfig": {
"accountNoList": [
"1234",
"5678"
],
"libEdiCode": "testLibEdiCode",
"libEdiType": "014/EAN"
"vendorEdiCode": "testVendorEdiCode",
"vendorEdiType": "014/EAN",
"notes": "test notes 123!",
"ediNamingConvention": "testEdiNamingConvention",
"defaultAcquisitionMethods": [
"346b6c7f-0b8a-43b9-b35d-6489e6daee33",
"446b6c7f-0b8a-43b9-b35d-6489e6daee44"
],
"sendAccountNumber": false,
"supportOrder": false,
"supportInvoice": false,
},
"ediFtp": {
"ftpConnMode": "Active",
"invoiceDirectory": "testInvoiceDirectory",
"ftpFormat": "SFTP",
"isPrimaryTransmissionMethod": true,
"password": "testpassword",
"notes": "notes!!!",
"orderDirectory": "testOrderDirectory",
"serverAddress": "testServerAddress",
"ftpMode": "ASCII",
"ftpPort": 6,
"username": "testusername"
},
"ediSchedule": {
"scheduleParameters": {
"scheduleFrequency": 1,
"scheduleTime": "testScheduleTime",
"schedulingDate": "2000-01-23T04:56:07.000+00:00",
"weekDays": [
"MONDAY",
"FRIDAY"
],
"timeZone": "UTC",
"id": "546b6c7f-0b8a-43b9-b35d-6489e6daee55",
"schedulePeriod": "MONTH"
},
"schedulingNotes": "testSchedulingNotes",
"enableScheduledExport": false
},
"isDefaultConfig": false
}