eddy 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +103 -37
  3. data/.solargraph.yml +4 -0
  4. data/.vscode/settings.json +17 -0
  5. data/.yardopts +2 -2
  6. data/CHANGELOG.md +50 -0
  7. data/Gemfile.lock +21 -7
  8. data/README.md +32 -3
  9. data/Rakefile +1 -10
  10. data/data/004010/code-lists/100.tsv +164 -0
  11. data/data/004010/code-lists/156.tsv +52 -0
  12. data/data/004010/code-lists/26.tsv +499 -0
  13. data/data/004010/code-lists/etc/100-fancy-definitions.tsv +164 -0
  14. data/data/004010/code-lists/etc/100-with-funds-codes.tsv +180 -0
  15. data/data/004010/code-lists/etc/26-alpha2.tsv +250 -0
  16. data/data/004010/code-lists/etc/26-alpha3.tsv +250 -0
  17. data/data/004010/elements-short.tsv +1405 -0
  18. data/data/004010/elements.tsv +3 -3
  19. data/data/004010/segments.tsv +1009 -1003
  20. data/data/004010/segments/ack.segment.yml +15 -0
  21. data/data/004010/segments/bak.segment.yml +9 -0
  22. data/data/004010/segments/beg.segment.yml +17 -0
  23. data/data/004010/segments/big.segment.yml +10 -0
  24. data/data/004010/segments/bsn.segment.yml +10 -0
  25. data/data/004010/segments/cad.segment.yml +14 -0
  26. data/data/004010/segments/ctp.segment.yml +19 -0
  27. data/data/004010/segments/ctt.segment.yml +13 -0
  28. data/data/004010/segments/dtm.segment.yml +7 -0
  29. data/data/004010/segments/envelope/ge.segment.yml +7 -0
  30. data/data/004010/segments/envelope/gs.segment.yml +13 -0
  31. data/data/004010/segments/envelope/iea.segment.yml +8 -0
  32. data/data/004010/segments/envelope/isa.segment.yml +22 -0
  33. data/data/004010/segments/envelope/se.segment.yml +7 -0
  34. data/data/004010/segments/envelope/st.segment.yml +12 -0
  35. data/data/004010/segments/hl.segment.yml +9 -0
  36. data/data/004010/segments/it1.segment.yml +20 -0
  37. data/data/004010/segments/lin.segment.yml +10 -0
  38. data/data/004010/segments/loop/hl.segment.yml +8 -0
  39. data/data/004010/segments/man.segment.yml +7 -0
  40. data/data/004010/segments/n1.segment.yml +9 -0
  41. data/data/004010/segments/n2.segment.yml +7 -0
  42. data/data/004010/segments/n3.segment.yml +6 -0
  43. data/data/004010/segments/n4.segment.yml +9 -0
  44. data/data/004010/segments/pid.segment.yml +10 -0
  45. data/data/004010/segments/po1.segment.yml +14 -0
  46. data/data/004010/segments/prf.segment.yml +9 -0
  47. data/data/004010/segments/ref.segment.yml +7 -0
  48. data/data/004010/segments/sac.segment.yml +20 -0
  49. data/data/004010/segments/sln.segment.yml +12 -0
  50. data/data/004010/segments/sn1.segment.yml +11 -0
  51. data/data/004010/segments/td1.segment.yml +13 -0
  52. data/data/004010/segments/td5.segment.yml +11 -0
  53. data/data/004010/segments/tds.segment.yml +10 -0
  54. data/data/schema/element_summary.json +60 -0
  55. data/data/schema/loop_summary.json +49 -0
  56. data/data/schema/segment_summary.json +66 -0
  57. data/data/schema/src/element_summary.schema.yml +73 -0
  58. data/data/schema/src/loop_summary.schema.yml +50 -0
  59. data/data/schema/src/segment_summary.schema.yml +59 -0
  60. data/data/schema/src/transaction_set_summary.schema.yml +27 -0
  61. data/data/schema/transaction_set_summary.json +33 -0
  62. data/data/sources.md +114 -145
  63. data/eddy.gemspec +6 -3
  64. data/exe/eddy +14 -0
  65. data/lib/definitions/elements/generated/1005.hierarchical_structure_code.rb +98 -0
  66. data/lib/definitions/elements/generated/1019.invoice_type_code.rb +40 -0
  67. data/lib/definitions/elements/generated/103.packaging_code.rb +29 -0
  68. data/lib/definitions/elements/generated/1166.contract_type_code.rb +87 -0
  69. data/lib/definitions/elements/generated/1232.purchase_category.rb +53 -0
  70. data/lib/definitions/elements/generated/127.reference_identification.rb +29 -0
  71. data/lib/definitions/elements/generated/128.reference_identification_qualifier.rb +1540 -0
  72. data/lib/definitions/elements/generated/1300.service_promotion_allowance_or_charge_code.rb +1090 -0
  73. data/lib/definitions/elements/generated/1301.agency_service_promotion_allowance_or_charge_code.rb +29 -0
  74. data/lib/definitions/elements/generated/133.routing_sequence_code.rb +60 -0
  75. data/lib/definitions/elements/generated/166.address_information.rb +29 -0
  76. data/lib/definitions/elements/generated/183.volume.rb +29 -0
  77. data/lib/definitions/elements/generated/187.weight_qualifier.rb +88 -0
  78. data/lib/definitions/elements/generated/19.city_name.rb +29 -0
  79. data/lib/definitions/elements/generated/206.equipment_initial.rb +29 -0
  80. data/lib/definitions/elements/generated/207.equipment_number.rb +29 -0
  81. data/lib/definitions/elements/generated/212.unit_price.rb +29 -0
  82. data/lib/definitions/elements/generated/22.commodity_code.rb +29 -0
  83. data/lib/definitions/elements/generated/23.commodity_code_qualifier.rb +60 -0
  84. data/lib/definitions/elements/generated/234.product_service_id.rb +29 -0
  85. data/lib/definitions/elements/generated/235.product_service_id_qualifier.rb +514 -0
  86. data/lib/definitions/elements/generated/236.price_identifier_code.rb +201 -0
  87. data/lib/definitions/elements/generated/248.allowance_or_charge_indicator.rb +44 -0
  88. data/lib/definitions/elements/generated/26.country_code.rb +535 -0
  89. data/lib/definitions/elements/generated/284.service_level_code.rb +103 -0
  90. data/lib/definitions/elements/generated/324.purchase_order_number.rb +29 -0
  91. data/lib/definitions/elements/generated/326.request_reference_number.rb +29 -0
  92. data/lib/definitions/elements/generated/327.change_order_sequence_number.rb +29 -0
  93. data/lib/definitions/elements/generated/328.release_number.rb +29 -0
  94. data/lib/definitions/elements/generated/330.quantity_ordered.rb +29 -0
  95. data/lib/definitions/elements/generated/347.hash_total.rb +29 -0
  96. data/lib/definitions/elements/generated/349.item_description_type.rb +40 -0
  97. data/lib/definitions/elements/generated/352.description.rb +29 -0
  98. data/lib/definitions/elements/generated/353.transaction_set_purpose_code.rb +102 -0
  99. data/lib/definitions/elements/generated/354.number_of_line_items.rb +30 -0
  100. data/lib/definitions/elements/generated/355.unit_or_basis_for_measurement_code.rb +831 -0
  101. data/lib/definitions/elements/generated/358.quantity_invoiced.rb +29 -0
  102. data/lib/definitions/elements/generated/367.contract_number.rb +29 -0
  103. data/lib/definitions/elements/generated/368.shipment_order_status_code.rb +139 -0
  104. data/lib/definitions/elements/generated/374.date_time_qualifier.rb +1149 -0
  105. data/lib/definitions/elements/generated/380.quantity.rb +29 -0
  106. data/lib/definitions/elements/generated/382.number_of_units_shipped.rb +29 -0
  107. data/lib/definitions/elements/generated/387.routing.rb +29 -0
  108. data/lib/definitions/elements/generated/396.shipment_identification.rb +29 -0
  109. data/lib/definitions/elements/generated/559.agency_qualifier_code.rb +213 -0
  110. data/lib/definitions/elements/generated/587.acknowledgment_type.rb +52 -0
  111. data/lib/definitions/elements/generated/610.amount.rb +30 -0
  112. data/lib/definitions/elements/generated/639.basis_of_unit_price_code.rb +128 -0
  113. data/lib/definitions/elements/generated/640.transaction_type_code.rb +483 -0
  114. data/lib/definitions/elements/generated/646.quantity_shipped_to_date.rb +29 -0
  115. data/lib/definitions/elements/generated/648.price_multiplier_qualifier.rb +43 -0
  116. data/lib/definitions/elements/generated/649.multiplier.rb +29 -0
  117. data/lib/definitions/elements/generated/66.identification_code_qualifier.rb +252 -0
  118. data/lib/definitions/elements/generated/662.relationship_code.rb +42 -0
  119. data/lib/definitions/elements/generated/668.line_item_status_code.rb +63 -0
  120. data/lib/definitions/elements/generated/67.identification_code.rb +29 -0
  121. data/lib/definitions/elements/generated/687.class_of_trade_code.rb +89 -0
  122. data/lib/definitions/elements/generated/750.product_process_characteristic_code.rb +254 -0
  123. data/lib/definitions/elements/generated/751.product_description_code.rb +29 -0
  124. data/lib/definitions/elements/generated/76.invoice_number.rb +29 -0
  125. data/lib/definitions/elements/generated/782.monetary_amount.rb +29 -0
  126. data/lib/definitions/elements/generated/786.security_level_code.rb +54 -0
  127. data/lib/definitions/elements/generated/79.lading_description.rb +29 -0
  128. data/lib/definitions/elements/generated/80.lading_quantity.rb +30 -0
  129. data/lib/definitions/elements/generated/87.marks_and_numbers.rb +29 -0
  130. data/lib/definitions/elements/generated/88.marks_and_numbers_qualifier.rb +57 -0
  131. data/lib/definitions/elements/generated/91.transportation_method_type_code.rb +108 -0
  132. data/lib/definitions/elements/generated/92.purchase_order_type_code.rb +106 -0
  133. data/lib/definitions/elements/generated/98.entity_identifier_code.rb +1349 -0
  134. data/lib/definitions/elements/manual/116.postal_code.rb +44 -0
  135. data/lib/definitions/elements/manual/124.application_receivers_code.rb +29 -0
  136. data/lib/definitions/elements/manual/140.standard_carrier_alpha_code.rb +211 -0
  137. data/lib/definitions/elements/manual/142.application_senders_code.rb +29 -0
  138. data/lib/definitions/elements/manual/143.transaction_set_identifier_code.rb +335 -0
  139. data/lib/definitions/elements/manual/156.state_or_province_code.rb +92 -0
  140. data/lib/definitions/elements/manual/28.group_control_number.rb +34 -0
  141. data/lib/definitions/elements/manual/329.transactional_set_control_number.rb +35 -0
  142. data/lib/definitions/elements/manual/337.time.rb +30 -0
  143. data/lib/definitions/elements/manual/350.assigned_identification.rb +33 -0
  144. data/lib/definitions/elements/manual/373.date.rb +30 -0
  145. data/lib/definitions/elements/manual/455.responsible_agency_code.rb +43 -0
  146. data/lib/definitions/elements/manual/479.functional_identifier_code.rb +271 -0
  147. data/lib/definitions/elements/manual/480.version_release_industry_identifier_code.rb +145 -0
  148. data/lib/definitions/elements/manual/784.length_of_binary_data.rb +30 -0
  149. data/lib/definitions/elements/manual/785.binary_data.rb +30 -0
  150. data/lib/definitions/elements/manual/96.number_of_included_segments.rb +30 -0
  151. data/lib/definitions/elements/manual/97.number_of_transaction_sets_included.rb +30 -0
  152. data/lib/definitions/elements/manual/hl/628.hierarchical_id_number.rb +29 -0
  153. data/lib/definitions/elements/manual/hl/734.hierarchical_parent_id_number.rb +29 -0
  154. data/lib/definitions/elements/manual/hl/735.hierarchical_level_code.rb +207 -0
  155. data/lib/definitions/elements/manual/hl/736.hierarchical_child_code.rb +39 -0
  156. data/lib/definitions/elements/manual/i/I01.authorization_information_qualifier.rb +48 -0
  157. data/lib/definitions/elements/manual/i/I02.authorization_information.rb +33 -0
  158. data/lib/definitions/elements/manual/i/I03.security_information_qualifier.rb +43 -0
  159. data/lib/definitions/elements/manual/i/I04.security_information.rb +33 -0
  160. data/lib/definitions/elements/manual/i/I05.interchange_id_qualifier.rb +75 -0
  161. data/lib/definitions/elements/manual/i/I06.interchange_sender_id.rb +29 -0
  162. data/lib/definitions/elements/manual/i/I07.interchange_receiver_id.rb +29 -0
  163. data/lib/definitions/elements/manual/i/I08.interchange_date.rb +35 -0
  164. data/lib/definitions/elements/manual/i/I09.interchange_time.rb +36 -0
  165. data/lib/definitions/elements/manual/i/I10.interchange_control_standards_identifier.rb +42 -0
  166. data/lib/definitions/elements/manual/i/I11.interchange_control_version_number.rb +55 -0
  167. data/lib/definitions/elements/manual/i/I12.interchange_control_number.rb +34 -0
  168. data/lib/definitions/elements/manual/i/I13.acknowledgment_requested.rb +43 -0
  169. data/lib/definitions/elements/manual/i/I14.usage_indicator.rb +40 -0
  170. data/lib/definitions/elements/manual/i/I15.component_element_separator.rb +36 -0
  171. data/lib/definitions/elements/manual/i/I16.number_of_included_functional_groups.rb +30 -0
  172. data/lib/definitions/elements/manual/misc/81.weight.rb +29 -0
  173. data/lib/definitions/elements/manual/misc/93.name.rb +29 -0
  174. data/lib/definitions/segments/generated/ack.rb +192 -0
  175. data/lib/definitions/segments/generated/bak.rb +90 -0
  176. data/lib/definitions/segments/generated/beg.rb +226 -0
  177. data/lib/definitions/segments/generated/big.rb +107 -0
  178. data/lib/definitions/segments/generated/bsn.rb +107 -0
  179. data/lib/definitions/segments/generated/cad.rb +175 -0
  180. data/lib/definitions/segments/generated/ctp.rb +158 -0
  181. data/lib/definitions/segments/generated/ctt.rb +141 -0
  182. data/lib/definitions/segments/generated/dtm.rb +56 -0
  183. data/lib/definitions/segments/generated/it1.rb +277 -0
  184. data/lib/definitions/segments/generated/lin.rb +107 -0
  185. data/lib/definitions/segments/generated/man.rb +56 -0
  186. data/lib/definitions/segments/generated/n1.rb +90 -0
  187. data/lib/definitions/segments/generated/n3.rb +39 -0
  188. data/lib/definitions/segments/generated/n4.rb +90 -0
  189. data/lib/definitions/segments/generated/pid.rb +107 -0
  190. data/lib/definitions/segments/generated/po1.rb +175 -0
  191. data/lib/definitions/segments/generated/prf.rb +90 -0
  192. data/lib/definitions/segments/generated/ref.rb +56 -0
  193. data/lib/definitions/segments/generated/sac.rb +107 -0
  194. data/lib/definitions/segments/generated/sln.rb +141 -0
  195. data/lib/definitions/segments/generated/sn1.rb +124 -0
  196. data/lib/definitions/segments/generated/td1.rb +158 -0
  197. data/lib/definitions/segments/generated/td5.rb +107 -0
  198. data/lib/definitions/segments/generated/tds.rb +39 -0
  199. data/lib/definitions/segments/manual/envelopes/ge.rb +53 -0
  200. data/lib/definitions/segments/manual/envelopes/gs.rb +163 -0
  201. data/lib/definitions/segments/manual/envelopes/iea.rb +53 -0
  202. data/lib/definitions/segments/manual/envelopes/isa.rb +295 -0
  203. data/lib/definitions/segments/manual/envelopes/se.rb +52 -0
  204. data/lib/definitions/segments/manual/envelopes/st.rb +52 -0
  205. data/lib/definitions/segments/manual/hl.rb +96 -0
  206. data/lib/definitions/segments/manual/n2.rb +52 -0
  207. data/lib/definitions/transaction_sets/manual/810/810.rb +143 -0
  208. data/lib/definitions/transaction_sets/manual/810/loops.rb +109 -0
  209. data/lib/definitions/transaction_sets/manual/850/850.rb +92 -0
  210. data/lib/definitions/transaction_sets/manual/850/loops.rb +58 -0
  211. data/lib/definitions/transaction_sets/manual/855/855.rb +83 -0
  212. data/lib/definitions/transaction_sets/manual/855/loops.rb +104 -0
  213. data/lib/definitions/transaction_sets/manual/856/856.rb +83 -0
  214. data/lib/definitions/transaction_sets/manual/856/loops.rb +155 -0
  215. data/lib/eddy.rb +29 -7
  216. data/lib/eddy/build/build.rb +47 -0
  217. data/lib/eddy/build/elements/element.rb +67 -0
  218. data/lib/eddy/build/elements/elements.rb +46 -0
  219. data/lib/eddy/build/elements/id.rb +55 -0
  220. data/lib/eddy/build/elements/n.rb +48 -0
  221. data/lib/eddy/build/loop_builder.rb +93 -0
  222. data/lib/eddy/build/segment_builder.rb +169 -0
  223. data/lib/eddy/build/transaction_set_builder.rb +218 -0
  224. data/lib/eddy/cli/cli.rb +39 -0
  225. data/lib/eddy/config.rb +51 -0
  226. data/lib/eddy/data.rb +50 -0
  227. data/lib/eddy/data/persistence/active_record.rb +10 -0
  228. data/lib/eddy/data/persistence/base.rb +47 -0
  229. data/lib/eddy/data/persistence/file.rb +50 -0
  230. data/lib/eddy/data/persistence/memory.rb +65 -0
  231. data/lib/eddy/data/store.rb +108 -0
  232. data/lib/eddy/errors.rb +112 -0
  233. data/lib/eddy/models/element.rb +14 -0
  234. data/lib/eddy/models/element/an.rb +55 -0
  235. data/lib/eddy/models/element/b.rb +53 -0
  236. data/lib/eddy/models/element/base.rb +116 -0
  237. data/lib/eddy/models/element/composite.rb +6 -0
  238. data/lib/eddy/models/element/dt.rb +100 -0
  239. data/lib/eddy/models/element/id.rb +58 -0
  240. data/lib/eddy/models/element/n.rb +94 -0
  241. data/lib/eddy/models/element/r.rb +84 -0
  242. data/lib/eddy/models/element/tm.rb +113 -0
  243. data/lib/eddy/models/loop.rb +74 -0
  244. data/lib/eddy/models/segment.rb +35 -0
  245. data/lib/eddy/models/transaction_set.rb +101 -0
  246. data/lib/eddy/parse.rb +58 -0
  247. data/lib/eddy/schema/element_summary.rb +123 -0
  248. data/lib/eddy/schema/loop_summary.rb +101 -0
  249. data/lib/eddy/schema/segment_summary.rb +116 -0
  250. data/lib/eddy/schema/transaction_set_summary.rb +96 -0
  251. data/lib/eddy/schema/validate.rb +41 -0
  252. data/lib/eddy/util.rb +16 -0
  253. data/lib/eddy/util/clean_folder.rb +14 -0
  254. data/lib/eddy/util/edi_data.rb +153 -0
  255. data/lib/eddy/util/new_number.rb +24 -0
  256. data/lib/eddy/util/normalize.rb +51 -0
  257. data/lib/eddy/util/paths.rb +19 -0
  258. data/lib/eddy/util/read.rb +38 -0
  259. data/lib/eddy/util/time.rb +56 -0
  260. data/lib/eddy/util/timestamp.rb +12 -0
  261. data/lib/eddy/util/trim.rb +29 -0
  262. data/lib/eddy/version.rb +1 -1
  263. data/lib/eddy/write/functional_group.rb +33 -0
  264. data/lib/eddy/write/interchange.rb +28 -0
  265. data/lib/eddy/write/simple_interchange.rb +57 -0
  266. data/lib/generators/eddy/initializer/initializer_generator.rb +17 -0
  267. data/lib/generators/eddy/initializer/templates/eddy.rb.erb +6 -0
  268. data/lib/generators/eddy/migration/migration_generator.rb +53 -0
  269. data/lib/generators/eddy/migration/templates/migration.rb.erb +35 -0
  270. data/tasks/build.rake +15 -0
  271. data/tasks/misc/gemspec.rake +12 -0
  272. data/tasks/misc/missing_lists.rake +240 -0
  273. data/tasks/misc/yaml2json.rake +20 -0
  274. data/todo.txt +16 -0
  275. metadata +297 -42
  276. data/data/004010/segments/ISA.tsv +0 -17
  277. data/data/schema.jsonc +0 -67
  278. data/lib/eddy/build/build_an.rb +0 -31
  279. data/lib/eddy/build/build_dt.rb +0 -46
  280. data/lib/eddy/build/build_elements.rb +0 -181
  281. data/lib/eddy/build/build_id.rb +0 -56
  282. data/lib/eddy/build/build_r_and_n.rb +0 -69
  283. data/lib/eddy/build/build_tm.rb +0 -52
  284. data/lib/eddy/build/segments.rb +0 -25
  285. data/lib/eddy/definitions/manual/elements/109.dt.pickup_date.rb +0 -20
  286. data/lib/eddy/definitions/manual/elements/111.tm.pickup_time.rb +0 -20
  287. data/lib/eddy/definitions/manual/elements/112.an.pier_name.rb +0 -19
  288. data/lib/eddy/definitions/manual/elements/785.b.binary_data.rb +0 -19
  289. data/lib/eddy/definitions/manual/elements/81.r.weight.rb +0 -19
  290. data/lib/eddy/definitions/manual/elements/86.n0.total_equipment.rb +0 -20
  291. data/lib/eddy/definitions/manual/elements/I02.authorization_information.rb +0 -20
  292. data/lib/eddy/definitions/manual/elements/I04.security_information.rb +0 -20
  293. data/lib/eddy/definitions/manual/elements/I08.interchange_date.rb +0 -20
  294. data/lib/eddy/definitions/manual/elements/I09.interchange_time.rb +0 -20
  295. data/lib/eddy/definitions/manual/elements/I15.component_element_separator.rb +0 -32
  296. data/lib/eddy/definitions/manual/segments/n1.rb +0 -14
  297. data/lib/eddy/element.rb +0 -14
  298. data/lib/eddy/element/an.rb +0 -36
  299. data/lib/eddy/element/b.rb +0 -9
  300. data/lib/eddy/element/base.rb +0 -37
  301. data/lib/eddy/element/dt.rb +0 -89
  302. data/lib/eddy/element/id.rb +0 -40
  303. data/lib/eddy/element/n.rb +0 -43
  304. data/lib/eddy/element/r.rb +0 -47
  305. data/lib/eddy/element/tm.rb +0 -108
  306. data/lib/eddy/error.rb +0 -14
  307. data/lib/eddy/helpers.rb +0 -31
  308. data/lib/eddy/segment.rb +0 -12
  309. data/lib/eddy/transaction_set.rb +0 -35
