{"id":13591975,"url":"https://github.com/walmartlabs/gozer","last_synced_at":"2025-04-09T06:13:19.447Z","repository":{"id":31759579,"uuid":"128812322","full_name":"walmartlabs/gozer","owner":"walmartlabs","description":"Open source library to parse various X12 file formats for retail/supply chain","archived":false,"fork":false,"pushed_at":"2024-11-08T19:18:06.000Z","size":838,"stargazers_count":68,"open_issues_count":8,"forks_count":26,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-02T05:07:52.708Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/walmartlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-09T17:53:20.000Z","updated_at":"2024-11-08T19:18:10.000Z","dependencies_parsed_at":"2025-01-08T00:12:38.261Z","dependency_job_id":"e61b71d9-2c93-408a-a768-ab80d065e7de","html_url":"https://github.com/walmartlabs/gozer","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walmartlabs%2Fgozer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walmartlabs%2Fgozer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walmartlabs%2Fgozer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/walmartlabs%2Fgozer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/walmartlabs","download_url":"https://codeload.github.com/walmartlabs/gozer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247987285,"owners_count":21028895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T16:01:04.353Z","updated_at":"2025-04-09T06:13:19.422Z","avatar_url":"https://github.com/walmartlabs.png","language":"Java","funding_links":[],"categories":["Libraries"],"sub_categories":["Java"],"readme":"[![Build Status](https://github.com/walmartlabs/gozer/workflows/Gozer-CI/badge.svg)](https://github.com/walmartlabs/gozer/actions)\n\n[![codecov](https://codecov.io/gh/walmartlabs/gozer/branch/master/graph/badge.svg)](https://codecov.io/gh/walmartlabs/gozer)\n\n# EDI X12 Standard Parsing Library\n\nThe EDI X12 Standard provides a uniform way for companies to exchange information across different sectors. \n\nThis open source library, available through @WalmartLabs, provides Java based classes that can parse various X12 file formats into a representative Java object model. It's primary focus is on those formats related to the Supply Chain sector.\n\n## Supported X12 Format Parsers and Transaction Set Parsers\n\n| X12     \t| Name                             \t    | Description \t  | X12 Version(s) |\n|---------\t|-------------------------------------   |-------------\t  |--------------  |\n| Generic \t| Handles X12 Standard Documents in a generic way\t  | Generic | 5010      |\n| DEX 894 \t| Delivery/Return Base Record \t        | DSD deliveries | 4010,5010      |\n| DEX 895 \t| Delivery/Return Acknowledgment Record  | DSD delivery acknowledgement | Under consideration     |\n| EDI 856   \t| Ship Notice/Manifest Transaction Set   | Advance Ship Notice (ASN) | 5010 |\n| EDI 850   \t| PO Transaction Set                     | Purchase Order (PO) | WIP |\n| EDI 855   \t| PO Acknowledgment Transaction Set      | Purchase Order acknowledgement| Under consideration |\n| EDI 810   | Invoice Transaction Set                | Invoice | Under consideration     |\n| EDI 214   | Shipment Status Transaction Set        | Shipment Status  | Under consideration     |\n\n## Why the name Gozer\n\nThe Agile development team at @WalmartLabs that is responsible for the design and development of \"inbound processing\" products is called the GhostBusters. Inbound Processing covers the broad array of micro-services involved with moving and receiving merchandise between locations, including the supplier to the distribution center, the supplier to the store (DSD), and the distribution center to the store. \n\n## Basic Design Approach\n\nGozer seeks to provide more than a generic X12 parsing capability that turns an EDI X12 message into a list of segments and elements, although it does have that capability. Gozer hopes to provide a library of easy to use classes, that can transform a parsed EDI message into a set of POJOs that corresponds with a specific X12 format. Attributes are labeled with their business names rather than the more cryptic segment identifiers. In addition, there are numerous interfaces and various extension points allowing users to customize some of the parsing approaches that are offered in Gozer.\n\nThe initial design provided some basic validation capabilities but most of that was updated in 0.3.0. It is now recommended that users of the framework build out validation capabilities so that they can enforce compliance with the guides that are agreed upon between the various parties. This also allows users to decide how best to handle the generation of 824 warnings and errors when validation fails.  \n\n### Practical Approach to Parsing\nEach X12 format that is supported will have a Java implementation of the `X12Parser`. The parser will be responsible for parsing the message in the given format to an `X12Document`, which is the representative Java object model (POJO).\n\n```java\npublic interface X12Parser\u003cT extends X12Document\u003e {\n   /**\n   * parse the X12 transmission into a representative Java object\n   *\n   * @return the representative Java object\n   * @throws X12ParserException\n   */\n   T parse(String sourceData);\n```\n\nThe Gozer parsers that implement `X12Parser` are designed to parse a specific EDI X12 document type. In order for a document to be considered successfully parsed the message MUST be well-formed. That means that the segments must have the correct segment identifiers, which must be nested correctly and appear in the proper order. If the X12 message is not well-formed and can't be parsed the parser will throw an `X12ParserException`. \n\nIf the EDI message was well-formed and successfully parsed that does not mean that it is valid. The parsers, intentionally, do not attempt to validate any values within the segment elements (other than segment identifiers). They are intended to be as loose as possible regarding validation during the parsing of different versions of the EDI X12 message. Validation can be performed against the `X12Document` that is returned by the parser when it is successful.\n\nGozer currently provides two implementations of the `X12Parser`. \n\n- The `StandardX12Parser` for most EDI documents wrapped in ISA/ISE envelopes and contain transaction sets.\n- The `DefaultDex894Parser` to handle DEX 894 documents.\n\nUsing Gozer is as easy as passing the contents of the EDI message to an instantiated parser:\n\n\tX12Document x12Doc = x12Parser.parse(x12Message);\n\t\nCreating an instance of the `X12Parser` will vary depending on which one is being used. \n\n# Getting Started: The Standard EDI Parser and Document in Gozer\n\nMost EDI/X12 messages adhere to a common format that wraps transaction sets in an envelope. These can all be parsed using the `StandardX12Parser`.  \n\nCreating an instance of the `StandardX12Parser` is very simple:\n\n```java\ntry {\n   StandardX12Parser x12Parser = new StandardX12Parser();\n   StandardX12Document x12Document = x12Parser.parse(new String(ediMessage));\n} catch (X12ParserException e) {\n   // parsing did not go well\n}\n```\n\t\nHowever, please check out the section **Handling Transaction Sets** to make sure the `StandardX12Parser` is setup correctly.\n\n## Exploring the Standard EDI message format\n\nEach message will have an envelope that contains a set  of groups. Each group will contain a set of transaction sets. \n\n```\nISA*...\n\tGS*...*12345*X*005010\n\t\tST*856*00001\n\t\t\t...\n\t\tSE*100*00001\n\tGE*1*12345\nISE*...\n```\n\nThese types of messages can be parsed using the `StandardX12Parser`. This is an implementation of the `X12Parser` interface that returns a `StandardX12Document`. \n\nValid, well-formed messages will be wrapped in an interchange control envelope. This envelope will require the first segment to start with `ISA` and the last segment to end with an `ISE`. \n\n```\nISA*...\n\t...\nISE*...\n```\n\nThe parser will place the elements found in the interchange control envelope in the object `InterchangeControlEnvelope`.\n\nInside the interchange control envelope, the message can contain one or more groups. Each group will start with a `GS` segment line and end with the first occurrence of a segment that has the identifier `GE`. \n\n```\nISA*...\n\tGS*...*12345*X*005010\n\t\t...\n\tGE*1*12345\nISE*...\n```\n\nThe `StandardX12Document` will hold a list of `X12Group`s. Each instance in the list will map to a group in the message. \n\nInside each group, the message can contain one or more transaction sets. Each transaction set will start with an `ST` segment line and end with the first occurrence of a segment that has the identifier `SE`. It is the transaction set that contains an EDI document.\n\n```\nISA*...\n\tGS*...*12345*X*005010\n\t\tST*856*00001\n\t\t\t...\n\t\tSE*100*00001\n\tGE*1*12345\nISE*...\n```\n\nThe attributes in each transaction set will be stored in an object that implements the `X12TransactionSet` interface (more on that later). All of the transaction sets for a particular a group will be placed in the corresponding `X12Group` as a list. \n\nTherefore this EDI message:\n\n```\nISA*...\n\tGS*...*12345*X*005010\n\t\tST*856*00001\n\t\t\tBSN*00*001*20190823*2112*0001\n\t\tSE*100*00001\n\t\tST*856*00002\n\t\t\tBSN*00*002*20190823*2112*0001\n\t\tSE*100*00002\n\tGE*1*12345\n\tGS*...*12346*X*005010\n\t\tST*856*00003\n\t\t\tBSN*00*003*20190823*2112*0001\n\t\tSE*100*00003\n\tGE*2*12346\t\nISE*...\n```\n\nwould be stored in a `StandardX12Document` as follows:\n* One `InterchangeControlEnvelope`\n* list with two `X12Group` objects\n* the first `X12Group` would have a list with two `X12TransactionSet`s\n* the second `X12Group` would have a list with one `X12TransactionSet`\n\t\n\n## Handling Transaction Sets\nEach EDI transmission can contain one or more transaction sets. Each transaction set can represent a different document type. For example the ASN (856) or a Purchase Order (850). Each of these document types are comprised of a variety of different segments. \n\nWhen the `StandardX12Parser` is instantiated it will not be able to parse any EDI document types. \n\n\tStandardX12Parser x12Parser = new StandardX12Parser();\n\nOne or more `TransactionSetParser` implementations must be registered so that the parser will work correctly. Each `TransactionSetParser` will understand a different document type. \n\nThe `GenericTransactionSetParser` is designed to work with any document type but will only be able to return a list of generic `X12Segment`s instead of a more user-friendly domain object. \n\n\tStandardX12Parser x12Parser = new StandardX12Parser();\n\tx12Parser.registerTransactionSetParser(new GenericTransactionSetParser());\n\nIn order to take advantage of the set of POJOs that corresponds with a specific X12 format, each individual `TransactionSetParser` implementation that a user is interested in must be registered individually.\n\n\t// setting up the standard X12 parser to work\n\t// with ASN 856 and PO 850 documents\n\t// all other documents will be ignored\n\tStandardX12Parser x12Parser = new StandardX12Parser();\n\tx12Parser.registerTransactionSetParser(new DefaultAsn856TransactionSetParser());\n\tx12Parser.registerTransactionSetParser(new DefaultPo950TransactionSetParser());\n\nWhen a transaction set does not have a registered parser the `X12StandardParser` will send the list of segments associated with it to an extension point. By default, the extension point will ignore any transaction set that it receives. When it is important to interact with a transaction set that had no `TransactionSetParser` implementation registered a custom class that implements `UnhandledTransactionSet` can be registered. \n\n```java\nStandardX12Parser x12Parser = new StandardX12Parser();\nx12Parser.registerTransactionSetParser(new DefaultAsn856TransactionSetParser());\nx12Parser.registerUnhandledTransactionSet(new CustomHandlerForUnhandledTransactionSet());\n```\n\nLook at the [Sample](https://github.com/walmartlabs/gozer/tree/master/src/test/java/sample) to see a very simplified example of how to register a transaction set parser and use the `StandardX12Parser`.\n\n## Using the parsed document data\n\nThe `StandardX12Document` provides access to the entire parsed EDI message which may contain one or more transaction sets.\n\nIn order to access the first transaction set on the first group:\n\n```java\n// parse an EDI file transmission\nStandardX12Document x12 = x12Parser.parse(new String(ediMessage));\n\t\n// access to envelope\nInterchangeControlEnvelope envelope = x12.getInterchangeControlEnvelope();\n\t\n// access to the groups\nList\u003cX12Group\u003e groups = x12.getGroups();\n\t\n// retrieve the transaction sets from the first group\nList\u003cX12TransactionSet\u003e txForGroupOne = groups.get(0).getTransactions();\n\t\n// retrieve the first transaction set from the first group\nX12TransactionSet txSet = txForGroupOne.get(0);\n\t\n// identify which EDI document type \n// the transaction set represents\nif (\"856\".equals(txSet.getTransactionSetIdentifierCode()) {\n   // we have an ASN\n   AsnTransactionSet asnTx = (AsnTransactionSet) txSet;\n```\t\n\n### Dealing with Hierarchy Loops\n\nSome of the EDI documents have hierarchy loops. Each of the hierarchy segments is related to the others using a set of indexes. \n\n\tHL*1**S\n\tHL*2*1*O\n\tHL*3*2*P\n\tHL*4*3*I\n\tHL*5*3*I\n\nThe basic looping structure (used on an ASN) above denotes a hierarchy of data that starts with a shipment loop. \n\n\t- S(hipment) \n\t\t- O(rder)\n\t\t\t- P(ack)\n\t\t\t\t- I(tem)\n\t\t\t\t- I(item)\n\t\nEach loop may have other segments associated with it. \nFor example this is a pack loop with a MAN segment providing a pack label\n\n\tHL*3*2*P\n\tMAN*GM*00001914178883300010\n\t\nAll looping information will be available in the `X12TransactionSet` object returned by the `TransactionSetParser`.\n\n```java\n// after parsing an EDI message\nif (\"856\".equals(txSet.getTransactionSetIdentifierCode()) {\n   // we have an ASN\n   AsnTransactionSet asnTx = (AsnTransactionSet) txSet;\n   // the first loop is an X12Loop of type Shipment\n   Shipment shipment = asnTx.getShipment()\n\t\n   // get the children loops\n   List\u003cX12Loop\u003e shipmentChildLoops = shipment.getParsedChildrenLoops();\n\t\n   // the Shipment has one or more Order loops\n   // get the first child\n   X12Loop loop = shipmentChildLoops.get(0);\n   if (\"O\".equals(loop.getCode()) {\n      // we have an Order loop\n      Order orderLoop = (Order) loop;\n      // access a segment on the order loop\n      order.getPrf().getPurchaseOrderNumber();\n   \n      List\u003cX12Loop\u003e orderChildLoops = order.getParsedChildrenLoops();\n      X12Loop orderChildLoop = orderChildLoops.get(0);\n\t\t\n      // examine loops on the order\n      switch (orderChildLoop.getCode()) {\n         case \"T\" :\n            // found a tare\n            this.processTare((Tare)orderChildLoop);\n            break;\n         case \"P\" :\n             // found a pack\n            this.processPack((Pack)orderChildLoop);\n            break;\n         case  \"I\" :\n            // found an item\n            this.processItem((Item)orderChildLoop);\n            break;\n         default:\n            break;\n      }\n   \n```\n\nLook at the [X12LoopUtilTest](https://github.com/walmartlabs/gozer/tree/master/src/test/java/com/walmartlabs/x12/util/loop/X12LoopUtilTest) to see how to walk through loops and examine the segments associated with each one.\n\nLook at the [DefaultAsn856TransactionSetParserEntireTxSetTest](https://github.com/walmartlabs/gozer/blob/master/src/test/java/com/walmartlabs/x12/asn856/DefaultAsn856TransactionSetParserEntireTxSetTest.java) to see how to access various parts of the parsed document. \n\nIn earlier versions any error detected during looping would throw an `X12ParserException` stopping any further parsing. Starting with 0.3.0, when an error in looping occurs an exception will no longer be thrown. Instead the parser will set an attribute to indicate how that part of the parsing went. Invalid looping is now treated as a post-parsing validation error. It will be up to the user of the framework to check the value of this attribute and assess the looping issues.\n\n### Dealing with Hierarchy Loop errors\nIt is expected that after parsing, the code should verify how looping was handled.\n\t\n```java\nX12TransactionSet txSet = txForGroupOne.get(0);\nif (txSet.hasLooping()) {\n   if (txSet.isLoopingValid()) {\n      // looping ok\n   } else {\n      // handle looping errors\n      List\u003cX12ErrorDetail\u003e loopingErrors = asnTx.getLoopingErrors();\n   }\n```\n\nAfter parsing, it is considered the responsibility of the consumer to perform any additional validations on the data that was provided in various segments and elements. That can be done through custom code. \n\n\n# Getting Started: The DEX 894 Parser and Document in Gozer\nThe DEX EDI/X12 message format does not follow the standard message format. It has a separate parser, however it still implements the `X12Parser` interface. This allows it to be used in any product with the standard Gozer parser without any special considerations. Since there are no transaction sets in DEX there is nothing extra to register. This parser will work correctly after instantiation. \n\n```java\nString dexMessage = ...\nDefaultDex894Parser dexParser = new DefaultDex894Parser();\nDex894 dexDoc = dexParser.parse(dexMessage);\n```\n\nThe `DefaultDex894Parser` returns an `X12Document` of the type `Dex894`.\n\n### Using utilities after parsing\nA parsed DEX document can be used similar to a standard X12 document. Various utilities can be used for post-processing the data. \nFor example:\n\n```java\nDex894 dex = dexParser.parse(dexMessage);\nDex894Item dexItem = dex.getItems().get(0);\n\n// check CRC on each DEX transaction\nCyclicRedundancyCheck crc16 = new CyclicRedundancyCheck();\nList\u003cDex894TransactionSet\u003e dexTxList = dex.getTransactions();\nfor (Dex894TransactionSet dexTx : dexTxList) {\n   if (crc16.verifyBlockOfText(dexTx.getIntegrityCheckValue(), dexTx.getTransactionData())) {\n      // passed CRC check\n   } else {\n      // failed CRC check\n   }\n}\n\n```\n\n# Contributing to Gozer\n\n## Getting Started: Writing a Parser\n[Guide for writing EDI parsers](AddingParsers.md)\n\n## Getting Started: Writing a TransactionSetParser\n[Guide for writing EDI parsers](AddingTransactionSetParsers.md)\n\n## More Information\n\n[About EDI Standards](http://ediacademy.com/blog/edi-x12-standard/)\n\n[EDI file format basics](https://www.xtranslator.com/prod/beginguidex12.pdf)\n\n[ASC X12 Standards](http://edi.aaltsys.info/01_standards.html)\n\n[EDI transaction set codes](https://www.spscommerce.com/resources/edi-documents-transactions/)\n\n[GTIN formats](https://www.gtin.info/)\n\n[Converting between GTIN formats](https://www.free-barcode-generator.net/ean-14/)\n\n[ITF-14 format](https://www.free-barcode-generator.net/itf-14/)\n\n## Build and Release\n\n```\nmvn clean install\n```\n\nSee [walmartlabs-pom for more information](https://github.com/walmartlabs/walmartlabs-pom)\n\n## Licensing\n\nCopyright 2011-present Walmart Inc.\n\nThis software is licensed under the [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0)\n\nAlso see LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwalmartlabs%2Fgozer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwalmartlabs%2Fgozer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwalmartlabs%2Fgozer/lists"}