stupidedi 1.1.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 (500) hide show
  1. data/README.md +215 -0
  2. data/Rakefile +108 -0
  3. data/bin/edi-ed +71 -0
  4. data/bin/edi-pp +81 -0
  5. data/doc/Defining.md +0 -0
  6. data/doc/Generating.md +321 -0
  7. data/doc/LICENSE.md +0 -0
  8. data/doc/Navigating.md +645 -0
  9. data/doc/Parsing.md +0 -0
  10. data/doc/Serializing.md +7 -0
  11. data/doc/Tokenizing.md +0 -0
  12. data/doc/Validating.md +0 -0
  13. data/doc/design/Parser.md +0 -0
  14. data/doc/design/Reader.md +0 -0
  15. data/lib/ruby/array.rb +164 -0
  16. data/lib/ruby/blank.rb +67 -0
  17. data/lib/ruby/enumerable.rb +35 -0
  18. data/lib/ruby/exception.rb +33 -0
  19. data/lib/ruby/hash.rb +4 -0
  20. data/lib/ruby/instance_exec.rb +26 -0
  21. data/lib/ruby/module.rb +79 -0
  22. data/lib/ruby/object.rb +63 -0
  23. data/lib/ruby/string.rb +73 -0
  24. data/lib/ruby/symbol.rb +24 -0
  25. data/lib/ruby/to_d.rb +81 -0
  26. data/lib/ruby/to_date.rb +33 -0
  27. data/lib/ruby/to_time.rb +24 -0
  28. data/lib/ruby/try.rb +43 -0
  29. data/lib/stupidedi/blank_slate.rb +11 -0
  30. data/lib/stupidedi/builder/builder_dsl.rb +281 -0
  31. data/lib/stupidedi/builder/constraint_table.rb +418 -0
  32. data/lib/stupidedi/builder/generation.rb +112 -0
  33. data/lib/stupidedi/builder/instruction.rb +102 -0
  34. data/lib/stupidedi/builder/instruction_table.rb +204 -0
  35. data/lib/stupidedi/builder/navigation.rb +655 -0
  36. data/lib/stupidedi/builder/state_machine.rb +55 -0
  37. data/lib/stupidedi/builder/states/abstract_state.rb +332 -0
  38. data/lib/stupidedi/builder/states/failure_state.rb +69 -0
  39. data/lib/stupidedi/builder/states/functional_group_state.rb +97 -0
  40. data/lib/stupidedi/builder/states/initial_state.rb +63 -0
  41. data/lib/stupidedi/builder/states/interchange_state.rb +94 -0
  42. data/lib/stupidedi/builder/states/loop_state.rb +79 -0
  43. data/lib/stupidedi/builder/states/table_state.rb +96 -0
  44. data/lib/stupidedi/builder/states/transaction_set_state.rb +112 -0
  45. data/lib/stupidedi/builder/states/transmission_state.rb +59 -0
  46. data/lib/stupidedi/builder/tokenization.rb +196 -0
  47. data/lib/stupidedi/builder.rb +23 -0
  48. data/lib/stupidedi/color.rb +93 -0
  49. data/lib/stupidedi/config/code_list_config.rb +42 -0
  50. data/lib/stupidedi/config/editor_config.rb +51 -0
  51. data/lib/stupidedi/config/functional_group_config.rb +62 -0
  52. data/lib/stupidedi/config/interchange_config.rb +79 -0
  53. data/lib/stupidedi/config/transaction_set_config.rb +91 -0
  54. data/lib/stupidedi/config.rb +101 -0
  55. data/lib/stupidedi/editor/00501.rb +341 -0
  56. data/lib/stupidedi/editor/005010/N2.rb +0 -0
  57. data/lib/stupidedi/editor/005010/N3.rb +0 -0
  58. data/lib/stupidedi/editor/005010/N4.rb +63 -0
  59. data/lib/stupidedi/editor/005010/NM1.rb +0 -0
  60. data/lib/stupidedi/editor/005010.rb +469 -0
  61. data/lib/stupidedi/editor/X222-HC837.rb +195 -0
  62. data/lib/stupidedi/editor/abstract_ed.rb +36 -0
  63. data/lib/stupidedi/editor/claim_ack.rb +9 -0
  64. data/lib/stupidedi/editor/implementation_ack.rb +213 -0
  65. data/lib/stupidedi/editor/interchange_ack.rb +9 -0
  66. data/lib/stupidedi/editor/result.rb +100 -0
  67. data/lib/stupidedi/editor/result_set.rb +69 -0
  68. data/lib/stupidedi/editor/transaction_set_ed.rb +275 -0
  69. data/lib/stupidedi/editor/transmission_ed.rb +90 -0
  70. data/lib/stupidedi/editor.rb +37 -0
  71. data/lib/stupidedi/either.rb +287 -0
  72. data/lib/stupidedi/exceptions/invalid_element_error.rb +8 -0
  73. data/lib/stupidedi/exceptions/invalid_schema_error.rb +8 -0
  74. data/lib/stupidedi/exceptions/output_error.rb +8 -0
  75. data/lib/stupidedi/exceptions/parse_error.rb +8 -0
  76. data/lib/stupidedi/exceptions/stupidedi_error.rb +8 -0
  77. data/lib/stupidedi/exceptions/tokenize_error.rb +8 -0
  78. data/lib/stupidedi/exceptions/zipper_error.rb +8 -0
  79. data/lib/stupidedi/exceptions.rb +11 -0
  80. data/lib/stupidedi/guides/005010/X214-HN277.rb +409 -0
  81. data/lib/stupidedi/guides/005010/X221-HP835.rb +613 -0
  82. data/lib/stupidedi/guides/005010/X221A1-HP835.rb +613 -0
  83. data/lib/stupidedi/guides/005010/X222-HC837P.rb +2291 -0
  84. data/lib/stupidedi/guides/005010/X222A1-HC837P.rb +2297 -0
  85. data/lib/stupidedi/guides/005010/X231-FA999.rb +123 -0
  86. data/lib/stupidedi/guides/005010/X231A1-FA999.rb +119 -0
  87. data/lib/stupidedi/guides/005010/element_reqs.rb +38 -0
  88. data/lib/stupidedi/guides/005010/guide_builder.rb +180 -0
  89. data/lib/stupidedi/guides/005010/segment_reqs.rb +32 -0
  90. data/lib/stupidedi/guides/005010.rb +64 -0
  91. data/lib/stupidedi/guides.rb +5 -0
  92. data/lib/stupidedi/inspect.rb +26 -0
  93. data/lib/stupidedi/reader/input/abstract_input.rb +133 -0
  94. data/lib/stupidedi/reader/input/delegated_input.rb +111 -0
  95. data/lib/stupidedi/reader/input/file_input.rb +155 -0
  96. data/lib/stupidedi/reader/input.rb +30 -0
  97. data/lib/stupidedi/reader/position.rb +69 -0
  98. data/lib/stupidedi/reader/result.rb +168 -0
  99. data/lib/stupidedi/reader/segment_dict.rb +175 -0
  100. data/lib/stupidedi/reader/separators.rb +85 -0
  101. data/lib/stupidedi/reader/stream_reader.rb +172 -0
  102. data/lib/stupidedi/reader/token_reader.rb +466 -0
  103. data/lib/stupidedi/reader/tokens/component_element_tok.rb +56 -0
  104. data/lib/stupidedi/reader/tokens/composite_element_tok.rb +64 -0
  105. data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +64 -0
  106. data/lib/stupidedi/reader/tokens/segment_tok.rb +51 -0
  107. data/lib/stupidedi/reader/tokens/simple_element_tok.rb +63 -0
  108. data/lib/stupidedi/reader.rb +121 -0
  109. data/lib/stupidedi/schema/abstract_def.rb +74 -0
  110. data/lib/stupidedi/schema/abstract_use.rb +73 -0
  111. data/lib/stupidedi/schema/code_list.rb +94 -0
  112. data/lib/stupidedi/schema/element_def.rb +173 -0
  113. data/lib/stupidedi/schema/element_req.rb +56 -0
  114. data/lib/stupidedi/schema/element_use.rb +251 -0
  115. data/lib/stupidedi/schema/functional_group_def.rb +114 -0
  116. data/lib/stupidedi/schema/interchange_def.rb +93 -0
  117. data/lib/stupidedi/schema/loop_def.rb +152 -0
  118. data/lib/stupidedi/schema/repeat_count.rb +85 -0
  119. data/lib/stupidedi/schema/segment_def.rb +108 -0
  120. data/lib/stupidedi/schema/segment_req.rb +43 -0
  121. data/lib/stupidedi/schema/segment_use.rb +98 -0
  122. data/lib/stupidedi/schema/syntax_note.rb +63 -0
  123. data/lib/stupidedi/schema/table_def.rb +139 -0
  124. data/lib/stupidedi/schema/transaction_set_def.rb +88 -0
  125. data/lib/stupidedi/schema.rb +28 -0
  126. data/lib/stupidedi/sets/absolute_set.rb +297 -0
  127. data/lib/stupidedi/sets/abstract_set.rb +174 -0
  128. data/lib/stupidedi/sets/null_set.rb +125 -0
  129. data/lib/stupidedi/sets/relative_complement.rb +137 -0
  130. data/lib/stupidedi/sets/relative_set.rb +269 -0
  131. data/lib/stupidedi/sets/universal_set.rb +104 -0
  132. data/lib/stupidedi/sets.rb +57 -0
  133. data/lib/stupidedi/tail_call.rb +109 -0
  134. data/lib/stupidedi/thread_local.rb +174 -0
  135. data/lib/stupidedi/values/abstract_element_val.rb +19 -0
  136. data/lib/stupidedi/values/abstract_val.rb +130 -0
  137. data/lib/stupidedi/values/composite_element_val.rb +95 -0
  138. data/lib/stupidedi/values/functional_group_val.rb +102 -0
  139. data/lib/stupidedi/values/interchange_val.rb +86 -0
  140. data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
  141. data/lib/stupidedi/values/invalid_segment_val.rb +78 -0
  142. data/lib/stupidedi/values/loop_val.rb +70 -0
  143. data/lib/stupidedi/values/repeated_element_val.rb +105 -0
  144. data/lib/stupidedi/values/segment_val.rb +104 -0
  145. data/lib/stupidedi/values/segment_val_group.rb +20 -0
  146. data/lib/stupidedi/values/simple_element_val.rb +80 -0
  147. data/lib/stupidedi/values/table_val.rb +66 -0
  148. data/lib/stupidedi/values/transaction_set_val.rb +66 -0
  149. data/lib/stupidedi/values/transmission_val.rb +52 -0
  150. data/lib/stupidedi/values.rb +21 -0
  151. data/lib/stupidedi/version.rb +3 -0
  152. data/lib/stupidedi/versions/functional_groups/004010/element_defs.rb +54 -0
  153. data/lib/stupidedi/versions/functional_groups/004010/element_reqs.rb +18 -0
  154. data/lib/stupidedi/versions/functional_groups/004010/element_types/date_val.rb +527 -0
  155. data/lib/stupidedi/versions/functional_groups/004010/element_types/fixnum_val.rb +335 -0
  156. data/lib/stupidedi/versions/functional_groups/004010/element_types/float_val.rb +299 -0
  157. data/lib/stupidedi/versions/functional_groups/004010/element_types/identifier_val.rb +287 -0
  158. data/lib/stupidedi/versions/functional_groups/004010/element_types/string_val.rb +338 -0
  159. data/lib/stupidedi/versions/functional_groups/004010/element_types/time_val.rb +309 -0
  160. data/lib/stupidedi/versions/functional_groups/004010/element_types.rb +124 -0
  161. data/lib/stupidedi/versions/functional_groups/004010/functional_group_def.rb +30 -0
  162. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GE.rb +20 -0
  163. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GS.rb +27 -0
  164. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/SE.rb +20 -0
  165. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/ST.rb +20 -0
  166. data/lib/stupidedi/versions/functional_groups/004010/segment_defs.rb +23 -0
  167. data/lib/stupidedi/versions/functional_groups/004010/segment_reqs.rb +18 -0
  168. data/lib/stupidedi/versions/functional_groups/004010/syntax_notes.rb +174 -0
  169. data/lib/stupidedi/versions/functional_groups/004010.rb +38 -0
  170. data/lib/stupidedi/versions/functional_groups/005010/element_defs.rb +1405 -0
  171. data/lib/stupidedi/versions/functional_groups/005010/element_reqs.rb +18 -0
  172. data/lib/stupidedi/versions/functional_groups/005010/element_types/date_val.rb +577 -0
  173. data/lib/stupidedi/versions/functional_groups/005010/element_types/fixnum_val.rb +322 -0
  174. data/lib/stupidedi/versions/functional_groups/005010/element_types/float_val.rb +354 -0
  175. data/lib/stupidedi/versions/functional_groups/005010/element_types/identifier_val.rb +368 -0
  176. data/lib/stupidedi/versions/functional_groups/005010/element_types/operators.rb +117 -0
  177. data/lib/stupidedi/versions/functional_groups/005010/element_types/string_val.rb +398 -0
  178. data/lib/stupidedi/versions/functional_groups/005010/element_types/time_val.rb +327 -0
  179. data/lib/stupidedi/versions/functional_groups/005010/element_types.rb +132 -0
  180. data/lib/stupidedi/versions/functional_groups/005010/functional_group_def.rb +30 -0
  181. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK1.rb +21 -0
  182. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK2.rb +21 -0
  183. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK9.rb +28 -0
  184. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AMT.rb +21 -0
  185. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BHT.rb +24 -0
  186. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BPR.rb +49 -0
  187. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CAS.rb +56 -0
  188. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CL1.rb +22 -0
  189. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLM.rb +41 -0
  190. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLP.rb +34 -0
  191. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CN1.rb +24 -0
  192. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR1.rb +32 -0
  193. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR2.rb +35 -0
  194. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR3.rb +25 -0
  195. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CRC.rb +26 -0
  196. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTP.rb +36 -0
  197. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTX.rb +24 -0
  198. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CUR.rb +57 -0
  199. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DMG.rb +34 -0
  200. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN1.rb +22 -0
  201. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN2.rb +24 -0
  202. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTM.rb +24 -0
  203. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTP.rb +21 -0
  204. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/FRM.rb +25 -0
  205. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GE.rb +20 -0
  206. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GS.rb +27 -0
  207. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HCP.rb +39 -0
  208. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HI.rb +31 -0
  209. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HL.rb +22 -0
  210. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK3.rb +22 -0
  211. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK4.rb +22 -0
  212. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK5.rb +24 -0
  213. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/K3.rb +21 -0
  214. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LIN.rb +69 -0
  215. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LQ.rb +22 -0
  216. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LX.rb +19 -0
  217. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MEA.rb +39 -0
  218. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MIA.rb +45 -0
  219. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MOA.rb +28 -0
  220. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N1.rb +24 -0
  221. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N2.rb +20 -0
  222. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N3.rb +20 -0
  223. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N4.rb +30 -0
  224. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NM1.rb +35 -0
  225. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NTE.rb +20 -0
  226. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/OI.rb +24 -0
  227. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PAT.rb +31 -0
  228. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PER.rb +32 -0
  229. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PLB.rb +40 -0
  230. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PRV.rb +26 -0
  231. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PS1.rb +21 -0
  232. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PWK.rb +30 -0
  233. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/QTY.rb +25 -0
  234. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/RDM.rb +23 -0
  235. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/REF.rb +23 -0
  236. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SBR.rb +28 -0
  237. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SE.rb +20 -0
  238. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/ST.rb +21 -0
  239. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/STC.rb +30 -0
  240. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV1.rb +44 -0
  241. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV2.rb +29 -0
  242. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV3.rb +30 -0
  243. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV5.rb +29 -0
  244. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVC.rb +26 -0
  245. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVD.rb +24 -0
  246. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TOO.rb +21 -0
  247. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TRN.rb +22 -0
  248. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS2.rb +40 -0
  249. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS3.rb +45 -0
  250. data/lib/stupidedi/versions/functional_groups/005010/segment_defs.rb +227 -0
  251. data/lib/stupidedi/versions/functional_groups/005010/segment_reqs.rb +18 -0
  252. data/lib/stupidedi/versions/functional_groups/005010/syntax_notes.rb +165 -0
  253. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/FA999.rb +38 -0
  254. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HB271.rb +85 -0
  255. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HC837.rb +163 -0
  256. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HI278.rb +64 -0
  257. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HN277.rb +74 -0
  258. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HP835.rb +68 -0
  259. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HR276.rb +57 -0
  260. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HS270.rb +53 -0
  261. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/RA820.rb +240 -0
  262. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs.rb +68 -0
  263. data/lib/stupidedi/versions/functional_groups/005010.rb +38 -0
  264. data/lib/stupidedi/versions/functional_groups.rb +8 -0
  265. data/lib/stupidedi/versions/interchanges/00401/element_defs.rb +224 -0
  266. data/lib/stupidedi/versions/interchanges/00401/interchange_def.rb +45 -0
  267. data/lib/stupidedi/versions/interchanges/00401/segment_defs/IEA.rb +20 -0
  268. data/lib/stupidedi/versions/interchanges/00401/segment_defs/ISA.rb +34 -0
  269. data/lib/stupidedi/versions/interchanges/00401/segment_defs/TA1.rb +23 -0
  270. data/lib/stupidedi/versions/interchanges/00401/segment_defs.rb +28 -0
  271. data/lib/stupidedi/versions/interchanges/00401.rb +23 -0
  272. data/lib/stupidedi/versions/interchanges/00501/element_defs.rb +269 -0
  273. data/lib/stupidedi/versions/interchanges/00501/interchange_def.rb +47 -0
  274. data/lib/stupidedi/versions/interchanges/00501/segment_defs/IEA.rb +20 -0
  275. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISA.rb +34 -0
  276. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISB.rb +18 -0
  277. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISE.rb +18 -0
  278. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA1.rb +23 -0
  279. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA3.rb +18 -0
  280. data/lib/stupidedi/versions/interchanges/00501/segment_defs.rb +37 -0
  281. data/lib/stupidedi/versions/interchanges/00501.rb +23 -0
  282. data/lib/stupidedi/versions/interchanges.rb +8 -0
  283. data/lib/stupidedi/versions.rb +6 -0
  284. data/lib/stupidedi/writer/claredi.rb +142 -0
  285. data/lib/stupidedi/writer/default.rb +124 -0
  286. data/lib/stupidedi/writer.rb +6 -0
  287. data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
  288. data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
  289. data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
  290. data/lib/stupidedi/zipper/memoized_cursor.rb +131 -0
  291. data/lib/stupidedi/zipper/path.rb +124 -0
  292. data/lib/stupidedi/zipper/root_cursor.rb +120 -0
  293. data/lib/stupidedi/zipper.rb +25 -0
  294. data/lib/stupidedi.rb +66 -0
  295. data/spec/examples/integration/generating.example +551 -0
  296. data/spec/examples/integration/navigating.example +214 -0
  297. data/spec/examples/integration/parsing.example +445 -0
  298. data/spec/examples/ruby/array.example +476 -0
  299. data/spec/examples/ruby/blank.example +62 -0
  300. data/spec/examples/ruby/count.example +68 -0
  301. data/spec/examples/ruby/object.example +99 -0
  302. data/spec/examples/ruby/string.example +111 -0
  303. data/spec/examples/ruby/symbol.example +117 -0
  304. data/spec/examples/ruby/to_d.example +90 -0
  305. data/spec/examples/ruby/try.example +50 -0
  306. data/spec/examples/stupidedi/either.example +375 -0
  307. data/spec/examples/stupidedi/reader/failure.example +68 -0
  308. data/spec/examples/stupidedi/reader/input/delegated_input.example +292 -0
  309. data/spec/examples/stupidedi/reader/separators.example +73 -0
  310. data/spec/examples/stupidedi/reader/stream_reader.example +48 -0
  311. data/spec/examples/stupidedi/reader/success.example +34 -0
  312. data/spec/examples/stupidedi/reader/token_reader.example +775 -0
  313. data/spec/examples/stupidedi/reader.example +168 -0
  314. data/spec/examples/stupidedi/sets/absolute_set.example +1577 -0
  315. data/spec/examples/stupidedi/sets/null_set.example +2 -0
  316. data/spec/examples/stupidedi/sets/relative_set.example +2 -0
  317. data/spec/examples/stupidedi/sets/universal_set.example +1 -0
  318. data/spec/examples/stupidedi/versions/005010/element_types/an.example +201 -0
  319. data/spec/examples/stupidedi/versions/005010/element_types/dt.example +258 -0
  320. data/spec/examples/stupidedi/versions/005010/element_types/id.example +192 -0
  321. data/spec/examples/stupidedi/versions/005010/element_types/nn.example +177 -0
  322. data/spec/examples/stupidedi/versions/005010/element_types/r.example +178 -0
  323. data/spec/examples/stupidedi/versions/005010/element_types/tm.example +2 -0
  324. data/spec/examples/stupidedi/zipper/abstract_cursor.example +417 -0
  325. data/spec/examples/stupidedi/zipper.example +9 -0
  326. data/spec/fixtures/X186-AG824/1-bad.txt +21 -0
  327. data/spec/fixtures/X186-AG824/1-good.txt +17 -0
  328. data/spec/fixtures/X186-AG824/2-bad.txt +26 -0
  329. data/spec/fixtures/X186-AG824/2-good.txt +21 -0
  330. data/spec/fixtures/X186-AG824/3-bad.txt +87 -0
  331. data/spec/fixtures/X186-AG824/3-good.txt +61 -0
  332. data/spec/fixtures/X212-HN277/1-bad.txt +54 -0
  333. data/spec/fixtures/X212-HN277/1-good.txt +46 -0
  334. data/spec/fixtures/X212-HN277/2-bad.txt +37 -0
  335. data/spec/fixtures/X212-HN277/2-good.txt +29 -0
  336. data/spec/fixtures/X212-HN277/3-bad.txt +22 -0
  337. data/spec/fixtures/X212-HN277/3-good.txt +17 -0
  338. data/spec/fixtures/X212-HN277/4-bad.txt +30 -0
  339. data/spec/fixtures/X212-HN277/4-good.txt +24 -0
  340. data/spec/fixtures/X212-HR276/1-bad.txt +53 -0
  341. data/spec/fixtures/X212-HR276/1-good.txt +46 -0
  342. data/spec/fixtures/X212-HR276/2-bad.txt +45 -0
  343. data/spec/fixtures/X212-HR276/2-good.txt +38 -0
  344. data/spec/fixtures/X212-HR276/3-bad.txt +32 -0
  345. data/spec/fixtures/X212-HR276/3-good.txt +26 -0
  346. data/spec/fixtures/X212-HR276/4-bad.txt +32 -0
  347. data/spec/fixtures/X212-HR276/4-good.txt +26 -0
  348. data/spec/fixtures/X214-HN277/1-bad.txt +58 -0
  349. data/spec/fixtures/X214-HN277/1-good.txt +47 -0
  350. data/spec/fixtures/X214-HN277/2-bad.txt +34 -0
  351. data/spec/fixtures/X214-HN277/2-good.txt +22 -0
  352. data/spec/fixtures/X214-HN277/3-bad.txt +64 -0
  353. data/spec/fixtures/X214-HN277/3-good.txt +54 -0
  354. data/spec/fixtures/X214-HN277/4-bad.txt +77 -0
  355. data/spec/fixtures/X214-HN277/4-good.txt +63 -0
  356. data/spec/fixtures/X216-HI278/1-bad.txt +42 -0
  357. data/spec/fixtures/X216-HI278/1-good.txt +27 -0
  358. data/spec/fixtures/X216-HI278/2-bad.txt +43 -0
  359. data/spec/fixtures/X216-HI278/2-good.txt +29 -0
  360. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1.txt +24 -0
  361. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1_Clean.txt +20 -0
  362. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2.txt +46 -0
  363. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2_Clean.txt +30 -0
  364. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3.txt +38 -0
  365. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3_Clean.txt +24 -0
  366. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a.txt +39 -0
  367. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a_Clean.txt +24 -0
  368. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b.txt +43 -0
  369. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b_Clean.txt +25 -0
  370. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5.txt +63 -0
  371. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5_Clean.txt +41 -0
  372. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6.txt +36 -0
  373. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6_Clean.txt +20 -0
  374. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r.txt +34 -0
  375. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r_Clean.txt +23 -0
  376. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r.txt +46 -0
  377. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r_Clean.txt +31 -0
  378. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r.txt +44 -0
  379. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r_Clean.txt +26 -0
  380. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4ar_Clean.txt +28 -0
  381. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4br_Clean.txt +35 -0
  382. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r.txt +60 -0
  383. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r_Clean.txt +42 -0
  384. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r.txt +40 -0
  385. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r_Clean.txt +24 -0
  386. data/spec/fixtures/X218-RA820/1-bad.txt +31 -0
  387. data/spec/fixtures/X218-RA820/1-good.txt +25 -0
  388. data/spec/fixtures/X218-RA820/2-bad.txt +37 -0
  389. data/spec/fixtures/X218-RA820/2-good.txt +29 -0
  390. data/spec/fixtures/X218-RA820/3-bad.txt +29 -0
  391. data/spec/fixtures/X218-RA820/3-good.txt +23 -0
  392. data/spec/fixtures/X218-RA820/4-bad.txt +36 -0
  393. data/spec/fixtures/X218-RA820/4-good.txt +27 -0
  394. data/spec/fixtures/X220-BE834/1-bad.txt +35 -0
  395. data/spec/fixtures/X220-BE834/1-good.txt +29 -0
  396. data/spec/fixtures/X220-BE834/10-bad.txt +26 -0
  397. data/spec/fixtures/X220-BE834/10-good.txt +19 -0
  398. data/spec/fixtures/X220-BE834/2-bad.txt +31 -0
  399. data/spec/fixtures/X220-BE834/2-good.txt +23 -0
  400. data/spec/fixtures/X220-BE834/3-bad.txt +36 -0
  401. data/spec/fixtures/X220-BE834/3-good.txt +26 -0
  402. data/spec/fixtures/X220-BE834/4-bad.txt +27 -0
  403. data/spec/fixtures/X220-BE834/4-good.txt +21 -0
  404. data/spec/fixtures/X220-BE834/5-bad.txt +26 -0
  405. data/spec/fixtures/X220-BE834/5-good.txt +17 -0
  406. data/spec/fixtures/X220-BE834/6-bad.txt +25 -0
  407. data/spec/fixtures/X220-BE834/6-good.txt +20 -0
  408. data/spec/fixtures/X220-BE834/7-bad.txt +25 -0
  409. data/spec/fixtures/X220-BE834/7-good.txt +20 -0
  410. data/spec/fixtures/X220-BE834/8-bad.txt +25 -0
  411. data/spec/fixtures/X220-BE834/8-good.txt +20 -0
  412. data/spec/fixtures/X220-BE834/9-bad.txt +27 -0
  413. data/spec/fixtures/X220-BE834/9-good.txt +21 -0
  414. data/spec/fixtures/X221-HP835/1-bad.txt +58 -0
  415. data/spec/fixtures/X221-HP835/1-good.txt +40 -0
  416. data/spec/fixtures/X221-HP835/2-bad.txt +51 -0
  417. data/spec/fixtures/X221-HP835/2-good.txt +40 -0
  418. data/spec/fixtures/X221-HP835/3a-bad.txt +78 -0
  419. data/spec/fixtures/X221-HP835/3a-good.txt +49 -0
  420. data/spec/fixtures/X221-HP835/3b-bad.txt +60 -0
  421. data/spec/fixtures/X221-HP835/3b-good.txt +32 -0
  422. data/spec/fixtures/X221-HP835/3c-bad.txt +55 -0
  423. data/spec/fixtures/X221-HP835/3c-good.txt +34 -0
  424. data/spec/fixtures/X222-HC837/1-bad.txt +60 -0
  425. data/spec/fixtures/X222-HC837/1-good.txt +53 -0
  426. data/spec/fixtures/X222-HC837/10a-bad.txt +52 -0
  427. data/spec/fixtures/X222-HC837/10a-good.txt +40 -0
  428. data/spec/fixtures/X222-HC837/10b-bad.txt +99 -0
  429. data/spec/fixtures/X222-HC837/10b-good.txt +80 -0
  430. data/spec/fixtures/X222-HC837/10c-bad.txt +105 -0
  431. data/spec/fixtures/X222-HC837/10c-good.txt +80 -0
  432. data/spec/fixtures/X222-HC837/11-bad.txt +69 -0
  433. data/spec/fixtures/X222-HC837/11-good.txt +45 -0
  434. data/spec/fixtures/X222-HC837/12-bad.txt +73 -0
  435. data/spec/fixtures/X222-HC837/12-good.txt +51 -0
  436. data/spec/fixtures/X222-HC837/13-bad.txt +64 -0
  437. data/spec/fixtures/X222-HC837/13-good.txt +46 -0
  438. data/spec/fixtures/X222-HC837/3a-bad.txt +83 -0
  439. data/spec/fixtures/X222-HC837/3a-good.txt +59 -0
  440. data/spec/fixtures/X222-HC837/3b-bad.txt +97 -0
  441. data/spec/fixtures/X222-HC837/3b-good.txt +70 -0
  442. data/spec/fixtures/X222-HC837/3c-bad.txt +95 -0
  443. data/spec/fixtures/X222-HC837/3c-good.txt +74 -0
  444. data/spec/fixtures/X222-HC837/4-bad.txt +67 -0
  445. data/spec/fixtures/X222-HC837/4-good.txt +48 -0
  446. data/spec/fixtures/X222-HC837/5-bad.txt +73 -0
  447. data/spec/fixtures/X222-HC837/5-good.txt +60 -0
  448. data/spec/fixtures/X222-HC837/6-bad.txt +50 -0
  449. data/spec/fixtures/X222-HC837/6-good.txt +39 -0
  450. data/spec/fixtures/X222-HC837/7-bad.txt +93 -0
  451. data/spec/fixtures/X222-HC837/7-good.txt +78 -0
  452. data/spec/fixtures/X222-HC837/8-bad.txt +64 -0
  453. data/spec/fixtures/X222-HC837/8-good.txt +52 -0
  454. data/spec/fixtures/X222-HC837/9-bad.txt +56 -0
  455. data/spec/fixtures/X222-HC837/9-good.txt +38 -0
  456. data/spec/fixtures/X223-HC837/1-bad.txt +66 -0
  457. data/spec/fixtures/X223-HC837/1-good.txt +53 -0
  458. data/spec/fixtures/X223-HC837/2-bad.txt +69 -0
  459. data/spec/fixtures/X223-HC837/2-good.txt +60 -0
  460. data/spec/fixtures/X223-HC837/3-bad.txt +89 -0
  461. data/spec/fixtures/X223-HC837/3-good.txt +61 -0
  462. data/spec/fixtures/X223-HC837/4-bad.txt +60 -0
  463. data/spec/fixtures/X223-HC837/4-good.txt +40 -0
  464. data/spec/fixtures/X223-HC837/5-bad.txt +75 -0
  465. data/spec/fixtures/X223-HC837/5-good.txt +58 -0
  466. data/spec/fixtures/X224-HC837/1-bad.txt +54 -0
  467. data/spec/fixtures/X224-HC837/1-good.txt +44 -0
  468. data/spec/fixtures/X224-HC837/2a-bad.txt +52 -0
  469. data/spec/fixtures/X224-HC837/2a-good.txt +42 -0
  470. data/spec/fixtures/X224-HC837/2b-bad.txt +67 -0
  471. data/spec/fixtures/X224-HC837/2b-good.txt +52 -0
  472. data/spec/fixtures/X224-HC837/3-bad.txt +67 -0
  473. data/spec/fixtures/X224-HC837/3-good.txt +51 -0
  474. data/spec/fixtures/X224-HC837/4-bad.txt +49 -0
  475. data/spec/fixtures/X224-HC837/4-good.txt +40 -0
  476. data/spec/fixtures/X230-FA997/1-bad.txt +19 -0
  477. data/spec/fixtures/X230-FA997/1-good.txt +16 -0
  478. data/spec/fixtures/X231-FA999/1-bad.txt +20 -0
  479. data/spec/fixtures/X231-FA999/1-good.txt +20 -0
  480. data/spec/fixtures/X279-HB271/1-bad.txt +36 -0
  481. data/spec/fixtures/X279-HB271/1-good.txt +30 -0
  482. data/spec/fixtures/X279-HB271/2-bad.txt +22 -0
  483. data/spec/fixtures/X279-HB271/2-good.txt +16 -0
  484. data/spec/fixtures/X279-HB271/3-bad.txt +44 -0
  485. data/spec/fixtures/X279-HB271/3-good.txt +36 -0
  486. data/spec/fixtures/X279-HS270/1-bad.txt +29 -0
  487. data/spec/fixtures/X279-HS270/1-good.txt +23 -0
  488. data/spec/fixtures/X279-HS270/2-bad.txt +32 -0
  489. data/spec/fixtures/X279-HS270/2-good.txt +25 -0
  490. data/spec/spec_helper.rb +34 -0
  491. data/spec/support/fixtures.rb +26 -0
  492. data/spec/support/matchers/either_matchers.rb +26 -0
  493. data/spec/support/matchers/navigation_matchers.rb +247 -0
  494. data/spec/support/node.rb +41 -0
  495. data/spec/support/quickcheck/characters.rb +28 -0
  496. data/spec/support/quickcheck/property.rb +105 -0
  497. data/spec/support/quickcheck/serialized_edi.rb +399 -0
  498. data/spec/support/quickcheck.rb +302 -0
  499. data/spec/support/rcov.rb +34 -0
  500. metadata +577 -0