@@ -0,0 +1,51 @@
1
+ module Eddy
2
+ module Util
3
+ # @!group Normalize
4
+
5
+ # Given an Element Id (positive number under 1688, or I01-I64), returns a string sutable for use as a Ruby class name.
6
+ #
7
+ # @param id [String]
8
+ # @return [String]
9
+ def self.normalize_id(id)
10
+ name_regex = /\A(?<prefix>[iI]{1})?(?<numbers>\d+)\Z/
11
+ res = ""
12
+ if matches = id.match(name_regex)
13
+ if matches[:prefix]
14
+ res << "I"
15
+ else
16
+ res << "E"
17
+ end
18
+ res << matches[:numbers]
19
+ else
20
+ raise Eddy::Errors::BuildError, "invalid element id"
21
+ end
22
+ end
23
+
24
+ # Convert a string to [*PascalCase*](http://wiki.c2.com/?PascalCase), or *UpperCamelCase*
25
+ # Remove dashes, slashes, underscores, spaces, periods, and parens from a string then titleize it.
26
+ #
27
+ # @param name [String]
28
+ # @return [String]
29
+ def self.normalize_name(name)
30
+ return name.gsub(/\s*\(.*\)|[']/, "")
31
+ .gsub(%r{[.,_\-/]}, " ")
32
+ .split(" ")
33
+ .map(&:capitalize)
34
+ .join("")
35
+ end
36
+
37
+ # Convert a string to [*snake_case*](https://en.wikipedia.org/wiki/Snake_case)
38
+ #
39
+ # @param name [String]
40
+ # @return [String]
41
+ def self.snake_case(name)
42
+ return name.gsub(/\s*\(.*\)|['.]/, "")
43
+ .gsub(%r{[,_\-/]}, " ")
44
+ .split(" ")
45
+ .map(&:downcase)
46
+ .join("_")
47
+ end
48
+
49
+ # @!endgroup Normalize
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ module Eddy
2
+ module Util
3
+ # @!group Paths
4
+
5
+ # Directory where the gem is located.
6
+ # @return [String]
7
+ def self.root_dir
8
+ return File.expand_path("../../../..", __FILE__)
9
+ end
10
+
11
+ # Directory containing EDI data & definitions.
12
+ # @return [String]
13
+ def self.data_dir
14
+ return File.join(self.root_dir, "data")
15
+ end
16
+
17
+ # @!endgroup Paths
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ require "csv"
2
+ require "json"
3
+ require "yaml"
4
+
5
+ module Eddy
6
+ module Util
7
+
8
+ # Read a TSV file and return its contents as an array of hashes.
9
+ #
10
+ # @param filepath [String] Path to the TSV file.
11
+ # @return [Array<Hash{Symbol => String}>]
12
+ def self.parse_tsv(filepath)
13
+ return CSV.read(
14
+ filepath,
15
+ col_sep: "\t",
16
+ headers: true,
17
+ quote_char: "\x00",
18
+ header_converters: :symbol,
19
+ ).map(&:to_hash)
20
+ end
21
+
22
+ # Read data in from either a JSON or YAML file.
23
+ #
24
+ # @param path [String] Path to the file.
25
+ # @param symbolize [Boolean] (true)
26
+ # @return [Hash{Symbol => Object}]
27
+ def self.read_json_or_yaml(path, symbolize: true)
28
+ path = File.expand_path(path)
29
+ data = case File.extname(path).downcase
30
+ when /\.ya?ml/ then YAML.safe_load(File.read(path), symbolize_names: symbolize)
31
+ when ".json" then JSON.parse(File.read(path), symbolize_names: symbolize)
32
+ else raise Eddy::Errors::Error
33
+ end
34
+ return data
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,56 @@
1
+ module Eddy
2
+ module Util
3
+ # Functions for formatting [Time](https://ruby-doc.org/stdlib-2.6.5/libdoc/time/rdoc/Time.html) objects.
4
+ module Time
5
+
6
+ # @!group DT
7
+
8
+ # Generates an timestamp in `CCYYMMDD` format.
9
+ #
10
+ # @param date [Time] A *UTC* formatted `Time` object.
11
+ # @return [String]
12
+ def self.ccyymmdd(date = Time.now.utc)
13
+ return date.strftime("%Y%m%d")
14
+ end
15
+
16
+ # Generates an timestamp in `YYMMDD` format.
17
+ #
18
+ # @param date [Time] A *UTC* formatted `Time` object.
19
+ # @return [String]
20
+ def self.yymmdd(date = Time.now.utc)
21
+ return date.strftime("%y%m%d")
22
+ end
23
+
24
+ # @!endgroup DT
25
+
26
+ # @!group TM
27
+
28
+ # @param time [Time] A *UTC* formatted `Time` object.
29
+ # @return [String]
30
+ def self.hhmm(time = Time.now.utc)
31
+ return time.strftime("%H%M")
32
+ end
33
+
34
+ # @param time [Time] A *UTC* formatted `Time` object.
35
+ # @return [String]
36
+ def self.hhmmss(time = Time.now.utc)
37
+ return time.strftime("%H%M%S")
38
+ end
39
+
40
+ # @param time [Time] A *UTC* formatted `Time` object.
41
+ # @return [String]
42
+ def self.hhmmssd(time = Time.now.utc)
43
+ return time.strftime("%H%M%S%1N")
44
+ end
45
+
46
+ # @param time [Time] A *UTC* formatted `Time` object.
47
+ # @return [String]
48
+ def self.hhmmssdd(time = Time.now.utc)
49
+ return time.strftime("%H%M%S%2N")
50
+ end
51
+
52
+ # @!endgroup TM
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,12 @@
1
+ require "time"
2
+
3
+ module Eddy
4
+ module Util
5
+
6
+ # @return [String]
7
+ def self.timestamp
8
+ return ::Time.now.strftime("%m-%d-%Y-%H-%M-%S")
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ module Eddy
2
+ module Util
3
+ # @!group Normalize
4
+
5
+ # See: [Trailing delimiters and 999 response - X12 RFI](http://www.x12.org/rfis/Trailing%20delimiters%20and%20999%20response.pdf)
6
+ #
7
+ # @param itch [String] String containing an EDI Interchange.
8
+ # @param element_separator [String] ("*")
9
+ # @param segment_separator [String] ("~")
10
+ # @return [String]
11
+ def self.trim_delims_from_interchange(itch, element_separator: "*", segment_separator: "~")
12
+ e_sep = Regexp.escape(element_separator)
13
+ s_sep = Regexp.escape(segment_separator)
14
+ return itch.gsub(/#{e_sep}+(?=#{s_sep})/, "")
15
+ end
16
+
17
+ # See: [Trailing delimiters and 999 response - X12 RFI](http://www.x12.org/rfis/Trailing%20delimiters%20and%20999%20response.pdf)
18
+ #
19
+ # @param segment [String] String containing an EDI segment.
20
+ # @param separator [String] ("*")
21
+ # @return [String]
22
+ def self.trim_delims_from_segment(segment, separator: "*")
23
+ e_sep = Regexp.escape(separator)
24
+ return segment.gsub(/#{e_sep}+(?=$)/, "")
25
+ end
26
+
27
+ # @!endgroup Normalize
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module Eddy
2
- VERSION = "0.1.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
@@ -0,0 +1,33 @@
1
+ module Eddy
2
+ # A group of `Eddy::TransactionSet::Base` classes.
3
+ class FunctionalGroup
4
+
5
+ # @return [Eddy::Data::Store] Data store for the Interchange and all encompassed components.
6
+ attr_accessor :store
7
+ # Class for making new Transaction Sets.
8
+ # @return [Eddy::TransactionSet]
9
+ attr_accessor :transaction_set
10
+ # An array of Transaction Set instances
11
+ # @return [Array<Eddy::TransactionSet>]
12
+ attr_accessor :transaction_sets
13
+
14
+ # @param store [Eddy::Data::Store]
15
+ # @param transaction_set [Eddy::TransactionSet]
16
+ # @return [void]
17
+ def initialize(store, transaction_set)
18
+ self.store = store
19
+ self.transaction_set = transaction_set
20
+ self.transaction_sets = []
21
+ end
22
+
23
+ # @return [String]
24
+ def render()
25
+ number_of_included_functional_groups = self.store.number_of_included_functional_groups
26
+ gs = Eddy::Segments::GS.new(store, number_of_included_functional_groups, self.transaction_set)
27
+ ge = Eddy::Segments::GE.new(store, number_of_included_functional_groups, self.transaction_set)
28
+ segments = [gs, self.transaction_sets, ge].flatten
29
+ return segments.join(self.store.segment_separator) + segment_separator
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module Eddy
2
+ # Top level EDI interchange.
3
+ class Interchange
4
+ # @return [Eddy::Data::Store] Data store for the Interchange.
5
+ attr_accessor :store
6
+ # @return [Array<Eddy::Write::FunctionalGroup>]
7
+ attr_accessor :functional_groups
8
+
9
+ # @return [void]
10
+ def initialize()
11
+ self.store = Eddy::Data::Store.new()
12
+ self.functional_groups = []
13
+ end
14
+
15
+ # @param _transaction_sets [Array<Eddy::TransactionSet>]
16
+ # @return [Eddy::Interchange]
17
+ def self.create(_transaction_sets)
18
+ itch = Eddy::Interchange.new()
19
+ return itch
20
+ end
21
+
22
+ # @return [String]
23
+ def render()
24
+ raise NotImplementedError
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,57 @@
1
+ module Eddy
2
+ # An EDI interchange with one Transaction Set.
3
+ class SimpleInterchange
4
+ # @return [Eddy::Data::Store] Data store for the Interchange and all encompassed components.
5
+ attr_accessor :store
6
+ # @return [Eddy::TransactionSet]
7
+ attr_accessor :transaction_set
8
+ # @return [Array]
9
+ attr_accessor :components
10
+
11
+ # Initialize an interchange with one Functional Group containing one Transaction Set.
12
+ #
13
+ # @param transaction_set [Eddy::TransactionSet]
14
+ # @param store [Eddy::Data::Store] (Eddy::Data::Store.new)
15
+ # @return [void]
16
+ def initialize(transaction_set, store: Eddy::Data::Store.new())
17
+ self.components = []
18
+ self.transaction_set = transaction_set
19
+ self.store = store
20
+ self.store.number_of_transaction_sets_included = 1
21
+ self.store.number_of_included_functional_groups = 1
22
+ end
23
+
24
+ # @yieldparam [Eddy::Segments::ISA] isa
25
+ # @yieldparam [Eddy::Segments::IEA] iea
26
+ # @yieldparam [Eddy::Segments::GS] gs
27
+ # @yieldparam [Eddy::Segments::GE] ge
28
+ # @return [String]
29
+ def render()
30
+ itch_ctrl_num = Eddy::Data.new_interchange_control_number()
31
+ isa = Eddy::Segments::ISA.new(store, itch_ctrl_num)
32
+ iea = Eddy::Segments::IEA.new(store, itch_ctrl_num)
33
+ number_of_included_functional_groups = self.store.number_of_included_functional_groups
34
+ gs = Eddy::Segments::GS.new(store, number_of_included_functional_groups, self.transaction_set)
35
+ ge = Eddy::Segments::GE.new(store, number_of_included_functional_groups)
36
+ yield(isa, iea, gs, ge) if block_given?
37
+ self.components.prepend(gs)
38
+ self.components.prepend(isa)
39
+ self.components.append(ge)
40
+ self.components.append(iea)
41
+ segments = self.components.map(&:render).flatten().join(store.segment_separator) + store.segment_separator
42
+ return segments
43
+ end
44
+
45
+ # @raise [ArgumentError] Unless `transaction_set` is a subclass of {Eddy::TransactionSet}
46
+ # @param transaction_set [Eddy::TransactionSet]
47
+ # @return [void]
48
+ def verify_transaction_set(transaction_set)
49
+ raise ArgumentError unless transaction_set < Eddy::TransactionSet
50
+ raise ArgumentError unless transaction_set <= Eddy::TransactionSet
51
+ raise ArgumentError unless transaction_set.ancestors.include?(Eddy::TransactionSet)
52
+ raise ArgumentError unless transaction_set.superclass == Eddy::TransactionSet
53
+ return nil
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,17 @@
1
+ require "rails/generators"
2
+
3
+ module Eddy
4
+ module Generators
5
+ # Generate an initializer file for Eddy.
6
+ class InitializersGenerator < Rails::Generators::Base
7
+ desc "This generator creates an initializer file at config/initializers/eddy.rb for Eddy"
8
+ source_root File.expand_path("templates", __dir__)
9
+
10
+ # @return [void]
11
+ def copy_initializer
12
+ template "eddy.rb.erb", "config/initializers/eddy.rb"
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ Eddy.configure do |config|
2
+ config.env = Rails.env
3
+ config.persistence_method = :memory
4
+ config.tmp_dir = Rails.root.join('tmp')
5
+ config.tmp_dir = Rails.root.join('tmp', 'build')
6
+ end
@@ -0,0 +1,53 @@
1
+ require "rails/generators"
2
+ require "rails/generators/active_record"
3
+
4
+ module Eddy
5
+ module Generators
6
+ # Generate migrations to set up database tables for use by Eddy.
7
+ #
8
+ # See:
9
+ #
10
+ # - [Rails Guides - Generators](https://edgeguides.rubyonrails.org/generators.html)
11
+ # - [`Rails::Generators::Migration`](https://api.rubyonrails.org/classes/Rails/Generators/Migration.html)
12
+ # - [StackOverflow Question](https://stackoverflow.com/questions/53212961/how-to-make-a-custom-generator-which-also-generates-a-migration-in-rails)
13
+ # - ["index: true" in Rails migrations does not work as you'd expect](https://makandracards.com/makandra/32353-psa-index-true-in-rails-migrations-does-not-work-as-you-d-expect)
14
+ class MigrationGenerator < Rails::Generators::Base
15
+
16
+ include Rails::Generators::Migration
17
+ desc "This generator creates a migration file in db/migrate that will set up database tables for use by Eddy"
18
+ source_root File.expand_path("templates", __dir__)
19
+
20
+ # @return [void]
21
+ def generate_migration
22
+ migration_template(
23
+ "migration.rb.erb",
24
+ "db/migrate/#{self.migration_file_name()}",
25
+ migration_version: self.migration_version(),
26
+ )
27
+ end
28
+
29
+ # @return [String]
30
+ def migration_file_name()
31
+ return "create_eddy_tables.rb"
32
+ # return "#{self.timestamp()}_create_eddy_tables.rb"
33
+ end
34
+
35
+ # @return [String]
36
+ def timestamp()
37
+ return Time.now.utc.strftime("%Y%m%d%H%M%S")
38
+ end
39
+
40
+ # @return [String]
41
+ def migration_version()
42
+ return "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
43
+ end
44
+
45
+ # for generating a timestamp when using `create_migration`
46
+ # Sole from - https://github.com/thoughtbot/clearance/blob/master/lib/generators/clearance/install/install_generator.rb#L116
47
+ def self.next_migration_number(dir)
48
+ ActiveRecord::Generators::Base.next_migration_number(dir)
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,35 @@
1
+ class EddyCreateTables < ActiveRecord::Migration<%= migration_version %>
2
+
3
+ def self.up
4
+ create_table :eddy_interchange_control_numbers do |t|
5
+ t.integer :control_number, null: false
6
+ t.boolean :received
7
+ t.boolean :sent
8
+ t.timestamps null: false
9
+ end
10
+ create_table :eddy_functional_group_control_numbers do |t|
11
+ t.integer :control_number, null: false
12
+ t.string :functional_group, null: false
13
+ t.boolean :received
14
+ t.boolean :sent
15
+ t.timestamps null: false
16
+ end
17
+ create_table :eddy_transaction_set_control_numbers do |t|
18
+ t.integer :control_number, null: false
19
+ t.string :transaction_set, null: false
20
+ t.boolean :received
21
+ t.boolean :sent
22
+ t.timestamps null: false
23
+ end
24
+ add_index :eddy_interchange_control_numbers, :control_number, unique: true
25
+ add_index :eddy_functional_group_control_numbers, :control_number, unique: true
26
+ add_index :eddy_transaction_set_control_numbers, :control_number, unique: true
27
+ end
28
+
29
+ def self.down
30
+ drop_table :eddy_interchange_control_numbers
31
+ drop_table :eddy_functional_group_control_numbers
32
+ drop_table :eddy_transaction_set_control_numbers
33
+ end
34
+
35
+ end