@@ -0,0 +1,469 @@
1
+ module Stupidedi
2
+ module Editor
3
+
4
+ #
5
+ # Critiques (edits) a "005010" functional groups (GS/GE), then selects the
6
+ # appropriate editor, according to the config, and edits each transaction
7
+ # set (ST/SE)
8
+ #
9
+ class FiftyTenEd < AbstractEd
10
+
11
+ # @return [Config]
12
+ attr_reader :config
13
+
14
+ # @return [Time]
15
+ attr_reader :received
16
+
17
+ def initialize(config, received)
18
+ @config, @received =
19
+ config, received
20
+ end
21
+
22
+ def critique(gs, acc)
23
+ acc.tap { critique_gs(gs, acc) }
24
+ end
25
+
26
+ private
27
+
28
+ def critique_gs(gs, acc)
29
+ # Functional Group Code
30
+ edit(:GS01) do
31
+ gs.element(1).tap do |e|
32
+ if e.node.blank?
33
+ if e.node.usage.required?
34
+ acc.ak905(e, "R", "1", "must be present")
35
+ end
36
+ elsif e.node.usage.forbidden?
37
+ acc.ak905(e, "R", "1", "must not be present")
38
+ else
39
+ # @todo: The allowed value depends on the child transaction set,
40
+ # but the GS segment is not declared in the transaction set def.
41
+ # Furthermore, the functional group may contain many transaction
42
+ # sets, so we need to check it once we get to the ST segment...
43
+ end
44
+ end
45
+ end
46
+
47
+ # Application Sender's Code
48
+ edit(:GS02) do
49
+ gs.element(2).tap do |e|
50
+ if e.node.blank?
51
+ if e.node.usage.required?
52
+ acc.ak905(e, "R", "14", "must be present")
53
+ end
54
+ elsif e.node.usage.forbidden?
55
+ acc.ak905(e, "R", "14", "must not be present")
56
+ elsif e.node.invalid? or not config.editor.an?(e.node)
57
+ acc.ak905(e, "R", "14", "is not a valid string")
58
+ end
59
+ end
60
+ end
61
+
62
+ # Application Receiver's Code
63
+ edit(:GS03) do
64
+ gs.element(3).tap do |e|
65
+ if e.node.blank?
66
+ acc.ak905(e, "R", "13", "must be present")
67
+ elsif e.node.invalid? or not config.editor.an?(e.node)
68
+ acc.ak905(e, "R", "13", "is not a valid string")
69
+ end
70
+ end
71
+ end
72
+
73
+ # Date
74
+ edit(:GS04) do
75
+ gs.element(4).tap do |e|
76
+ if e.node.blank?
77
+ acc.ta105(e, "R", "024", "must be present")
78
+ elsif e.node.invalid?
79
+ acc.ta105(e, "R", "024", "is not a valid date")
80
+ elsif e.node > received.utc.send(:to_date)
81
+ acc.ta105(e, "R", "024", "must not be a future date")
82
+ end
83
+ end
84
+ end
85
+
86
+ # Time
87
+ edit(:GS05) do
88
+ gs.element(5).tap do |e|
89
+ if e.node.blank?
90
+ acc.ta105(e, "R", "024", "must be present")
91
+ elsif e.node.invalid?
92
+ acc.ta105(e, "R", "024", "is not a valid time")
93
+ else
94
+ gs.element(4).reject{|f| f.node.invalid? }.tap do |f|
95
+ if e.node.to_time(f.node) > received.utc
96
+ acc.ta105(e, "R", "024", "must not be a future date")
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ # Group Control Number
104
+ edit(:GS06) do
105
+ gs.element(6).tap do |e|
106
+ if e.node.blank?
107
+ acc.ak905(e, "R", "6", "must be present")
108
+ elsif e.node.invalid?
109
+ acc.ak905(e, "R", "6", "is not a valid string")
110
+ elsif e.node < 0
111
+ acc.ak905(e, "R", "6", "must be positive")
112
+ elsif e.node > 999_999_999
113
+ acc.ak905(e, "R", "6", "is too long")
114
+ end
115
+ end
116
+ end
117
+
118
+ # Responsible Agency Code
119
+ edit(:GS07) do
120
+ gs.element(7).tap do |e|
121
+ if e.node.blank?
122
+ acc.ta105(e, "R", "024", "must be present")
123
+ elsif e.node.invalid?
124
+ acc.ta105(e, "R", "024", "is not a valid string")
125
+ elsif not e.node.allowed?
126
+ acc.ta105(e, "R", "024", "is not an allowed value")
127
+ end
128
+ end
129
+ end
130
+
131
+ # Version/Release/Industry Identifier Code
132
+ edit(:GS08) do
133
+ gs.element(8).tap do |e|
134
+ if e.node.blank?
135
+ acc.ak905(e, "R", "2", "must be present")
136
+ end
137
+ end
138
+ end
139
+
140
+ st, st02s = gs.find!(:ST), Hash.new{|h,k| h[k] = [] }
141
+ # Collect all the ST02 elements within this functional group
142
+ while st.defined?
143
+ st = st.flatmap do |st|
144
+ critique_st(st, acc)
145
+
146
+ st.element(2).
147
+ tap{|e| st02s[e.node.to_s] << e }.
148
+ explain do
149
+ # The #element method failed because this was an invalid ST
150
+ # segment. To workaround that, we can get the SegmentTok and
151
+ # select the ST02 ElementTok (zero-based index)
152
+ st.segment.tap do |s|
153
+ elements = s.node.segment_tok.element_toks
154
+ st02s[elements.at(1).value] << s
155
+ end
156
+ end
157
+
158
+ st.find!(:ST)
159
+ end
160
+ end
161
+
162
+ edit(:ST) do
163
+ if st02s.empty?
164
+ gs.segment.tap{|s| acc.ik502(s, "R", "1", "missing ST segment") }
165
+ end
166
+ end
167
+
168
+ edit(:ST02) do
169
+ st02s.each do |number, es|
170
+ next if number.blank?
171
+ es.tail.each do |e|
172
+ acc.ik502(e, "R", "23", "must be unique within functional group")
173
+ end
174
+ end
175
+ end
176
+
177
+ edit(:GE) do
178
+ gs.find(:GE).tap do |ge|
179
+ critique_ge(ge, gs, st02s.length, acc)
180
+ end.explain do
181
+ gs.segment.tap{|s| acc.ak905(s, "R", "3", "missing GE segment") }
182
+ end
183
+ end
184
+ end
185
+
186
+ def critique_ge(ge, gs, st_count, acc)
187
+ # Number of Transaction Sets Included
188
+ edit(:GE01) do
189
+ ge.element(1).tap do |e|
190
+ if e.node.empty?
191
+ acc.ak905(e, "R", "5", "must be present")
192
+ elsif e.node.invalid?
193
+ acc.ak905(e, "R", "5", "must be numeric")
194
+ elsif e.node != st_count
195
+ acc.ak905(e, "R", "5", "must equal the number of transactions")
196
+ end
197
+ end
198
+ end
199
+
200
+ # Group Control Number
201
+ edit(:GE02) do
202
+ ge.element(2).tap do |e|
203
+ if e.node.empty?
204
+ acc.ak905(e, "R", "4", "must be present")
205
+ else
206
+ gs.element(6).reject{|f| e.node == f.node }.tap do |f|
207
+ acc.ak905(e, "R", "4", "must match functional group header control number")
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ def critique_st(st, acc)
215
+ st.segment.tap do |x|
216
+ unless x.node.invalid?
217
+ # Invoke a general transaction set editor, which will later
218
+ # dispatch to a guide-specific transaction set editor
219
+ editor = TransactionSetEd.new(config, received)
220
+ editor.critique(st, acc)
221
+ else
222
+ acc.ik502(x, "R", "I6", x.node.reason)
223
+ return
224
+ end
225
+ end
226
+
227
+ # Transaction Set Identifier Code
228
+ edit(:ST01) do
229
+ st.element(1).tap do |e|
230
+ if e.node.blank?
231
+ if e.node.usage.required?
232
+ acc.ik502(e, "R", "6", "must be present")
233
+ end
234
+ elsif e.node.usage.forbidden?
235
+ acc.ik502(e, "R", "6", "must not be present")
236
+ elsif e.node.invalid?
237
+ acc.ik502(e, "R", "6", "is not a valid identifier")
238
+ elsif not e.node.allowed?
239
+ acc.ik502(e, "R", "6", "is not an allowed value")
240
+ end
241
+ end
242
+ end
243
+
244
+ # Transaction Set Control Number
245
+ edit(:ST02) do
246
+ st.element(2).tap do |e|
247
+ if e.node.blank?
248
+ if e.node.usage.required?
249
+ acc.ik502(e, "R", "7", "must be present")
250
+ elsif e.node.usage.forbidden?
251
+ acc.ik502(e, "R", "7", "must not be present")
252
+ elsif e.node.invalid?
253
+ acc.ik502(e, "R", "7", "is not a valid string")
254
+ end
255
+ end
256
+ end
257
+ end
258
+
259
+ # Implementation Convention Reference
260
+ edit(:ST03) do
261
+ st.element(3).tap do |e|
262
+ if e.node.blank?
263
+ if e.node.usage.required?
264
+ acc.ik502(e, "R", "I6", "must be present")
265
+ end
266
+ elsif e.node.usage.forbidden?
267
+ acc.ik502(e, "R", "I6", "must not be present")
268
+ elsif e.node.invalid?
269
+ acc.ik502(e, "R", "I6", "is not a valid string")
270
+ elsif not e.node.allowed?
271
+ acc.ik502(e, "R", "I6", "is not an allowed value")
272
+ end
273
+ end
274
+ end
275
+
276
+ edit(:SE) do
277
+ st.find(:SE).tap do |se|
278
+ critique_se(se, st, acc)
279
+ end.explain do
280
+ st.segment.tap{|s| acc.ik502(s, "R", "2", "missing SE segment") }
281
+ end
282
+ end
283
+ end
284
+
285
+ def critique_se(se, st, acc)
286
+ # Number of Included Segments
287
+ edit(:SE01) do
288
+ se.element(1).tap do |e|
289
+ if e.node.empty?
290
+ if e.node.usage.required?
291
+ acc.ik502(e, "R", "4", "must be present")
292
+ end
293
+ elsif e.node.usage.forbidden?
294
+ acc.ik502(e, "R", "4", "must not be present")
295
+ elsif e.node.invalid?
296
+ acc.ik502(e, "R", "4", "must be numeric")
297
+ else
298
+ st.distance(se).tap do |d|
299
+ unless e.node == d + 1
300
+ acc.ik502(e, "R", "4", "must equal the transaction segment count")
301
+ end
302
+ end
303
+ end
304
+ end
305
+ end
306
+
307
+ # Transaction Set Control Number
308
+ edit(:SE02) do
309
+ se.element(2).tap do |e|
310
+ if e.node.empty?
311
+ if e.node.usage.required?
312
+ acc.ik502(e, "R", "3", "must be present")
313
+ end
314
+ elsif e.node.usage.forbidden?
315
+ acc.ik502(e, "R", "3", "must not be present")
316
+ elsif e.node.invalid?
317
+ acc.ik502(e, "R", "3", "is not a valid string")
318
+ else
319
+ st.element(2).reject{|f| f.node == e.node }.tap do
320
+ acc.ik502(e, "R", "3", "must equal transaction header control number")
321
+ end
322
+ end
323
+ end
324
+ end
325
+ end
326
+
327
+ def critique_nm1(nm1, acc)
328
+ edit(:NM1) do
329
+ # Organization/last name
330
+ nm1.element(3).tap do |e|
331
+ if e.node.blank? and e.node.usage.optional?
332
+ acc.warn(e, "optional element is not present")
333
+ end
334
+ end
335
+
336
+ # Non-person entity
337
+ if nm1.element(2).select{|e| e.node == "2" }.defined?
338
+ # First name
339
+ nm1.element(4).tap do |e|
340
+ if e.node.present? and e.node.usage.optional?
341
+ acc.stc01(e, "T", "A8", "505", "must not be present when NM102 is 2")
342
+ end
343
+ end
344
+
345
+ # Middle name
346
+ nm1.element(5).tap do |e|
347
+ if e.node.present? and e.node.usage.optional?
348
+ acc.stc01(e, "T", "A8", "514", "must not be present when NM102 is 2")
349
+ end
350
+ end
351
+
352
+ # Prefix name
353
+ nm1.element(6).tap do |e|
354
+ if e.node.present? and e.node.usage.optional?
355
+ acc.stc01(e, "T", "A8", "125", "must not be present when NM102 is 2")
356
+ end
357
+ end
358
+
359
+ # Suffix name
360
+ nm1.element(7).tap do |e|
361
+ if e.node.present? and e.node.usage.optional?
362
+ acc.stc01(e, "T", "A8", "125", "must not be present when NM102 is 2")
363
+ end
364
+ end
365
+ end
366
+
367
+ # Person
368
+ if nm1.element(2).select{|e| e.node == "1" }.defined?
369
+ # First name
370
+ nm1.element(4).tap do |e|
371
+ if e.node.blank? and e.node.usage.optional?
372
+ acc.warn(e, "optional element is not present")
373
+ end
374
+ end
375
+
376
+ # Middle name
377
+ nm1.element(5).tap do |e|
378
+ if e.node.blank? and e.node.usage.optional?
379
+ acc.warn(e, "optional element is not present")
380
+ end
381
+ end
382
+
383
+ # Prefix name
384
+ nm1.element(6).tap do |e|
385
+ if e.node.blank? and e.node.usage.optional?
386
+ acc.warn(e, "optional element is not present")
387
+ end
388
+ end
389
+
390
+ # Suffix name
391
+ nm1.element(7).tap do |e|
392
+ if e.node.blank? and e.node.usage.optional?
393
+ acc.warn(e, "optional element is not present")
394
+ end
395
+ end
396
+ end
397
+ end
398
+ end
399
+
400
+ def critique_n3(n3, acc)
401
+ edit(:N3) do
402
+ n3.element(2).tap do |e|
403
+ if e.node.usage.optional?
404
+ unless n3.element(1).relect(&:blank?).defined?
405
+ # Second address line (N302) shouldn't be present if the
406
+ # first (N301) isn't also present
407
+ acc.warn(e, "second address line present without first line")
408
+ end
409
+ end
410
+ end
411
+ end
412
+ end
413
+
414
+ def critique_n4(n4, acc)
415
+ edit(:N4) do
416
+ usa_canada =
417
+ n4.element(2).select(&:present?).defined? ||
418
+ n4.element(4).select(&:blank?).defined? ||
419
+ n4.element(4).select{|e| e.node == "US" }.defined? ||
420
+ n4.element(7).select(&:blank?).defined?
421
+
422
+ # State or Province Code
423
+ n4.element(2).tap do |e|
424
+ if usa_canada
425
+ if e.node.blank? and e.node.situational?
426
+ # Required
427
+ end
428
+ else
429
+ if e.node.present? and e.node.situational?
430
+ # Forbidden
431
+ end
432
+ end
433
+ end
434
+
435
+ # Postal Code
436
+ n4.element(3).tap do |e|
437
+ if usa_canada
438
+ # US zipcodes must be 9-digits
439
+ end
440
+ end
441
+
442
+ # Country Code
443
+ n4.element(4).tap do |e|
444
+ if usa_canada
445
+ if e.node.present? and e.node.situational?
446
+ # Forbidden
447
+ end
448
+ else
449
+ # Country codes 2-digit from ISO 3166
450
+ end
451
+ end
452
+
453
+ # Country Subdivision Code
454
+ n4.element(7).tap do |e|
455
+ if usa_canada
456
+ if e.node.present? and e.node.situational?
457
+ # Forbidden
458
+ end
459
+ else
460
+ # Country subdivision codes from ISO 3166
461
+ end
462
+ end
463
+ end
464
+ end
465
+
466
+ end
467
+
468
+ end
469
+ end
@@ -0,0 +1,195 @@
1
+ module Stupidedi
2
+ module Editor
3
+
4
+ class X222 < AbstractEd
5
+
6
+ # @return [Config]
7
+ attr_reader :config
8
+
9
+ # @return [Time]
10
+ attr_reader :received
11
+
12
+ def initialize(config, received)
13
+ @config, @received =
14
+ config, received
15
+ end
16
+
17
+ def critique(st, acc)
18
+ acc.tap do
19
+ critique_st(st, acc)
20
+
21
+ # st.find(:SE).tap do |se|
22
+ # st.distance(se).tap do |n|
23
+ # n.times { st.next.tap{|z| z }}
24
+ # end
25
+ # end
26
+
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ # The X222 implementation guide places constraints on the interchange
33
+ # header and trailer that are not modeled in Guide::X222, because the
34
+ # scope is limited to the contents of the transaction set envelope.
35
+ def critique_isa(isa, acc)
36
+ edit(:ISA05) do
37
+ isa.element(5).tap do |e|
38
+ if e.node.present? and e.node.valid?
39
+ unless %w(27 28 ZZ).include?(e.node)
40
+ acc.ta105(e, "R", "005", "must be '27', '28', or 'ZZ'")
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ edit(:ISA07) do
47
+ isa.element(7).tap do |e|
48
+ if e.node.present? and e.node.valid?
49
+ unless %w(27 28 ZZ).include?(e.node)
50
+ acc.ta105(e, "R", "005", "must be '27', '28', or 'ZZ'")
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ edit(:ISA12) do
57
+ isa.element(12).tap do |e|
58
+ if e.node.present? and e.node.valid?
59
+ unless e.node == "00501"
60
+ acc.ta105(e, "R", "017", "must be '00501'")
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ # The X222 implementation guide places constraints on the functional
68
+ # group header and trailer that are not modeled in Guide::X222, because
69
+ # the scope is limited to the contents of the transaction set envelope.
70
+ def critique_gs(gs, acc)
71
+ # ... However these are all handled generically in TransactionSetEd
72
+ # and are driven by the definition of the transaction set.
73
+ end
74
+
75
+ def critique_st(st, acc)
76
+ st.parent.tap do |gs|
77
+ gs.parent.tap do |isa|
78
+ critique_isa(isa, acc)
79
+ end
80
+
81
+ critique_gs(gs, acc)
82
+ end
83
+ end
84
+
85
+ # IK403 "I10" element must not be present has action "E"
86
+
87
+ # X222.074.1000A.NM104.010
88
+ # X222.074.1000A.NM105.020
89
+ # X222.074.1000A.NM109.070
90
+ # X222.076.1000A.PER02.020
91
+ # X222.076.1000A.PER02.040
92
+ # X222.076.1000A.PER05.020
93
+ # X222.076.1000A.PER07.030
94
+ # X222.074.1000B.NM109.050
95
+ # X222.081.2000A.HL01.040
96
+ # X222.083.2000A.PRV03.020 *
97
+ # X222.084.2000A.CUR.010 * Medicare specific
98
+ # X222.084.2000A.CUR.010 * Medicare specific
99
+ # X222.087.2010AA.NM108.010 * Trailblazer specific
100
+ # X222.087.2010AA.NM108.020 * Medicare specific (except Trailblazer)
101
+ # X222.087.2010AA.NM109.030
102
+ # X222.087.2010AA.NM109.040
103
+ # X222.087.2010AA.N302.060 * "Post Office Box", "P.O. Box", "PO Box", "Lock Box", "Lock Bin"
104
+
105
+ def critique_nm1(nm1, acc)
106
+ edit(:NM1) do
107
+ # Organization/last name
108
+ nm1.element(3).tap do |e|
109
+ if e.node.blank? and e.node.usage.optional?
110
+ acc.warn(e, "optional element is not present")
111
+ end
112
+ end
113
+
114
+ # Non-person entity
115
+ if nm1.element(2).select{|e| e.node == "2" }.defined?
116
+ # First name
117
+ nm1.element(4).tap do |e|
118
+ if e.node.present? and e.node.usage.optional?
119
+ acc.stc01(e, "T", "A8", "505", "must not be present when NM102 is 2")
120
+ end
121
+ end
122
+
123
+ # Middle name
124
+ nm1.element(5).tap do |e|
125
+ if e.node.present? and e.node.usage.optional?
126
+ acc.stc01(e, "T", "A8", "514", "must not be present when NM102 is 2")
127
+ end
128
+ end
129
+
130
+ # Prefix name
131
+ nm1.element(6).tap do |e|
132
+ if e.node.present? and e.node.usage.optional?
133
+ acc.stc01(e, "T", "A8", "125", "must not be present when NM102 is 2")
134
+ end
135
+ end
136
+
137
+ # Suffix name
138
+ nm1.element(7).tap do |e|
139
+ if e.node.present? and e.node.usage.optional?
140
+ acc.stc01(e, "T", "A8", "125", "must not be present when NM102 is 2")
141
+ end
142
+ end
143
+ end
144
+
145
+ # Person
146
+ if nm1.element(2).select{|e| e.node == "1" }.defined?
147
+ # First name
148
+ nm1.element(4).tap do |e|
149
+ if e.node.blank? and e.node.usage.optional?
150
+ acc.warn(e, "optional element is not present")
151
+ end
152
+ end
153
+
154
+ # Middle name
155
+ nm1.element(5).tap do |e|
156
+ if e.node.blank? and e.node.usage.optional?
157
+ acc.warn(e, "optional element is not present")
158
+ end
159
+ end
160
+
161
+ # Prefix name
162
+ nm1.element(6).tap do |e|
163
+ if e.node.blank? and e.node.usage.optional?
164
+ acc.warn(e, "optional element is not present")
165
+ end
166
+ end
167
+
168
+ # Suffix name
169
+ nm1.element(7).tap do |e|
170
+ if e.node.blank? and e.node.usage.optional?
171
+ acc.warn(e, "optional element is not present")
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ def critique_n3(n3, acc)
179
+ edit(:N3) do
180
+ n3.element(2).tap do |e|
181
+ if e.node.usage.optional?
182
+ unless n3.element(1).reject(&:blank?).defined?
183
+ # Second address line (N302) shouldn't be present if the
184
+ # first (N301) isn't also present
185
+ acc.warn(e, "second address line present without first line")
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ end
193
+
194
+ end
195
+ end
@@ -0,0 +1,36 @@
1
+ module Stupidedi
2
+ module Editor
3
+
4
+ class AbstractEd
5
+ include Inspect
6
+
7
+ # @return [Config]
8
+ abstract :config
9
+
10
+ # @return [ResultSet]
11
+ abstract :critique
12
+
13
+ def edit(id)
14
+ if config.editor.enabled?(id)
15
+ # puts "#{self.class.name.split("::").last}.edit(#{id})"
16
+ yield
17
+ end
18
+ end
19
+
20
+ def rewrite(id)
21
+ if config.editor.enabled?(id)
22
+ yield
23
+ end
24
+ end
25
+ end
26
+
27
+ class << AbstractEd
28
+ def edit(*args)
29
+ end
30
+
31
+ def rewrite(*args)
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,9 @@
1
+ module Stupidedi
2
+ module Editor
3
+
4
+ # Generates a 277CA acknowledgement
5
+ class ClaimAck
6
+ end
7
+
8
+ end
9
+ end