From ae1abca95a3834f9ab954ebc0a5958d34f1cd2de Mon Sep 17 00:00:00 2001 From: raftmsohani <97037188+raftmsohani@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:47:15 -0500 Subject: [PATCH] 2599-error-report-excel-format (#2734) * Added formating for header and autofit columns * Formatted the headers * added year/month to the columns * Added contants - translation column * added friendly names to T1 and T2 * added friendly name to m1 and m2 * added friendly name to m3 * added friendly_name to t3 * added friendly_name to t4 and t5 * added friendly_name to t7 * correct missing friendly_name * correction on failing tests * addedfriendly name to excel report * linting * linting * linting * delete contants.py * added test for json field in error model * linting * linting * linting * 2599-added friendly name to postparsing validators * refining the validator tests * added returning fields names to validators * added friendly_name to error field * linting * corrections on views/tests * corrections for fields * failing test corrected * failing test corrected * correcting test failures * linting * corrected the excel fiel generator * removed excessive space in validator * linting * listing * added m6 * lint * corrected new line break * refactored validator logic * linting and correction on t1 * friendly_name correction from comments * friendly_name correction * corrected failing test for m5 * refactor the field_json creation DRY * friendly_name corrections * linting and cleaning errors * linting * correction on friendly_names * corrected friendly_name for test_util * correction child care - number of months * fixed a few more typos and some spacing. (#2767) * fixed a few more typos and some spacing. * fixed linting issues * missed a spot. --------- Co-authored-by: George Hudson * fields_json Backward compatibility * remove PATCH from black list * backward compatibility * linting * add PATCH to allowed * readded internal_name * added a function * remove NoneType from fields_json * linting * Update tdrs-backend/tdpservice/parsers/schema_defs/tanf/t5.py Co-authored-by: Alex P. <63075587+ADPennington@users.noreply.github.com> * Update tdrs-backend/tdpservice/parsers/schema_defs/ssp/m5.py Co-authored-by: Alex P. <63075587+ADPennington@users.noreply.github.com> * corrections on friendly names * Update tdrs-backend/tdpservice/parsers/schema_defs/ssp/m2.py Co-authored-by: Alex P. <63075587+ADPennington@users.noreply.github.com> * Update tdrs-backend/tdpservice/parsers/schema_defs/ssp/m5.py Co-authored-by: Alex P. <63075587+ADPennington@users.noreply.github.com> * correction on friendly names --------- Co-authored-by: George Hudson Co-authored-by: George Hudson Co-authored-by: Alex P. <63075587+ADPennington@users.noreply.github.com> --- tdrs-backend/Pipfile | 3 +- tdrs-backend/Pipfile.lock | 1002 ++++++++------- tdrs-backend/tdpservice/parsers/fields.py | 30 +- tdrs-backend/tdpservice/parsers/row_schema.py | 6 +- .../tdpservice/parsers/schema_defs/header.py | 73 +- .../tdpservice/parsers/schema_defs/ssp/m1.py | 747 +++++++---- .../tdpservice/parsers/schema_defs/ssp/m2.py | 1092 ++++++++++++----- .../tdpservice/parsers/schema_defs/ssp/m3.py | 764 ++++++++---- .../tdpservice/parsers/schema_defs/ssp/m4.py | 16 +- .../tdpservice/parsers/schema_defs/ssp/m5.py | 30 +- .../tdpservice/parsers/schema_defs/ssp/m6.py | 534 ++++++-- .../tdpservice/parsers/schema_defs/ssp/m7.py | 6 + .../tdpservice/parsers/schema_defs/tanf/t1.py | 49 +- .../tdpservice/parsers/schema_defs/tanf/t2.py | 72 +- .../tdpservice/parsers/schema_defs/tanf/t3.py | 45 +- .../tdpservice/parsers/schema_defs/tanf/t4.py | 16 +- .../tdpservice/parsers/schema_defs/tanf/t5.py | 32 +- .../tdpservice/parsers/schema_defs/tanf/t6.py | 108 +- .../tdpservice/parsers/schema_defs/tanf/t7.py | 6 + .../tdpservice/parsers/schema_defs/trailer.py | 27 +- .../small_incorrect_file_cross_validator.txt | 3 + .../tdpservice/parsers/test/test_parse.py | 8 + .../tdpservice/parsers/test/test_util.py | 226 +++- .../parsers/test/test_validators.py | 229 ++-- .../tdpservice/parsers/test/test_views.py | 85 ++ tdrs-backend/tdpservice/parsers/util.py | 11 +- tdrs-backend/tdpservice/parsers/validators.py | 326 +++-- tdrs-backend/tdpservice/parsers/views.py | 75 +- tdrs-frontend/nginx/cloud.gov/locations.conf | 4 +- 29 files changed, 3927 insertions(+), 1698 deletions(-) create mode 100644 tdrs-backend/tdpservice/parsers/test/data/small_incorrect_file_cross_validator.txt create mode 100644 tdrs-backend/tdpservice/parsers/test/test_views.py diff --git a/tdrs-backend/Pipfile b/tdrs-backend/Pipfile index b360c8e31..0aa6e5b40 100644 --- a/tdrs-backend/Pipfile +++ b/tdrs-backend/Pipfile @@ -58,7 +58,8 @@ django-elasticsearch-dsl = "==7.3" django-elasticsearch-dsl-drf = "==0.22.5" requests-aws4auth = "==1.1.2" cerberus = "==1.3.4" -xlsxwriter = "==3.0.1" +xlsxwriter = "==3.1.9" +openpyxl = "==3.1.2" sendgrid = "==6.10.0" [requires] diff --git a/tdrs-backend/Pipfile.lock b/tdrs-backend/Pipfile.lock index bc99d280f..b813960d6 100644 --- a/tdrs-backend/Pipfile.lock +++ b/tdrs-backend/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0ef020105fbcbee223abce4021a7599bff6bea6bce8bd4285ba36d3a4fc7994d" + "sha256": "b5dc98d1853dfbc3fc4cf27e370277bce4b6979094bda1d183b7ce369382e3ce" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "amqp": { "hashes": [ - "sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2", - "sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359" + "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637", + "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd" ], "markers": "python_version >= '3.6'", - "version": "==5.1.1" + "version": "==5.2.0" }, "asgiref": { "hashes": [ @@ -34,44 +34,33 @@ }, "asttokens": { "hashes": [ - "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3", - "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c" + "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24", + "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0" ], - "version": "==2.2.1" - }, - "backcall": { - "hashes": [ - "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e", - "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255" - ], - "version": "==0.2.0" + "version": "==2.4.1" }, "bcrypt": { "hashes": [ - "sha256:089098effa1bc35dc055366740a067a2fc76987e8ec75349eb9484061c54f535", - "sha256:08d2947c490093a11416df18043c27abe3921558d2c03e2076ccb28a116cb6d0", - "sha256:0eaa47d4661c326bfc9d08d16debbc4edf78778e6aaba29c1bc7ce67214d4410", - "sha256:27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd", - "sha256:2b3ac11cf45161628f1f3733263e63194f22664bf4d0c0f3ab34099c02134665", - "sha256:2caffdae059e06ac23fce178d31b4a702f2a3264c20bfb5ff541b338194d8fab", - "sha256:3100851841186c25f127731b9fa11909ab7b1df6fc4b9f8353f4f1fd952fbf71", - "sha256:5ad4d32a28b80c5fa6671ccfb43676e8c1cc232887759d1cd7b6f56ea4355215", - "sha256:67a97e1c405b24f19d08890e7ae0c4f7ce1e56a712a016746c8b2d7732d65d4b", - "sha256:705b2cea8a9ed3d55b4491887ceadb0106acf7c6387699fca771af56b1cdeeda", - "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9", - "sha256:a522427293d77e1c29e303fc282e2d71864579527a04ddcfda6d4f8396c6c36a", - "sha256:ae88eca3024bb34bb3430f964beab71226e761f51b912de5133470b649d82344", - "sha256:b1023030aec778185a6c16cf70f359cbb6e0c289fd564a7cfa29e727a1c38f8f", - "sha256:b3b85202d95dd568efcb35b53936c5e3b3600c7cdcc6115ba461df3a8e89f38d", - "sha256:b57adba8a1444faf784394de3436233728a1ecaeb6e07e8c22c8848f179b893c", - "sha256:bf4fa8b2ca74381bb5442c089350f09a3f17797829d958fad058d6e44d9eb83c", - "sha256:ca3204d00d3cb2dfed07f2d74a25f12fc12f73e606fcaa6975d1f7ae69cacbb2", - "sha256:cbb03eec97496166b704ed663a53680ab57c5084b2fc98ef23291987b525cb7d", - "sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e", - "sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3" + "sha256:12611c4b0a8b1c461646228344784a1089bc0c49975680a2f54f516e71e9b79e", + "sha256:12f40f78dcba4aa7d1354d35acf45fae9488862a4fb695c7eeda5ace6aae273f", + "sha256:14d41933510717f98aac63378b7956bbe548986e435df173c841d7f2bd0b2de7", + "sha256:196008d91201bbb1aa4e666fee5e610face25d532e433a560cabb33bfdff958b", + "sha256:24c2ebd287b5b11016f31d506ca1052d068c3f9dc817160628504690376ff050", + "sha256:2ade10e8613a3b8446214846d3ddbd56cfe9205a7d64742f0b75458c868f7492", + "sha256:2e197534c884336f9020c1f3a8efbaab0aa96fc798068cb2da9c671818b7fbb0", + "sha256:3d6c4e0d6963c52f8142cdea428e875042e7ce8c84812d8e5507bd1e42534e07", + "sha256:476aa8e8aca554260159d4c7a97d6be529c8e177dbc1d443cb6b471e24e82c74", + "sha256:755b9d27abcab678e0b8fb4d0abdebeea1f68dd1183b3f518bad8d31fa77d8be", + "sha256:a7a7b8a87e51e5e8ca85b9fdaf3a5dc7aaf123365a09be7a27883d54b9a0c403", + "sha256:bab33473f973e8058d1b2df8d6e095d237c49fbf7a02b527541a86a5d1dc4444", + "sha256:c6450538a0fc32fb7ce4c6d511448c54c4ff7640b2ed81badf9898dcb9e5b737", + "sha256:d573885b637815a7f3a3cd5f87724d7d0822da64b0ab0aa7f7c78bae534e86dc", + "sha256:df37f5418d4f1cdcff845f60e747a015389fa4e63703c918330865e06ad80007", + "sha256:f33b385c3e80b5a26b3a5e148e6165f873c1c202423570fdf45fe34e00e5f3e5", + "sha256:fb931cd004a7ad36a89789caf18a54c20287ec1cd62161265344b9c4554fdb2e" ], - "markers": "python_version >= '3.6'", - "version": "==4.0.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.1" }, "billiard": { "hashes": [ @@ -86,6 +75,7 @@ "sha256:92c0631ab91b4c5aa0e18a90b4d12df361723c6df1ef7e346db71f2ad0803ab3" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.28.4" }, "botocore": { @@ -94,6 +84,7 @@ "sha256:f9738a23b03c55c2958ebdee65273afeda80deaeefebe595887fc3251e48293a" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.31.4" }, "celery": { @@ -102,6 +93,7 @@ "sha256:da31f8eae7607b1582e5ee2d3f2d6f58450585afd23379491e3d9229d08102d0" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==5.2.6" }, "cerberus": { @@ -109,84 +101,74 @@ "sha256:d1b21b3954b2498d9a79edf16b3170a3ac1021df88d197dc2ce5928ba519237c" ], "index": "pypi", + "markers": "python_version >= '2.7'", "version": "==1.3.4" }, "certifi": { "hashes": [ - "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", - "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" + "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", + "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" ], "markers": "python_version >= '3.6'", - "version": "==2023.5.7" + "version": "==2023.11.17" }, "cffi": { "hashes": [ - "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", - "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", - "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", - "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", - "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", - "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", - "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", - "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", - "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", - "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", - "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", - "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", - "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", - "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", - "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", - "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", - "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", - "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", - "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", - "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", - "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", - "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", - "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", - "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", - "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", - "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", - "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", - "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", - "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", - "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", - "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", - "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", - "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", - "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", - "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", - "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", - "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", - "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", - "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", - "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", - "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", - "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", - "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", - "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", - "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", - "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", - "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", - "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", - "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", - "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", - "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", - "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", - "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", - "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", - "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", - "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", - "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", - "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", - "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", - "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", - "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", - "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", - "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", - "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" - ], - "version": "==1.15.1" + "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", + "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", + "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", + "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", + "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", + "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", + "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", + "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", + "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", + "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", + "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", + "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", + "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", + "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", + "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", + "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", + "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", + "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", + "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", + "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", + "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", + "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", + "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", + "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", + "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", + "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", + "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", + "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", + "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", + "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", + "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", + "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", + "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", + "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", + "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", + "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", + "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", + "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", + "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", + "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", + "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", + "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", + "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", + "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", + "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", + "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", + "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", + "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", + "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", + "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", + "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", + "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" + ], + "markers": "python_version >= '3.8'", + "version": "==1.16.0" }, "charset-normalizer": { "hashes": [ @@ -198,11 +180,11 @@ }, "click": { "hashes": [ - "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd", - "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "markers": "python_version >= '3.7'", - "version": "==8.1.6" + "version": "==8.1.7" }, "click-didyoumean": { "hashes": [ @@ -259,6 +241,7 @@ "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.4.7" }, "decorator": { @@ -291,6 +274,7 @@ "sha256:f71934b1a822f14a86c9ac9634053689279cd04ae69cb6ade4a59471b886582b" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.2.15" }, "django-admin-508": { @@ -307,6 +291,7 @@ "sha256:aedb5df940d32c10423d65136343bc009727df8a5a49ed0196e65241d823a890" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==1.0.2" }, "django-celery-beat": { @@ -319,10 +304,10 @@ }, "django-colorfield": { "hashes": [ - "sha256:208e04dae669ed95f18c4aef02865e9c785873521ffbe5b46fb6ea7a1500c979", - "sha256:7df5486de759dce70e54a1854f69bafd0a1e1bf98b66b09661d4d84342f447fc" + "sha256:05c38c8eb2a94938b810a19b2011846391a4ce71d1c92e88a35974fbcc8fc62e", + "sha256:460f40e6123b6ae0fb51a4eb86fc258fcdc0ea28f75102b685e8209b1eae9ec3" ], - "version": "==0.9.0" + "version": "==0.11.0" }, "django-configurations": { "hashes": [ @@ -338,6 +323,7 @@ "sha256:5f07e2ff8a95c887698e748588a4a0b2ad0ad1b5a292e2d33132f1253e2a97cb" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==3.12.0" }, "django-csp": { @@ -362,6 +348,7 @@ "sha256:fc0b3960e16f6c06de4f2ca4daf1134376fce4d496c1ddc218c23daddf6bcaa0" ], "index": "pypi", + "markers": "python_version >= '2.7'", "version": "==0.22.5" }, "django-extensions": { @@ -370,6 +357,7 @@ "sha256:5f0fea7bf131ca303090352577a9e7f8bfbf5489bd9d9c8aea9401db28db34a0" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.1.3" }, "django-filter": { @@ -378,6 +366,7 @@ "sha256:f4a6737a30104c98d2e2a5fb93043f36dd7978e0c7ddc92f5998e85433ea5063" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==21.1" }, "django-flat-responsive": { @@ -413,6 +402,7 @@ "sha256:a475edb2f0f04c4f7e548919a751ecd50117270833956ed5bd585c0575d2a5e7" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==1.12.3" }, "django-timezone-field": { @@ -437,6 +427,7 @@ "sha256:24c4bf58ed7e85d1fe4ba250ab2da926d263cd57d64b03e8dcef0ac683f8b1aa" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.13.1" }, "drf-yasg": { @@ -445,6 +436,7 @@ "sha256:d50f197c7f02545d0b736df88c6d5cf874f8fea2507ad85ad7de6ae5bf2d9e5a" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==1.20.0" }, "elasticsearch": { @@ -453,6 +445,7 @@ "sha256:5920df0ab2630778680376d86bea349dc99860977eec9b6d2bd0860f337313f2" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'", "version": "==7.13.4" }, "elasticsearch-dsl": { @@ -463,13 +456,30 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==7.4.1" }, - "executing": { + "et-xmlfile": { "hashes": [ - "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc", - "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107" + "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c", + "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada" ], + "markers": "python_version >= '3.6'", + "version": "==1.1.0" + }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", "version": "==1.2.0" }, + "executing": { + "hashes": [ + "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147", + "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc" + ], + "markers": "python_version >= '3.5'", + "version": "==2.0.1" + }, "flower": { "hashes": [ "sha256:77be4bece7330893703e8cca3f3baddba356a0019186594a961e3968289da7ec", @@ -484,23 +494,24 @@ "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==20.1.0" }, "humanize": { "hashes": [ - "sha256:7ca0e43e870981fa684acb5b062deb307218193bca1a01f2b2676479df849b3a", - "sha256:df7c429c2d27372b249d3f26eb53b07b166b661326e0325793e0a988082e3889" + "sha256:582a265c931c683a7e9b8ed9559089dea7edcf6cc95be39a3cbc2c5d5ac2bcfa", + "sha256:ce284a76d5b1377fd8836733b983bfb0b76f1aa1c090de2566fcf008d7f6ab16" ], "markers": "python_version >= '3.8'", - "version": "==4.7.0" + "version": "==4.9.0" }, "idna": { "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", + "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" ], "markers": "python_version >= '3'", - "version": "==3.4" + "version": "==3.6" }, "inflection": { "hashes": [ @@ -515,15 +526,16 @@ "sha256:951bd9a64731c444fd907a5ce268543020086a697f6be08f7cc2c9a752a278c5" ], "index": "pypi", + "markers": "python_version >= '2.7'", "version": "==0.13.9" }, "ipython": { "hashes": [ - "sha256:1d197b907b6ba441b692c48cf2a3a2de280dc0ac91a3405b39349a50272ca0a1", - "sha256:248aca623f5c99a6635bc3857677b7320b9b8039f99f070ee0d20a5ca5a8e6bf" + "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27", + "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397" ], "markers": "python_version >= '3.7'", - "version": "==8.14.0" + "version": "==8.18.1" }, "itypes": { "hashes": [ @@ -534,11 +546,11 @@ }, "jedi": { "hashes": [ - "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e", - "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612" + "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", + "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0" ], "markers": "python_version >= '3.6'", - "version": "==0.18.2" + "version": "==0.19.1" }, "jinja2": { "hashes": [ @@ -561,15 +573,16 @@ "sha256:54b551b115ffb4d12b1f1ee93b8ba2a71bb8556ba3d85d62f707549613da877c" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==1.3.1" }, "kombu": { "hashes": [ - "sha256:48ee589e8833126fd01ceaa08f8a2041334e9f5894e5763c8486a550454551e9", - "sha256:fbd7572d92c0bf71c112a6b45163153dea5a7b6a701ec16b568c27d0fd2370f2" + "sha256:0bb2e278644d11dea6272c17974a3dbb9688a949f3bb60aeb5b791329c44fadc", + "sha256:63bb093fc9bb80cfb3a0972336a5cec1fa7ac5f9ef7e8237c6bf8dda9469313e" ], "markers": "python_version >= '3.8'", - "version": "==5.3.1" + "version": "==5.3.4" }, "markdown": { "hashes": [ @@ -577,6 +590,7 @@ "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.3.7" }, "markupsafe": { @@ -585,8 +599,11 @@ "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", + "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", + "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", + "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", @@ -594,6 +611,7 @@ "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", + "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", @@ -602,6 +620,7 @@ "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", + "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", @@ -609,9 +628,12 @@ "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", + "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", + "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", + "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", @@ -630,7 +652,9 @@ "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", - "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" + "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", + "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2", + "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11" ], "markers": "python_version >= '3.7'", "version": "==2.1.3" @@ -643,13 +667,22 @@ "markers": "python_version >= '3.5'", "version": "==0.1.6" }, + "openpyxl": { + "hashes": [ + "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184", + "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==3.1.2" + }, "packaging": { "hashes": [ - "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", - "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" ], "markers": "python_version >= '3.7'", - "version": "==23.1" + "version": "==23.2" }, "paramiko": { "hashes": [ @@ -669,96 +702,87 @@ }, "pexpect": { "hashes": [ - "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", - "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" + "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", + "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f" ], "markers": "sys_platform != 'win32'", - "version": "==4.8.0" - }, - "pickleshare": { - "hashes": [ - "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", - "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" - ], - "version": "==0.7.5" + "version": "==4.9.0" }, "pillow": { "hashes": [ - "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5", - "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530", - "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d", - "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca", - "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891", - "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992", - "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7", - "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3", - "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba", - "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3", - "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3", - "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f", - "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538", - "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3", - "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d", - "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c", - "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017", - "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3", - "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223", - "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e", - "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3", - "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6", - "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640", - "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334", - "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1", - "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba", - "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa", - "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0", - "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396", - "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d", - "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485", - "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf", - "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43", - "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37", - "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2", - "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd", - "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86", - "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967", - "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629", - "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568", - "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed", - "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f", - "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551", - "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3", - "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614", - "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff", - "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d", - "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883", - "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684", - "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0", - "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de", - "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b", - "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3", - "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199", - "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51", - "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90" + "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d", + "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de", + "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616", + "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839", + "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099", + "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a", + "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219", + "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106", + "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b", + "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412", + "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b", + "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7", + "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2", + "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7", + "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14", + "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f", + "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27", + "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57", + "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262", + "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28", + "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610", + "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172", + "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273", + "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e", + "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d", + "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818", + "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f", + "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9", + "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01", + "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7", + "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651", + "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312", + "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80", + "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666", + "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061", + "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b", + "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992", + "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593", + "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4", + "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db", + "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba", + "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd", + "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e", + "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212", + "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb", + "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2", + "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34", + "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256", + "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f", + "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2", + "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38", + "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996", + "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", + "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" ], "markers": "python_version >= '3.8'", - "version": "==10.0.0" + "version": "==10.1.0" }, "prometheus-client": { "hashes": [ - "sha256:21e674f39831ae3f8acde238afd9a27a37d0d2fb5a28ea094f0ce25d2cbf2091", - "sha256:e537f37160f6807b8202a6fc4764cdd19bac5480ddd3e0d463c3002b34462101" + "sha256:4585b0d1223148c27a225b10dbec5ae9bc4c81a99a3fa80774fa6209935324e1", + "sha256:c88b1e6ecf6b41cd8fb5731c7ae919bf66df6ec6fafa555cd6c0e16ca169ae92" ], - "markers": "python_version >= '3.6'", - "version": "==0.17.1" + "markers": "python_version >= '3.8'", + "version": "==0.19.0" }, "prompt-toolkit": { "hashes": [ - "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", - "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88" + "sha256:3b50b5fc50660dc8e39dfe464b170959ad82ff185ffa53bfd3be02222e7156a1", + "sha256:bfbf7d6ea9744e4ec94c9a69539e8106c77a2a607d728ded87c9182a4aec39be" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.0.39" + "version": "==3.0.42" }, "psycopg2-binary": { "hashes": [ @@ -823,6 +847,7 @@ "sha256:ffb7a888a047696e7f8240d649b43fb3644f14f0ee229077e7f6b9f9081635bd" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==2.9.3" }, "ptyprocess": { @@ -848,11 +873,11 @@ }, "pygments": { "hashes": [ - "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c", - "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1" + "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", + "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" ], "markers": "python_version >= '3.7'", - "version": "==2.15.1" + "version": "==2.17.2" }, "pyjwt": { "hashes": [ @@ -860,6 +885,7 @@ "sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==2.4.0" }, "pynacl": { @@ -883,7 +909,6 @@ "sha256:b7ac34a23f63d77e27f67b6a81c9418243733f027eeb8a3061d965b2da7e5cab", "sha256:c5e8a37049866d4eabc711db9f1c09e1c02ab72ba290f5fd244939c9a188042f" ], - "index": "pypi", "version": "==1.3.0" }, "python-crontab": { @@ -916,7 +941,6 @@ ], "index": "pypi", "version": "==2022.1" - }, "redis": { "hashes": [ @@ -924,6 +948,7 @@ "sha256:f13eea4254e302485add677cadedaf1305c1b3a4e07535e23b7b239798ce9301" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==4.1.2" }, "requests": { @@ -932,6 +957,7 @@ "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==2.27.1" }, "requests-aws4auth": { @@ -952,63 +978,75 @@ }, "ruamel.yaml": { "hashes": [ - "sha256:23cd2ed620231677564646b0c6a89d138b6822a0d78656df7abda5879ec4f447", - "sha256:ec939063761914e14542972a5cba6d33c23b0859ab6342f61cf070cfc600efc2" + "sha256:61917e3a35a569c1133a8f772e1226961bf5a1198bea7e23f06a0841dea1ab0e", + "sha256:a013ac02f99a69cdd6277d9664689eb1acba07069f912823177c5eced21a6ada" ], - "markers": "python_version >= '3'", - "version": "==0.17.32" + "markers": "python_version >= '3.7'", + "version": "==0.18.5" }, "ruamel.yaml.clib": { "hashes": [ - "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e", - "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3", - "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5", - "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81", - "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497", - "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f", - "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac", - "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697", - "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763", - "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282", - "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94", - "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1", - "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072", - "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9", - "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5", - "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231", - "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93", - "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b", - "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb", - "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f", - "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307", - "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf", - "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8", - "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b", - "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b", - "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640", - "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7", - "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a", - "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71", - "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8", - "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122", - "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7", - "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80", - "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e", - "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab", - "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0", - "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646", - "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38" - ], - "markers": "python_version < '3.12' and platform_python_implementation == 'CPython'", - "version": "==0.2.7" + "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d", + "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001", + "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462", + "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9", + "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe", + "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b", + "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b", + "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615", + "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62", + "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15", + "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b", + "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1", + "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9", + "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675", + "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899", + "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7", + "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7", + "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312", + "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa", + "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91", + "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b", + "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6", + "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3", + "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334", + "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5", + "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3", + "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe", + "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c", + "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed", + "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337", + "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880", + "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f", + "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d", + "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248", + "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d", + "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf", + "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512", + "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069", + "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb", + "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942", + "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d", + "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31", + "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92", + "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5", + "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28", + "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d", + "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1", + "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2", + "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875", + "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" + ], + "markers": "python_version < '3.13' and platform_python_implementation == 'CPython'", + "version": "==0.2.8" }, "s3transfer": { "hashes": [ - "sha256:3c0da2d074bf35d6870ef157158641178a4204a6e689e82546083e31e0311346", - "sha256:640bb492711f4c0c0905e1f62b6aaeb771881935ad27884852411f8e9cacbca9" + "sha256:b014be3a8a2aab98cfe1abc7229cc5a9a0cf05eb9c1f2b86b230fd8df3f78084", + "sha256:cab66d3380cca3e70939ef2255d01cd8aece6a4907a9528740f668c4b0611861" ], "markers": "python_version >= '3.7'", - "version": "==0.6.1" + "version": "==0.6.2" }, "sendgrid": { "hashes": [ @@ -1016,15 +1054,16 @@ "sha256:9b15050c6f8826ee576f76a786efb15d956639f485478cbddd79ed69e8350ab8" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==6.10.0" }, "setuptools": { "hashes": [ - "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f", - "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235" + "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", + "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" ], - "markers": "python_version >= '3.7'", - "version": "==68.0.0" + "markers": "python_version >= '3.8'", + "version": "==69.0.2" }, "six": { "hashes": [ @@ -1044,10 +1083,10 @@ }, "stack-data": { "hashes": [ - "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815", - "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8" + "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", + "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695" ], - "version": "==0.6.2" + "version": "==0.6.3" }, "starkbank-ecdsa": { "hashes": [ @@ -1065,36 +1104,36 @@ }, "tornado": { "hashes": [ - "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4", - "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf", - "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d", - "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba", - "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe", - "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411", - "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2", - "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0", - "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c", - "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f", - "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829" + "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0", + "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63", + "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263", + "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052", + "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f", + "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee", + "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78", + "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579", + "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212", + "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e", + "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2" ], "markers": "python_version >= '3.8'", - "version": "==6.3.2" + "version": "==6.4" }, "traitlets": { "hashes": [ - "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8", - "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9" + "sha256:f14949d23829023013c47df20b4a76ccd1a85effb786dc060f34de7948361b33", + "sha256:fcdaa8ac49c04dfa0ed3ee3384ef6dfdb5d6f3741502be247279407679296772" ], - "markers": "python_version >= '3.7'", - "version": "==5.9.0" + "markers": "python_version >= '3.8'", + "version": "==5.14.0" }, "typing-extensions": { "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "markers": "python_version < '3.11'", - "version": "==4.7.1" + "version": "==4.9.0" }, "uritemplate": { "hashes": [ @@ -1106,19 +1145,19 @@ }, "urllib3": { "hashes": [ - "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f", - "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14" + "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", + "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.16" + "version": "==1.26.18" }, "vine": { "hashes": [ - "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30", - "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e" + "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc", + "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0" ], "markers": "python_version >= '3.6'", - "version": "==5.0.0" + "version": "==5.1.0" }, "wait-for-it": { "hashes": [ @@ -1126,103 +1165,100 @@ "sha256:f219db8fd96819b026df1dc6d93fb380cf6d81f20450115200dd901dea4b0c8f" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==2.2.0" }, "wcwidth": { "hashes": [ - "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", - "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" + "sha256:f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02", + "sha256:f26ec43d96c8cbfed76a5075dac87680124fa84e0855195a6184da9c187f133c" ], - "version": "==0.2.6" + "version": "==0.2.12" }, "wrapt": { "hashes": [ - "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0", - "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420", - "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a", - "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c", - "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079", - "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923", - "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f", - "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1", - "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8", - "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86", - "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0", - "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364", - "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e", - "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c", - "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e", - "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c", - "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727", - "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff", - "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e", - "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29", - "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7", - "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72", - "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475", - "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a", - "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317", - "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2", - "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd", - "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640", - "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98", - "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248", - "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e", - "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d", - "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec", - "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1", - "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e", - "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9", - "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92", - "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb", - "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094", - "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46", - "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29", - "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd", - "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705", - "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8", - "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975", - "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb", - "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e", - "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b", - "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418", - "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019", - "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1", - "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba", - "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6", - "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2", - "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3", - "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7", - "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752", - "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416", - "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f", - "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1", - "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc", - "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145", - "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee", - "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a", - "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7", - "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b", - "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653", - "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0", - "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90", - "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29", - "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6", - "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034", - "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09", - "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559", - "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639" + "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", + "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", + "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", + "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", + "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", + "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", + "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", + "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", + "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", + "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", + "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", + "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", + "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", + "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", + "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", + "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", + "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", + "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", + "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", + "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", + "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", + "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", + "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", + "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", + "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", + "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", + "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", + "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", + "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", + "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", + "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", + "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", + "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", + "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", + "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", + "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", + "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", + "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", + "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", + "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", + "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", + "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", + "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", + "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", + "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", + "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", + "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", + "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", + "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", + "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", + "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", + "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", + "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", + "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", + "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", + "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", + "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", + "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", + "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", + "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", + "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", + "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", + "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", + "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", + "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", + "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", + "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", + "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", + "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", + "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.15.0" + "markers": "python_version >= '3.6'", + "version": "==1.16.0" }, "xlsxwriter": { "hashes": [ - "sha256:2f2af944d2b4b5f21cd3ac8e01b2417ec74c60e2ca11cae90b4f32ee172c99d6", - "sha256:3f39bf581c55f3ad1438bc170d7f4c4649cee8b6b7a80d21f79508118eeea52a" + "sha256:b61c1a0c786f82644936c0936ec96ee96cd3afb9440094232f7faef9b38689f0", + "sha256:de810bf328c6a4550f4ffd6b0b34972aeb7ffcf40f3d285a0413734f9b63a929" ], "index": "pypi", - "version": "==3.0.1" + "markers": "python_version >= '3.6'", + "version": "==3.1.9" } }, "develop": { @@ -1232,6 +1268,7 @@ "sha256:75371ea153548a5ce3a1e16c5036e87d631950e27df0e0dd734050c0ae00746b" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.29.4" }, "awscli-local": { @@ -1247,6 +1284,7 @@ "sha256:92c0631ab91b4c5aa0e18a90b4d12df361723c6df1ef7e346db71f2ad0803ab3" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.28.4" }, "botocore": { @@ -1255,15 +1293,16 @@ "sha256:f9738a23b03c55c2958ebdee65273afeda80deaeefebe595887fc3251e48293a" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.31.4" }, "click": { "hashes": [ - "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd", - "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "markers": "python_version >= '3.7'", - "version": "==8.1.6" + "version": "==8.1.7" }, "colorama": { "hashes": [ @@ -1278,69 +1317,61 @@ "toml" ], "hashes": [ - "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f", - "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2", - "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a", - "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a", - "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01", - "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6", - "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7", - "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f", - "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02", - "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c", - "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063", - "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a", - "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5", - "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959", - "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97", - "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6", - "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f", - "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9", - "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5", - "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f", - "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562", - "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe", - "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9", - "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f", - "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb", - "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb", - "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1", - "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb", - "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250", - "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e", - "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511", - "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5", - "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59", - "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2", - "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d", - "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3", - "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4", - "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de", - "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9", - "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833", - "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0", - "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9", - "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d", - "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050", - "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d", - "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6", - "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353", - "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb", - "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e", - "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8", - "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495", - "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2", - "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd", - "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27", - "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1", - "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818", - "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4", - "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e", - "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850", - "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3" + "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", + "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", + "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", + "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", + "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", + "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", + "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", + "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", + "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", + "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", + "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", + "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", + "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", + "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", + "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", + "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", + "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", + "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", + "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", + "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", + "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", + "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", + "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", + "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", + "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", + "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", + "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", + "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", + "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", + "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", + "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", + "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", + "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", + "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", + "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", + "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", + "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", + "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", + "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", + "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", + "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", + "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", + "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", + "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", + "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", + "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", + "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", + "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", + "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", + "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", + "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", + "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" ], - "markers": "python_version >= '3.7'", - "version": "==7.2.7" + "markers": "python_version >= '3.8'", + "version": "==7.3.2" }, "docutils": { "hashes": [ @@ -1352,11 +1383,11 @@ }, "exceptiongroup": { "hashes": [ - "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5", - "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f" + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" ], "markers": "python_version < '3.11'", - "version": "==1.1.2" + "version": "==1.2.0" }, "factory-boy": { "hashes": [ @@ -1364,15 +1395,16 @@ "sha256:eb02a7dd1b577ef606b75a253b9818e6f9eaf996d94449c9d5ebb124f90dc795" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.2.1" }, "faker": { "hashes": [ - "sha256:4b7d5cd0c898f0b64f88fbf0a35aac66762f2273446ba4a4e459985a2e5c8f8c", - "sha256:d1eb772faf4a7c458c90b19d3626c40ae3460bd665ad7f5fb7b089e31d1a6dcf" + "sha256:562a3a09c3ed3a1a7b20e13d79f904dfdfc5e740f72813ecf95e4cf71e5a2f52", + "sha256:aeb3e26742863d1e387f9d156f1c36e14af63bf5e6f36fb39b8c27f6a903be38" ], "markers": "python_version >= '3.8'", - "version": "==19.1.0" + "version": "==20.1.0" }, "flake8": { "hashes": [ @@ -1380,6 +1412,7 @@ "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181" ], "index": "pypi", + "markers": "python_full_version >= '3.8.1'", "version": "==6.0.0" }, "flake8-docstrings": { @@ -1388,6 +1421,7 @@ "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.7.0" }, "ghp-import": { @@ -1419,6 +1453,7 @@ "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" ], "index": "pypi", + "markers": "python_full_version >= '3.8.0'", "version": "==5.12.0" }, "jinja2": { @@ -1439,9 +1474,9 @@ }, "localstack-client": { "hashes": [ - "sha256:3af9ab57d7744f64deb1912c1145b453db0233d8caaf6f71bd97380b5c4e45bb" + "sha256:8b8b2ee6013265a55d3e312a4513efccd222131bed79395545a4f643704f9213" ], - "version": "==2.2" + "version": "==2.5" }, "markdown": { "hashes": [ @@ -1449,6 +1484,7 @@ "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.3.7" }, "markupsafe": { @@ -1457,8 +1493,11 @@ "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", + "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", + "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", + "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", @@ -1466,6 +1505,7 @@ "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", + "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", @@ -1474,6 +1514,7 @@ "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", + "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", @@ -1481,9 +1522,12 @@ "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", + "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", + "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", + "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", @@ -1502,7 +1546,9 @@ "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", - "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" + "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", + "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2", + "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11" ], "markers": "python_version >= '3.7'", "version": "==2.1.3" @@ -1529,31 +1575,32 @@ "sha256:6ee46d309bda331aac915cd24aab882c179a933bd9e77b80ce7d2eaaa3f689dd" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.4.3" }, "packaging": { "hashes": [ - "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", - "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" ], "markers": "python_version >= '3.7'", - "version": "==23.1" + "version": "==23.2" }, "pluggy": { "hashes": [ - "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", - "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" + "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", + "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" ], - "markers": "python_version >= '3.7'", - "version": "==1.2.0" + "markers": "python_version >= '3.8'", + "version": "==1.3.0" }, "pyasn1": { "hashes": [ - "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57", - "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde" + "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58", + "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==0.5.0" + "version": "==0.5.1" }, "pycodestyle": { "hashes": [ @@ -1584,6 +1631,7 @@ "sha256:a97eb5ced266f45053ebb1f2c6c6d29091690503e3a5c14be7f908b37b06f2d4" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==1.11" }, "pyparsing": { @@ -1592,6 +1640,7 @@ "sha256:edb662d6fe322d6e990b1594b5feaeadf806803359e3d4d42f11e295e588f0ea" ], "index": "pypi", + "markers": "python_full_version >= '3.6.8'", "version": "==3.1.0" }, "pytest": { @@ -1600,6 +1649,7 @@ "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==7.4.0" }, "pytest-cov": { @@ -1608,6 +1658,7 @@ "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==4.1.0" }, "pytest-django": { @@ -1616,6 +1667,7 @@ "sha256:d9076f759bb7c36939dbdd5ae6633c18edfc2902d1a69fdbefd2426b970ce6c2" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==4.5.2" }, "pytest-factoryboy": { @@ -1624,6 +1676,7 @@ "sha256:7275a52299b20c0f58b63fdf7326b3fd2b7cbefbdaa90fdcfc776bbe92197484" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==2.5.1" }, "pytest-mock": { @@ -1632,6 +1685,7 @@ "sha256:9f732204aff799161cea6f818366bd254b41dbdfb6fd8fee4e04d332aba011d4" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==3.11.0" }, "python-dateutil": { @@ -1644,7 +1698,9 @@ }, "pyyaml": { "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", @@ -1652,7 +1708,10 @@ "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", @@ -1660,9 +1719,12 @@ "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", @@ -1677,7 +1739,9 @@ "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", @@ -1706,11 +1770,11 @@ }, "s3transfer": { "hashes": [ - "sha256:3c0da2d074bf35d6870ef157158641178a4204a6e689e82546083e31e0311346", - "sha256:640bb492711f4c0c0905e1f62b6aaeb771881935ad27884852411f8e9cacbca9" + "sha256:b014be3a8a2aab98cfe1abc7229cc5a9a0cf05eb9c1f2b86b230fd8df3f78084", + "sha256:cab66d3380cca3e70939ef2255d01cd8aece6a4907a9528740f668c4b0611861" ], "markers": "python_version >= '3.7'", - "version": "==0.6.1" + "version": "==0.6.2" }, "six": { "hashes": [ @@ -1737,19 +1801,19 @@ }, "typing-extensions": { "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "markers": "python_version < '3.11'", - "version": "==4.7.1" + "version": "==4.9.0" }, "urllib3": { "hashes": [ - "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f", - "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14" + "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", + "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.16" + "version": "==1.26.18" }, "watchdog": { "hashes": [ diff --git a/tdrs-backend/tdpservice/parsers/fields.py b/tdrs-backend/tdpservice/parsers/fields.py index c1b610821..acd94b14b 100644 --- a/tdrs-backend/tdpservice/parsers/fields.py +++ b/tdrs-backend/tdpservice/parsers/fields.py @@ -9,9 +9,20 @@ class Field: """Provides a mapping between a field name and its position.""" - def __init__(self, item, name, type, startIndex, endIndex, required=True, validators=[]): + def __init__( + self, + item, + name, + friendly_name, + type, + startIndex, + endIndex, + required=True, + validators=[], + ): self.item = item self.name = name + self.friendly_name = friendly_name self.type = type self.startIndex = startIndex self.endIndex = endIndex @@ -36,25 +47,34 @@ def parse_value(self, line): return None match self.type: - case 'number': + case "number": try: value = int(value) return value except ValueError: logger.error(f"Error parsing field value: {value} to integer.") return None - case 'string': + case "string": return value case _: logger.warn(f"Unknown field type: {self.type}.") return None + class TransformField(Field): """Represents a field that requires some transformation before serializing.""" - def __init__(self, transform_func, item, name, type, startIndex, endIndex, required=True, + def __init__(self, transform_func, item, name, friendly_name, type, startIndex, endIndex, required=True, validators=[], **kwargs): - super().__init__(item, name, type, startIndex, endIndex, required, validators) + super().__init__( + item=item, + name=name, + type=type, + friendly_name=friendly_name, + startIndex=startIndex, + endIndex=endIndex, + required=required, + validators=validators) self.transform_func = transform_func self.kwargs = kwargs diff --git a/tdrs-backend/tdpservice/parsers/row_schema.py b/tdrs-backend/tdpservice/parsers/row_schema.py index b7fafcdd8..97a9ccc65 100644 --- a/tdrs-backend/tdpservice/parsers/row_schema.py +++ b/tdrs-backend/tdpservice/parsers/row_schema.py @@ -151,16 +151,18 @@ def run_postparsing_validators(self, instance, generate_error): errors = [] for validator in self.postparsing_validators: - validator_is_valid, validator_error = validator(instance) + validator_is_valid, validator_error, field_names = validator(instance) is_valid = False if not validator_is_valid else is_valid if validator_error: + # get field from field name + fields = [self.get_field_by_name(name) for name in field_names] errors.append( generate_error( schema=self, error_category=ParserErrorCategoryChoices.VALUE_CONSISTENCY, error_message=validator_error, record=instance, - field=None + field=fields, ) ) diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/header.py b/tdrs-backend/tdpservice/parsers/schema_defs/header.py index deed0f416..a36d4d82f 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/header.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/header.py @@ -20,6 +20,7 @@ Field( item="2", name="title", + friendly_name="title", type="string", startIndex=0, endIndex=6, @@ -31,6 +32,7 @@ Field( item="4", name="year", + friendly_name="year", type="number", startIndex=6, endIndex=10, @@ -40,6 +42,7 @@ Field( item="5", name="quarter", + friendly_name="quarter", type="string", startIndex=10, endIndex=11, @@ -49,6 +52,7 @@ Field( item="6", name="type", + friendly_name="type", type="string", startIndex=11, endIndex=12, @@ -58,74 +62,23 @@ Field( item="1", name="state_fips", + friendly_name="state fips", type="string", startIndex=12, endIndex=14, required=True, validators=[ - validators.oneOf( - ( - "01", - "02", - "04", - "05", - "06", - "08", - "09", - "10", - "11", - "12", - "13", - "15", - "16", - "17", - "18", - "19", - "20", - "21", - "22", - "23", - "24", - "25", - "26", - "27", - "28", - "29", - "30", - "31", - "32", - "33", - "34", - "35", - "36", - "37", - "38", - "39", - "40", - "41", - "42", - "44", - "45", - "46", - "47", - "48", - "49", - "50", - "51", - "53", - "54", - "55", - "56", - "66", - "72", - "78", - ) - ) + validators.oneOf(("01", "02", "04", "05", "06", "08", "09", "10", "11", "12", "13", "15", + "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", + "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", + "40", "41", "42", "44", "45", "46", "47", "48", "49", "50", "51", "53", + "54", "55", "56", "66", "72", "78")) ], ), Field( item="3", name="tribe_code", + friendly_name="tribe code", type="string", startIndex=14, endIndex=17, @@ -135,6 +88,7 @@ Field( item="7", name="program_type", + friendly_name="program type", type="string", startIndex=17, endIndex=20, @@ -144,6 +98,7 @@ Field( item="8", name="edit", + friendly_name="edit", type="string", startIndex=20, endIndex=21, @@ -153,6 +108,7 @@ Field( item="9", name="encryption", + friendly_name="encryption", type="string", startIndex=21, endIndex=22, @@ -162,6 +118,7 @@ Field( item="10", name="update", + friendly_name="update", type="string", startIndex=22, endIndex=23, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m1.py b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m1.py index 5a3506194..ea0aaf189 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m1.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m1.py @@ -10,238 +10,525 @@ m1 = SchemaManager( schemas=[ RowSchema( - model=SSP_M1, - preparsing_validators=[ - validators.hasLength(150), - ], - postparsing_validators=[ - validators.if_then_validator( - condition_field='CASH_AMOUNT', condition_function=validators.isLargerThan(0), - result_field='NBR_MONTHS', result_function=validators.isLargerThan(0), - ), - validators.if_then_validator( - condition_field='CC_AMOUNT', condition_function=validators.isLargerThan(0), - result_field='CHILDREN_COVERED', result_function=validators.isLargerThan(0), - ), - validators.if_then_validator( - condition_field='CC_AMOUNT', condition_function=validators.isLargerThan(0), - result_field='CC_NBR_MONTHS', result_function=validators.isLargerThan(0), - ), - validators.if_then_validator( - condition_field='TRANSP_AMOUNT', condition_function=validators.isLargerThan(0), - result_field='TRANSP_NBR_MONTHS', result_function=validators.isLargerThan(0), - ), - validators.if_then_validator( - condition_field='SANC_REDUCTION_AMT', condition_function=validators.isLargerThan(0), - result_field='WORK_REQ_SANCTION', result_function=validators.oneOf((1, 2)), - ), - validators.if_then_validator( - condition_field='SANC_REDUCTION_AMT', condition_function=validators.isLargerThan(0), - result_field='SANC_TEEN_PARENT', result_function=validators.oneOf((1, 2)), - ), - validators.if_then_validator( - condition_field='SANC_REDUCTION_AMT', condition_function=validators.isLargerThan(0), - result_field='NON_COOPERATION_CSE', result_function=validators.oneOf((1, 2)), - ), - validators.if_then_validator( - condition_field='SANC_REDUCTION_AMT', condition_function=validators.isLargerThan(0), - result_field='FAILURE_TO_COMPLY', result_function=validators.oneOf((1, 2)), - ), - validators.if_then_validator( - condition_field='SANC_REDUCTION_AMT', condition_function=validators.isLargerThan(0), - result_field='OTHER_SANCTION', result_function=validators.oneOf((1, 2)), - ), - validators.if_then_validator( - condition_field='OTHER_TOTAL_REDUCTIONS', condition_function=validators.isLargerThan(0), - result_field='FAMILY_CAP', result_function=validators.oneOf((1, 2)), - ), - validators.if_then_validator( - condition_field='OTHER_TOTAL_REDUCTIONS', condition_function=validators.isLargerThan(0), - result_field='REDUCTIONS_ON_RECEIPTS', result_function=validators.oneOf((1, 2)), - ), - validators.if_then_validator( - condition_field='OTHER_TOTAL_REDUCTIONS', condition_function=validators.isLargerThan(0), - result_field='OTHER_NON_SANCTION', result_function=validators.oneOf((1, 2)), - ), - validators.sumIsLarger([ - "AMT_FOOD_STAMP_ASSISTANCE", - "AMT_SUB_CC", - "CASH_AMOUNT", - "CC_AMOUNT", - "CC_NBR_MONTHS" - ], 0) - ], - fields=[ - Field(item="0", name='RecordType', type='string', startIndex=0, endIndex=2, - required=True, validators=[]), - Field(item="3", name='RPT_MONTH_YEAR', type='number', startIndex=2, endIndex=8, - required=True, validators=[ + model=SSP_M1, + preparsing_validators=[ + validators.hasLength(150), + ], + postparsing_validators=[ + validators.if_then_validator( + condition_field='CASH_AMOUNT', + condition_function=validators.isLargerThan(0), + result_field='NBR_MONTHS', + result_function=validators.isLargerThan(0), + ), + validators.if_then_validator( + condition_field='CC_AMOUNT', + condition_function=validators.isLargerThan(0), + result_field='CHILDREN_COVERED', + result_function=validators.isLargerThan(0), + ), + validators.if_then_validator( + condition_field='CC_AMOUNT', + condition_function=validators.isLargerThan(0), + result_field='CC_NBR_MONTHS', + result_function=validators.isLargerThan(0), + ), + validators.if_then_validator( + condition_field='TRANSP_AMOUNT', + condition_function=validators.isLargerThan(0), + result_field='TRANSP_NBR_MONTHS', + result_function=validators.isLargerThan(0), + ), + validators.if_then_validator( + condition_field='SANC_REDUCTION_AMT', + condition_function=validators.isLargerThan(0), + result_field='WORK_REQ_SANCTION', + result_function=validators.oneOf((1, 2)), + ), + validators.if_then_validator( + condition_field='SANC_REDUCTION_AMT', + condition_function=validators.isLargerThan(0), + result_field='SANC_TEEN_PARENT', + result_function=validators.oneOf((1, 2)), + ), + validators.if_then_validator( + condition_field='SANC_REDUCTION_AMT', + condition_function=validators.isLargerThan(0), + result_field='NON_COOPERATION_CSE', + result_function=validators.oneOf((1, 2)), + ), + validators.if_then_validator( + condition_field='SANC_REDUCTION_AMT', + condition_function=validators.isLargerThan(0), + result_field='FAILURE_TO_COMPLY', + result_function=validators.oneOf((1, 2)), + ), + validators.if_then_validator( + condition_field='SANC_REDUCTION_AMT', + condition_function=validators.isLargerThan(0), + result_field='OTHER_SANCTION', + result_function=validators.oneOf((1, 2)), + ), + validators.if_then_validator( + condition_field='OTHER_TOTAL_REDUCTIONS', + condition_function=validators.isLargerThan(0), + result_field='FAMILY_CAP', + result_function=validators.oneOf((1, 2)), + ), + validators.if_then_validator( + condition_field='OTHER_TOTAL_REDUCTIONS', + condition_function=validators.isLargerThan(0), + result_field='REDUCTIONS_ON_RECEIPTS', + result_function=validators.oneOf((1, 2)), + ), + validators.if_then_validator( + condition_field='OTHER_TOTAL_REDUCTIONS', + condition_function=validators.isLargerThan(0), + result_field='OTHER_NON_SANCTION', + result_function=validators.oneOf((1, 2)), + ), + validators.sumIsLarger([ + "AMT_FOOD_STAMP_ASSISTANCE", + "AMT_SUB_CC", + "CASH_AMOUNT", + "CC_AMOUNT", + "CC_NBR_MONTHS"], 0) + ], + fields=[ + Field( + item="0", + name='RecordType', + friendly_name="record type", + type='string', + startIndex=0, + endIndex=2, + required=True, + validators=[] + ), + Field( + item="3", + name='RPT_MONTH_YEAR', + friendly_name="reporting month and year", + type='number', + startIndex=2, + endIndex=8, + required=True, + validators=[ validators.dateYearIsLargerThan(1998), validators.dateMonthIsValid(), - ]), - Field(item="5", name='CASE_NUMBER', type='string', startIndex=8, endIndex=19, - required=True, validators=[ - validators.isAlphaNumeric() - ]), - Field(item="2", name='COUNTY_FIPS_CODE', type='string', startIndex=19, endIndex=22, - required=True, validators=[ - validators.isNumber(), - ]), - Field(item="4", name='STRATUM', type='string', startIndex=22, endIndex=24, - required=False, validators=[ - validators.isInStringRange(0, 99), - ]), - Field(item="6", name='ZIP_CODE', type='string', startIndex=24, endIndex=29, - required=True, validators=[ - validators.isNumber(), - ]), - Field(item="7", name='DISPOSITION', type='number', startIndex=29, endIndex=30, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="8", name='NBR_FAMILY_MEMBERS', type='number', startIndex=30, endIndex=32, - required=True, validators=[ - validators.isInLimits(1, 99), - ]), - Field(item="9", name='FAMILY_TYPE', type='number', startIndex=32, endIndex=33, - required=True, validators=[ - validators.isInLimits(1, 3), - ]), - Field(item="10", name='TANF_ASST_IN_6MONTHS', type='number', startIndex=33, endIndex=34, - required=True, validators=[ - validators.isInLimits(1, 3), - ]), - Field(item="11", name='RECEIVES_SUB_HOUSING', type='number', startIndex=34, endIndex=35, - required=True, validators=[ - validators.isInLimits(1, 2), - ]), - Field(item="12", name='RECEIVES_MED_ASSISTANCE', type='number', startIndex=35, endIndex=36, - required=True, validators=[ - validators.isInLimits(1, 2), - ]), - Field(item="13", name='RECEIVES_FOOD_STAMPS', type='number', startIndex=36, endIndex=37, - required=False, validators=[ - validators.isInLimits(0, 2), - ]), - Field(item="14", name='AMT_FOOD_STAMP_ASSISTANCE', type='number', startIndex=37, endIndex=41, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="15", name='RECEIVES_SUB_CC', type='number', startIndex=41, endIndex=42, - required=False, validators=[ - validators.isInLimits(0, 2), - ]), - Field(item="16", name='AMT_SUB_CC', type='number', startIndex=42, endIndex=46, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="17", name='CHILD_SUPPORT_AMT', type='number', startIndex=46, endIndex=50, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="18", name='FAMILY_CASH_RESOURCES', type='number', startIndex=50, endIndex=54, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="19A", name='CASH_AMOUNT', type='number', startIndex=54, endIndex=58, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="19B", name='NBR_MONTHS', type='number', startIndex=58, endIndex=61, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="20A", name='CC_AMOUNT', type='number', startIndex=61, endIndex=65, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="20B", name='CHILDREN_COVERED', type='number', startIndex=65, endIndex=67, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="20C", name='CC_NBR_MONTHS', type='number', startIndex=67, endIndex=70, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="21A", name='TRANSP_AMOUNT', type='number', startIndex=70, endIndex=74, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="21B", name='TRANSP_NBR_MONTHS', type='number', startIndex=74, endIndex=77, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="22A", name='TRANSITION_SERVICES_AMOUNT', type='number', startIndex=77, endIndex=81, - required=False, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="22B", name='TRANSITION_NBR_MONTHS', type='number', startIndex=81, endIndex=84, - required=False, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="23A", name='OTHER_AMOUNT', type='number', startIndex=84, endIndex=88, - required=False, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="23B", name='OTHER_NBR_MONTHS', type='number', startIndex=88, endIndex=91, - required=False, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="24AI", name='SANC_REDUCTION_AMT', type='number', startIndex=91, endIndex=95, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="24AII", name='WORK_REQ_SANCTION', type='number', startIndex=95, endIndex=96, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="24AIII", name='FAMILY_SANC_ADULT', type='number', startIndex=96, endIndex=97, - required=False, validators=[ - validators.isInLimits(0, 9), - ]), - Field(item="24AIV", name='SANC_TEEN_PARENT', type='number', startIndex=97, endIndex=98, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="24AV", name='NON_COOPERATION_CSE', type='number', startIndex=98, endIndex=99, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="24AVI", name='FAILURE_TO_COMPLY', type='number', startIndex=99, endIndex=100, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="24AVII", name='OTHER_SANCTION', type='number', startIndex=100, endIndex=101, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="24B", name='RECOUPMENT_PRIOR_OVRPMT', type='number', startIndex=101, endIndex=105, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="24CI", name='OTHER_TOTAL_REDUCTIONS', type='number', startIndex=105, endIndex=109, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0), - ]), - Field(item="24CII", name='FAMILY_CAP', type='number', startIndex=109, endIndex=110, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="24CIII", name='REDUCTIONS_ON_RECEIPTS', type='number', startIndex=110, endIndex=111, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="24CIV", name='OTHER_NON_SANCTION', type='number', startIndex=111, endIndex=112, - required=True, validators=[ - validators.oneOf([1, 2]), - ]), - Field(item="25", name='WAIVER_EVAL_CONTROL_GRPS', type='number', startIndex=112, endIndex=113, - required=False, validators=[ - validators.isInLimits(0, 9), - ]), - Field(item="-1", name='BLANK', type='string', startIndex=113, endIndex=150, - required=False, validators=[]), - ] + ] + ), + Field( + item="5", + name='CASE_NUMBER', + friendly_name="case number", + type='string', + startIndex=8, + endIndex=19, + required=True, + validators=[validators.isAlphaNumeric()] + ), + Field( + item="2", + name='COUNTY_FIPS_CODE', + friendly_name="county fips code", + type='string', + startIndex=19, + endIndex=22, + required=True, + validators=[validators.isNumber(),] + ), + Field( + item="4", + name='STRATUM', + friendly_name="stratum", + type='string', + startIndex=22, + endIndex=24, + required=False, + validators=[validators.isInStringRange(0, 99),] + ), + Field( + item="6", + name='ZIP_CODE', + friendly_name="zip code", + type='string', + startIndex=24, + endIndex=29, + required=True, + validators=[validators.isNumber(),] + ), + Field( + item="7", + name='DISPOSITION', + friendly_name="disposition", + type='number', + startIndex=29, + endIndex=30, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="8", + name='NBR_FAMILY_MEMBERS', + friendly_name="number of family members", + type='number', + startIndex=30, + endIndex=32, + required=True, + validators=[validators.isInLimits(1, 99),] + ), + Field( + item="9", + name='FAMILY_TYPE', + friendly_name="family type", + type='number', + startIndex=32, + endIndex=33, + required=True, + validators=[validators.isInLimits(1, 3),] + ), + Field( + item="10", + name='TANF_ASST_IN_6MONTHS', + friendly_name="tanf assistance in 6 months", + type='number', + startIndex=33, + endIndex=34, + required=True, + validators=[validators.isInLimits(1, 3),] + ), + Field( + item="11", + name='RECEIVES_SUB_HOUSING', + friendly_name="receives subsidized housing", + type='number', + startIndex=34, + endIndex=35, + required=True, + validators=[validators.isInLimits(1, 2),] + ), + Field( + item="12", + name='RECEIVES_MED_ASSISTANCE', + friendly_name="receives medical assistance", + type='number', + startIndex=35, + endIndex=36, + required=True, + validators=[validators.isInLimits(1, 2),] + ), + Field( + item="13", + name='RECEIVES_FOOD_STAMPS', + friendly_name="receives food assistance", + type='number', + startIndex=36, + endIndex=37, + required=False, + validators=[validators.isInLimits(0, 2),] + ), + Field( + item="14", + name='AMT_FOOD_STAMP_ASSISTANCE', + friendly_name="amount of food stamp assistance/stamps", + type='number', + startIndex=37, + endIndex=41, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="15", + name='RECEIVES_SUB_CC', + friendly_name="receives subsidized child care", + type='number', + startIndex=41, + endIndex=42, + required=False, + validators=[validators.isInLimits(0, 2),] + ), + Field( + item="16", + name='AMT_SUB_CC', + friendly_name="amount of subsidized child care", + type='number', + startIndex=42, + endIndex=46, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="17", + name='CHILD_SUPPORT_AMT', + friendly_name="child support amount", + type='number', + startIndex=46, + endIndex=50, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="18", + name='FAMILY_CASH_RESOURCES', + friendly_name="family cash resources", + type='number', + startIndex=50, + endIndex=54, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="19A", + name='CASH_AMOUNT', + friendly_name="cash amount", + type='number', + startIndex=54, + endIndex=58, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="19B", + name='NBR_MONTHS', + friendly_name="number of months", + type='number', + startIndex=58, + endIndex=61, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="20A", + name='CC_AMOUNT', + friendly_name="child care amount", + type='number', + startIndex=61, + endIndex=65, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="20B", + name='CHILDREN_COVERED', + friendly_name="children covered", + type='number', + startIndex=65, + endIndex=67, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="20C", + name='CC_NBR_MONTHS', + friendly_name="child care - number of months", + type='number', + startIndex=67, + endIndex=70, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="21A", + name='TRANSP_AMOUNT', + friendly_name="transportation amount", + type='number', + startIndex=70, + endIndex=74, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="21B", + name='TRANSP_NBR_MONTHS', + friendly_name="transportation - number of months", + type='number', + startIndex=74, + endIndex=77, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="22A", + name='TRANSITION_SERVICES_AMOUNT', + friendly_name="transition services amount", + type='number', + startIndex=77, + endIndex=81, + required=False, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="22B", + name='TRANSITION_NBR_MONTHS', + friendly_name="transition services - number of months", + type='number', + startIndex=81, + endIndex=84, + required=False, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="23A", + name='OTHER_AMOUNT', + friendly_name="other amount", + type='number', + startIndex=84, + endIndex=88, + required=False, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="23B", + name='OTHER_NBR_MONTHS', + friendly_name="other - number of months", + type='number', + startIndex=88, + endIndex=91, + required=False, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="24AI", + name='SANC_REDUCTION_AMT', + friendly_name="sanction reduction amount", + type='number', + startIndex=91, + endIndex=95, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="24AII", + name='WORK_REQ_SANCTION', + friendly_name="work requirements sanction", + type='number', + startIndex=95, + endIndex=96, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="24AIII", + name='FAMILY_SANC_ADULT', + friendly_name="family sanction for adult", + type='number', + startIndex=96, + endIndex=97, + required=False, + validators=[validators.isInLimits(0, 9),] + ), + Field( + item="24AIV", + name='SANC_TEEN_PARENT', + friendly_name="sanction for teen parent", + type='number', + startIndex=97, + endIndex=98, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="24AV", + name='NON_COOPERATION_CSE', + friendly_name="non-cooperation with child support", + type='number', + startIndex=98, + endIndex=99, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="24AVI", + name='FAILURE_TO_COMPLY', + friendly_name="failure to comply", + type='number', + startIndex=99, + endIndex=100, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="24AVII", + name='OTHER_SANCTION', + friendly_name="other sanction", + type='number', + startIndex=100, + endIndex=101, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="24B", + name='RECOUPMENT_PRIOR_OVRPMT', + friendly_name="recoupment prior overpayment", + type='number', + startIndex=101, + endIndex=105, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="24CI", + name='OTHER_TOTAL_REDUCTIONS', + friendly_name="other total reductions", + type='number', + startIndex=105, + endIndex=109, + required=True, + validators=[validators.isLargerThanOrEqualTo(0),] + ), + Field( + item="24CII", + name='FAMILY_CAP', + friendly_name="family cap", + type='number', + startIndex=109, + endIndex=110, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="24CIII", + name='REDUCTIONS_ON_RECEIPTS', + friendly_name="reductions on receipts", + type='number', + startIndex=110, + endIndex=111, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="24CIV", + name='OTHER_NON_SANCTION', + friendly_name="other non-sanction", + type='number', + startIndex=111, + endIndex=112, + required=True, + validators=[validators.oneOf([1, 2]),] + ), + Field( + item="25", + name='WAIVER_EVAL_CONTROL_GRPS', + friendly_name="waiver evaluation experimental and control groups", + type='number', + startIndex=112, + endIndex=113, + required=False, + validators=[validators.isInLimits(0, 9),] + ), + Field( + item="-1", + name='BLANK', + friendly_name="blank", + type='string', + startIndex=113, + endIndex=150, + required=False, + validators=[] + ), + ] ) ] ) diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m2.py b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m2.py index 7636e45a5..4dd0a00ec 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m2.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m2.py @@ -12,357 +12,793 @@ m2 = SchemaManager( schemas=[ RowSchema( - model=SSP_M2, - preparsing_validators=[ - validators.hasLength(150), - ], - postparsing_validators=[ - validators.validate__FAM_AFF__SSN(), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(1), - result_field='SSN', result_function=validators.validateSSN(), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='RACE_HISPANIC', result_function=validators.isInLimits(1, 2), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='RACE_AMER_INDIAN', result_function=validators.isInLimits(1, 2), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='RACE_ASIAN', result_function=validators.isInLimits(1, 2), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='RACE_BLACK', result_function=validators.isInLimits(1, 2), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='RACE_HAWAIIAN', result_function=validators.isInLimits(1, 2), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='RACE_WHITE', result_function=validators.isInLimits(1, 2), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='MARITAL_STATUS', result_function=validators.isInLimits(1, 5), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 2), - result_field='PARENT_MINOR_CHILD', result_function=validators.isInLimits(1, 3), - ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='EDUCATION_LEVEL', result_function=validators.or_validators( + model=SSP_M2, + preparsing_validators=[ + validators.hasLength(150), + ], + postparsing_validators=[ + validators.validate__FAM_AFF__SSN(), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(1), + result_field='SSN', + result_function=validators.validateSSN(), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='RACE_HISPANIC', + result_function=validators.isInLimits(1, 2), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='RACE_AMER_INDIAN', + result_function=validators.isInLimits(1, 2), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='RACE_ASIAN', + result_function=validators.isInLimits(1, 2), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='RACE_BLACK', + result_function=validators.isInLimits(1, 2), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='RACE_HAWAIIAN', + result_function=validators.isInLimits(1, 2), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='RACE_WHITE', + result_function=validators.isInLimits(1, 2), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='MARITAL_STATUS', + result_function=validators.isInLimits(1, 5), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 2), + result_field='PARENT_MINOR_CHILD', + result_function=validators.isInLimits(1, 3), + ), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='EDUCATION_LEVEL', + result_function=validators.or_validators( validators.isInStringRange(1, 16), validators.isInStringRange(98, 99) ), ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(1), - result_field='CITIZENSHIP_STATUS', result_function=validators.oneOf((1, 2)), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(1), + result_field='CITIZENSHIP_STATUS', + result_function=validators.oneOf((1, 2)), ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='COOPERATION_CHILD_SUPPORT', result_function=validators.oneOf((1, 2, 9)), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='COOPERATION_CHILD_SUPPORT', + result_function=validators.oneOf((1, 2, 9)), ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.isInLimits(1, 3), - result_field='EMPLOYMENT_STATUS', result_function=validators.isInLimits(1, 3), + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.isInLimits(1, 3), + result_field='EMPLOYMENT_STATUS', + result_function=validators.isInLimits(1, 3), ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='WORK_ELIGIBLE_INDICATOR', result_function=validators.or_validators( + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='WORK_ELIGIBLE_INDICATOR', + result_function=validators.or_validators( validators.isInLimits(1, 9), validators.oneOf((11, 12)) ), ), - validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='WORK_PART_STATUS', result_function=validators.oneOf([ - 1, 2, 5, 7, 9, - 15, 16, 17, 18, 99 - ]), - ), - validators.if_then_validator( - condition_field='WORK_ELIGIBLE_INDICATOR', condition_function=validators.isInLimits(1, 5), - result_field='WORK_PART_STATUS', result_function=validators.notMatches(99), - ), - ], - fields=[ - Field(item="0", name='RecordType', type='string', startIndex=0, endIndex=2, - required=True, validators=[]), - Field(item="3", name='RPT_MONTH_YEAR', type='number', startIndex=2, endIndex=8, - required=True, validators=[ + validators.if_then_validator( + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='WORK_PART_STATUS', + result_function=validators.oneOf([1, 2, 5, 7, 9, 15, 16, 17, 18, 99]), + ), + validators.if_then_validator( + condition_field='WORK_ELIGIBLE_INDICATOR', + condition_function=validators.isInLimits(1, 5), + result_field='WORK_PART_STATUS', + result_function=validators.notMatches(99), + ), + ], + fields=[ + Field( + item="0", + name='RecordType', + friendly_name="record type", + type='string', + startIndex=0, + endIndex=2, + required=True, + validators=[] + ), + Field( + item="3", + name='RPT_MONTH_YEAR', + friendly_name="reporting month and year", + type='number', + startIndex=2, + endIndex=8, + required=True, + validators=[ validators.dateYearIsLargerThan(1998), validators.dateMonthIsValid(), - ]), - Field(item="5", name='CASE_NUMBER', type='string', startIndex=8, endIndex=19, - required=True, validators=[ - validators.isAlphaNumeric() - ]), - Field(item="26", name='FAMILY_AFFILIATION', type='number', startIndex=19, endIndex=20, - required=True, validators=[ - validators.oneOf([1, 2, 3, 5]) - ]), - Field(item="27", name='NONCUSTODIAL_PARENT', type='number', startIndex=20, endIndex=21, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="28", name='DATE_OF_BIRTH', type='number', startIndex=21, endIndex=29, - required=True, validators=[ - validators.isLargerThan(0) - ]), - TransformField(transform_func=ssp_ssn_decryption_func, item="29", name='SSN', type='string', - startIndex=29, endIndex=38, required=True, validators=[validators.validateSSN()], - is_encrypted=False), - Field(item="30A", name='RACE_HISPANIC', type='number', startIndex=38, endIndex=39, required=False, + ] + ), + Field( + item="5", + name='CASE_NUMBER', + friendly_name="case number", + type='string', + startIndex=8, + endIndex=19, + required=True, + validators=[validators.isAlphaNumeric()] + ), + Field( + item="26", + name='FAMILY_AFFILIATION', + friendly_name="family affiliation", + type='number', + startIndex=19, + endIndex=20, + required=True, + validators=[validators.oneOf([1, 2, 3, 5])] + ), + Field( + item="27", + name='NONCUSTODIAL_PARENT', + friendly_name="noncustodial parent", + type='number', + startIndex=20, + endIndex=21, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="28", + name='DATE_OF_BIRTH', + friendly_name="date of birth", + type='number', + startIndex=21, + endIndex=29, + required=True, + validators=[validators.isLargerThan(0)] + ), + TransformField( + transform_func=ssp_ssn_decryption_func, + item="29", + name='SSN', + friendly_name="social security number", + type='string', + startIndex=29, + endIndex=38, + required=True, + validators=[validators.validateSSN()], + is_encrypted=False + ), + Field( + item="30A", + name='RACE_HISPANIC', + type='number', + friendly_name="race hispanic", + startIndex=38, + endIndex=39, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="30B", + name='RACE_AMER_INDIAN', + friendly_name="race american-indian", + type='number', + startIndex=39, + endIndex=40, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="30C", + name='RACE_ASIAN', + friendly_name="race asian", + type='number', + startIndex=40, + endIndex=41, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="30D", + name='RACE_BLACK', + friendly_name="race black", + type='number', + startIndex=41, + endIndex=42, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="30E", + name='RACE_HAWAIIAN', + friendly_name="race hawaiian", + type='number', + startIndex=42, + endIndex=43, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="30F", + name='RACE_WHITE', + friendly_name="race white", + type='number', + startIndex=43, + endIndex=44, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="31", + name='GENDER', + friendly_name="gender", + type='number', + startIndex=44, + endIndex=45, + required=True, + validators=[validators.isLargerThanOrEqualTo(0)] + ), + Field( + item="32A", + name='FED_OASDI_PROGRAM', + friendly_name="federal old-age survivors and disability insurance program", + type='number', + startIndex=45, + endIndex=46, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="32B", + name='FED_DISABILITY_STATUS', + friendly_name="federal disability status", + type='number', + startIndex=46, + endIndex=47, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="32C", + name='DISABLED_TITLE_XIVAPDT', + friendly_name="received aid under Title XIV-APDT", + type='number', + startIndex=47, + endIndex=48, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="32D", + name='AID_AGED_BLIND', + friendly_name="receives from aid to the aged, blind, and disabled program", + type='number', + startIndex=48, + endIndex=49, + required=False, + validators=[validators.isLargerThanOrEqualTo(0)] + ), + Field( + item="32E", + name='RECEIVE_SSI', + friendly_name="receives SSI", + type='number', + startIndex=49, + endIndex=50, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="33", + name='MARITAL_STATUS', + friendly_name="marital status", + type='number', + startIndex=50, + endIndex=51, + required=False, + validators=[validators.isInLimits(0, 5)] + ), + Field( + item="34", + name='RELATIONSHIP_HOH', + friendly_name="relationship to head of household", + type='string', + startIndex=51, + endIndex=53, + required=True, + validators=[validators.isInStringRange(1, 10)] + ), + Field( + item="35", + name='PARENT_MINOR_CHILD', + friendly_name="parent of minor child", + type='number', + startIndex=53, + endIndex=54, + required=False, + validators=[validators.isInLimits(0, 3)] + ), + Field( + item="36", + name='NEEDS_PREGNANT_WOMAN', + friendly_name="needs of pregnant woman", + type='number', + startIndex=54, + endIndex=55, + required=False, + validators=[validators.isInLimits(0, 9)] + ), + Field( + item="37", + name='EDUCATION_LEVEL', + friendly_name="education level", + type='number', + startIndex=55, + endIndex=57, + required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="30B", name='RACE_AMER_INDIAN', type='number', startIndex=39, endIndex=40, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="30C", name='RACE_ASIAN', type='number', startIndex=40, endIndex=41, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="30D", name='RACE_BLACK', type='number', startIndex=41, endIndex=42, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="30E", name='RACE_HAWAIIAN', type='number', startIndex=42, endIndex=43, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="30F", name='RACE_WHITE', type='number', startIndex=43, endIndex=44, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="31", name='GENDER', type='number', startIndex=44, endIndex=45, - required=True, validators=[ - validators.isLargerThanOrEqualTo(0) - ]), - Field(item="32A", name='FED_OASDI_PROGRAM', type='number', startIndex=45, endIndex=46, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="32B", name='FED_DISABILITY_STATUS', type='number', startIndex=46, endIndex=47, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="32C", name='DISABLED_TITLE_XIVAPDT', type='number', startIndex=47, endIndex=48, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="32D", name='AID_AGED_BLIND', type='number', startIndex=48, endIndex=49, - required=False, validators=[ - validators.isLargerThanOrEqualTo(0) - ]), - Field(item="32E", name='RECEIVE_SSI', type='number', startIndex=49, endIndex=50, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="33", name='MARITAL_STATUS', type='number', startIndex=50, endIndex=51, - required=False, validators=[ - validators.isInLimits(0, 5) - ]), - Field(item="34", name='RELATIONSHIP_HOH', type='string', startIndex=51, endIndex=53, - required=True, validators=[ - validators.isInStringRange(1, 10) - ]), - Field(item="35", name='PARENT_MINOR_CHILD', type='number', startIndex=53, endIndex=54, - required=False, validators=[ - validators.isInLimits(0, 3) - ]), - Field(item="36", name='NEEDS_PREGNANT_WOMAN', type='number', startIndex=54, endIndex=55, - required=False, validators=[ - validators.isInLimits(0, 9) - ]), - Field(item="37", name='EDUCATION_LEVEL', type='number', startIndex=55, endIndex=57, - required=False, validators=[ validators.or_validators( validators.isInLimits(0, 16), validators.isInLimits(98, 99) ) - ]), - Field(item="38", name='CITIZENSHIP_STATUS', type='number', startIndex=57, endIndex=58, - required=False, validators=[ - validators.oneOf([0, 1, 2, 3, 9]) - ]), - Field(item="39", name='COOPERATION_CHILD_SUPPORT', type='number', startIndex=58, endIndex=59, - required=False, validators=[ - validators.oneOf([0, 1, 2, 9]) - ]), - Field(item="40", name='EMPLOYMENT_STATUS', type='number', startIndex=59, endIndex=60, - required=False, validators=[ - validators.isInLimits(0, 3) - ]), - Field(item="41", name='WORK_ELIGIBLE_INDICATOR', type='number', startIndex=60, endIndex=62, - required=True, validators=[ + ] + ), + Field( + item="38", + name='CITIZENSHIP_STATUS', + friendly_name="citizenship status", + type='number', + startIndex=57, + endIndex=58, + required=False, + validators=[validators.oneOf([0, 1, 2, 3, 9])] + ), + Field( + item="39", + name='COOPERATION_CHILD_SUPPORT', + friendly_name="cooperation with child support", + type='number', + startIndex=58, + endIndex=59, + required=False, + validators=[validators.oneOf([0, 1, 2, 9])] + ), + Field( + item="40", + name='EMPLOYMENT_STATUS', + friendly_name="employment status", + type='number', + startIndex=59, + endIndex=60, + required=False, + validators=[validators.isInLimits(0, 3)] + ), + Field( + item="41", + name='WORK_ELIGIBLE_INDICATOR', + friendly_name="work eligible indicator", + type='number', + startIndex=60, + endIndex=62, + required=True, + validators=[ validators.or_validators( validators.isInLimits(1, 4), validators.isInLimits(6, 9), validators.isInLimits(11, 12) ) - ]), - Field(item="42", name='WORK_PART_STATUS', type='number', startIndex=62, endIndex=64, - required=False, validators=[ - validators.oneOf([1, 2, 5, 7, 9, 15, 16, 17, 18, 19, 99]) - ]), - Field(item="43", name='UNSUB_EMPLOYMENT', type='number', startIndex=64, endIndex=66, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="44", name='SUB_PRIVATE_EMPLOYMENT', type='number', startIndex=66, endIndex=68, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="45", name='SUB_PUBLIC_EMPLOYMENT', type='number', startIndex=68, endIndex=70, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="46A", name='WORK_EXPERIENCE_HOP', type='number', startIndex=70, endIndex=72, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="46B", name='WORK_EXPERIENCE_EA', type='number', startIndex=72, endIndex=74, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="46C", name='WORK_EXPERIENCE_HOL', type='number', startIndex=74, endIndex=76, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="47", name='OJT', type='number', startIndex=76, endIndex=78, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="48A", name='JOB_SEARCH_HOP', type='number', startIndex=78, endIndex=80, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="48B", name='JOB_SEARCH_EA', type='number', startIndex=80, endIndex=82, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="48C", name='JOB_SEARCH_HOL', type='number', startIndex=82, endIndex=84, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="49A", name='COMM_SERVICES_HOP', type='number', startIndex=84, endIndex=86, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="49B", name='COMM_SERVICES_EA', type='number', startIndex=86, endIndex=88, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="49C", name='COMM_SERVICES_HOL', type='number', startIndex=88, endIndex=90, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="50A", name='VOCATIONAL_ED_TRAINING_HOP', type='number', startIndex=90, endIndex=92, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="50B", name='VOCATIONAL_ED_TRAINING_EA', type='number', startIndex=92, endIndex=94, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="50C", name='VOCATIONAL_ED_TRAINING_HOL', type='number', startIndex=94, endIndex=96, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="51A", name='JOB_SKILLS_TRAINING_HOP', type='number', startIndex=96, endIndex=98, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="51B", name='JOB_SKILLS_TRAINING_EA', type='number', startIndex=98, endIndex=100, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="51C", name='JOB_SKILLS_TRAINING_HOL', type='number', startIndex=100, endIndex=102, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="52A", name='ED_NO_HIGH_SCHOOL_DIPL_HOP', type='number', startIndex=102, endIndex=104, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="52B", name='ED_NO_HIGH_SCHOOL_DIPL_EA', type='number', startIndex=104, endIndex=106, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="52C", name='ED_NO_HIGH_SCHOOL_DIPL_HOL', type='number', startIndex=106, endIndex=108, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="53A", name='SCHOOL_ATTENDENCE_HOP', type='number', startIndex=108, endIndex=110, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="53B", name='SCHOOL_ATTENDENCE_EA', type='number', startIndex=110, endIndex=112, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="53C", name='SCHOOL_ATTENDENCE_HOL', type='number', startIndex=112, endIndex=114, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="54A", name='PROVIDE_CC_HOP', type='number', startIndex=114, endIndex=116, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="54B", name='PROVIDE_CC_EA', type='number', startIndex=116, endIndex=118, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="54C", name='PROVIDE_CC_HOL', type='number', startIndex=118, endIndex=120, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="55", name='OTHER_WORK_ACTIVITIES', type='number', startIndex=120, endIndex=122, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="56", name='DEEMED_HOURS_FOR_OVERALL', type='number', startIndex=122, endIndex=124, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="57", name='DEEMED_HOURS_FOR_TWO_PARENT', type='number', startIndex=124, endIndex=126, - required=False, validators=[ - validators.isInLimits(0, 99) - ]), - Field(item="58", name='EARNED_INCOME', type='number', startIndex=126, endIndex=130, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]), - Field(item="59A", name='UNEARNED_INCOME_TAX_CREDIT', type='number', startIndex=130, endIndex=134, - required=False, validators=[ - validators.isInLimits(0, 9999) - ]), - Field(item="59B", name='UNEARNED_SOCIAL_SECURITY', type='number', startIndex=134, endIndex=138, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]), - Field(item="59C", name='UNEARNED_SSI', type='number', startIndex=138, endIndex=142, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]), - Field(item="59D", name='UNEARNED_WORKERS_COMP', type='number', startIndex=142, endIndex=146, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]), - Field(item="59E", name='OTHER_UNEARNED_INCOME', type='number', startIndex=146, endIndex=150, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]), - ], + ] + ), + Field( + item="42", + name='WORK_PART_STATUS', + friendly_name="work participation status", + type='number', + startIndex=62, + endIndex=64, + required=False, + validators=[validators.oneOf([1, 2, 5, 7, 9, 15, 16, 17, 18, 19, 99])] + ), + Field( + item="43", + name='UNSUB_EMPLOYMENT', + friendly_name="unsubsidized employment", + type='number', + startIndex=64, + endIndex=66, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="44", + name='SUB_PRIVATE_EMPLOYMENT', + friendly_name="subsidized private employment", + type='number', + startIndex=66, + endIndex=68, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="45", + name='SUB_PUBLIC_EMPLOYMENT', + friendly_name="subsidized public employment", + type='number', + startIndex=68, + endIndex=70, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="46A", + name='WORK_EXPERIENCE_HOP', + friendly_name="work experience - hours of participation", + type='number', + startIndex=70, + endIndex=72, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="46B", + name='WORK_EXPERIENCE_EA', + friendly_name="work experience - excused absence", + type='number', + startIndex=72, + endIndex=74, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="46C", + name='WORK_EXPERIENCE_HOL', + friendly_name="work experience hours - holiday", + type='number', + startIndex=74, + endIndex=76, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="47", + name='OJT', + friendly_name="OJT", + type='number', + startIndex=76, + endIndex=78, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="48A", + name='JOB_SEARCH_HOP', + friendly_name="job search - hours of participation", + type='number', + startIndex=78, + endIndex=80, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="48B", + name='JOB_SEARCH_EA', + friendly_name="job search - excused absence", + type='number', + startIndex=80, + endIndex=82, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="48C", + name='JOB_SEARCH_HOL', + friendly_name="job search - holiday", + type='number', + startIndex=82, + endIndex=84, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="49A", + name='COMM_SERVICES_HOP', + friendly_name="community services - hours of participation", + type='number', + startIndex=84, + endIndex=86, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="49B", + name='COMM_SERVICES_EA', + friendly_name="community services - excused absence", + type='number', + startIndex=86, + endIndex=88, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="49C", + name='COMM_SERVICES_HOL', + friendly_name="community services - holiday", + type='number', + startIndex=88, + endIndex=90, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="50A", + name='VOCATIONAL_ED_TRAINING_HOP', + friendly_name="vocational education training - hours of participation", + type='number', + startIndex=90, + endIndex=92, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="50B", + name='VOCATIONAL_ED_TRAINING_EA', + friendly_name="vocational education training - excused absence", + type='number', + startIndex=92, + endIndex=94, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="50C", + name='VOCATIONAL_ED_TRAINING_HOL', + friendly_name="vocational education training - holiday", + type='number', + startIndex=94, + endIndex=96, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="51A", + name='JOB_SKILLS_TRAINING_HOP', + friendly_name="job skills training - hours of participation", + type='number', + startIndex=96, + endIndex=98, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="51B", + name='JOB_SKILLS_TRAINING_EA', + friendly_name="job skills training - excused absence", + type='number', + startIndex=98, + endIndex=100, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="51C", + name='JOB_SKILLS_TRAINING_HOL', + friendly_name="job skills training - holiday", + type='number', + startIndex=100, + endIndex=102, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="52A", + name='ED_NO_HIGH_SCHOOL_DIPL_HOP', + friendly_name="education no high school diploma - hours of participation", + type='number', + startIndex=102, + endIndex=104, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="52B", + name='ED_NO_HIGH_SCHOOL_DIPL_EA', + friendly_name="education no high school diploma - excused absence", + type='number', + startIndex=104, + endIndex=106, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="52C", + name='ED_NO_HIGH_SCHOOL_DIPL_HOL', + friendly_name="education no high school diploma - holiday", + type='number', + startIndex=106, + endIndex=108, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="53A", + name='SCHOOL_ATTENDENCE_HOP', + friendly_name="school attendance - hours of participation", + type='number', + startIndex=108, + endIndex=110, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="53B", + name='SCHOOL_ATTENDENCE_EA', + friendly_name="school attendance - excused absence", + type='number', + startIndex=110, + endIndex=112, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="53C", + name='SCHOOL_ATTENDENCE_HOL', + friendly_name="school attendance - holiday", + type='number', + startIndex=112, + endIndex=114, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="54A", + name='PROVIDE_CC_HOP', + friendly_name="provide child care - hours of participation", + type='number', + startIndex=114, + endIndex=116, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="54B", + name='PROVIDE_CC_EA', + friendly_name="provide child care - excused absence", + type='number', + startIndex=116, + endIndex=118, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="54C", + name='PROVIDE_CC_HOL', + friendly_name="provide child care - holiday", + type='number', + startIndex=118, + endIndex=120, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="55", + name='OTHER_WORK_ACTIVITIES', + friendly_name="other work activities", + type='number', + startIndex=120, + endIndex=122, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="56", + name='DEEMED_HOURS_FOR_OVERALL', + friendly_name="deemed hours for overall", + type='number', + startIndex=122, + endIndex=124, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="57", + name='DEEMED_HOURS_FOR_TWO_PARENT', + friendly_name="deemed hours for two parents", + type='number', + startIndex=124, + endIndex=126, + required=False, + validators=[validators.isInLimits(0, 99)] + ), + Field( + item="58", + name='EARNED_INCOME', + friendly_name="earned income", + type='number', + startIndex=126, + endIndex=130, + required=True, + validators=[validators.isInLimits(0, 9999)] + ), + Field( + item="59A", + name='UNEARNED_INCOME_TAX_CREDIT', + friendly_name="unearned income tax credit", + type='number', + startIndex=130, + endIndex=134, + required=False, + validators=[validators.isInLimits(0, 9999)] + ), + Field( + item="59B", + name='UNEARNED_SOCIAL_SECURITY', + friendly_name="unearned social security", + type='number', + startIndex=134, + endIndex=138, + required=True, + validators=[validators.isInLimits(0, 9999)] + ), + Field( + item="59C", + name='UNEARNED_SSI', + friendly_name="unearned SSI benefit", + type='number', + startIndex=138, + endIndex=142, + required=True, + validators=[validators.isInLimits(0, 9999)] + ), + Field( + item="59D", + name='UNEARNED_WORKERS_COMP', + friendly_name="unearned workers compensation", + type='number', + startIndex=142, + endIndex=146, + required=True, + validators=[validators.isInLimits(0, 9999)] + ), + Field( + item="59E", + name='OTHER_UNEARNED_INCOME', + friendly_name="other unearned income", + type='number', + startIndex=146, + endIndex=150, + required=True, + validators=[validators.isInLimits(0, 9999)] + ), + ], ) ] ) diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m3.py b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m3.py index 8ac92f061..fb05903f6 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m3.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m3.py @@ -15,142 +15,302 @@ ], postparsing_validators=[ validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(1), - result_field='SSN', result_function=validators.validateSSN(), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(1), + result_field='SSN', + result_function=validators.validateSSN(), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_HISPANIC', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_HISPANIC', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_AMER_INDIAN', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_AMER_INDIAN', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_ASIAN', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_ASIAN', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_BLACK', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_BLACK', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_HAWAIIAN', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_HAWAIIAN', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_WHITE', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_WHITE', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RELATIONSHIP_HOH', result_function=validators.isInLimits(4, 9), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RELATIONSHIP_HOH', + result_function=validators.isInLimits(4, 9), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='PARENT_MINOR_CHILD', result_function=validators.oneOf((1, 2, 3)), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='PARENT_MINOR_CHILD', + result_function=validators.oneOf((1, 2, 3)), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(1), - result_field='EDUCATION_LEVEL', result_function=validators.notMatches(99), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(1), + result_field='EDUCATION_LEVEL', + result_function=validators.notMatches(99), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(1), - result_field='CITIZENSHIP_STATUS', result_function=validators.oneOf((1, 2)), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(1), + result_field='CITIZENSHIP_STATUS', + result_function=validators.oneOf((1, 2)), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(2), - result_field='CITIZENSHIP_STATUS', result_function=validators.oneOf((1, 2, 3, 9)), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(2), + result_field='CITIZENSHIP_STATUS', + result_function=validators.oneOf((1, 2, 3, 9)), ), ], fields=[ - Field(item="0", name='RecordType', type='string', startIndex=0, endIndex=2, - required=True, validators=[]), - Field(item="3", name='RPT_MONTH_YEAR', type='number', startIndex=2, endIndex=8, - required=True, validators=[ - validators.dateYearIsLargerThan(1998), - validators.dateMonthIsValid(), - ]), - Field(item="5", name='CASE_NUMBER', type='string', startIndex=8, endIndex=19, - required=True, validators=[ - validators.isAlphaNumeric() - ]), - Field(item="60", name='FAMILY_AFFILIATION', type='number', startIndex=19, endIndex=20, - required=True, validators=[ - validators.oneOf([1, 2, 4]) - ]), - Field(item="61", name='DATE_OF_BIRTH', type='string', startIndex=20, endIndex=28, - required=True, validators=[ - validators.dateYearIsLargerThan(1998), - validators.dateMonthIsValid(), - ]), - TransformField(transform_func=ssp_ssn_decryption_func, item="62", name='SSN', type='string', startIndex=28, - endIndex=37, required=True, is_encrypted=False, validators=[ - validators.validateSSN() - ]), - Field(item="63A", name='RACE_HISPANIC', type='number', startIndex=37, endIndex=38, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63B", name='RACE_AMER_INDIAN', type='number', startIndex=38, endIndex=39, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63C", name='RACE_ASIAN', type='number', startIndex=39, endIndex=40, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63D", name='RACE_BLACK', type='number', startIndex=40, endIndex=41, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63E", name='RACE_HAWAIIAN', type='number', startIndex=41, endIndex=42, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63F", name='RACE_WHITE', type='number', startIndex=42, endIndex=43, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="64", name='GENDER', type='number', startIndex=43, endIndex=44, - required=True, validators=[ - validators.isInLimits(0, 9) - ]), - Field(item="65A", name='RECEIVE_NONSSI_BENEFITS', type='number', startIndex=44, endIndex=45, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="65B", name='RECEIVE_SSI', type='number', startIndex=45, endIndex=46, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="66", name='RELATIONSHIP_HOH', type='number', startIndex=46, endIndex=48, - required=False, validators=[ - validators.isInStringRange(0, 10) - ]), - Field(item="67", name='PARENT_MINOR_CHILD', type='number', startIndex=48, endIndex=49, - required=False, validators=[ - validators.oneOf([0, 2, 3]) - ]), - Field(item="68", name='EDUCATION_LEVEL', type='number', startIndex=49, endIndex=51, - required=True, validators=[ - validators.or_validators( - validators.isInStringRange(0, 16), - validators.isInStringRange(98, 99) - ) - ]), - Field(item="69", name='CITIZENSHIP_STATUS', type='number', startIndex=51, endIndex=52, - required=False, validators=[ - validators.oneOf([0, 1, 2, 3, 9]) - ]), - Field(item="70A", name='UNEARNED_SSI', type='number', startIndex=52, endIndex=56, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]), - Field(item="70B", name='OTHER_UNEARNED_INCOME', type='number', startIndex=56, endIndex=60, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]) + Field( + item="0", + name='RecordType', + friendly_name="record type", + type='string', + startIndex=0, + endIndex=2, + required=True, + validators=[] + ), + Field( + item="3", + name='RPT_MONTH_YEAR', + friendly_name="reporting month and year", + type='number', + startIndex=2, + endIndex=8, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.dateMonthIsValid(), + ] + ), + Field( + item="5", + name='CASE_NUMBER', + friendly_name="case number", + type='string', + startIndex=8, + endIndex=19, + required=True, + validators=[validators.isAlphaNumeric()] + ), + Field( + item="60", + name='FAMILY_AFFILIATION', + friendly_name="family affiliation", + type='number', + startIndex=19, + endIndex=20, + required=True, + validators=[validators.oneOf([1, 2, 4])] + ), + Field( + item="61", + name='DATE_OF_BIRTH', + friendly_name="date of birth", + type='string', + startIndex=20, + endIndex=28, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.dateMonthIsValid(), + ] + ), + TransformField( + transform_func=ssp_ssn_decryption_func, + item="62", + name='SSN', + friendly_name="social security number", + type='string', + startIndex=28, + endIndex=37, + required=True, + is_encrypted=False, + validators=[validators.validateSSN()] + ), + Field( + item="63A", + name='RACE_HISPANIC', + friendly_name="race hispanic", + type='number', + startIndex=37, + endIndex=38, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63B", + name='RACE_AMER_INDIAN', + friendly_name="race american-indian", + type='number', + startIndex=38, + endIndex=39, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63C", + name='RACE_ASIAN', + friendly_name="race asian", + type='number', + startIndex=39, + endIndex=40, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63D", + name='RACE_BLACK', + friendly_name="race black", + type='number', + startIndex=40, + endIndex=41, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63E", + name='RACE_HAWAIIAN', + friendly_name="race hawaiian", + type='number', + startIndex=41, + endIndex=42, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63F", + name='RACE_WHITE', + friendly_name="race white", + type='number', + startIndex=42, + endIndex=43, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="64", + name='GENDER', + friendly_name="gender", + type='number', + startIndex=43, + endIndex=44, + required=True, + validators=[validators.isInLimits(0, 9)] + ), + Field( + item="65A", + name='RECEIVE_NONSSI_BENEFITS', + friendly_name="receive non-SSI benefits", + type='number', + startIndex=44, + endIndex=45, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="65B", + name='RECEIVE_SSI', + friendly_name="receives SSI", + type='number', + startIndex=45, + endIndex=46, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="66", + name='RELATIONSHIP_HOH', + friendly_name="relationship to head of household", + type='number', + startIndex=46, + endIndex=48, + required=False, + validators=[validators.isInStringRange(0, 10)] + ), + Field( + item="67", + name='PARENT_MINOR_CHILD', + friendly_name="parent of minor child", + type='number', + startIndex=48, + endIndex=49, + required=False, + validators=[validators.oneOf([0, 2, 3])] + ), + Field( + item="68", + name='EDUCATION_LEVEL', + friendly_name="education level", + type='number', + startIndex=49, + endIndex=51, + required=True, + validators=[ + validators.or_validators( + validators.isInStringRange(0, 16), + validators.isInStringRange(98, 99) + ) + ] + ), + Field( + item="69", + name='CITIZENSHIP_STATUS', + friendly_name="citizenship status", + type='number', + startIndex=51, + endIndex=52, + required=False, + validators=[validators.oneOf([0, 1, 2, 3, 9])] + ), + Field( + item="70A", + name='UNEARNED_SSI', + friendly_name="unearned SSI benefit", + type='number', + startIndex=52, + endIndex=56, + required=True, + validators=[validators.isInLimits(0, 9999)] + ), + Field( + item="70B", + name='OTHER_UNEARNED_INCOME', + friendly_name="other unearned income", + type='number', + startIndex=56, + endIndex=60, + required=True, + validators=[validators.isInLimits(0, 9999)] + ) ] ) @@ -162,142 +322,302 @@ ], postparsing_validators=[ validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(1), - result_field='SSN', result_function=validators.validateSSN(), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(1), + result_field='SSN', + result_function=validators.validateSSN(), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_HISPANIC', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_HISPANIC', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_AMER_INDIAN', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_AMER_INDIAN', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_ASIAN', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_ASIAN', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_BLACK', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_BLACK', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_HAWAIIAN', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_HAWAIIAN', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RACE_WHITE', result_function=validators.isInLimits(1, 2), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RACE_WHITE', + result_function=validators.isInLimits(1, 2), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='RELATIONSHIP_HOH', result_function=validators.isInStringRange(4, 9), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='RELATIONSHIP_HOH', + result_function=validators.isInStringRange(4, 9), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.oneOf((1, 2)), - result_field='PARENT_MINOR_CHILD', result_function=validators.oneOf((1, 2, 3)), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.oneOf((1, 2)), + result_field='PARENT_MINOR_CHILD', + result_function=validators.oneOf((1, 2, 3)), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(1), - result_field='EDUCATION_LEVEL', result_function=validators.notMatches(99), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(1), + result_field='EDUCATION_LEVEL', + result_function=validators.notMatches(99), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(1), - result_field='CITIZENSHIP_STATUS', result_function=validators.oneOf((1, 2)), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(1), + result_field='CITIZENSHIP_STATUS', + result_function=validators.oneOf((1, 2)), ), validators.if_then_validator( - condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(2), - result_field='CITIZENSHIP_STATUS', result_function=validators.oneOf((1, 2, 3, 9)), + condition_field='FAMILY_AFFILIATION', + condition_function=validators.matches(2), + result_field='CITIZENSHIP_STATUS', + result_function=validators.oneOf((1, 2, 3, 9)), ), ], fields=[ - Field(item="0", name='RecordType', type='string', startIndex=0, endIndex=2, - required=True, validators=[]), - Field(item="3", name='RPT_MONTH_YEAR', type='number', startIndex=2, endIndex=8, - required=True, validators=[ - validators.dateYearIsLargerThan(1998), - validators.dateMonthIsValid(), - ]), - Field(item="5", name='CASE_NUMBER', type='string', startIndex=8, endIndex=19, - required=True, validators=[ - validators.isAlphaNumeric() - ]), - Field(item="60", name='FAMILY_AFFILIATION', type='number', startIndex=60, endIndex=61, - required=True, validators=[ - validators.oneOf([1, 2, 4]) - ]), - Field(item="61", name='DATE_OF_BIRTH', type='string', startIndex=61, endIndex=69, - required=True, validators=[ - validators.dateYearIsLargerThan(1998), - validators.dateMonthIsValid(), - ]), - TransformField(transform_func=ssp_ssn_decryption_func, item="62", name='SSN', type='string', startIndex=69, - endIndex=78, required=True, is_encrypted=False, validators=[ - validators.validateSSN() - ]), - Field(item="63A", name='RACE_HISPANIC', type='number', startIndex=78, endIndex=79, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63B", name='RACE_AMER_INDIAN', type='number', startIndex=79, endIndex=80, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63C", name='RACE_ASIAN', type='number', startIndex=80, endIndex=81, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63D", name='RACE_BLACK', type='number', startIndex=81, endIndex=82, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63E", name='RACE_HAWAIIAN', type='number', startIndex=82, endIndex=83, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="63F", name='RACE_WHITE', type='number', startIndex=83, endIndex=84, - required=False, validators=[ - validators.isInLimits(0, 2) - ]), - Field(item="64", name='GENDER', type='number', startIndex=84, endIndex=85, - required=True, validators=[ - validators.isInLimits(0, 9) - ]), - Field(item="65A", name='RECEIVE_NONSSI_BENEFITS', type='number', startIndex=85, endIndex=86, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="65B", name='RECEIVE_SSI', type='number', startIndex=86, endIndex=87, - required=True, validators=[ - validators.oneOf([1, 2]) - ]), - Field(item="66", name='RELATIONSHIP_HOH', type='number', startIndex=87, endIndex=89, - required=False, validators=[ - validators.isInLimits(0, 10) - ]), - Field(item="67", name='PARENT_MINOR_CHILD', type='number', startIndex=89, endIndex=90, - required=False, validators=[ - validators.oneOf([0, 2, 3]) - ]), - Field(item="68", name='EDUCATION_LEVEL', type='number', startIndex=90, endIndex=92, - required=True, validators=[ - validators.or_validators( - validators.isInStringRange(0, 16), - validators.isInStringRange(98, 99) - ) - ]), - Field(item="69", name='CITIZENSHIP_STATUS', type='number', startIndex=92, endIndex=93, - required=False, validators=[ - validators.oneOf([0, 1, 2, 3, 9]) - ]), - Field(item="70A", name='UNEARNED_SSI', type='number', startIndex=93, endIndex=97, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]), - Field(item="70B", name='OTHER_UNEARNED_INCOME', type='number', startIndex=97, endIndex=101, - required=True, validators=[ - validators.isInLimits(0, 9999) - ]) + Field( + item="0", + name='RecordType', + friendly_name="record type", + type='string', + startIndex=0, + endIndex=2, + required=True, + validators=[] + ), + Field( + item="3", + name='RPT_MONTH_YEAR', + friendly_name="reporting month and year", + type='number', + startIndex=2, + endIndex=8, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.dateMonthIsValid(), + ] + ), + Field( + item="5", + name='CASE_NUMBER', + friendly_name="case number", + type='string', + startIndex=8, + endIndex=19, + required=True, + validators=[validators.isAlphaNumeric()] + ), + Field( + item="60", + name='FAMILY_AFFILIATION', + friendly_name="family affiliation", + type='number', + startIndex=60, + endIndex=61, + required=True, + validators=[validators.oneOf([1, 2, 4])] + ), + Field( + item="61", + name='DATE_OF_BIRTH', + friendly_name="date of birth", + type='string', + startIndex=61, + endIndex=69, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.dateMonthIsValid(), + ] + ), + TransformField( + transform_func=ssp_ssn_decryption_func, + item="62", + name='SSN', + friendly_name="social security number", + type='string', + startIndex=69, + endIndex=78, + required=True, + is_encrypted=False, + validators=[validators.validateSSN()] + ), + Field( + item="63A", + name='RACE_HISPANIC', + friendly_name="race hispanic", + type='number', + startIndex=78, + endIndex=79, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63B", + name='RACE_AMER_INDIAN', + friendly_name="race american-indian", + type='number', + startIndex=79, + endIndex=80, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63C", + name='RACE_ASIAN', + friendly_name="race asian", + type='number', + startIndex=80, + endIndex=81, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63D", + name='RACE_BLACK', + friendly_name="race black", + type='number', + startIndex=81, + endIndex=82, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63E", + name='RACE_HAWAIIAN', + friendly_name="race hawaiian", + type='number', + startIndex=82, + endIndex=83, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="63F", + name='RACE_WHITE', + friendly_name="race white", + type='number', + startIndex=83, + endIndex=84, + required=False, + validators=[validators.isInLimits(0, 2)] + ), + Field( + item="64", + name='GENDER', + friendly_name="gender", + type='number', + startIndex=84, + endIndex=85, + required=True, + validators=[validators.isInLimits(0, 9)] + ), + Field( + item="65A", + name='RECEIVE_NONSSI_BENEFITS', + friendly_name="receives non-SSI benefit", + type='number', + startIndex=85, + endIndex=86, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="65B", + name='RECEIVE_SSI', + friendly_name="receives ssi", + type='number', + startIndex=86, + endIndex=87, + required=True, + validators=[validators.oneOf([1, 2])] + ), + Field( + item="66", + name='RELATIONSHIP_HOH', + friendly_name="relationship to head of household", + type='number', + startIndex=87, + endIndex=89, + required=False, + validators=[validators.isInLimits(0, 10)] + ), + Field( + item="67", + name='PARENT_MINOR_CHILD', + friendly_name="parent of minor child", + type='number', + startIndex=89, + endIndex=90, + required=False, + validators=[validators.oneOf([0, 2, 3])] + ), + Field( + item="68", + name='EDUCATION_LEVEL', + friendly_name="education level", + type='number', + startIndex=90, + endIndex=92, + required=True, + validators=[ + validators.or_validators( + validators.isInStringRange(0, 16), + validators.isInStringRange(98, 99) + ) + ] + ), + Field( + item="69", + name='CITIZENSHIP_STATUS', + friendly_name="citizenship status", + type='number', + startIndex=92, + endIndex=93, + required=False, + validators=[validators.oneOf([0, 1, 2, 3, 9])] + ), + Field( + item="70A", + name='UNEARNED_SSI', + friendly_name="unearned SSI benefit", + type='number', + startIndex=93, + endIndex=97, + required=True, + validators=[validators.isInLimits(0, 9999)] + ), + Field( + item="70B", + name='OTHER_UNEARNED_INCOME', + friendly_name="other unearned income", + type='number', + startIndex=97, + endIndex=101, + required=True, + validators=[validators.isInLimits(0, 9999)] + ) ] ) diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m4.py b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m4.py index e23a279aa..4d8f04f64 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m4.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m4.py @@ -19,6 +19,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -28,6 +29,7 @@ Field( item="3", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=8, @@ -40,6 +42,7 @@ Field( item="5", name="CASE_NUMBER", + friendly_name="case number", type="string", startIndex=8, endIndex=19, @@ -49,6 +52,7 @@ Field( item="2", name="COUNTY_FIPS_CODE", + friendly_name="county fips code", type="string", startIndex=19, endIndex=22, @@ -58,6 +62,7 @@ Field( item="4", name="STRATUM", + friendly_name="stratum", type="string", startIndex=22, endIndex=24, @@ -67,6 +72,7 @@ Field( item="6", name="ZIP_CODE", + friendly_name="zip code", type="string", startIndex=24, endIndex=29, @@ -76,6 +82,7 @@ Field( item="7", name="DISPOSITION", + friendly_name="disposition", type="number", startIndex=29, endIndex=30, @@ -85,19 +92,22 @@ Field( item="8", name="CLOSURE_REASON", + friendly_name="closure reason", type="string", startIndex=30, endIndex=32, required=True, validators=[ validators.or_validators( - validators.isInStringRange(1, 19), validators.matches("99") + validators.isInStringRange(1, 19), + validators.matches("99") ) ], ), Field( item="9", name="REC_SUB_HOUSING", + friendly_name="receives subsidized housing", type="number", startIndex=32, endIndex=33, @@ -107,6 +117,7 @@ Field( item="10`", name="REC_MED_ASSIST", + friendly_name="receives medical assistance", type="number", startIndex=33, endIndex=34, @@ -116,6 +127,7 @@ Field( item="11", name="REC_FOOD_STAMPS", + friendly_name="receives food stamps", type="number", startIndex=34, endIndex=35, @@ -125,6 +137,7 @@ Field( item="12", name="REC_SUB_CC", + friendly_name="receives subsidized child care", type="number", startIndex=35, endIndex=36, @@ -134,6 +147,7 @@ Field( item="-1", name="BLANK", + friendly_name="blank", type="string", startIndex=36, endIndex=66, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m5.py b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m5.py index 98c2b6f83..a63cd6591 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m5.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m5.py @@ -104,6 +104,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -113,6 +114,7 @@ Field( item="3", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=8, @@ -125,6 +127,7 @@ Field( item="5", name="CASE_NUMBER", + friendly_name="case number", type="string", startIndex=8, endIndex=19, @@ -134,6 +137,7 @@ Field( item="13", name="FAMILY_AFFILIATION", + friendly_name="family affiliation", type="number", startIndex=19, endIndex=20, @@ -143,6 +147,7 @@ Field( item="14", name="DATE_OF_BIRTH", + friendly_name="date of birth", type="string", startIndex=20, endIndex=28, @@ -156,6 +161,7 @@ transform_func=ssp_ssn_decryption_func, item="15", name="SSN", + friendly_name="social security number", type="string", startIndex=28, endIndex=37, @@ -166,6 +172,7 @@ Field( item="16A", name="RACE_HISPANIC", + friendly_name="race hispanic", type="number", startIndex=37, endIndex=38, @@ -175,6 +182,7 @@ Field( item="16B", name="RACE_AMER_INDIAN", + friendly_name="race american-indian", type="number", startIndex=38, endIndex=39, @@ -184,6 +192,7 @@ Field( item="16C", name="RACE_ASIAN", + friendly_name="race asian", type="number", startIndex=39, endIndex=40, @@ -193,6 +202,7 @@ Field( item="16D", name="RACE_BLACK", + friendly_name="race black", type="number", startIndex=40, endIndex=41, @@ -202,6 +212,7 @@ Field( item="16E", name="RACE_HAWAIIAN", + friendly_name="race hawaiian", type="number", startIndex=41, endIndex=42, @@ -211,6 +222,7 @@ Field( item="16F", name="RACE_WHITE", + friendly_name="race white", type="number", startIndex=42, endIndex=43, @@ -220,6 +232,7 @@ Field( item="17", name="GENDER", + friendly_name="gender", type="number", startIndex=43, endIndex=44, @@ -229,6 +242,7 @@ Field( item="18A", name="REC_OASDI_INSURANCE", + friendly_name="receives old-age survivors and disability insurance", type="number", startIndex=44, endIndex=45, @@ -238,6 +252,7 @@ Field( item="18B", name="REC_FEDERAL_DISABILITY", + friendly_name="receives federal disability", type="number", startIndex=45, endIndex=46, @@ -247,6 +262,7 @@ Field( item="18C", name="REC_AID_TOTALLY_DISABLED", + friendly_name="receives aid for totally disabled", type="number", startIndex=46, endIndex=47, @@ -256,6 +272,7 @@ Field( item="18D", name="REC_AID_AGED_BLIND", + friendly_name="receives from aid to the aged, blind, and disabled program", type="number", startIndex=47, endIndex=48, @@ -265,6 +282,7 @@ Field( item="18E", name="REC_SSI", + friendly_name="receives SSI", type="number", startIndex=48, endIndex=49, @@ -274,6 +292,7 @@ Field( item="19", name="MARITAL_STATUS", + friendly_name="marital status", type="number", startIndex=49, endIndex=50, @@ -283,6 +302,7 @@ Field( item="20", name="RELATIONSHIP_HOH", + friendly_name="relationship to head of household", type="string", startIndex=50, endIndex=52, @@ -292,6 +312,7 @@ Field( item="21", name="PARENT_MINOR_CHILD", + friendly_name="parent of minor child", type="number", startIndex=52, endIndex=53, @@ -301,6 +322,7 @@ Field( item="22", name="NEEDS_OF_PREGNANT_WOMAN", + friendly_name="needs of pregnant woman", type="number", startIndex=53, endIndex=54, @@ -310,6 +332,7 @@ Field( item="23", name="EDUCATION_LEVEL", + friendly_name="education level", type="string", startIndex=54, endIndex=56, @@ -324,19 +347,22 @@ Field( item="24", name="CITIZENSHIP_STATUS", + friendly_name="citizenship status", type="number", startIndex=56, endIndex=57, required=False, validators=[ validators.or_validators( - validators.isInLimits(0, 3), validators.matches(9) + validators.isInLimits(0, 3), + validators.matches(9) ) ], ), Field( item="25", name="EMPLOYMENT_STATUS", + friendly_name="employment status", type="number", startIndex=57, endIndex=58, @@ -346,6 +372,7 @@ Field( item="26", name="AMOUNT_EARNED_INCOME", + friendly_name="amount of earned income", type="string", startIndex=58, endIndex=62, @@ -355,6 +382,7 @@ Field( item="27", name="AMOUNT_UNEARNED_INCOME", + friendly_name="amount of unearned income", type="string", startIndex=62, endIndex=66, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m6.py b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m6.py index 6bea60b11..6f266168b 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m6.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m6.py @@ -15,39 +15,157 @@ ], postparsing_validators=[ validators.sumIsEqual( - "SSPMOE_FAMILIES", ["NUM_2_PARENTS", "NUM_1_PARENTS", "NUM_NO_PARENTS"]), + "SSPMOE_FAMILIES", [ + "NUM_2_PARENTS", + "NUM_1_PARENTS", + "NUM_NO_PARENTS" + ] + ), validators.sumIsEqual( - "NUM_RECIPIENTS", ["ADULT_RECIPIENTS", "CHILD_RECIPIENTS"]), + "NUM_RECIPIENTS", [ + "ADULT_RECIPIENTS", + "CHILD_RECIPIENTS" + ] + ), ], fields=[ - Field(item="0", name='RecordType', type='string', startIndex=0, endIndex=2, - required=True, validators=[]), - Field(item="2", name='CALENDAR_QUARTER', type='number', startIndex=2, endIndex=7, - required=True, validators=[validators.dateYearIsLargerThan(1998), - validators.quarterIsValid()]), - TransformField(calendar_quarter_to_rpt_month_year(0), item="2B", name='RPT_MONTH_YEAR', type='number', - startIndex=2, endIndex=7, required=True, validators=[validators.dateYearIsLargerThan(1998), - validators.dateMonthIsValid()]), - Field(item="3A", name='SSPMOE_FAMILIES', type='number', startIndex=7, endIndex=15, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="4A", name='NUM_2_PARENTS', type='number', startIndex=31, endIndex=39, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="5A", name='NUM_1_PARENTS', type='number', startIndex=55, endIndex=63, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="6A", name='NUM_NO_PARENTS', type='number', startIndex=79, endIndex=87, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="7A", name='NUM_RECIPIENTS', type='number', startIndex=103, endIndex=111, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="8A", name='ADULT_RECIPIENTS', type='number', startIndex=127, endIndex=135, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="9A", name='CHILD_RECIPIENTS', type='number', startIndex=151, endIndex=159, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="10A", name='NONCUSTODIALS', type='number', startIndex=175, endIndex=183, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="11A", name='AMT_ASSISTANCE', type='number', startIndex=199, endIndex=211, - required=True, validators=[validators.isInLimits(0, 999999999999)]), - Field(item="12A", name='CLOSED_CASES', type='number', startIndex=235, endIndex=243, - required=True, validators=[validators.isInLimits(0, 99999999)]), + Field( + item="0", + name='RecordType', + friendly_name='record type', + type='string', + startIndex=0, + endIndex=2, + required=True, + validators=[] + ), + Field( + item="2", + name='CALENDAR_QUARTER', + friendly_name='calendar quarter', + type='number', + startIndex=2, + endIndex=7, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.quarterIsValid() + ] + ), + TransformField( + calendar_quarter_to_rpt_month_year(0), + item="2B", + name='RPT_MONTH_YEAR', + friendly_name='reporting month and year', + type='number', + startIndex=2, + endIndex=7, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.dateMonthIsValid() + ] + ), + Field( + item="3A", + name='SSPMOE_FAMILIES', + friendly_name='ssp/moe families', + type='number', + startIndex=7, + endIndex=15, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="4A", + name='NUM_2_PARENTS', + friendly_name='number of two-parent families', + type='number', + startIndex=31, + endIndex=39, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="5A", + name='NUM_1_PARENTS', + friendly_name='number of one-parent families', + type='number', + startIndex=55, + endIndex=63, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="6A", + name='NUM_NO_PARENTS', + friendly_name='number of no-parent families', + type='number', + startIndex=79, + endIndex=87, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="7A", + name='NUM_RECIPIENTS', + friendly_name='number of recipients', + type='number', + startIndex=103, + endIndex=111, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="8A", + name='ADULT_RECIPIENTS', + friendly_name='number of adult recipients', + type='number', + startIndex=127, + endIndex=135, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="9A", + name='CHILD_RECIPIENTS', + friendly_name='number of child recipients', + type='number', + startIndex=151, + endIndex=159, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="10A", + name='NONCUSTODIALS', + friendly_name='number of noncustodial parents', + type='number', + startIndex=175, + endIndex=183, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="11A", + name='AMT_ASSISTANCE', + friendly_name='amount of assistance', + type='number', + startIndex=199, + endIndex=211, + required=True, + validators=[validators.isInLimits(0, 999999999999)] + ), + Field( + item="12A", + name='CLOSED_CASES', + friendly_name='number of closed cases', + type='number', + startIndex=235, + endIndex=243, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), ], ) @@ -58,39 +176,157 @@ ], postparsing_validators=[ validators.sumIsEqual( - "SSPMOE_FAMILIES", ["NUM_2_PARENTS", "NUM_1_PARENTS", "NUM_NO_PARENTS"]), + "SSPMOE_FAMILIES", [ + "NUM_2_PARENTS", + "NUM_1_PARENTS", + "NUM_NO_PARENTS" + ] + ), validators.sumIsEqual( - "NUM_RECIPIENTS", ["ADULT_RECIPIENTS", "CHILD_RECIPIENTS"]), + "NUM_RECIPIENTS", [ + "ADULT_RECIPIENTS", + "CHILD_RECIPIENTS" + ] + ), ], fields=[ - Field(item="0", name='RecordType', type='string', startIndex=0, endIndex=2, - required=True, validators=[]), - Field(item="2", name='CALENDAR_QUARTER', type='number', startIndex=2, endIndex=7, - required=True, validators=[validators.dateYearIsLargerThan(1998), - validators.quarterIsValid()]), - TransformField(calendar_quarter_to_rpt_month_year(1), item="2B", name='RPT_MONTH_YEAR', type='number', - startIndex=2, endIndex=7, required=True, validators=[validators.dateYearIsLargerThan(1998), - validators.dateMonthIsValid()]), - Field(item="3B", name='SSPMOE_FAMILIES', type='number', startIndex=15, endIndex=23, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="4B", name='NUM_2_PARENTS', type='number', startIndex=39, endIndex=47, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="5B", name='NUM_1_PARENTS', type='number', startIndex=63, endIndex=71, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="6B", name='NUM_NO_PARENTS', type='number', startIndex=87, endIndex=95, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="7B", name='NUM_RECIPIENTS', type='number', startIndex=111, endIndex=119, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="8B", name='ADULT_RECIPIENTS', type='number', startIndex=135, endIndex=143, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="9B", name='CHILD_RECIPIENTS', type='number', startIndex=159, endIndex=167, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="10B", name='NONCUSTODIALS', type='number', startIndex=183, endIndex=191, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="11B", name='AMT_ASSISTANCE', type='number', startIndex=211, endIndex=223, - required=True, validators=[validators.isInLimits(0, 999999999999)]), - Field(item="12B", name='CLOSED_CASES', type='number', startIndex=243, endIndex=251, - required=True, validators=[validators.isInLimits(0, 99999999)]), + Field( + item="0", + name='RecordType', + friendly_name='record type', + type='string', + startIndex=0, + endIndex=2, + required=True, + validators=[] + ), + Field( + item="2", + name='CALENDAR_QUARTER', + friendly_name='calendar quarter', + type='number', + startIndex=2, + endIndex=7, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.quarterIsValid() + ] + ), + TransformField( + calendar_quarter_to_rpt_month_year(1), + item="2B", + name='RPT_MONTH_YEAR', + friendly_name='reporting month and year', + type='number', + startIndex=2, + endIndex=7, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.dateMonthIsValid() + ] + ), + Field( + item="3B", + name='SSPMOE_FAMILIES', + friendly_name='ssp/moe families', + type='number', + startIndex=15, + endIndex=23, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="4B", + name='NUM_2_PARENTS', + friendly_name='number of two-parent families', + type='number', + startIndex=39, + endIndex=47, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="5B", + name='NUM_1_PARENTS', + friendly_name='number of one-parent families', + type='number', + startIndex=63, + endIndex=71, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="6B", + name='NUM_NO_PARENTS', + friendly_name='number of no-parent families', + type='number', + startIndex=87, + endIndex=95, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="7B", + name='NUM_RECIPIENTS', + friendly_name='number of recipients', + type='number', + startIndex=111, + endIndex=119, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="8B", + name='ADULT_RECIPIENTS', + friendly_name='number of adult recipients', + type='number', + startIndex=135, + endIndex=143, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="9B", + name='CHILD_RECIPIENTS', + friendly_name='number of child recipients', + type='number', + startIndex=159, + endIndex=167, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="10B", + name='NONCUSTODIALS', + friendly_name='number of noncustodial parents', + type='number', + startIndex=183, + endIndex=191, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="11B", + name='AMT_ASSISTANCE', + friendly_name='amount of assistance', + type='number', + startIndex=211, + endIndex=223, + required=True, + validators=[validators.isInLimits(0, 999999999999)] + ), + Field( + item="12B", + name='CLOSED_CASES', + friendly_name='number of closed cases', + type='number', + startIndex=243, + endIndex=251, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), ], ) @@ -101,39 +337,157 @@ ], postparsing_validators=[ validators.sumIsEqual( - "SSPMOE_FAMILIES", ["NUM_2_PARENTS", "NUM_1_PARENTS", "NUM_NO_PARENTS"]), + "SSPMOE_FAMILIES", [ + "NUM_2_PARENTS", + "NUM_1_PARENTS", + "NUM_NO_PARENTS" + ] + ), validators.sumIsEqual( - "NUM_RECIPIENTS", ["ADULT_RECIPIENTS", "CHILD_RECIPIENTS"]), + "NUM_RECIPIENTS", [ + "ADULT_RECIPIENTS", + "CHILD_RECIPIENTS" + ] + ), ], fields=[ - Field(item="0", name='RecordType', type='string', startIndex=0, endIndex=2, - required=True, validators=[]), - Field(item="2", name='CALENDAR_QUARTER', type='number', startIndex=2, endIndex=7, - required=True, validators=[validators.dateYearIsLargerThan(1998), - validators.quarterIsValid()]), - TransformField(calendar_quarter_to_rpt_month_year(2), item="2B", name='RPT_MONTH_YEAR', type='number', - startIndex=2, endIndex=7, required=True, validators=[validators.dateYearIsLargerThan(1998), - validators.dateMonthIsValid()]), - Field(item="3C", name='SSPMOE_FAMILIES', type='number', startIndex=23, endIndex=31, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="4C", name='NUM_2_PARENTS', type='number', startIndex=47, endIndex=55, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="5C", name='NUM_1_PARENTS', type='number', startIndex=71, endIndex=79, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="6C", name='NUM_NO_PARENTS', type='number', startIndex=95, endIndex=103, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="7C", name='NUM_RECIPIENTS', type='number', startIndex=119, endIndex=127, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="8C", name='ADULT_RECIPIENTS', type='number', startIndex=143, endIndex=151, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="9C", name='CHILD_RECIPIENTS', type='number', startIndex=167, endIndex=175, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="10C", name='NONCUSTODIALS', type='number', startIndex=191, endIndex=199, - required=True, validators=[validators.isInLimits(0, 99999999)]), - Field(item="11C", name='AMT_ASSISTANCE', type='number', startIndex=223, endIndex=235, - required=True, validators=[validators.isInLimits(0, 999999999999)]), - Field(item="12C", name='CLOSED_CASES', type='number', startIndex=251, endIndex=259, - required=True, validators=[validators.isInLimits(0, 99999999)]), + Field( + item="0", + name='RecordType', + friendly_name='record type', + type='string', + startIndex=0, + endIndex=2, + required=True, + validators=[] + ), + Field( + item="2", + name='CALENDAR_QUARTER', + friendly_name='calendar quarter', + type='number', + startIndex=2, + endIndex=7, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.quarterIsValid() + ] + ), + TransformField( + calendar_quarter_to_rpt_month_year(2), + item="2B", + name='RPT_MONTH_YEAR', + friendly_name='reporting month and year', + type='number', + startIndex=2, + endIndex=7, + required=True, + validators=[ + validators.dateYearIsLargerThan(1998), + validators.dateMonthIsValid() + ] + ), + Field( + item="3C", + name='SSPMOE_FAMILIES', + friendly_name='ssp/moe families', + type='number', + startIndex=23, + endIndex=31, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="4C", + name='NUM_2_PARENTS', + friendly_name='number of two-parent families', + type='number', + startIndex=47, + endIndex=55, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="5C", + name='NUM_1_PARENTS', + friendly_name='number of one-parent families', + type='number', + startIndex=71, + endIndex=79, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="6C", + name='NUM_NO_PARENTS', + friendly_name='number of no-parent families', + type='number', + startIndex=95, + endIndex=103, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="7C", + name='NUM_RECIPIENTS', + friendly_name='number of recipients', + type='number', + startIndex=119, + endIndex=127, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="8C", + name='ADULT_RECIPIENTS', + friendly_name='number of adult recipients', + type='number', + startIndex=143, + endIndex=151, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="9C", + name='CHILD_RECIPIENTS', + friendly_name='number of child recipients', + type='number', + startIndex=167, + endIndex=175, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="10C", + name='NONCUSTODIALS', + friendly_name='number of noncustodial parents', + type='number', + startIndex=191, + endIndex=199, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), + Field( + item="11C", + name='AMT_ASSISTANCE', + friendly_name='amount of assistance', + type='number', + startIndex=223, + endIndex=235, + required=True, + validators=[validators.isInLimits(0, 999999999999)] + ), + Field( + item="12C", + name='CLOSED_CASES', + friendly_name='number of closed cases', + type='number', + startIndex=251, + endIndex=259, + required=True, + validators=[validators.isInLimits(0, 99999999)] + ), ], ) diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m7.py b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m7.py index 1fb1aa8fa..cde0c1fc3 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m7.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/ssp/m7.py @@ -32,6 +32,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -41,6 +42,7 @@ Field( item="2", name="CALENDAR_QUARTER", + friendly_name="calendar quarter", type="number", startIndex=2, endIndex=7, @@ -54,6 +56,7 @@ transform_func=calendar_quarter_to_rpt_month_year((i - 1) % 3), item="2A", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=7, @@ -66,6 +69,7 @@ Field( item="3", name="TDRS_SECTION_IND", + friendly_name="tdrs section indicator", type="string", startIndex=section_ind_index, endIndex=section_ind_index + 1, @@ -75,6 +79,7 @@ Field( item="4", name="STRATUM", + friendly_name="stratum", type="string", startIndex=stratum_index, endIndex=stratum_index + 2, @@ -84,6 +89,7 @@ Field( item=families_item_numbers[i - 1], name="FAMILIES_MONTH", + friendly_name="families month", type="number", startIndex=families_index, endIndex=families_index + 7, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t1.py b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t1.py index fa7e4cef9..76ce8f0f5 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t1.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t1.py @@ -122,6 +122,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -131,6 +132,7 @@ Field( item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=8, @@ -143,6 +145,7 @@ Field( item="6", name="CASE_NUMBER", + friendly_name="case number", type="string", startIndex=8, endIndex=19, @@ -152,6 +155,7 @@ Field( item="2", name="COUNTY_FIPS_CODE", + friendly_name="county fips code", type="string", startIndex=19, endIndex=22, @@ -163,6 +167,7 @@ Field( item="5", name="STRATUM", + friendly_name="stratum", type="string", startIndex=22, endIndex=24, @@ -174,6 +179,7 @@ Field( item="7", name="ZIP_CODE", + friendly_name="zip code", type="string", startIndex=24, endIndex=29, @@ -185,6 +191,7 @@ Field( item="8", name="FUNDING_STREAM", + friendly_name="funding stream", type="number", startIndex=29, endIndex=30, @@ -196,6 +203,7 @@ Field( item="9", name="DISPOSITION", + friendly_name="disposition", type="number", startIndex=30, endIndex=31, @@ -207,6 +215,7 @@ Field( item="10", name="NEW_APPLICANT", + friendly_name="new applicant", type="number", startIndex=31, endIndex=32, @@ -218,6 +227,7 @@ Field( item="11", name="NBR_FAMILY_MEMBERS", + friendly_name="number of family members", type="number", startIndex=32, endIndex=34, @@ -229,6 +239,7 @@ Field( item="12", name="FAMILY_TYPE", + friendly_name="family type", type="number", startIndex=34, endIndex=35, @@ -240,6 +251,7 @@ Field( item="13", name="RECEIVES_SUB_HOUSING", + friendly_name="receives subsidized housing", type="number", startIndex=35, endIndex=36, @@ -251,6 +263,7 @@ Field( item="14", name="RECEIVES_MED_ASSISTANCE", + friendly_name="receives medical assistance", type="number", startIndex=36, endIndex=37, @@ -262,6 +275,7 @@ Field( item="15", name="RECEIVES_FOOD_STAMPS", + friendly_name="receives food stamps", type="number", startIndex=37, endIndex=38, @@ -273,6 +287,7 @@ Field( item="16", name="AMT_FOOD_STAMP_ASSISTANCE", + friendly_name="amount of food stamp assistance", type="number", startIndex=38, endIndex=42, @@ -284,6 +299,7 @@ Field( item="17", name="RECEIVES_SUB_CC", + friendly_name="receives subsidized child care", type="number", startIndex=42, endIndex=43, @@ -295,6 +311,7 @@ Field( item="18", name="AMT_SUB_CC", + friendly_name="amount of subsidized child care", type="number", startIndex=43, endIndex=47, @@ -306,6 +323,7 @@ Field( item="19", name="CHILD_SUPPORT_AMT", + friendly_name="child support amount", type="number", startIndex=47, endIndex=51, @@ -317,6 +335,7 @@ Field( item="20", name="FAMILY_CASH_RESOURCES", + friendly_name="family cash resources", type="number", startIndex=51, endIndex=55, @@ -328,6 +347,7 @@ Field( item="21A", name="CASH_AMOUNT", + friendly_name="cash amount", type="number", startIndex=55, endIndex=59, @@ -339,6 +359,7 @@ Field( item="21B", name="NBR_MONTHS", + friendly_name="number of months", type="number", startIndex=59, endIndex=62, @@ -350,6 +371,7 @@ Field( item="22A", name="CC_AMOUNT", + friendly_name="child care amount", type="number", startIndex=62, endIndex=66, @@ -361,6 +383,7 @@ Field( item="22B", name="CHILDREN_COVERED", + friendly_name="children covered", type="number", startIndex=66, endIndex=68, @@ -372,6 +395,7 @@ Field( item="22C", name="CC_NBR_MONTHS", + friendly_name="child care - number of months", type="number", startIndex=68, endIndex=71, @@ -383,6 +407,7 @@ Field( item="23A", name="TRANSP_AMOUNT", + friendly_name="transportation amount", type="number", startIndex=71, endIndex=75, @@ -394,6 +419,7 @@ Field( item="23B", name="TRANSP_NBR_MONTHS", + friendly_name="transportation - number of months", type="number", startIndex=75, endIndex=78, @@ -405,6 +431,7 @@ Field( item="24A", name="TRANSITION_SERVICES_AMOUNT", + friendly_name="transition services amount", type="number", startIndex=78, endIndex=82, @@ -416,6 +443,7 @@ Field( item="24B", name="TRANSITION_NBR_MONTHS", + friendly_name="transition services - number of months", type="number", startIndex=82, endIndex=85, @@ -427,6 +455,7 @@ Field( item="25A", name="OTHER_AMOUNT", + friendly_name="other amount", type="number", startIndex=85, endIndex=89, @@ -438,6 +467,7 @@ Field( item="25B", name="OTHER_NBR_MONTHS", + friendly_name="other - number of months", type="number", startIndex=89, endIndex=92, @@ -449,6 +479,7 @@ Field( item="26AI", name="SANC_REDUCTION_AMT", + friendly_name="sanction reduction amount", type="number", startIndex=92, endIndex=96, @@ -460,6 +491,7 @@ Field( item="26AII", name="WORK_REQ_SANCTION", + friendly_name="work requirement sanction", type="number", startIndex=96, endIndex=97, @@ -471,6 +503,7 @@ Field( item="26AIII", name="FAMILY_SANC_ADULT", + friendly_name="family sanction adult", type="number", startIndex=97, endIndex=98, @@ -482,6 +515,7 @@ Field( item="26AIV", name="SANC_TEEN_PARENT", + friendly_name="sanctioned teen parent", type="number", startIndex=98, endIndex=99, @@ -493,6 +527,7 @@ Field( item="26AV", name="NON_COOPERATION_CSE", + friendly_name="non-cooperation with child support", type="number", startIndex=99, endIndex=100, @@ -504,6 +539,7 @@ Field( item="26AVI", name="FAILURE_TO_COMPLY", + friendly_name="failure to comply", type="number", startIndex=100, endIndex=101, @@ -515,6 +551,7 @@ Field( item="26AVII", name="OTHER_SANCTION", + friendly_name="other sanction", type="number", startIndex=101, endIndex=102, @@ -526,6 +563,7 @@ Field( item="26B", name="RECOUPMENT_PRIOR_OVRPMT", + friendly_name="recoupment prior overpayment", type="number", startIndex=102, endIndex=106, @@ -537,6 +575,7 @@ Field( item="26CI", name="OTHER_TOTAL_REDUCTIONS", + friendly_name="other total reductions", type="number", startIndex=106, endIndex=110, @@ -548,6 +587,7 @@ Field( item="26CII", name="FAMILY_CAP", + friendly_name="family cap", type="number", startIndex=110, endIndex=111, @@ -559,6 +599,7 @@ Field( item="26CIII", name="REDUCTIONS_ON_RECEIPTS", + friendly_name="reductions on receipts", type="number", startIndex=111, endIndex=112, @@ -570,6 +611,7 @@ Field( item="26CIV", name="OTHER_NON_SANCTION", + friendly_name="other non-sanction", type="number", startIndex=112, endIndex=113, @@ -581,13 +623,15 @@ Field( item="27", name="WAIVER_EVAL_CONTROL_GRPS", + friendly_name="waiver evaluation control groups", type="string", startIndex=113, endIndex=114, required=False, validators=[ validators.or_validators( - validators.matches("9"), validators.isEmpty() + validators.matches("9"), + validators.isEmpty() ), validators.isAlphaNumeric(), ], @@ -595,6 +639,7 @@ Field( item="28", name="FAMILY_EXEMPT_TIME_LIMITS", + friendly_name="family exempt time limits", type="number", startIndex=114, endIndex=116, @@ -604,6 +649,7 @@ Field( item="29", name="FAMILY_NEW_CHILD", + friendly_name="family new child", type="number", startIndex=116, endIndex=117, @@ -615,6 +661,7 @@ Field( item="-1", name="BLANK", + friendly_name="blank", type="string", startIndex=117, endIndex=156, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t2.py b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t2.py index 82d42be72..63f8706ac 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t2.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t2.py @@ -127,6 +127,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -136,6 +137,7 @@ Field( item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=8, @@ -148,6 +150,7 @@ Field( item="6", name="CASE_NUMBER", + friendly_name="case number", type="string", startIndex=8, endIndex=19, @@ -157,6 +160,7 @@ Field( item="30", name="FAMILY_AFFILIATION", + friendly_name="family affiliation", type="number", startIndex=19, endIndex=20, @@ -166,6 +170,7 @@ Field( item="31", name="NONCUSTODIAL_PARENT", + friendly_name="noncustodial parent", type="number", startIndex=20, endIndex=21, @@ -175,6 +180,7 @@ Field( item="32", name="DATE_OF_BIRTH", + friendly_name="date of birth", type="number", startIndex=21, endIndex=29, @@ -188,6 +194,7 @@ transform_func=tanf_ssn_decryption_func, item="33", name="SSN", + friendly_name="social security number", type="string", startIndex=29, endIndex=38, @@ -198,6 +205,7 @@ Field( item="34A", name="RACE_HISPANIC", + friendly_name="race hispanic", type="number", startIndex=38, endIndex=39, @@ -207,6 +215,7 @@ Field( item="34B", name="RACE_AMER_INDIAN", + friendly_name="race american-indian", type="number", startIndex=39, endIndex=40, @@ -216,6 +225,7 @@ Field( item="34C", name="RACE_ASIAN", + friendly_name="race asian", type="number", startIndex=40, endIndex=41, @@ -225,6 +235,7 @@ Field( item="34D", name="RACE_BLACK", + friendly_name="race black", type="number", startIndex=41, endIndex=42, @@ -234,6 +245,7 @@ Field( item="34E", name="RACE_HAWAIIAN", + friendly_name="race hawaiian", type="number", startIndex=42, endIndex=43, @@ -243,6 +255,7 @@ Field( item="34F", name="RACE_WHITE", + friendly_name="race white", type="number", startIndex=43, endIndex=44, @@ -252,6 +265,7 @@ Field( item="35", name="GENDER", + friendly_name="gender", type="number", startIndex=44, endIndex=45, @@ -263,6 +277,7 @@ Field( item="36A", name="FED_OASDI_PROGRAM", + friendly_name="federal old age survivors and disability insurance program", type="number", startIndex=45, endIndex=46, @@ -272,6 +287,7 @@ Field( item="36B", name="FED_DISABILITY_STATUS", + friendly_name="federal disability status", type="number", startIndex=46, endIndex=47, @@ -281,19 +297,22 @@ Field( item="36C", name="DISABLED_TITLE_XIVAPDT", + friendly_name="received aid under Title XIV-APDT", type="string", startIndex=47, endIndex=48, required=True, validators=[ validators.or_validators( - validators.oneOf(["1", "2"]), validators.isBlank() + validators.oneOf(["1", "2"]), + validators.isBlank() ) ], ), Field( item="36D", name="AID_AGED_BLIND", + friendly_name="receives from the aid to the aged, blind, and disabled program", type="number", startIndex=48, endIndex=49, @@ -305,6 +324,7 @@ Field( item="36E", name="RECEIVE_SSI", + friendly_name="receives SSI", type="number", startIndex=49, endIndex=50, @@ -316,6 +336,7 @@ Field( item="37", name="MARITAL_STATUS", + friendly_name="marital status", type="number", startIndex=50, endIndex=51, @@ -327,6 +348,7 @@ Field( item="38", name="RELATIONSHIP_HOH", + friendly_name="relationship to head of household", type="string", startIndex=51, endIndex=53, @@ -338,6 +360,7 @@ Field( item="39", name="PARENT_WITH_MINOR_CHILD", + friendly_name="parent with minor child", type="number", startIndex=53, endIndex=54, @@ -349,6 +372,7 @@ Field( item="40", name="NEEDS_PREGNANT_WOMAN", + friendly_name="needs of pregnant woman", type="number", startIndex=54, endIndex=55, @@ -360,6 +384,7 @@ Field( item="41", name="EDUCATION_LEVEL", + friendly_name="education level", type="string", startIndex=55, endIndex=57, @@ -374,6 +399,7 @@ Field( item="42", name="CITIZENSHIP_STATUS", + friendly_name="citizenship status", type="number", startIndex=57, endIndex=58, @@ -383,6 +409,7 @@ Field( item="43", name="COOPERATION_CHILD_SUPPORT", + friendly_name="cooperation with child support", type="number", startIndex=58, endIndex=59, @@ -394,6 +421,7 @@ Field( item="44", name="MONTHS_FED_TIME_LIMIT", + friendly_name="countable months toward federal time limit", type="string", startIndex=59, endIndex=62, @@ -405,6 +433,7 @@ Field( item="45", name="MONTHS_STATE_TIME_LIMIT", + friendly_name="months of state time limit", type="string", startIndex=62, endIndex=64, @@ -416,6 +445,7 @@ Field( item="46", name="CURRENT_MONTH_STATE_EXEMPT", + friendly_name="current month state exempt", type="number", startIndex=64, endIndex=65, @@ -427,6 +457,7 @@ Field( item="47", name="EMPLOYMENT_STATUS", + friendly_name="employment status", type="number", startIndex=65, endIndex=66, @@ -438,6 +469,7 @@ Field( item="48", name="WORK_ELIGIBLE_INDICATOR", + friendly_name="work eligible indicator", type="string", startIndex=66, endIndex=68, @@ -452,6 +484,7 @@ Field( item="49", name="WORK_PART_STATUS", + friendly_name="work participation status", type="string", startIndex=68, endIndex=70, @@ -477,6 +510,7 @@ Field( item="50", name="UNSUB_EMPLOYMENT", + friendly_name="unsubsidized employment", type="string", startIndex=70, endIndex=72, @@ -488,6 +522,7 @@ Field( item="51", name="SUB_PRIVATE_EMPLOYMENT", + friendly_name="subsidized private employment", type="string", startIndex=72, endIndex=74, @@ -499,6 +534,7 @@ Field( item="52", name="SUB_PUBLIC_EMPLOYMENT", + friendly_name="subsidized public employment", type="string", startIndex=74, endIndex=76, @@ -510,6 +546,7 @@ Field( item="53A", name="WORK_EXPERIENCE_HOP", + friendly_name="work experience - hours of participation", type="string", startIndex=76, endIndex=78, @@ -521,6 +558,7 @@ Field( item="53B", name="WORK_EXPERIENCE_EA", + friendly_name="work experience - excused absence", type="string", startIndex=78, endIndex=80, @@ -532,6 +570,7 @@ Field( item="53C", name="WORK_EXPERIENCE_HOL", + friendly_name="work experience - holiday", type="string", startIndex=80, endIndex=82, @@ -543,6 +582,7 @@ Field( item="54", name="OJT", + friendly_name="on the job training", type="string", startIndex=82, endIndex=84, @@ -554,6 +594,7 @@ Field( item="55A", name="JOB_SEARCH_HOP", + friendly_name="job search - hours of participation", type="string", startIndex=84, endIndex=86, @@ -565,6 +606,7 @@ Field( item="55B", name="JOB_SEARCH_EA", + friendly_name="job search - excused absence", type="string", startIndex=86, endIndex=88, @@ -576,6 +618,7 @@ Field( item="55C", name="JOB_SEARCH_HOL", + friendly_name="job search - holidays", type="string", startIndex=88, endIndex=90, @@ -587,6 +630,7 @@ Field( item="56A", name="COMM_SERVICES_HOP", + friendly_name="community service - hours of participation", type="string", startIndex=90, endIndex=92, @@ -598,6 +642,7 @@ Field( item="56B", name="COMM_SERVICES_EA", + friendly_name="community service - excused absence", type="string", startIndex=92, endIndex=94, @@ -609,6 +654,7 @@ Field( item="56C", name="COMM_SERVICES_HOL", + friendly_name="community service - hours of leave", type="string", startIndex=94, endIndex=96, @@ -620,6 +666,7 @@ Field( item="57A", name="VOCATIONAL_ED_TRAINING_HOP", + friendly_name="vocational education training - hours of participation", type="string", startIndex=96, endIndex=98, @@ -631,6 +678,7 @@ Field( item="57B", name="VOCATIONAL_ED_TRAINING_EA", + friendly_name="vocational education training - excused absence", type="string", startIndex=98, endIndex=100, @@ -642,6 +690,7 @@ Field( item="57C", name="VOCATIONAL_ED_TRAINING_HOL", + friendly_name="vocational education training - hours of leave", type="string", startIndex=100, endIndex=102, @@ -653,6 +702,7 @@ Field( item="58A", name="JOB_SKILLS_TRAINING_HOP", + friendly_name="job skills training - hours of participation", type="string", startIndex=102, endIndex=104, @@ -664,6 +714,7 @@ Field( item="58B", name="JOB_SKILLS_TRAINING_EA", + friendly_name="job skills training - excused absence", type="string", startIndex=104, endIndex=106, @@ -675,6 +726,7 @@ Field( item="58C", name="JOB_SKILLS_TRAINING_HOL", + friendly_name="job skills training - hours of leave", type="string", startIndex=106, endIndex=108, @@ -686,6 +738,7 @@ Field( item="59A", name="ED_NO_HIGH_SCHOOL_DIPL_HOP", + friendly_name="education no high school diploma - hours of participation", type="string", startIndex=108, endIndex=110, @@ -697,6 +750,7 @@ Field( item="59B", name="ED_NO_HIGH_SCHOOL_DIPL_EA", + friendly_name="education no high school diploma - excused absence", type="string", startIndex=110, endIndex=112, @@ -708,6 +762,7 @@ Field( item="59C", name="ED_NO_HIGH_SCHOOL_DIPL_HOL", + friendly_name="education no high school diploma - holiday", type="string", startIndex=112, endIndex=114, @@ -719,6 +774,7 @@ Field( item="60A", name="SCHOOL_ATTENDENCE_HOP", + friendly_name="school attendance - hours of participation", type="string", startIndex=114, endIndex=116, @@ -730,6 +786,7 @@ Field( item="60B", name="SCHOOL_ATTENDENCE_EA", + friendly_name="school attendance - excused absence", type="string", startIndex=116, endIndex=118, @@ -741,6 +798,7 @@ Field( item="60C", name="SCHOOL_ATTENDENCE_HOL", + friendly_name="school attendance - holiday", type="string", startIndex=118, endIndex=120, @@ -752,6 +810,7 @@ Field( item="61A", name="PROVIDE_CC_HOP", + friendly_name="provide child care - hours of participation", type="string", startIndex=120, endIndex=122, @@ -763,6 +822,7 @@ Field( item="61B", name="PROVIDE_CC_EA", + friendly_name="provide child care - excused absence", type="string", startIndex=122, endIndex=124, @@ -774,6 +834,7 @@ Field( item="61C", name="PROVIDE_CC_HOL", + friendly_name="provide child care - holiday", type="string", startIndex=124, endIndex=126, @@ -785,6 +846,7 @@ Field( item="62", name="OTHER_WORK_ACTIVITIES", + friendly_name="other work activities", type="string", startIndex=126, endIndex=128, @@ -796,6 +858,7 @@ Field( item="63", name="DEEMED_HOURS_FOR_OVERALL", + friendly_name="deemed hours for overall", type="string", startIndex=128, endIndex=130, @@ -807,6 +870,7 @@ Field( item="64", name="DEEMED_HOURS_FOR_TWO_PARENT", + friendly_name="deemed hours for two parent", type="string", startIndex=130, endIndex=132, @@ -818,6 +882,7 @@ Field( item="65", name="EARNED_INCOME", + friendly_name="earned income", type="string", startIndex=132, endIndex=136, @@ -829,6 +894,7 @@ Field( item="66A", name="UNEARNED_INCOME_TAX_CREDIT", + friendly_name="unearned income tax credit", type="string", startIndex=136, endIndex=140, @@ -840,6 +906,7 @@ Field( item="66B", name="UNEARNED_SOCIAL_SECURITY", + friendly_name="unearned social security", type="string", startIndex=140, endIndex=144, @@ -851,6 +918,7 @@ Field( item="66C", name="UNEARNED_SSI", + friendly_name="unearned SSI benefit", type="string", startIndex=144, endIndex=148, @@ -862,6 +930,7 @@ Field( item="66D", name="UNEARNED_WORKERS_COMP", + friendly_name="unearned workers compensation", type="string", startIndex=148, endIndex=152, @@ -873,6 +942,7 @@ Field( item="66E", name="OTHER_UNEARNED_INCOME", + friendly_name="other unearned income", type="string", startIndex=152, endIndex=156, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t3.py b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t3.py index 1ffe8b90c..54995f23a 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t3.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t3.py @@ -92,6 +92,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -101,6 +102,7 @@ Field( item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=8, @@ -110,6 +112,7 @@ Field( item="6", name="CASE_NUMBER", + friendly_name="case number", type="string", startIndex=8, endIndex=19, @@ -119,6 +122,7 @@ Field( item="67", name="FAMILY_AFFILIATION", + friendly_name="family affiliation", type="number", startIndex=19, endIndex=20, @@ -128,6 +132,7 @@ Field( item="68", name="DATE_OF_BIRTH", + friendly_name="date of birth", type="number", startIndex=20, endIndex=28, @@ -141,6 +146,7 @@ transform_func=tanf_ssn_decryption_func, item="69", name="SSN", + friendly_name="social security number", type="string", startIndex=28, endIndex=37, @@ -151,6 +157,7 @@ Field( item="70A", name="RACE_HISPANIC", + friendly_name="race hispanic", type="number", startIndex=37, endIndex=38, @@ -160,6 +167,7 @@ Field( item="70B", name="RACE_AMER_INDIAN", + friendly_name="race american-indian", type="number", startIndex=38, endIndex=39, @@ -169,6 +177,7 @@ Field( item="70C", name="RACE_ASIAN", + friendly_name="race asian", type="number", startIndex=39, endIndex=40, @@ -178,6 +187,7 @@ Field( item="70D", name="RACE_BLACK", + friendly_name="race black", type="number", startIndex=40, endIndex=41, @@ -187,6 +197,7 @@ Field( item="70E", name="RACE_HAWAIIAN", + friendly_name="race hawaiian", type="number", startIndex=41, endIndex=42, @@ -196,6 +207,7 @@ Field( item="70F", name="RACE_WHITE", + friendly_name="race white", type="number", startIndex=42, endIndex=43, @@ -205,6 +217,7 @@ Field( item="71", name="GENDER", + friendly_name="gender", type="number", startIndex=43, endIndex=44, @@ -214,6 +227,7 @@ Field( item="72A", name="RECEIVE_NONSSA_BENEFITS", + friendly_name="receives non-social security act benefits", type="number", startIndex=44, endIndex=45, @@ -223,6 +237,7 @@ Field( item="72B", name="RECEIVE_SSI", + friendly_name="receives SSI", type="number", startIndex=45, endIndex=46, @@ -232,6 +247,7 @@ Field( item="73", name="RELATIONSHIP_HOH", + friendly_name="relationship to head of household", type="string", startIndex=46, endIndex=48, @@ -241,6 +257,7 @@ Field( item="74", name="PARENT_MINOR_CHILD", + friendly_name="parent of minor child", type="number", startIndex=48, endIndex=49, @@ -250,6 +267,7 @@ Field( item="75", name="EDUCATION_LEVEL", + friendly_name="education level", type="string", startIndex=49, endIndex=51, @@ -264,6 +282,7 @@ Field( item="76", name="CITIZENSHIP_STATUS", + friendly_name="citizenship status", type="number", startIndex=51, endIndex=52, @@ -273,6 +292,7 @@ Field( item="77A", name="UNEARNED_SSI", + friendly_name="unearned SSI benefit", type="string", startIndex=52, endIndex=56, @@ -282,6 +302,7 @@ Field( item="77B", name="OTHER_UNEARNED_INCOME", + friendly_name="other unearned income", type="string", startIndex=56, endIndex=60, @@ -375,6 +396,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -384,6 +406,7 @@ Field( item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=8, @@ -393,6 +416,7 @@ Field( item="6", name="CASE_NUMBER", + friendly_name="case number", type="string", startIndex=8, endIndex=19, @@ -402,6 +426,7 @@ Field( item="67", name="FAMILY_AFFILIATION", + friendly_name="family affiliation", type="number", startIndex=60, endIndex=61, @@ -411,6 +436,7 @@ Field( item="68", name="DATE_OF_BIRTH", + friendly_name="date of birth", type="number", startIndex=61, endIndex=69, @@ -424,6 +450,7 @@ transform_func=tanf_ssn_decryption_func, item="69", name="SSN", + friendly_name="social security number", type="string", startIndex=69, endIndex=78, @@ -434,6 +461,7 @@ Field( item="70A", name="RACE_HISPANIC", + friendly_name="race hispanic", type="number", startIndex=78, endIndex=79, @@ -443,6 +471,7 @@ Field( item="70B", name="RACE_AMER_INDIAN", + friendly_name="race american-indian", type="number", startIndex=79, endIndex=80, @@ -452,6 +481,7 @@ Field( item="70C", name="RACE_ASIAN", + friendly_name="race asian", type="number", startIndex=80, endIndex=81, @@ -461,6 +491,7 @@ Field( item="70D", name="RACE_BLACK", + friendly_name="race black", type="number", startIndex=81, endIndex=82, @@ -470,6 +501,7 @@ Field( item="70E", name="RACE_HAWAIIAN", + friendly_name="race hawaiian", type="number", startIndex=82, endIndex=83, @@ -479,6 +511,7 @@ Field( item="70F", name="RACE_WHITE", + friendly_name="race white", type="number", startIndex=83, endIndex=84, @@ -488,6 +521,7 @@ Field( item="71", name="GENDER", + friendly_name="gender", type="number", startIndex=84, endIndex=85, @@ -497,6 +531,7 @@ Field( item="72A", name="RECEIVE_NONSSA_BENEFITS", + friendly_name="receives non-ssa benefits", type="number", startIndex=85, endIndex=86, @@ -506,6 +541,7 @@ Field( item="72B", name="RECEIVE_SSI", + friendly_name="receives SSI", type="number", startIndex=86, endIndex=87, @@ -515,6 +551,7 @@ Field( item="73", name="RELATIONSHIP_HOH", + friendly_name="relationship to head of household", type="string", startIndex=87, endIndex=89, @@ -524,6 +561,7 @@ Field( item="74", name="PARENT_MINOR_CHILD", + friendly_name="parent of minor child", type="number", startIndex=89, endIndex=90, @@ -533,19 +571,22 @@ Field( item="75", name="EDUCATION_LEVEL", + friendly_name="education level", type="string", startIndex=90, endIndex=92, required=True, validators=[ validators.or_validators( - validators.isInStringRange(0, 16), validators.oneOf(["98", "99"]) + validators.isInStringRange(0, 16), + validators.oneOf(["98", "99"]) ) ], ), Field( item="76", name="CITIZENSHIP_STATUS", + friendly_name="citizenship status", type="number", startIndex=92, endIndex=93, @@ -555,6 +596,7 @@ Field( item="77A", name="UNEARNED_SSI", + friendly_name="unearned SSI benefit", type="string", startIndex=93, endIndex=97, @@ -564,6 +606,7 @@ Field( item="77B", name="OTHER_UNEARNED_INCOME", + friendly_name="other unearned income", type="string", startIndex=97, endIndex=101, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t4.py b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t4.py index 8b7fec0bd..1a5a13c54 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t4.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t4.py @@ -20,6 +20,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -29,6 +30,7 @@ Field( item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=8, @@ -41,6 +43,7 @@ Field( item="6", name="CASE_NUMBER", + friendly_name="case number", type="string", startIndex=8, endIndex=19, @@ -50,6 +53,7 @@ Field( item="2", name="COUNTY_FIPS_CODE", + friendly_name="county fips code", type="string", startIndex=19, endIndex=22, @@ -59,6 +63,7 @@ Field( item="5", name="STRATUM", + friendly_name="stratum", type="string", startIndex=22, endIndex=24, @@ -68,6 +73,7 @@ Field( item="7", name="ZIP_CODE", + friendly_name="zip code", type="string", startIndex=24, endIndex=29, @@ -77,6 +83,7 @@ Field( item="8", name="DISPOSITION", + friendly_name="disposition", type="number", startIndex=29, endIndex=30, @@ -86,19 +93,22 @@ Field( item="9", name="CLOSURE_REASON", + friendly_name="closure reason", type="string", startIndex=30, endIndex=32, required=True, validators=[ validators.or_validators( - validators.isInStringRange(1, 19), validators.matches("99") + validators.isInStringRange(1, 19), + validators.matches("99") ) ], ), Field( item="10", name="REC_SUB_HOUSING", + friendly_name="receives subsidized housing", type="number", startIndex=32, endIndex=33, @@ -108,6 +118,7 @@ Field( item="11", name="REC_MED_ASSIST", + friendly_name="receives medical assistance", type="number", startIndex=33, endIndex=34, @@ -117,6 +128,7 @@ Field( item="12", name="REC_FOOD_STAMPS", + friendly_name="receives food stamps", type="number", startIndex=34, endIndex=35, @@ -126,6 +138,7 @@ Field( item="13", name="REC_SUB_CC", + friendly_name="receives subsidized child care", type="number", startIndex=35, endIndex=36, @@ -135,6 +148,7 @@ Field( item="14", name="BLANK", + friendly_name="blank", type="string", startIndex=36, endIndex=71, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t5.py b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t5.py index 75eaea400..199c08f0c 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t5.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t5.py @@ -105,6 +105,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -114,6 +115,7 @@ Field( item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=8, @@ -126,6 +128,7 @@ Field( item="6", name="CASE_NUMBER", + friendly_name="case number", type="string", startIndex=8, endIndex=19, @@ -135,6 +138,7 @@ Field( item="14", name="FAMILY_AFFILIATION", + friendly_name="family affiliation", type="number", startIndex=19, endIndex=20, @@ -144,6 +148,7 @@ Field( item="15", name="DATE_OF_BIRTH", + friendly_name="date of birth", type="number", startIndex=20, endIndex=28, @@ -157,6 +162,7 @@ transform_func=tanf_ssn_decryption_func, item="16", name="SSN", + friendly_name="social security number", type="string", startIndex=28, endIndex=37, @@ -167,6 +173,7 @@ Field( item="17A", name="RACE_HISPANIC", + friendly_name="race hispanic", type="number", startIndex=37, endIndex=38, @@ -176,6 +183,7 @@ Field( item="17B", name="RACE_AMER_INDIAN", + friendly_name="race american-indian", type="number", startIndex=38, endIndex=39, @@ -185,6 +193,7 @@ Field( item="17C", name="RACE_ASIAN", + friendly_name="race asian", type="number", startIndex=39, endIndex=40, @@ -194,6 +203,7 @@ Field( item="17D", name="RACE_BLACK", + friendly_name="race black", type="number", startIndex=40, endIndex=41, @@ -203,6 +213,7 @@ Field( item="17E", name="RACE_HAWAIIAN", + friendly_name="race hawaiian", type="number", startIndex=41, endIndex=42, @@ -212,6 +223,7 @@ Field( item="17F", name="RACE_WHITE", + friendly_name="race white", type="number", startIndex=42, endIndex=43, @@ -221,6 +233,7 @@ Field( item="18", name="GENDER", + friendly_name="gender", type="number", startIndex=43, endIndex=44, @@ -230,6 +243,7 @@ Field( item="19A", name="REC_OASDI_INSURANCE", + friendly_name="receives old-age survivors and disability insurance", type="number", startIndex=44, endIndex=45, @@ -239,6 +253,7 @@ Field( item="19B", name="REC_FEDERAL_DISABILITY", + friendly_name="receives federal disability", type="number", startIndex=45, endIndex=46, @@ -248,6 +263,7 @@ Field( item="19C", name="REC_AID_TOTALLY_DISABLED", + friendly_name="receives aid for totally disabled", type="number", startIndex=46, endIndex=47, @@ -257,6 +273,7 @@ Field( item="19D", name="REC_AID_AGED_BLIND", + friendly_name="receives from the aid to the aged, blind, and disabled program", type="number", startIndex=47, endIndex=48, @@ -266,6 +283,7 @@ Field( item="19E", name="REC_SSI", + friendly_name="receives SSI", type="number", startIndex=48, endIndex=49, @@ -275,6 +293,7 @@ Field( item="20", name="MARITAL_STATUS", + friendly_name="marital status", type="number", startIndex=49, endIndex=50, @@ -284,6 +303,7 @@ Field( item="21", name="RELATIONSHIP_HOH", + friendly_name="relationship to head of household", type="string", startIndex=50, endIndex=52, @@ -293,6 +313,7 @@ Field( item="22", name="PARENT_MINOR_CHILD", + friendly_name="parent of minor child", type="number", startIndex=52, endIndex=53, @@ -302,6 +323,7 @@ Field( item="23", name="NEEDS_OF_PREGNANT_WOMAN", + friendly_name="needs of pregnant woman", type="number", startIndex=53, endIndex=54, @@ -311,6 +333,7 @@ Field( item="24", name="EDUCATION_LEVEL", + friendly_name="educational level", type="string", startIndex=54, endIndex=56, @@ -325,19 +348,22 @@ Field( item="25", name="CITIZENSHIP_STATUS", + friendly_name="citizenship status", type="number", startIndex=56, endIndex=57, required=True, validators=[ validators.or_validators( - validators.isInLimits(0, 2), validators.matches(9) + validators.isInLimits(0, 2), + validators.matches(9) ) ], ), Field( item="26", name="COUNTABLE_MONTH_FED_TIME", + friendly_name="countable months toward federal time", type="string", startIndex=57, endIndex=60, @@ -347,6 +373,7 @@ Field( item="27", name="COUNTABLE_MONTHS_STATE_TRIBE", + friendly_name="countable months remaining under state tribe", type="string", startIndex=60, endIndex=62, @@ -356,6 +383,7 @@ Field( item="28", name="EMPLOYMENT_STATUS", + friendly_name="employment status", type="number", startIndex=62, endIndex=63, @@ -365,6 +393,7 @@ Field( item="29", name="AMOUNT_EARNED_INCOME", + friendly_name="amount of earned income", type="string", startIndex=63, endIndex=67, @@ -374,6 +403,7 @@ Field( item="30", name="AMOUNT_UNEARNED_INCOME", + friendly_name="amount of unearned income", type="string", startIndex=67, endIndex=71, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t6.py b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t6.py index 46b0f0a95..77925781a 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t6.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t6.py @@ -15,18 +15,31 @@ validators.hasLength(379), ], postparsing_validators=[ - validators.sumIsEqual("NUM_APPLICATIONS", ["NUM_APPROVED", "NUM_DENIED"]), validators.sumIsEqual( - "NUM_FAMILIES", ["NUM_2_PARENTS", "NUM_1_PARENTS", "NUM_NO_PARENTS"] + "NUM_APPLICATIONS", [ + "NUM_APPROVED", + "NUM_DENIED" + ] ), validators.sumIsEqual( - "NUM_RECIPIENTS", ["NUM_ADULT_RECIPIENTS", "NUM_CHILD_RECIPIENTS"] + "NUM_FAMILIES", [ + "NUM_2_PARENTS", + "NUM_1_PARENTS", + "NUM_NO_PARENTS" + ] + ), + validators.sumIsEqual( + "NUM_RECIPIENTS", [ + "NUM_ADULT_RECIPIENTS", + "NUM_CHILD_RECIPIENTS" + ] ), ], fields=[ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -36,6 +49,7 @@ Field( item="3", name="CALENDAR_QUARTER", + friendly_name="calendar quarter", type="number", startIndex=2, endIndex=7, @@ -49,6 +63,7 @@ calendar_quarter_to_rpt_month_year(0), item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=7, @@ -61,6 +76,7 @@ Field( item="4A", name="NUM_APPLICATIONS", + friendly_name="total number of applications", type="number", startIndex=7, endIndex=15, @@ -70,6 +86,7 @@ Field( item="5A", name="NUM_APPROVED", + friendly_name="total number of approved applications", type="number", startIndex=31, endIndex=39, @@ -79,6 +96,7 @@ Field( item="6A", name="NUM_DENIED", + friendly_name="total number of denied applications", type="number", startIndex=55, endIndex=63, @@ -88,6 +106,7 @@ Field( item="7A", name="ASSISTANCE", + friendly_name="total amount of assistance", type="number", startIndex=79, endIndex=91, @@ -97,6 +116,7 @@ Field( item="8A", name="NUM_FAMILIES", + friendly_name="number of families", type="number", startIndex=115, endIndex=123, @@ -106,6 +126,7 @@ Field( item="9A", name="NUM_2_PARENTS", + friendly_name="number of two-parent families", type="number", startIndex=139, endIndex=147, @@ -115,6 +136,7 @@ Field( item="10A", name="NUM_1_PARENTS", + friendly_name="total number of one-parent families", type="number", startIndex=163, endIndex=171, @@ -124,6 +146,7 @@ Field( item="11A", name="NUM_NO_PARENTS", + friendly_name="total number of no-parent families", type="number", startIndex=187, endIndex=195, @@ -133,6 +156,7 @@ Field( item="12A", name="NUM_RECIPIENTS", + friendly_name="total number of recipients", type="number", startIndex=211, endIndex=219, @@ -142,6 +166,7 @@ Field( item="13A", name="NUM_ADULT_RECIPIENTS", + friendly_name="total number of adult recipients", type="number", startIndex=235, endIndex=243, @@ -151,6 +176,7 @@ Field( item="14A", name="NUM_CHILD_RECIPIENTS", + friendly_name="total number of child recipients", type="number", startIndex=259, endIndex=267, @@ -160,6 +186,7 @@ Field( item="15A", name="NUM_NONCUSTODIALS", + friendly_name="total number of noncustodial parents participating in work activities", type="number", startIndex=283, endIndex=291, @@ -169,6 +196,7 @@ Field( item="16A", name="NUM_BIRTHS", + friendly_name="total number of births", type="number", startIndex=307, endIndex=315, @@ -178,6 +206,7 @@ Field( item="17A", name="NUM_OUTWEDLOCK_BIRTHS", + friendly_name="total number of out-of-wedlock births", type="number", startIndex=331, endIndex=339, @@ -187,6 +216,7 @@ Field( item="18A", name="NUM_CLOSED_CASES", + friendly_name="total number of closed cases", type="number", startIndex=355, endIndex=363, @@ -202,18 +232,31 @@ validators.hasLength(379), ], postparsing_validators=[ - validators.sumIsEqual("NUM_APPLICATIONS", ["NUM_APPROVED", "NUM_DENIED"]), validators.sumIsEqual( - "NUM_FAMILIES", ["NUM_2_PARENTS", "NUM_1_PARENTS", "NUM_NO_PARENTS"] + "NUM_APPLICATIONS", [ + "NUM_APPROVED", + "NUM_DENIED" + ] + ), + validators.sumIsEqual( + "NUM_FAMILIES", [ + "NUM_2_PARENTS", + "NUM_1_PARENTS", + "NUM_NO_PARENTS" + ] ), validators.sumIsEqual( - "NUM_RECIPIENTS", ["NUM_ADULT_RECIPIENTS", "NUM_CHILD_RECIPIENTS"] + "NUM_RECIPIENTS", [ + "NUM_ADULT_RECIPIENTS", + "NUM_CHILD_RECIPIENTS" + ] ), ], fields=[ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -223,6 +266,7 @@ Field( item="3", name="CALENDAR_QUARTER", + friendly_name="calendar quarter", type="number", startIndex=2, endIndex=7, @@ -233,6 +277,7 @@ calendar_quarter_to_rpt_month_year(1), item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=7, @@ -242,6 +287,7 @@ Field( item="4B", name="NUM_APPLICATIONS", + friendly_name="total number of applications", type="number", startIndex=15, endIndex=23, @@ -251,6 +297,7 @@ Field( item="5B", name="NUM_APPROVED", + friendly_name="total number of approved cases", type="number", startIndex=39, endIndex=47, @@ -260,6 +307,7 @@ Field( item="6B", name="NUM_DENIED", + friendly_name="total number of denied", type="number", startIndex=63, endIndex=71, @@ -269,6 +317,7 @@ Field( item="7B", name="ASSISTANCE", + friendly_name="assistance", type="number", startIndex=91, endIndex=103, @@ -278,6 +327,7 @@ Field( item="8B", name="NUM_FAMILIES", + friendly_name="total of number of families", type="number", startIndex=123, endIndex=131, @@ -287,6 +337,7 @@ Field( item="9B", name="NUM_2_PARENTS", + friendly_name="number of two-parent families", type="number", startIndex=147, endIndex=155, @@ -296,6 +347,7 @@ Field( item="10B", name="NUM_1_PARENTS", + friendly_name="total number of one-parent families", type="number", startIndex=171, endIndex=179, @@ -305,6 +357,7 @@ Field( item="11B", name="NUM_NO_PARENTS", + friendly_name="total number of no-parent families", type="number", startIndex=195, endIndex=203, @@ -314,6 +367,7 @@ Field( item="12B", name="NUM_RECIPIENTS", + friendly_name="total number of recipients", type="number", startIndex=219, endIndex=227, @@ -323,6 +377,7 @@ Field( item="13B", name="NUM_ADULT_RECIPIENTS", + friendly_name="total number of adult recipients", type="number", startIndex=243, endIndex=251, @@ -332,6 +387,7 @@ Field( item="14B", name="NUM_CHILD_RECIPIENTS", + friendly_name="total number of child recipients", type="number", startIndex=267, endIndex=275, @@ -341,6 +397,7 @@ Field( item="15B", name="NUM_NONCUSTODIALS", + friendly_name="total number of noncustodial parents", type="number", startIndex=291, endIndex=299, @@ -350,6 +407,7 @@ Field( item="16B", name="NUM_BIRTHS", + friendly_name="total number of births", type="number", startIndex=315, endIndex=323, @@ -359,6 +417,7 @@ Field( item="17B", name="NUM_OUTWEDLOCK_BIRTHS", + friendly_name="total number of out-of-wedlock births", type="number", startIndex=339, endIndex=347, @@ -368,6 +427,7 @@ Field( item="18B", name="NUM_CLOSED_CASES", + friendly_name="total number of closed assets", type="number", startIndex=363, endIndex=371, @@ -383,18 +443,31 @@ validators.hasLength(379), ], postparsing_validators=[ - validators.sumIsEqual("NUM_APPLICATIONS", ["NUM_APPROVED", "NUM_DENIED"]), validators.sumIsEqual( - "NUM_FAMILIES", ["NUM_2_PARENTS", "NUM_1_PARENTS", "NUM_NO_PARENTS"] + "NUM_APPLICATIONS", [ + "NUM_APPROVED", + "NUM_DENIED" + ] + ), + validators.sumIsEqual( + "NUM_FAMILIES", [ + "NUM_2_PARENTS", + "NUM_1_PARENTS", + "NUM_NO_PARENTS" + ] ), validators.sumIsEqual( - "NUM_RECIPIENTS", ["NUM_ADULT_RECIPIENTS", "NUM_CHILD_RECIPIENTS"] + "NUM_RECIPIENTS", [ + "NUM_ADULT_RECIPIENTS", + "NUM_CHILD_RECIPIENTS" + ] ), ], fields=[ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -404,6 +477,7 @@ Field( item="3", name="CALENDAR_QUARTER", + friendly_name="calendar quarter", type="number", startIndex=2, endIndex=7, @@ -414,6 +488,7 @@ calendar_quarter_to_rpt_month_year(2), item="4", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=7, @@ -423,6 +498,7 @@ Field( item="4C", name="NUM_APPLICATIONS", + friendly_name="total number of applications", type="number", startIndex=23, endIndex=31, @@ -432,6 +508,7 @@ Field( item="5C", name="NUM_APPROVED", + friendly_name="total number of approved applications", type="number", startIndex=47, endIndex=55, @@ -441,6 +518,7 @@ Field( item="6C", name="NUM_DENIED", + friendly_name="total number of denied applications", type="number", startIndex=71, endIndex=79, @@ -450,6 +528,7 @@ Field( item="7C", name="ASSISTANCE", + friendly_name="total amount of assistance", type="number", startIndex=103, endIndex=115, @@ -459,6 +538,7 @@ Field( item="8C", name="NUM_FAMILIES", + friendly_name="total number of families", type="number", startIndex=131, endIndex=139, @@ -468,6 +548,7 @@ Field( item="9C", name="NUM_2_PARENTS", + friendly_name="number of two-parent families", type="number", startIndex=155, endIndex=163, @@ -477,6 +558,7 @@ Field( item="10C", name="NUM_1_PARENTS", + friendly_name="total number of one-parent families", type="number", startIndex=179, endIndex=187, @@ -486,6 +568,7 @@ Field( item="11C", name="NUM_NO_PARENTS", + friendly_name="total number of no-parent families", type="number", startIndex=203, endIndex=211, @@ -495,6 +578,7 @@ Field( item="12C", name="NUM_RECIPIENTS", + friendly_name="total number of recipients", type="number", startIndex=227, endIndex=235, @@ -504,6 +588,7 @@ Field( item="13C", name="NUM_ADULT_RECIPIENTS", + friendly_name="total number of adult recipients", type="number", startIndex=251, endIndex=259, @@ -513,6 +598,7 @@ Field( item="14C", name="NUM_CHILD_RECIPIENTS", + friendly_name="total number of child recipients", type="number", startIndex=275, endIndex=283, @@ -522,6 +608,7 @@ Field( item="15C", name="NUM_NONCUSTODIALS", + friendly_name="total number of noncustodial parents", type="number", startIndex=299, endIndex=307, @@ -531,6 +618,7 @@ Field( item="16C", name="NUM_BIRTHS", + friendly_name="total number of births", type="number", startIndex=323, endIndex=331, @@ -540,6 +628,7 @@ Field( item="17C", name="NUM_OUTWEDLOCK_BIRTHS", + friendly_name="total number of out-of-wedlock births", type="number", startIndex=347, endIndex=355, @@ -549,6 +638,7 @@ Field( item="18C", name="NUM_CLOSED_CASES", + friendly_name="total number of closed cases", type="number", startIndex=371, endIndex=379, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t7.py b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t7.py index ec09891b5..e6a05bb9a 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t7.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/tanf/t7.py @@ -32,6 +32,7 @@ Field( item="0", name="RecordType", + friendly_name="record type", type="string", startIndex=0, endIndex=2, @@ -41,6 +42,7 @@ Field( item="3", name="CALENDAR_QUARTER", + friendly_name="calendar quarter", type="number", startIndex=2, endIndex=7, @@ -54,6 +56,7 @@ transform_func=calendar_quarter_to_rpt_month_year(month_index), item="3A", name="RPT_MONTH_YEAR", + friendly_name="reporting month and year", type="number", startIndex=2, endIndex=7, @@ -66,6 +69,7 @@ Field( item="4", name="TDRS_SECTION_IND", + friendly_name="tdrs section indicator", type="string", startIndex=section_ind_index, endIndex=section_ind_index + 1, @@ -75,6 +79,7 @@ Field( item="5", name="STRATUM", + friendly_name="stratum", type="string", startIndex=stratum_index, endIndex=stratum_index + 2, @@ -84,6 +89,7 @@ Field( item=families_value_item_number, name="FAMILIES_MONTH", + friendly_name="families month", type="number", startIndex=families_index, endIndex=families_index + 7, diff --git a/tdrs-backend/tdpservice/parsers/schema_defs/trailer.py b/tdrs-backend/tdpservice/parsers/schema_defs/trailer.py index d1ad29da7..8b3325424 100644 --- a/tdrs-backend/tdpservice/parsers/schema_defs/trailer.py +++ b/tdrs-backend/tdpservice/parsers/schema_defs/trailer.py @@ -19,30 +19,39 @@ fields=[ Field( item="1", - name="title", - type="string", + name='title', + friendly_name='title', + type='string', startIndex=0, endIndex=7, required=True, - validators=[validators.matches("TRAILER")], + validators=[ + validators.matches('TRAILER') + ] ), Field( item="2", - name="record_count", - type="number", + name='record_count', + friendly_name='record count', + type='number', startIndex=7, endIndex=14, required=True, - validators=[validators.between(0, 9999999)], + validators=[ + validators.between(0, 9999999) + ] ), Field( item="-1", - name="blank", - type="string", + name='blank', + friendly_name='blank', + type='string', startIndex=14, endIndex=23, required=False, - validators=[validators.matches(" ")], + validators=[ + validators.matches(' ') + ] ), ], ) diff --git a/tdrs-backend/tdpservice/parsers/test/data/small_incorrect_file_cross_validator.txt b/tdrs-backend/tdpservice/parsers/test/data/small_incorrect_file_cross_validator.txt new file mode 100644 index 000000000..f01ab84d1 --- /dev/null +++ b/tdrs-backend/tdpservice/parsers/test/data/small_incorrect_file_cross_validator.txt @@ -0,0 +1,3 @@ +HEADER20204A06 TAN1 N +T12020101111111111223003403361110213120000300000000000008730000000000000000000000000000000000000222222000000002229012 +TRAILER0000001 \ No newline at end of file diff --git a/tdrs-backend/tdpservice/parsers/test/test_parse.py b/tdrs-backend/tdpservice/parsers/test/test_parse.py index d61f1cfc1..6b6a7489d 100644 --- a/tdrs-backend/tdpservice/parsers/test/test_parse.py +++ b/tdrs-backend/tdpservice/parsers/test/test_parse.py @@ -469,6 +469,14 @@ def test_parse_ssp_section1_datafile(ssp_section1_datafile): parse.parse_datafile(ssp_section1_datafile) parser_errors = ParserError.objects.filter(file=ssp_section1_datafile) + + err = parser_errors.first() + + assert err.row_number == 2 + assert err.error_type == ParserErrorCategoryChoices.FIELD_VALUE + assert err.error_message == '3 is not larger or equal to 1 and smaller or equal to 2.' + assert err.content_type is not None + assert err.object_id is not None assert parser_errors.count() == 19846 assert SSP_M1.objects.count() == expected_m1_record_count diff --git a/tdrs-backend/tdpservice/parsers/test/test_util.py b/tdrs-backend/tdpservice/parsers/test/test_util.py index d7b2afc0e..5bb8c72e2 100644 --- a/tdrs-backend/tdpservice/parsers/test/test_util.py +++ b/tdrs-backend/tdpservice/parsers/test/test_util.py @@ -3,7 +3,7 @@ import pytest from ..fields import Field from ..row_schema import RowSchema -from ..util import SchemaManager +from ..util import SchemaManager, make_generate_parser_error, create_test_datafile def passing_validator(): @@ -15,6 +15,14 @@ def failing_validator(): """Fake validator that always returns invalid.""" return lambda _: (False, 'Value is not valid.') +def passing_postparsing_validator(): + """Fake validator that always returns valid.""" + return lambda _: (True, None, []) + + +def failing_postparsing_validator(): + """Fake validator that always returns invalid.""" + return lambda _: (False, 'Value is not valid.', []) def error_func(schema, error_category, error_message, record, field): """Fake error func that returns an error_message.""" @@ -56,11 +64,11 @@ def test_parse_line_parses_line_from_schema_to_dict(): schema = RowSchema( model=dict, fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=3), - Field(item=2, name='second', type='string', startIndex=3, endIndex=4), - Field(item=3, name='third', type='string', startIndex=4, endIndex=5), - Field(item=4, name='fourth', type='number', startIndex=5, endIndex=7), - Field(item=5, name='fifth', type='number', startIndex=7, endIndex=8), + Field(item=1, name='first', friendly_name='first', type='string', startIndex=0, endIndex=3), + Field(item=2, name='second', friendly_name='second', type='string', startIndex=3, endIndex=4), + Field(item=3, name='third', friendly_name='third', type='string', startIndex=4, endIndex=5), + Field(item=4, name='fourth', friendly_name='fourth', type='number', startIndex=5, endIndex=7), + Field(item=5, name='fifth', friendly_name='fifth', type='number', startIndex=7, endIndex=8), ] ) @@ -86,11 +94,11 @@ class TestModel: schema = RowSchema( model=TestModel, fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=3), - Field(item=2, name='second', type='string', startIndex=3, endIndex=4), - Field(item=3, name='third', type='string', startIndex=4, endIndex=5), - Field(item=4, name='fourth', type='number', startIndex=5, endIndex=7), - Field(item=5, name='fifth', type='number', startIndex=7, endIndex=8), + Field(item=1, name='first', friendly_name='first', type='string', startIndex=0, endIndex=3), + Field(item=2, name='second', friendly_name='second', type='string', startIndex=3, endIndex=4), + Field(item=3, name='third', friendly_name='third', type='string', startIndex=4, endIndex=5), + Field(item=4, name='fourth', friendly_name='fourth', type='number', startIndex=5, endIndex=7), + Field(item=5, name='fifth', friendly_name='fifth', type='number', startIndex=7, endIndex=8), ] ) @@ -113,13 +121,13 @@ def test_run_field_validators_returns_valid_with_dict(): schema = RowSchema( model=dict, fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=3, validators=[ + Field(item=1, name='first', friendly_name='first', type='string', startIndex=0, endIndex=3, validators=[ passing_validator() ]), - Field(item=2, name='second', type='string', startIndex=3, endIndex=4, validators=[ + Field(item=2, name='second', friendly_name='second', type='string', startIndex=3, endIndex=4, validators=[ passing_validator() ]), - Field(item=3, name='third', type='string', startIndex=4, endIndex=5, validators=[ + Field(item=3, name='third', friendly_name='third', type='string', startIndex=4, endIndex=5, validators=[ passing_validator() ]), ] @@ -145,13 +153,13 @@ class TestModel: schema = RowSchema( model=TestModel, fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=3, validators=[ + Field(item=1, name='first', friendly_name='first', type='string', startIndex=0, endIndex=3, validators=[ passing_validator() ]), - Field(item=2, name='second', type='string', startIndex=3, endIndex=4, validators=[ + Field(item=2, name='second', friendly_name='second', type='string', startIndex=3, endIndex=4, validators=[ passing_validator() ]), - Field(item=3, name='third', type='string', startIndex=4, endIndex=5, validators=[ + Field(item=3, name='third', friendly_name='third', type='string', startIndex=4, endIndex=5, validators=[ passing_validator() ]), ] @@ -172,14 +180,14 @@ def test_run_field_validators_returns_invalid_with_dict(): schema = RowSchema( model=dict, fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=3, validators=[ + Field(item=1, name='first', friendly_name='first', type='string', startIndex=0, endIndex=3, validators=[ passing_validator(), failing_validator() ]), - Field(item=2, name='second', type='string', startIndex=3, endIndex=4, validators=[ + Field(item=2, name='second', friendly_name='second', type='string', startIndex=3, endIndex=4, validators=[ passing_validator() ]), - Field(item=3, name='third', type='string', startIndex=4, endIndex=5, validators=[ + Field(item=3, name='third', friendly_name='third', type='string', startIndex=4, endIndex=5, validators=[ passing_validator() ]), ] @@ -205,14 +213,14 @@ class TestModel: schema = RowSchema( model=TestModel, fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=3, validators=[ + Field(item=1, name='first', friendly_name='first', type='string', startIndex=0, endIndex=3, validators=[ passing_validator(), failing_validator() ]), - Field(item=2, name='second', type='string', startIndex=3, endIndex=4, validators=[ + Field(item=2, name='second', friendly_name='second', type='string', startIndex=3, endIndex=4, validators=[ passing_validator() ]), - Field(item=3, name='third', type='string', startIndex=4, endIndex=5, validators=[ + Field(item=3, name='third', friendly_name='third', type='string', startIndex=4, endIndex=5, validators=[ passing_validator() ]), ] @@ -238,12 +246,30 @@ def test_field_validators_blank_and_required_returns_error(first, second): schema = RowSchema( model=dict, fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=1, required=True, validators=[ - passing_validator(), - ]), - Field(item=2, name='second', type='string', startIndex=1, endIndex=3, required=True, validators=[ - passing_validator(), - ]), + Field( + item=1, + name='first', + friendly_name='first', + type='string', + startIndex=0, + endIndex=1, + required=True, + validators=[ + passing_validator(), + ] + ), + Field( + item=2, + name='second', + friendly_name='second', + type='string', + startIndex=1, + endIndex=3, + required=True, + validators=[ + passing_validator(), + ] + ), ] ) @@ -255,12 +281,12 @@ def test_field_validators_blank_and_required_returns_error(first, second): ] -@pytest.mark.parametrize('first', [ - (' '), - ('#'), - (None), +@pytest.mark.parametrize('first, expected_valid, expected_errors', [ + (' ', True, []), + ('####', False, ['Value is not valid.']), + (None, True, []), ]) -def test_field_validators_blank_and_not_required_returns_valid(first): +def test_field_validators_blank_and_not_required_returns_valid(first, expected_valid, expected_errors): """Test not required field returns valid if value not provided (blank).""" instance = { 'first': first, @@ -268,16 +294,25 @@ def test_field_validators_blank_and_not_required_returns_valid(first): schema = RowSchema( model=dict, fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=1, required=False, validators=[ - passing_validator(), - failing_validator() - ]), + Field( + item=1, + name='first', + friendly_name='first', + type='string', + startIndex=0, + endIndex=3, + required=False, + validators=[ + passing_validator(), + failing_validator() + ] + ), ] ) is_valid, errors = schema.run_field_validators(instance, error_func) - assert is_valid is True - assert errors == [] + assert is_valid is expected_valid + assert errors == expected_errors def test_run_postparsing_validators_returns_valid(): @@ -285,7 +320,7 @@ def test_run_postparsing_validators_returns_valid(): instance = {} schema = RowSchema( postparsing_validators=[ - passing_validator() + passing_postparsing_validator() ] ) @@ -299,8 +334,8 @@ def test_run_postparsing_validators_returns_invalid_and_errors(): instance = {} schema = RowSchema( postparsing_validators=[ - passing_validator(), - failing_validator() + passing_postparsing_validator(), + failing_postparsing_validator() ] ) @@ -320,12 +355,18 @@ def test_multi_record_schema_parses_and_validates(): passing_validator() ], postparsing_validators=[ - failing_validator() + failing_postparsing_validator() ], fields=[ - Field(item=1, name='first', type='string', startIndex=0, endIndex=3, validators=[ - passing_validator() - ]), + Field( + item=1, + name='first', + friendly_name='first', + type='string', + startIndex=0, + endIndex=3, + validators=[passing_validator()] + ), ] ), RowSchema( @@ -334,12 +375,17 @@ def test_multi_record_schema_parses_and_validates(): passing_validator() ], postparsing_validators=[ - passing_validator() + passing_postparsing_validator() ], fields=[ - Field(item=2, name='second', type='string', startIndex=2, endIndex=4, validators=[ - passing_validator() - ]), + Field( + item=2, + name='second', + friendly_name='second', + type='string', + startIndex=2, + endIndex=4, + validators=[passing_validator()]), ] ), RowSchema( @@ -348,12 +394,18 @@ def test_multi_record_schema_parses_and_validates(): failing_validator() ], postparsing_validators=[ - passing_validator() + passing_postparsing_validator() ], fields=[ - Field(item=3, name='third', type='string', startIndex=4, endIndex=5, validators=[ - passing_validator() - ]), + Field( + item=3, + name='third', + friendly_name='third', + type='string', + startIndex=4, + endIndex=5, + validators=[passing_validator()] + ), ] ), RowSchema( @@ -362,12 +414,18 @@ def test_multi_record_schema_parses_and_validates(): passing_validator() ], postparsing_validators=[ - passing_validator() + passing_postparsing_validator() ], fields=[ - Field(item=4, name='fourth', type='string', startIndex=4, endIndex=5, validators=[ - failing_validator() - ]), + Field( + item=4, + name='fourth', + friendly_name='fourth', + type='string', + startIndex=4, + endIndex=5, + validators=[failing_validator()] + ), ] ) ] @@ -395,3 +453,53 @@ def test_multi_record_schema_parses_and_validates(): assert r3_record == {'fourth': '5'} assert r3_is_valid is False assert r3_errors == ['Value is not valid.'] + +@pytest.fixture +def test_datafile_empty_file(stt_user, stt): + """Fixture for small_correct_file.""" + return create_test_datafile('empty_file', stt_user, stt) + +@pytest.mark.django_db() +def test_run_postparsing_validators_returns_frinedly_fieldnames(test_datafile_empty_file): + """Test run_postparsing_validators executes all postparsing_validators provided in schema.""" + + def postparse_validator(): + """Fake validator that always returns valid.""" + return lambda _: (False, "an Error", ["FIRST", "SECOND"]) + + instance = {} + schema = RowSchema( + model=dict, + postparsing_validators=[ + postparse_validator() + ], + fields=[ + Field( + item=1, + name='FIRST', + friendly_name='first', + type='string', + startIndex=0, + endIndex=3, + required=False, + validators=[] + ), + Field( + item=2, + name='SECOND', + friendly_name='second', + type='string', + startIndex=3, + endIndex=4, + required=False, + validators=[] + ), + ] + ) + + is_valid, errors = schema.run_postparsing_validators(instance, make_generate_parser_error( + test_datafile_empty_file, 10 + )) + assert is_valid is False + assert errors[0].fields_json == {'friendly_name': {'FIRST': 'first', 'SECOND': 'second'}} + assert errors[0].error_message == "an Error" diff --git a/tdrs-backend/tdpservice/parsers/test/test_validators.py b/tdrs-backend/tdpservice/parsers/test/test_validators.py index 79e52518b..dc65d2745 100644 --- a/tdrs-backend/tdpservice/parsers/test/test_validators.py +++ b/tdrs-backend/tdpservice/parsers/test/test_validators.py @@ -68,14 +68,14 @@ def test_if_validators(): condition_field="Field1", condition_function=validators.matches('1'), result_field="Field2", result_function=validators.matches('2'), ) - assert validator(value) == (True, None) + assert validator(value) == (True, None, ['Field1', 'Field2']) validator = validator = validators.if_then_validator( condition_field="Field1", condition_function=validators.matches('1'), result_field="Field2", result_function=validators.matches('1'), ) result = validator(value) - assert result == (False, 'if Field1 :1 validator1 passed then Field2 2 does not match 1.') + assert result == (False, 'if Field1 :1 validator1 passed then Field2 2 does not match 1.', ['Field1', 'Field2']) def test_and_validators(): @@ -94,10 +94,11 @@ def test_validate__FAM_AFF__SSN(): } result = validators.validate__FAM_AFF__SSN()(instance) assert result == (False, - 'If FAMILY_AFFILIATION ==2 and CITIZENSHIP_STATUS==1 or 2, then SSN != 000000000 -- 999999999.') + 'If FAMILY_AFFILIATION ==2 and CITIZENSHIP_STATUS==1 or 2, then SSN != 000000000 -- 999999999.', + ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS', 'SSN']) instance['SSN'] = '1'*8 + '0' result = validators.validate__FAM_AFF__SSN()(instance) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS', 'SSN']) def test_dateYearIsLargerThan(): """Test `dateYearIsLargerThan` gives a valid result.""" @@ -365,12 +366,13 @@ def test_validate_food_stamps(self, record): record.RECEIVES_FOOD_STAMPS = 1 record.AMT_FOOD_STAMP_ASSISTANCE = 1 result = val(record) - assert result == (True, None) + assert result == (True, None, ['RECEIVES_FOOD_STAMPS', 'AMT_FOOD_STAMP_ASSISTANCE']) record.AMT_FOOD_STAMP_ASSISTANCE = 0 result = val(record) assert result == (False, 'if RECEIVES_FOOD_STAMPS :1 validator1 passed then ' - + 'AMT_FOOD_STAMP_ASSISTANCE 0 is not larger than 0.') + + 'AMT_FOOD_STAMP_ASSISTANCE 0 is not larger than 0.', + ['RECEIVES_FOOD_STAMPS', 'AMT_FOOD_STAMP_ASSISTANCE']) def test_validate_subsidized_child_care(self, record): """Test cat3 validator for subsidized child care.""" @@ -381,12 +383,13 @@ def test_validate_subsidized_child_care(self, record): record.RECEIVES_SUB_CC = 4 record.AMT_SUB_CC = 1 result = val(record) - assert result == (True, None) + assert result == (True, None, ['RECEIVES_SUB_CC', 'AMT_SUB_CC']) record.RECEIVES_SUB_CC = 4 record.AMT_SUB_CC = 0 result = val(record) - assert result == (False, 'if RECEIVES_SUB_CC :4 validator1 passed then AMT_SUB_CC 0 is not larger than 0.') + assert result == (False, 'if RECEIVES_SUB_CC :4 validator1 passed then AMT_SUB_CC 0 is not larger than 0.', + ['RECEIVES_SUB_CC', 'AMT_SUB_CC']) def test_validate_cash_amount_and_nbr_months(self, record): """Test cat3 validator for cash amount and number of months.""" @@ -395,12 +398,13 @@ def test_validate_cash_amount_and_nbr_months(self, record): result_field='NBR_MONTHS', result_function=validators.isLargerThan(0), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['CASH_AMOUNT', 'NBR_MONTHS']) record.CASH_AMOUNT = 1 record.NBR_MONTHS = -1 result = val(record) - assert result == (False, 'if CASH_AMOUNT :1 validator1 passed then NBR_MONTHS -1 is not larger than 0.') + assert result == (False, 'if CASH_AMOUNT :1 validator1 passed then NBR_MONTHS -1 is not larger than 0.', + ['CASH_AMOUNT', 'NBR_MONTHS']) def test_validate_child_care(self, record): """Test cat3 validator for child care.""" @@ -409,12 +413,13 @@ def test_validate_child_care(self, record): result_field='CHILDREN_COVERED', result_function=validators.isLargerThan(0), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['CC_AMOUNT', 'CHILDREN_COVERED']) record.CC_AMOUNT = 1 record.CHILDREN_COVERED = -1 result = val(record) - assert result == (False, 'if CC_AMOUNT :1 validator1 passed then CHILDREN_COVERED -1 is not larger than 0.') + assert result == (False, 'if CC_AMOUNT :1 validator1 passed then CHILDREN_COVERED -1 is not larger than 0.', + ['CC_AMOUNT', 'CHILDREN_COVERED']) val = validators.if_then_validator( condition_field='CC_AMOUNT', condition_function=validators.isLargerThan(0), @@ -423,7 +428,8 @@ def test_validate_child_care(self, record): record.CC_AMOUNT = 10 record.CC_NBR_MONTHS = -1 result = val(record) - assert result == (False, 'if CC_AMOUNT :10 validator1 passed then CC_NBR_MONTHS -1 is not larger than 0.') + assert result == (False, 'if CC_AMOUNT :10 validator1 passed then CC_NBR_MONTHS -1 is not larger than 0.', + ['CC_AMOUNT', 'CC_NBR_MONTHS']) def test_validate_transportation(self, record): """Test cat3 validator for transportation.""" @@ -432,13 +438,14 @@ def test_validate_transportation(self, record): result_field='TRANSP_NBR_MONTHS', result_function=validators.isLargerThan(0), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['TRANSP_AMOUNT', 'TRANSP_NBR_MONTHS']) record.TRANSP_AMOUNT = 1 record.TRANSP_NBR_MONTHS = -1 result = val(record) assert result == (False, 'if TRANSP_AMOUNT :1 validator1 passed then ' - + 'TRANSP_NBR_MONTHS -1 is not larger than 0.') + + 'TRANSP_NBR_MONTHS -1 is not larger than 0.', + ['TRANSP_AMOUNT', 'TRANSP_NBR_MONTHS']) def test_validate_transitional_services(self, record): """Test cat3 validator for transitional services.""" @@ -447,13 +454,14 @@ def test_validate_transitional_services(self, record): result_field='TRANSITION_NBR_MONTHS', result_function=validators.isLargerThan(0), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['TRANSITION_SERVICES_AMOUNT', 'TRANSITION_NBR_MONTHS']) record.TRANSITION_SERVICES_AMOUNT = 1 record.TRANSITION_NBR_MONTHS = -1 result = val(record) assert result == (False, 'if TRANSITION_SERVICES_AMOUNT :1 validator1 passed then ' - + 'TRANSITION_NBR_MONTHS -1 is not larger than 0.') + + 'TRANSITION_NBR_MONTHS -1 is not larger than 0.', + ['TRANSITION_SERVICES_AMOUNT', 'TRANSITION_NBR_MONTHS']) def test_validate_other(self, record): """Test cat3 validator for other.""" @@ -462,12 +470,13 @@ def test_validate_other(self, record): result_field='OTHER_NBR_MONTHS', result_function=validators.isLargerThan(0), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['OTHER_AMOUNT', 'OTHER_NBR_MONTHS']) record.OTHER_AMOUNT = 1 record.OTHER_NBR_MONTHS = -1 result = val(record) - assert result == (False, 'if OTHER_AMOUNT :1 validator1 passed then OTHER_NBR_MONTHS -1 is not larger than 0.') + assert result == (False, 'if OTHER_AMOUNT :1 validator1 passed then OTHER_NBR_MONTHS -1 is not larger than 0.', + ['OTHER_AMOUNT', 'OTHER_NBR_MONTHS']) def test_validate_reasons_for_amount_of_assistance_reductions(self, record): """Test cat3 validator for assistance reductions.""" @@ -477,20 +486,22 @@ def test_validate_reasons_for_amount_of_assistance_reductions(self, record): ) record.SANC_REDUCTION_AMT = 1 result = val(record) - assert result == (True, None) + assert result == (True, None, ['SANC_REDUCTION_AMT', 'WORK_REQ_SANCTION']) record.SANC_REDUCTION_AMT = 10 record.WORK_REQ_SANCTION = -1 result = val(record) assert result == (False, 'if SANC_REDUCTION_AMT :10 validator1 passed then ' - + 'WORK_REQ_SANCTION -1 is not in (1, 2).') + + 'WORK_REQ_SANCTION -1 is not in (1, 2).', + ['SANC_REDUCTION_AMT', 'WORK_REQ_SANCTION']) def test_validate_sum(self, record): """Test cat3 validator for sum of cash fields.""" val = validators.sumIsLarger(("AMT_FOOD_STAMP_ASSISTANCE", "AMT_SUB_CC", "CC_AMOUNT", "TRANSP_AMOUNT", "TRANSITION_SERVICES_AMOUNT", "OTHER_AMOUNT"), 0) result = val(record) - assert result == (True, None) + assert result == (True, None, ['AMT_FOOD_STAMP_ASSISTANCE', 'AMT_SUB_CC', 'CC_AMOUNT', 'TRANSP_AMOUNT', + 'TRANSITION_SERVICES_AMOUNT', 'OTHER_AMOUNT']) record.AMT_FOOD_STAMP_ASSISTANCE = 0 record.AMT_SUB_CC = 0 @@ -500,7 +511,9 @@ def test_validate_sum(self, record): record.OTHER_AMOUNT = 0 result = val(record) assert result == (False, "The sum of ('AMT_FOOD_STAMP_ASSISTANCE', 'AMT_SUB_CC', 'CC_AMOUNT', " + - "'TRANSP_AMOUNT', 'TRANSITION_SERVICES_AMOUNT', 'OTHER_AMOUNT') is not larger than 0.") + "'TRANSP_AMOUNT', 'TRANSITION_SERVICES_AMOUNT', 'OTHER_AMOUNT') is not larger than 0.", + ['AMT_FOOD_STAMP_ASSISTANCE', 'AMT_SUB_CC', 'CC_AMOUNT', 'TRANSP_AMOUNT', + 'TRANSITION_SERVICES_AMOUNT', 'OTHER_AMOUNT']) class TestT2Cat3Validators(TestCat3ValidatorsBase): @@ -523,7 +536,7 @@ def test_validate_ssn(self, record): record.SSN = "999989999" record.FAMILY_AFFILIATION = 1 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'SSN']) record.FAMILY_AFFILIATION = 1 record.SSN = "999999999" @@ -531,7 +544,7 @@ def test_validate_ssn(self, record): assert result == (False, "if FAMILY_AFFILIATION :1 validator1 passed then " + "SSN 999999999 is in ('000000000', '111111111', " + "'222222222', '333333333', '444444444', '555555555', '666666666', '777777777', '888888888'," + - " '999999999').") + " '999999999').", ['FAMILY_AFFILIATION', 'SSN']) def test_validate_race_ethnicity(self, record): """Test cat3 validator for race/ethnicity.""" @@ -543,7 +556,7 @@ def test_validate_race_ethnicity(self, record): result_field=race, result_function=validators.isInLimits(1, 2), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', race]) record.FAMILY_AFFILIATION = 0 for race in races: @@ -552,7 +565,7 @@ def test_validate_race_ethnicity(self, record): result_field=race, result_function=validators.isInLimits(1, 2) ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', race]) def test_validate_marital_status(self, record): """Test cat3 validator for marital status.""" @@ -562,13 +575,13 @@ def test_validate_marital_status(self, record): ) record.FAMILY_AFFILIATION = 1 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'MARITAL_STATUS']) record.FAMILY_AFFILIATION = 3 record.MARITAL_STATUS = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :3 validator1 passed then MARITAL_STATUS 0 is not larger or ' + - 'equal to 1 and smaller or equal to 5.') + 'equal to 1 and smaller or equal to 5.', ['FAMILY_AFFILIATION', 'MARITAL_STATUS']) def test_validate_parent_with_minor(self, record): """Test cat3 validator for parent with a minor child.""" @@ -577,12 +590,13 @@ def test_validate_parent_with_minor(self, record): result_field='PARENT_WITH_MINOR_CHILD', result_function=validators.isInLimits(1, 3), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'PARENT_WITH_MINOR_CHILD']) record.PARENT_WITH_MINOR_CHILD = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then PARENT_WITH_MINOR_CHILD 0 is not ' + - 'larger or equal to 1 and smaller or equal to 3.') + 'larger or equal to 1 and smaller or equal to 3.', + ['FAMILY_AFFILIATION', 'PARENT_WITH_MINOR_CHILD']) def test_validate_education_level(self, record): """Test cat3 validator for education level.""" @@ -595,14 +609,15 @@ def test_validate_education_level(self, record): ) record.FAMILY_AFFILIATION = 3 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'EDUCATION_LEVEL']) record.FAMILY_AFFILIATION = 1 record.EDUCATION_LEVEL = "00" result = val(record) assert result == (False, "if FAMILY_AFFILIATION :1 validator1 passed then " + "EDUCATION_LEVEL 00 is not in ('01', '02', '03', '04', '05', '06'," - + " '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '98', '99').") + + " '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '98', '99').", + ['FAMILY_AFFILIATION', 'EDUCATION_LEVEL']) def test_validate_citizenship(self, record): """Test cat3 validator for citizenship.""" @@ -612,13 +627,13 @@ def test_validate_citizenship(self, record): ) record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) record.FAMILY_AFFILIATION = 1 record.CITIZENSHIP_STATUS = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then CITIZENSHIP_STATUS 0 ' + - 'is not in (1, 2).') + 'is not in (1, 2).', ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) def test_validate_cooperation_with_child_support(self, record): """Test cat3 validator for cooperation with child support.""" @@ -628,13 +643,13 @@ def test_validate_cooperation_with_child_support(self, record): ) record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'COOPERATION_CHILD_SUPPORT']) record.FAMILY_AFFILIATION = 1 record.COOPERATION_CHILD_SUPPORT = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then COOPERATION_CHILD_SUPPORT 0 ' + - 'is not in (1, 2, 9).') + 'is not in (1, 2, 9).', ['FAMILY_AFFILIATION', 'COOPERATION_CHILD_SUPPORT']) def test_validate_months_federal_time_limit(self, record): """Test cat3 validator for federal time limit.""" @@ -642,14 +657,15 @@ def test_validate_months_federal_time_limit(self, record): val = validators.validate__FAM_AFF__HOH__Fed_Time() record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'RELATIONSHIP_HOH', 'MONTHS_FED_TIME_LIMIT']) record.FAMILY_AFFILIATION = 1 record.MONTHS_FED_TIME_LIMIT = "000" record.RELATIONSHIP_HOH = "01" result = val(record) assert result == (False, 'If FAMILY_AFFILIATION == 2 and MONTHS_FED_TIME_LIMIT== 1 or 2, ' + - 'then MONTHS_FED_TIME_LIMIT > 1.') + 'then MONTHS_FED_TIME_LIMIT > 1.', + ['FAMILY_AFFILIATION', 'MONTHS_FED_TIME_LIMIT']) def test_validate_employment_status(self, record): """Test cat3 validator for employment status.""" @@ -659,13 +675,13 @@ def test_validate_employment_status(self, record): ) record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'EMPLOYMENT_STATUS']) record.FAMILY_AFFILIATION = 3 record.EMPLOYMENT_STATUS = 4 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :3 validator1 passed then EMPLOYMENT_STATUS 4 is not larger ' + - 'or equal to 1 and smaller or equal to 3.') + 'or equal to 1 and smaller or equal to 3.', ['FAMILY_AFFILIATION', 'EMPLOYMENT_STATUS']) def test_validate_work_eligible_indicator(self, record): """Test cat3 validator for work eligibility.""" @@ -678,13 +694,14 @@ def test_validate_work_eligible_indicator(self, record): ) record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'WORK_ELIGIBLE_INDICATOR']) record.FAMILY_AFFILIATION = 1 record.WORK_ELIGIBLE_INDICATOR = "00" result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then WORK_ELIGIBLE_INDICATOR 00 is not ' + - 'in range [1, 9]. or 00 does not match 12.') + 'in range [1, 9]. or 00 does not match 12.', + ['FAMILY_AFFILIATION', 'WORK_ELIGIBLE_INDICATOR']) def test_validate_work_participation(self, record): """Test cat3 validator for work participation.""" @@ -696,13 +713,14 @@ def test_validate_work_participation(self, record): ) record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'WORK_PART_STATUS']) record.FAMILY_AFFILIATION = 2 record.WORK_PART_STATUS = "04" result = val(record) assert result == (False, "if FAMILY_AFFILIATION :2 validator1 passed then WORK_PART_STATUS 04 is not " + - "in ['01', '02', '05', '07', '09', '15', '17', '18', '19', '99'].") + "in ['01', '02', '05', '07', '09', '15', '17', '18', '19', '99'].", + ['FAMILY_AFFILIATION', 'WORK_PART_STATUS']) val = validators.if_then_validator( condition_field='WORK_ELIGIBLE_INDICATOR', condition_function=validators.isInStringRange(1, 5), @@ -712,7 +730,7 @@ def test_validate_work_participation(self, record): record.WORK_ELIGIBLE_INDICATOR = "01" result = val(record) assert result == (False, 'if WORK_ELIGIBLE_INDICATOR :01 validator1 passed then ' - + 'WORK_PART_STATUS 99 matches 99.') + + 'WORK_PART_STATUS 99 matches 99.', ['WORK_ELIGIBLE_INDICATOR', 'WORK_PART_STATUS']) class TestT3Cat3Validators(TestCat3ValidatorsBase): @@ -732,13 +750,13 @@ def test_validate_ssn(self, record): result_field='SSN', result_function=validators.notOneOf(("999999999", "000000000")), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'SSN']) record.FAMILY_AFFILIATION = 1 record.SSN = "999999999" result = val(record) assert result == (False, "if FAMILY_AFFILIATION :1 validator1 passed then " - + "SSN 999999999 is in ('999999999', '000000000').") + + "SSN 999999999 is in ('999999999', '000000000').", ['FAMILY_AFFILIATION', 'SSN']) def test_validate_t3_race_ethnicity(self, record): """Test cat3 validator for race/ethnicity.""" @@ -750,7 +768,7 @@ def test_validate_t3_race_ethnicity(self, record): result_field=race, result_function=validators.oneOf((1, 2)), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', race]) record.FAMILY_AFFILIATION = 0 for race in races: @@ -759,7 +777,7 @@ def test_validate_t3_race_ethnicity(self, record): result_field=race, result_function=validators.oneOf((1, 2)), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', race]) def test_validate_relationship_hoh(self, record): """Test cat3 validator for relationship to head of household.""" @@ -770,13 +788,13 @@ def test_validate_relationship_hoh(self, record): record.FAMILY_AFFILIATION = 0 record.RELATIONSHIP_HOH = "04" result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'RELATIONSHIP_HOH']) record.FAMILY_AFFILIATION = 1 record.RELATIONSHIP_HOH = "01" result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then RELATIONSHIP_HOH 01 is ' + - 'not in range [4, 9].') + 'not in range [4, 9].', ['FAMILY_AFFILIATION', 'RELATIONSHIP_HOH']) def test_validate_t3_education_level(self, record): """Test cat3 validator for education level.""" @@ -786,12 +804,13 @@ def test_validate_t3_education_level(self, record): ) record.FAMILY_AFFILIATION = 1 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'EDUCATION_LEVEL']) record.FAMILY_AFFILIATION = 1 record.EDUCATION_LEVEL = "99" result = val(record) - assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then EDUCATION_LEVEL 99 matches 99.') + assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then EDUCATION_LEVEL 99 matches 99.', + ['FAMILY_AFFILIATION', 'EDUCATION_LEVEL']) def test_validate_t3_citizenship(self, record): """Test cat3 validator for citizenship.""" @@ -801,13 +820,13 @@ def test_validate_t3_citizenship(self, record): ) record.FAMILY_AFFILIATION = 1 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) record.FAMILY_AFFILIATION = 1 record.CITIZENSHIP_STATUS = 3 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then CITIZENSHIP_STATUS 3 ' + - 'is not in (1, 2).') + 'is not in (1, 2).', ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) val = validators.if_then_validator( condition_field='FAMILY_AFFILIATION', condition_function=validators.matches(2), @@ -817,7 +836,7 @@ def test_validate_t3_citizenship(self, record): record.CITIZENSHIP_STATUS = 3 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :2 validator1 passed then CITIZENSHIP_STATUS 3 ' + - 'is not in (1, 2, 9).') + 'is not in (1, 2, 9).', ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) class TestT5Cat3Validators(TestCat3ValidatorsBase): @@ -836,27 +855,28 @@ def test_validate_ssn(self, record): ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'SSN']) record.SSN = "abc" record.FAMILY_AFFILIATION = 2 result = val(record) - assert result == (False, 'if FAMILY_AFFILIATION :2 validator1 passed then SSN abc is not a number.') + assert result == (False, 'if FAMILY_AFFILIATION :2 validator1 passed then SSN abc is not a number.', + ['FAMILY_AFFILIATION', 'SSN']) def test_validate_ssn_citizenship(self, record): """Test cat3 validator for SSN/citizenship.""" val = validators.validate__FAM_AFF__SSN() result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS', 'SSN']) record.FAMILY_AFFILIATION = 2 record.SSN = "000000000" result = val(record) assert result == (False, "If FAMILY_AFFILIATION ==2 and CITIZENSHIP_STATUS==1 or 2, then SSN " + - "!= 000000000 -- 999999999.") + "!= 000000000 -- 999999999.", ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS', 'SSN']) def test_validate_race_ethnicity(self, record): """Test cat3 validator for race/ethnicity.""" @@ -868,7 +888,7 @@ def test_validate_race_ethnicity(self, record): result_field='RACE_HISPANIC', result_function=validators.isInLimits(1, 2) ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'RACE_HISPANIC']) record.FAMILY_AFFILIATION = 1 record.RACE_HISPANIC = 0 @@ -884,7 +904,8 @@ def test_validate_race_ethnicity(self, record): ) result = val(record) assert result == (False, f'if FAMILY_AFFILIATION :1 validator1 passed then {race} 0 is not larger or ' + - 'equal to 1 and smaller or equal to 2.') + 'equal to 1 and smaller or equal to 2.', + ['FAMILY_AFFILIATION', race]) def test_validate_marital_status(self, record): """Test cat3 validator for marital status.""" @@ -895,14 +916,15 @@ def test_validate_marital_status(self, record): record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'MARITAL_STATUS']) record.FAMILY_AFFILIATION = 2 record.MARITAL_STATUS = 6 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :2 validator1 passed then MARITAL_STATUS 6 is not larger or ' + - 'equal to 0 and smaller or equal to 5.') + 'equal to 0 and smaller or equal to 5.', + ['FAMILY_AFFILIATION', 'MARITAL_STATUS']) def test_validate_parent_minor(self, record): """Test cat3 validator for parent with minor.""" @@ -913,14 +935,15 @@ def test_validate_parent_minor(self, record): record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'PARENT_MINOR_CHILD']) record.FAMILY_AFFILIATION = 2 record.PARENT_MINOR_CHILD = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :2 validator1 passed then PARENT_MINOR_CHILD 0 is not larger ' + - 'or equal to 1 and smaller or equal to 3.') + 'or equal to 1 and smaller or equal to 3.', + ['FAMILY_AFFILIATION', 'PARENT_MINOR_CHILD']) def test_validate_education(self, record): """Test cat3 validator for education level.""" @@ -934,14 +957,15 @@ def test_validate_education(self, record): record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'EDUCATION_LEVEL']) record.FAMILY_AFFILIATION = 2 record.EDUCATION_LEVEL = "0" result = val(record) assert result == (False, "if FAMILY_AFFILIATION :2 validator1 passed then EDUCATION_LEVEL 0 is not in range " + - "[1, 16]. or 0 is not in range [98, 99].") + "[1, 16]. or 0 is not in range [98, 99].", + ['FAMILY_AFFILIATION', 'EDUCATION_LEVEL']) def test_validate_citizenship_status(self, record): """Test cat3 validator for citizenship status.""" @@ -952,14 +976,15 @@ def test_validate_citizenship_status(self, record): record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) record.FAMILY_AFFILIATION = 1 record.CITIZENSHIP_STATUS = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then CITIZENSHIP_STATUS 0 is not larger ' + - 'or equal to 1 and smaller or equal to 2.') + 'or equal to 1 and smaller or equal to 2.', + ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) def test_validate_hoh_fed_time(self, record): """Test cat3 validator for federal disability.""" @@ -967,7 +992,7 @@ def test_validate_hoh_fed_time(self, record): record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'RELATIONSHIP_HOH', 'COUNTABLE_MONTH_FED_TIME']) record.FAMILY_AFFILIATION = 1 record.RELATIONSHIP_HOH = 1 @@ -975,7 +1000,8 @@ def test_validate_hoh_fed_time(self, record): result = val(record) assert result == (False, 'If FAMILY_AFFILIATION == 2 and COUNTABLE_MONTH_FED_TIME== 1 or 2, then ' + - 'COUNTABLE_MONTH_FED_TIME > 1.') + 'COUNTABLE_MONTH_FED_TIME > 1.', + ['FAMILY_AFFILIATION', 'RELATIONSHIP_HOH', 'COUNTABLE_MONTH_FED_TIME']) def test_validate_oasdi_insurance(self, record): """Test cat3 validator for OASDI insurance.""" @@ -986,14 +1012,14 @@ def test_validate_oasdi_insurance(self, record): record.DATE_OF_BIRTH = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['DATE_OF_BIRTH', 'REC_OASDI_INSURANCE']) record.DATE_OF_BIRTH = 200001 record.REC_OASDI_INSURANCE = 0 result = val(record) assert result == (False, 'if DATE_OF_BIRTH :200001 validator1 passed then REC_OASDI_INSURANCE 0 is not ' + - 'larger or equal to 1 and smaller or equal to 2.') + 'larger or equal to 1 and smaller or equal to 2.', ['DATE_OF_BIRTH', 'REC_OASDI_INSURANCE']) def test_validate_federal_disability(self, record): """Test cat3 validator for federal disability.""" @@ -1004,14 +1030,15 @@ def test_validate_federal_disability(self, record): record.FAMILY_AFFILIATION = 0 result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'REC_FEDERAL_DISABILITY']) record.FAMILY_AFFILIATION = 1 record.REC_FEDERAL_DISABILITY = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then REC_FEDERAL_DISABILITY 0 is not ' + - 'larger or equal to 1 and smaller or equal to 2.') + 'larger or equal to 1 and smaller or equal to 2.', + ['FAMILY_AFFILIATION', 'REC_FEDERAL_DISABILITY']) class TestT6Cat3Validators(TestCat3ValidatorsBase): @@ -1029,12 +1056,13 @@ def test_sum_of_applications(self, record): record.NUM_APPLICATIONS = 2 result = val(record) - assert result == (True, None) + assert result == (True, None, ['NUM_APPLICATIONS', 'NUM_APPROVED', 'NUM_DENIED']) record.NUM_APPLICATIONS = 1 result = val(record) - assert result == (False, "The sum of ['NUM_APPROVED', 'NUM_DENIED'] does not equal NUM_APPLICATIONS.") + assert result == (False, "The sum of ['NUM_APPROVED', 'NUM_DENIED'] does not equal NUM_APPLICATIONS.", + ['NUM_APPLICATIONS', 'NUM_APPROVED', 'NUM_DENIED']) def test_sum_of_families(self, record): """Test cat3 validator for sum of families.""" @@ -1043,13 +1071,13 @@ def test_sum_of_families(self, record): record.NUM_FAMILIES = 3 result = val(record) - assert result == (True, None) + assert result == (True, None, ['NUM_FAMILIES', 'NUM_2_PARENTS', 'NUM_1_PARENTS', 'NUM_NO_PARENTS']) record.NUM_FAMILIES = 1 result = val(record) assert result == (False, "The sum of ['NUM_2_PARENTS', 'NUM_1_PARENTS', 'NUM_NO_PARENTS'] does not equal " + - "NUM_FAMILIES.") + "NUM_FAMILIES.", ['NUM_FAMILIES', 'NUM_2_PARENTS', 'NUM_1_PARENTS', 'NUM_NO_PARENTS']) def test_sum_of_recipients(self, record): """Test cat3 validator for sum of recipients.""" @@ -1058,13 +1086,13 @@ def test_sum_of_recipients(self, record): record.NUM_RECIPIENTS = 2 result = val(record) - assert result == (True, None) + assert result == (True, None, ['NUM_RECIPIENTS', 'NUM_ADULT_RECIPIENTS', 'NUM_CHILD_RECIPIENTS']) record.NUM_RECIPIENTS = 1 result = val(record) assert result == (False, "The sum of ['NUM_ADULT_RECIPIENTS', 'NUM_CHILD_RECIPIENTS'] does not equal " + - "NUM_RECIPIENTS.") + "NUM_RECIPIENTS.", ['NUM_RECIPIENTS', 'NUM_ADULT_RECIPIENTS', 'NUM_CHILD_RECIPIENTS']) class TestM5Cat3Validators(TestCat3ValidatorsBase): """Test category three validators for TANF T6 records.""" @@ -1082,14 +1110,14 @@ def test_fam_affil_ssn(self, record): ) result = val(record) - assert result == (True, None) + assert result == (True, None, ["FAMILY_AFFILIATION", "SSN"]) record.SSN = '111111111' result = val(record) assert result == (False, "if FAMILY_AFFILIATION :1 validator1 passed then SSN 111111111 is in ['000000000', " + "'111111111', '222222222', '333333333', '444444444', '555555555', '666666666', '777777777'," + - " '888888888', '999999999'].") + " '888888888', '999999999'].", ["FAMILY_AFFILIATION", "SSN"]) def test_validate_race_ethnicity(self, record): """Test cat3 validator for race/ethnicity.""" @@ -1100,7 +1128,7 @@ def test_validate_race_ethnicity(self, record): result_field=race, result_function=validators.isInLimits(1, 2), ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', race]) def test_fam_affil_marital_stat(self, record): """Test cat3 validator for family affiliation, and marital status.""" @@ -1110,13 +1138,13 @@ def test_fam_affil_marital_stat(self, record): ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'MARITAL_STATUS']) record.MARITAL_STATUS = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then MARITAL_STATUS 0 is not larger ' + - 'or equal to 1 and smaller or equal to 5.') + 'or equal to 1 and smaller or equal to 5.', ['FAMILY_AFFILIATION', 'MARITAL_STATUS']) def test_fam_affil_parent_with_minor(self, record): """Test cat3 validator for family affiliation, and parent with minor child.""" @@ -1126,13 +1154,15 @@ def test_fam_affil_parent_with_minor(self, record): ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'PARENT_MINOR_CHILD']) record.PARENT_MINOR_CHILD = 0 result = val(record) - assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then PARENT_MINOR_CHILD 0 is not ' + - 'larger or equal to 1 and smaller or equal to 3.') + assert result == (False, + 'if FAMILY_AFFILIATION :1 validator1 passed then PARENT_MINOR_CHILD 0 is not ' + + 'larger or equal to 1 and smaller or equal to 3.', + ['FAMILY_AFFILIATION', 'PARENT_MINOR_CHILD']) def test_fam_affil_ed_level(self, record): """Test cat3 validator for family affiliation, and education level.""" @@ -1143,13 +1173,13 @@ def test_fam_affil_ed_level(self, record): ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'EDUCATION_LEVEL']) record.EDUCATION_LEVEL = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then EDUCATION_LEVEL 0 is not in range ' + - '[1, 16]. or 0 is not in range [98, 99].') + '[1, 16]. or 0 is not in range [98, 99].', ['FAMILY_AFFILIATION', 'EDUCATION_LEVEL']) def test_fam_affil_citz_stat(self, record): """Test cat3 validator for family affiliation, and citizenship status.""" @@ -1159,13 +1189,13 @@ def test_fam_affil_citz_stat(self, record): ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) record.CITIZENSHIP_STATUS = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then CITIZENSHIP_STATUS 0 is not larger ' + - 'or equal to 1 and smaller or equal to 3.') + 'or equal to 1 and smaller or equal to 3.', ['FAMILY_AFFILIATION', 'CITIZENSHIP_STATUS']) def test_dob_oasdi_insur(self, record): """Test cat3 validator for dob, and REC_OASDI_INSURANCE.""" @@ -1175,13 +1205,13 @@ def test_dob_oasdi_insur(self, record): ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['DATE_OF_BIRTH', 'REC_OASDI_INSURANCE']) record.REC_OASDI_INSURANCE = 0 result = val(record) assert result == (False, 'if DATE_OF_BIRTH :11111111 validator1 passed then REC_OASDI_INSURANCE 0 is not ' + - 'larger or equal to 1 and smaller or equal to 2.') + 'larger or equal to 1 and smaller or equal to 2.', ['DATE_OF_BIRTH', 'REC_OASDI_INSURANCE']) def test_fam_affil_fed_disability(self, record): """Test cat3 validator for family affiliation, and REC_FEDERAL_DISABILITY.""" @@ -1191,10 +1221,11 @@ def test_fam_affil_fed_disability(self, record): ) result = val(record) - assert result == (True, None) + assert result == (True, None, ['FAMILY_AFFILIATION', 'REC_FEDERAL_DISABILITY']) record.REC_FEDERAL_DISABILITY = 0 result = val(record) assert result == (False, 'if FAMILY_AFFILIATION :1 validator1 passed then REC_FEDERAL_DISABILITY 0 is not ' + - 'larger or equal to 1 and smaller or equal to 2.') + 'larger or equal to 1 and smaller or equal to 2.', + ['FAMILY_AFFILIATION', 'REC_FEDERAL_DISABILITY']) diff --git a/tdrs-backend/tdpservice/parsers/test/test_views.py b/tdrs-backend/tdpservice/parsers/test/test_views.py new file mode 100644 index 000000000..7f5c7ec35 --- /dev/null +++ b/tdrs-backend/tdpservice/parsers/test/test_views.py @@ -0,0 +1,85 @@ +"""Tests for the views in the parsers app.""" + +import pytest +import base64 +import openpyxl +from .. import parse +from tdpservice.parsers.views import ParsingErrorViewSet +from .. import util + +@pytest.fixture +def test_datafile(stt_user, stt): + """Fixture for small_correct_file.""" + return util.create_test_datafile('small_incorrect_file_cross_validator.txt', stt_user, stt) + + +@pytest.mark.django_db +def test_parsing_error_viewset_list(client, mocker, test_datafile): + """Test the django rest framework parsing error viewset list.""" + # parse datafile + parse.parse_datafile(test_datafile) + + id = test_datafile.id + view = ParsingErrorViewSet() + view.format_kwarg = None + request = mocker.Mock() + + request.query_params = {'file': id} + view.request = request + + ser = view.list(request).data['xls_report'] + + decoded_ser = base64.b64decode(ser) + # write the excel file to disk + with open('mycls.xlsx', 'wb') as f: + f.write(decoded_ser) + + # read the excel file from disk + wb = openpyxl.load_workbook('mycls.xlsx') + ws = wb.get_sheet_by_name('Sheet1') + + COL_ERROR_MESSAGE = 5 + + assert ws.cell(row=1, column=1).value == "Error reporting in TDP is still in development.We'll" \ + + " be in touch when it's ready to use!For now please refer to the reports you receive via email" + assert ws.cell(row=4, column=COL_ERROR_MESSAGE).value == "if cash amount :873 validator1 passed" \ + + " then number of months 0 is not larger than 0." + + +@pytest.mark.django_db +def test_parsing_error_viewset_list_no_fields_json(mocker, test_datafile): + """Test the django rest framework parsing error viewset list.""" + # parse datafile + parse.parse_datafile(test_datafile) + + # set fields_json to None + from tdpservice.parsers.models import ParserError + for error in ParserError.objects.all(): + error.fields_json = None + error.save() + + id = test_datafile.id + view = ParsingErrorViewSet() + view.format_kwarg = None + request = mocker.Mock() + + request.query_params = {'file': id} + view.request = request + + ser = view.list(request).data['xls_report'] + + decoded_ser = base64.b64decode(ser) + # write the excel file to disk + with open('mycls.xlsx', 'wb') as f: + f.write(decoded_ser) + + # read the excel file from disk + wb = openpyxl.load_workbook('mycls.xlsx') + ws = wb.get_sheet_by_name('Sheet1') + + COL_ERROR_MESSAGE = 5 + + assert ws.cell(row=1, column=1).value == "Error reporting in TDP is still in development.We'll" \ + + " be in touch when it's ready to use!For now please refer to the reports you receive via email" + assert ws.cell(row=4, column=COL_ERROR_MESSAGE).value == "if CASH_AMOUNT :873 validator1 passed" \ + + " then NBR_MONTHS 0 is not larger than 0." diff --git a/tdrs-backend/tdpservice/parsers/util.py b/tdrs-backend/tdpservice/parsers/util.py index c8f33d7a9..2a497e48e 100644 --- a/tdrs-backend/tdpservice/parsers/util.py +++ b/tdrs-backend/tdpservice/parsers/util.py @@ -30,6 +30,13 @@ def create_test_datafile(filename, stt_user, stt, section='Active Case Data'): def generate_parser_error(datafile, line_number, schema, error_category, error_message, record=None, field=None): """Create and return a ParserError using args.""" + fields = [*field] if type(field) is list else [field] + fields_json = { + "friendly_name": { + getattr(f, 'name', ''): getattr(f, 'friendly_name', '') for f in fields + } + } + return ParserError( file=datafile, row_number=line_number, @@ -44,7 +51,7 @@ def generate_parser_error(datafile, line_number, schema, error_category, error_m model=schema.model if schema else None ) if record and not isinstance(record, dict) else None, object_id=getattr(record, 'id', None) if record and not isinstance(record, dict) else None, - fields_json=None + fields_json=fields_json ) @@ -58,7 +65,7 @@ def generate(schema, error_category, error_message, record=None, field=None): error_category=error_category, error_message=error_message, record=record, - field=field + field=field, ) return generate diff --git a/tdrs-backend/tdpservice/parsers/validators.py b/tdrs-backend/tdpservice/parsers/validators.py index eb32c666e..ee86063fc 100644 --- a/tdrs-backend/tdpservice/parsers/validators.py +++ b/tdrs-backend/tdpservice/parsers/validators.py @@ -20,6 +20,7 @@ def value_is_empty(value, length): # higher order validator func + def make_validator(validator_func, error_func): """Return a function accepting a value input and returning (bool, string) to represent validation state.""" def validator(value): @@ -35,24 +36,47 @@ def validator(value): def or_validators(*args, **kwargs): """Return a validator that is true only if one of the validators is true.""" - return lambda value: (True, None) if any([validator(value)[0] for validator in args])\ - else (False, ' or '.join([validator(value)[1] for validator in args])) + return ( + lambda value: (True, None) + if any([validator(value)[0] for validator in args]) + else (False, " or ".join([validator(value)[1] for validator in args])) + ) def and_validators(validator1, validator2): """Return a validator that is true only if both validators are true.""" - return lambda value: (True, None) if (validator1(value)[0] and validator2(value)[0])\ - else (False, (validator1(value)[1]) if validator1(value)[1] is not None else '' + - ' and ' + validator2(value)[1] if validator2(value)[1] is not None else '') + return ( + lambda value: (True, None) + if (validator1(value)[0] and validator2(value)[0]) + else ( + False, + (validator1(value)[1]) + if validator1(value)[1] is not None + else "" + " and " + validator2(value)[1] + if validator2(value)[1] is not None + else "", + ) + ) + def extended_and_validators(*args, **kwargs): """Return a validator that is true only if all validators are true.""" - return lambda value: (True, None) if all([validator(value)[0] for validator in args])\ - else (False, ''.join([' and ' + validator(value)[1] if validator(value)[0] else '' for validator in args])) - - -def if_then_validator(condition_field, condition_function, - result_field, result_function): + def returned_func(value): + if all([validator(value)[0] for validator in args]): + return (True, None) + else: + return (False, "".join( + [ + " and " + validator(value)[1] if validator(value)[0] else "" + for validator in args + ] + )) + return returned_func + + +def if_then_validator( + condition_field, condition_function, result_field, result_function +): """Return second validation if the first validator is true. :param condition_field: function that returns (bool, string) to represent validation state @@ -60,79 +84,127 @@ def if_then_validator(condition_field, condition_function, :param result_field: function that returns (bool, string) to represent validation state :param result_function: function that returns (bool, string) to represent validation state """ + def if_then_validator_func(value): - value1 = value[condition_field] if type(value) is dict else getattr(value, condition_field) - value2 = value[result_field] if type(value) is dict else getattr(value, result_field) + value1 = ( + value[condition_field] + if type(value) is dict + else getattr(value, condition_field) + ) + value2 = ( + value[result_field] if type(value) is dict else getattr(value, result_field) + ) validator1_result = condition_function(value1) validator2_result = result_function(value2) - return (True, None) if not validator1_result[0] else ( - validator2_result[0], (f'if {condition_field} ' - + (validator1_result[1] if validator1_result[1] is not None - else f":{value1} validator1 passed") - + f' then {result_field} ' - + (validator2_result[1] if validator2_result[1] is not None - else "validator2 passed")) if not validator2_result[0] else None) + + if not validator1_result[0]: + returned_value = (True, None, [condition_field, result_field]) + else: + if not validator2_result[0]: + + # center of error message + if validator1_result[1] is not None: + center_error = validator1_result[1] + else: + center_error = f":{value1} validator1 passed" + + # ending of error message + if validator2_result[1] is not None: + ending_error = validator2_result[1] + else: + ending_error = "validator2 passed" + + error_message = f"if {condition_field} " + (center_error) + f" then {result_field} " + ending_error + else: + error_message = None + + returned_value = (validator2_result[0], error_message, [condition_field, result_field]) + + return returned_value return lambda value: if_then_validator_func(value) + def sumIsEqual(condition_field, sum_fields=[]): """Validate that the sum of the sum_fields equals the condition_field.""" + def sumIsEqualFunc(value): sum = 0 for field in sum_fields: val = value[field] if type(value) is dict else getattr(value, field) sum += 0 if val is None else val - condition_val = value[condition_field] if type(value) is dict else getattr(value, condition_field) - return (True, None) if sum == condition_val else (False, - f"The sum of {sum_fields} does not equal {condition_field}.") + condition_val = ( + value[condition_field] + if type(value) is dict + else getattr(value, condition_field) + ) + fields = [condition_field] + fields.extend(sum_fields) + return ( + (True, None, fields) + if sum == condition_val + else ( + False, + f"The sum of {sum_fields} does not equal {condition_field}.", + fields, + ) + ) return lambda value: sumIsEqualFunc(value) + def sumIsLarger(fields, val): """Validate that the sum of the fields is larger than val.""" + def sumIsLargerFunc(value): sum = 0 for field in fields: temp_val = value[field] if type(value) is dict else getattr(value, field) sum += 0 if temp_val is None else temp_val - return (True, None) if sum > val else (False, f"The sum of {fields} is not larger than {val}.") + return ( + (True, None, [field for field in fields]) + if sum > val + else ( + False, + f"The sum of {fields} is not larger than {val}.", + [field for field in fields], + ) + ) return lambda value: sumIsLargerFunc(value) # generic validators + def matches(option): """Validate that value is equal to option.""" return make_validator( - lambda value: value == option, - lambda value: f'{value} does not match {option}.' + lambda value: value == option, lambda value: f"{value} does not match {option}." ) + def notMatches(option): """Validate that value is not equal to option.""" return make_validator( - lambda value: value != option, - lambda value: f'{value} matches {option}.' + lambda value: value != option, lambda value: f"{value} matches {option}." ) def oneOf(options=[]): """Validate that value does not exist in the provided options array.""" return make_validator( - lambda value: value in options, - lambda value: f'{value} is not in {options}.' + lambda value: value in options, lambda value: f"{value} is not in {options}." ) def notOneOf(options=[]): """Validate that value exists in the provided options array.""" return make_validator( - lambda value: value not in options, - lambda value: f'{value} is in {options}.' + lambda value: value not in options, lambda value: f"{value} is in {options}." ) @@ -140,7 +212,7 @@ def between(min, max): """Validate value, when casted to int, is greater than min and less than max.""" return make_validator( lambda value: int(value) > min and int(value) < max, - lambda value: f'{value} is not between {min} and {max}.' + lambda value: f"{value} is not between {min} and {max}.", ) @@ -148,7 +220,9 @@ def hasLength(length, error_func=None): """Validate that value (string or array) has a length matching length param.""" return make_validator( lambda value: len(value) == length, - lambda value: error_func(value, length) if error_func else f'Value length {len(value)} does not match {length}.' + lambda value: error_func(value, length) + if error_func + else f"Value length {len(value)} does not match {length}.", ) @@ -156,7 +230,7 @@ def contains(substring): """Validate that string value contains the given substring param.""" return make_validator( lambda value: value.find(substring) != -1, - lambda value: f'{value} does not contain {substring}.' + lambda value: f"{value} does not contain {substring}.", ) @@ -164,43 +238,44 @@ def startsWith(substring): """Validate that string value starts with the given substring param.""" return make_validator( lambda value: value.startswith(substring), - lambda value: f'{value} does not start with {substring}.' + lambda value: f"{value} does not start with {substring}.", ) def isNumber(): """Validate that value can be casted to a number.""" return make_validator( - lambda value: value.isnumeric(), - lambda value: f'{value} is not a number.' + lambda value: value.isnumeric(), lambda value: f"{value} is not a number." ) + def isAlphaNumeric(): """Validate that value is alphanumeric.""" return make_validator( - lambda value: value.isalnum(), - lambda value: f'{value} is not alphanumeric.' + lambda value: value.isalnum(), lambda value: f"{value} is not alphanumeric." ) + def isBlank(): """Validate that string value is blank.""" return make_validator( - lambda value: value.isspace(), - lambda value: f'{value} is not blank.' + lambda value: value.isspace(), lambda value: f"{value} is not blank." ) + def isInStringRange(lower, upper): """Validate that string value is in a specific range.""" return make_validator( lambda value: int(value) >= lower and int(value) <= upper, - lambda value: f'{value} is not in range [{lower}, {upper}].' + lambda value: f"{value} is not in range [{lower}, {upper}].", ) + def isStringLargerThan(val): """Validate that string value is larger than val.""" return make_validator( lambda value: int(value) > val, - lambda value: f'{value} is not larger than {val}.' + lambda value: f"{value} is not larger than {val}.", ) @@ -218,6 +293,7 @@ def notEmpty(start=0, end=None): lambda value: f'{str(value)} contains blanks between positions {start} and {end if end else len(str(value))}.' ) + def isEmpty(start=0, end=None): """Validate that string value is only blanks.""" return make_validator( @@ -229,8 +305,7 @@ def isEmpty(start=0, end=None): def notZero(number_of_zeros=1): """Validate that value is not zero.""" return make_validator( - lambda value: value != '0' * number_of_zeros, - lambda value: f'{value} is zero.' + lambda value: value != "0" * number_of_zeros, lambda value: f"{value} is zero." ) @@ -238,7 +313,7 @@ def isLargerThan(LowerBound): """Validate that value is larger than the given value.""" return make_validator( lambda value: float(value) > LowerBound if value is not None else False, - lambda value: f'{value} is not larger than {LowerBound}.' + lambda value: f"{value} is not larger than {LowerBound}.", ) @@ -246,73 +321,82 @@ def isSmallerThan(UpperBound): """Validate that value is smaller than the given value.""" return make_validator( lambda value: value < UpperBound, - lambda value: f'{value} is not smaller than {UpperBound}.' + lambda value: f"{value} is not smaller than {UpperBound}.", ) + def isLargerThanOrEqualTo(LowerBound): """Validate that value is larger than the given value.""" return make_validator( lambda value: value >= LowerBound, - lambda value: f'{value} is not larger than {LowerBound}.' + lambda value: f"{value} is not larger than {LowerBound}.", ) + def isSmallerThanOrEqualTo(UpperBound): """Validate that value is smaller than the given value.""" return make_validator( lambda value: value <= UpperBound, - lambda value: f'{value} is not smaller than {UpperBound}.' + lambda value: f"{value} is not smaller than {UpperBound}.", ) + def isInLimits(LowerBound, UpperBound): """Validate that value is in a range including the limits.""" return make_validator( lambda value: value >= LowerBound and value <= UpperBound, - lambda value: f'{value} is not larger or equal to {LowerBound} and smaller or equal to {UpperBound}.' + lambda value: f"{value} is not larger or equal to {LowerBound} and smaller or equal to {UpperBound}.", ) + # custom validators + def dateMonthIsValid(): """Validate that in a monthyear combination, the month is a valid month.""" return make_validator( lambda value: int(str(value)[4:6]) in range(1, 13), - lambda value: f'{str(value)[4:6]} is not a valid month.' + lambda value: f"{str(value)[4:6]} is not a valid month.", ) + def olderThan(min_age): """Validate that value is larger than min_age.""" return make_validator( lambda value: date.today().year - int(str(value)[:4]) > min_age, - lambda value: f'{date.today().year - int(str(value)[:4])} is not larger than {min_age}.' + lambda value: f"{date.today().year - int(str(value)[:4])} is not larger than {min_age}.", ) + def dateYearIsLargerThan(year): """Validate that in a monthyear combination, the year is larger than the given year.""" return make_validator( lambda value: int(str(value)[:4]) > year, - lambda value: f'{str(value)[:4]} year must be larger than {year}.' + lambda value: f"{str(value)[:4]} year must be larger than {year}.", ) + def quarterIsValid(): """Validate in a year quarter combination, the quarter is valid.""" return make_validator( lambda value: int(str(value)[-1]) > 0 and int(str(value)[-1]) < 5, - lambda value: f'{str(value)[-1]} is not a valid quarter.' + lambda value: f"{str(value)[-1]} is not a valid quarter.", ) + def validateSSN(): """Validate that SSN value is not a repeating digit.""" - options = [str(i)*9 for i in range(0, 10)] + options = [str(i) * 9 for i in range(0, 10)] return make_validator( - lambda value: value not in options, - lambda value: f'{value} is in {options}.' + lambda value: value not in options, lambda value: f"{value} is in {options}." ) + def validateRace(): """Validate race.""" return make_validator( lambda value: value >= 0 and value <= 2, - lambda value: f'{value} is not greater than or equal to 0 or smaller than or equal to 1.' + lambda value: f"{value} is not greater than or equal to 0 or smaller than or equal to 1.", ) @@ -326,62 +410,126 @@ def validate__FAM_AFF__SSN(): """ # value is instance def validate(instance): - FAMILY_AFFILIATION = instance['FAMILY_AFFILIATION'] if type(instance) is dict else \ - getattr(instance, 'FAMILY_AFFILIATION') - CITIZENSHIP_STATUS = instance['CITIZENSHIP_STATUS'] if type(instance) is dict else \ - getattr(instance, 'CITIZENSHIP_STATUS') - SSN = instance['SSN'] if type(instance) is dict else getattr(instance, 'SSN') - if FAMILY_AFFILIATION == 2 and (CITIZENSHIP_STATUS == 1 or CITIZENSHIP_STATUS == 2): + FAMILY_AFFILIATION = ( + instance["FAMILY_AFFILIATION"] + if type(instance) is dict + else getattr(instance, "FAMILY_AFFILIATION") + ) + CITIZENSHIP_STATUS = ( + instance["CITIZENSHIP_STATUS"] + if type(instance) is dict + else getattr(instance, "CITIZENSHIP_STATUS") + ) + SSN = instance["SSN"] if type(instance) is dict else getattr(instance, "SSN") + if FAMILY_AFFILIATION == 2 and ( + CITIZENSHIP_STATUS == 1 or CITIZENSHIP_STATUS == 2 + ): if SSN in [str(i) * 9 for i in range(10)]: - return (False, - 'If FAMILY_AFFILIATION ==2 and CITIZENSHIP_STATUS==1 or 2, then SSN != 000000000 -- 999999999.') + return ( + False, + "If FAMILY_AFFILIATION ==2 and CITIZENSHIP_STATUS==1 or 2, then SSN != 000000000 -- 999999999.", + ["FAMILY_AFFILIATION", "CITIZENSHIP_STATUS", "SSN"], + ) else: - return (True, None) + return (True, None, ["FAMILY_AFFILIATION", "CITIZENSHIP_STATUS", "SSN"]) else: - return (True, None) + return (True, None, ["FAMILY_AFFILIATION", "CITIZENSHIP_STATUS", "SSN"]) + return lambda instance: validate(instance) + def validate__FAM_AFF__HOH__Fed_Time(): """If FAMILY_AFFILIATION == 1 and RELATIONSHIP_HOH== 1 or 2, then MONTHS_FED_TIME_LIMIT >= 1.""" # value is instance def validate(instance): - FAMILY_AFFILIATION = instance['FAMILY_AFFILIATION'] if type(instance) is dict else \ - getattr(instance, 'FAMILY_AFFILIATION') - RELATIONSHIP_HOH = instance['RELATIONSHIP_HOH'] if type(instance) is dict else \ - getattr(instance, 'RELATIONSHIP_HOH') + FAMILY_AFFILIATION = ( + instance["FAMILY_AFFILIATION"] + if type(instance) is dict + else getattr(instance, "FAMILY_AFFILIATION") + ) + RELATIONSHIP_HOH = ( + instance["RELATIONSHIP_HOH"] + if type(instance) is dict + else getattr(instance, "RELATIONSHIP_HOH") + ) RELATIONSHIP_HOH = int(RELATIONSHIP_HOH) - MONTHS_FED_TIME_LIMIT = instance['MONTHS_FED_TIME_LIMIT'] if type(instance) is dict else \ - getattr(instance, 'MONTHS_FED_TIME_LIMIT') + MONTHS_FED_TIME_LIMIT = ( + instance["MONTHS_FED_TIME_LIMIT"] + if type(instance) is dict + else getattr(instance, "MONTHS_FED_TIME_LIMIT") + ) if FAMILY_AFFILIATION == 1 and (RELATIONSHIP_HOH == 1 or RELATIONSHIP_HOH == 2): if MONTHS_FED_TIME_LIMIT is None or int(MONTHS_FED_TIME_LIMIT) < 1: return (False, - 'If FAMILY_AFFILIATION == 2 and MONTHS_FED_TIME_LIMIT== 1 or 2, then MONTHS_FED_TIME_LIMIT > 1.' + "If FAMILY_AFFILIATION == 2 and MONTHS_FED_TIME_LIMIT== 1 or 2," + + " then MONTHS_FED_TIME_LIMIT > 1.", + ['FAMILY_AFFILIATION', 'MONTHS_FED_TIME_LIMIT'] ) else: - return (True, None) + return ( + True, + None, + ["FAMILY_AFFILIATION", "RELATIONSHIP_HOH", "MONTHS_FED_TIME_LIMIT"], + ) else: - return (True, None) + return ( + True, + None, + ["FAMILY_AFFILIATION", "RELATIONSHIP_HOH", "MONTHS_FED_TIME_LIMIT"], + ) + return lambda instance: validate(instance) + def validate__FAM_AFF__HOH__Count_Fed_Time(): """If FAMILY_AFFILIATION == 1 and RELATIONSHIP_HOH== 1 or 2, then COUNTABLE_MONTH_FED_TIME >= 1.""" # value is instance def validate(instance): - FAMILY_AFFILIATION = instance['FAMILY_AFFILIATION'] if type(instance) is dict else \ - getattr(instance, 'FAMILY_AFFILIATION') - RELATIONSHIP_HOH = instance['RELATIONSHIP_HOH'] if type(instance) is dict else \ - getattr(instance, 'RELATIONSHIP_HOH') + FAMILY_AFFILIATION = ( + instance["FAMILY_AFFILIATION"] + if type(instance) is dict + else getattr(instance, "FAMILY_AFFILIATION") + ) + RELATIONSHIP_HOH = ( + instance["RELATIONSHIP_HOH"] + if type(instance) is dict + else getattr(instance, "RELATIONSHIP_HOH") + ) RELATIONSHIP_HOH = int(RELATIONSHIP_HOH) - COUNTABLE_MONTH_FED_TIME = instance['COUNTABLE_MONTH_FED_TIME'] if type(instance) is dict else \ - getattr(instance, 'COUNTABLE_MONTH_FED_TIME') + COUNTABLE_MONTH_FED_TIME = ( + instance["COUNTABLE_MONTH_FED_TIME"] + if type(instance) is dict + else getattr(instance, "COUNTABLE_MONTH_FED_TIME") + ) if FAMILY_AFFILIATION == 1 and (RELATIONSHIP_HOH == 1 or RELATIONSHIP_HOH == 2): if int(COUNTABLE_MONTH_FED_TIME) < 1: - return (False, 'If FAMILY_AFFILIATION == 2 and COUNTABLE_MONTH_FED_TIME== 1 or 2, then ' + - 'COUNTABLE_MONTH_FED_TIME > 1.') + return ( + False, + "If FAMILY_AFFILIATION == 2 and COUNTABLE_MONTH_FED_TIME== 1 or 2, then " + + "COUNTABLE_MONTH_FED_TIME > 1.", + [ + "FAMILY_AFFILIATION", + "RELATIONSHIP_HOH", + "COUNTABLE_MONTH_FED_TIME", + ], + ) else: - return (True, None) + return ( + True, + None, + [ + "FAMILY_AFFILIATION", + "RELATIONSHIP_HOH", + "COUNTABLE_MONTH_FED_TIME", + ], + ) else: - return (True, None) + return ( + True, + None, + ["FAMILY_AFFILIATION", "RELATIONSHIP_HOH", "COUNTABLE_MONTH_FED_TIME"], + ) + return lambda instance: validate(instance) @@ -396,7 +544,7 @@ def validate_header_section_matches_submission(datafile, section, generate_error error_category=ParserErrorCategoryChoices.PRE_CHECK, error_message=f"Data does not match the expected layout for {datafile.section}.", record=None, - field=None + field=None, ) return is_valid, error diff --git a/tdrs-backend/tdpservice/parsers/views.py b/tdrs-backend/tdpservice/parsers/views.py index 8e40b79e4..ef6f5f7cf 100644 --- a/tdrs-backend/tdpservice/parsers/views.py +++ b/tdrs-backend/tdpservice/parsers/views.py @@ -8,6 +8,7 @@ import base64 from io import BytesIO import xlsxwriter +import calendar logger = logging.getLogger() @@ -38,19 +39,49 @@ def get_queryset(self): def _get_xls_serialized_file(self, data): """Return xls file created from the error.""" + + def chk(x): + """Check if fields_json is not None.""" + x['fields_json'] = x['fields_json'] if x.get('fields_json', None) else { + 'friendly_name': { + x['field_name']: x['field_name'] + }, + } + x['fields_json']['friendly_name'] = x['fields_json']['friendly_name'] if x['fields_json'].get( + 'friendly_name', None) else { + x['field_name']: x['field_name'] + } + if None in x['fields_json']['friendly_name'].keys(): + x['fields_json']['friendly_name'].pop(None) + if None in x['fields_json']['friendly_name'].values(): + x['fields_json']['friendly_name'].pop() + return x + + def format_error_msg(x): + """Format error message.""" + error_msg = x['error_message'] + for key, value in x['fields_json']['friendly_name'].items(): + error_msg = error_msg.replace(key, value) if value else error_msg + return error_msg + row, col = 0, 0 output = BytesIO() workbook = xlsxwriter.Workbook(output) worksheet = workbook.add_worksheet() - - report_columns = ['case_number', - 'rpt_month_year', - 'error_type', - 'error_message', - 'item_number', - 'field_name', - 'row_number', - 'column_number'] + report_columns = [ + ('case_number', lambda x: x['case_number']), + ('year', lambda x: str(x['rpt_month_year'])[0:4] if x['rpt_month_year'] else None), + ('month', lambda x: calendar.month_name[ + int(str(x['rpt_month_year'])[4:]) + ] if x['rpt_month_year'] else None), + ('error_type', lambda x: x['error_type']), + ('error_message', lambda x: format_error_msg(chk(x))), + ('item_number', lambda x: x['item_number']), + ('item_name', lambda x: ','.join([i for i in chk(x)['fields_json']['friendly_name'].values()])), + ('internal_variable_name', lambda x: ','.join([i for i in chk(x)['fields_json']['friendly_name'].keys()])), + ('row_number', lambda x: x['row_number']), + ('column_number', lambda x: x['column_number']) + ] # write beta banner worksheet.write(row, col, @@ -59,14 +90,24 @@ def _get_xls_serialized_file(self, data): "For now please refer to the reports you receive via email") row, col = 2, 0 # write csv header - [worksheet.write(row, col, key) for col, key in enumerate(report_columns)] - - for i in data: - row += 1 - col = 0 - for key in report_columns: - worksheet.write(row, col, i[key]) # writes value by looking up data by key - col += 1 + bold = workbook.add_format({'bold': True}) + + def format_header(header_list: list): + """Format header.""" + return ' '.join([i.capitalize() for i in header_list.split('_')]) + + # We will write the headers in the first row + [worksheet.write(row, col, format_header(key[0]), bold) for col, key in enumerate(report_columns)] + + [ + worksheet.write(row + 3, col, key[1](data_i)) for col, key in enumerate(report_columns) + for row, data_i in enumerate(data) + ] + + # autofit all columns except for the first one + worksheet.autofit() + worksheet.set_column(0, 0, 20) + workbook.close() return {"data": data, "xls_report": base64.b64encode(output.getvalue()).decode("utf-8")} diff --git a/tdrs-frontend/nginx/cloud.gov/locations.conf b/tdrs-frontend/nginx/cloud.gov/locations.conf index 1bccf800e..a6c6d7b42 100644 --- a/tdrs-frontend/nginx/cloud.gov/locations.conf +++ b/tdrs-frontend/nginx/cloud.gov/locations.conf @@ -16,13 +16,13 @@ location ~ ^/(v1|admin|static/admin|swagger|redocs) { proxy_buffer_size 4k; proxy_temp_file_write_size 64k; - limit_except GET HEAD POST { deny all; + limit_except GET HEAD POST PATCH { deny all; } add_header Access-Control-Allow-Origin 's3-us-gov-west-1.amazonaws.com'; } -if ($request_method ~ ^(PATCH|TRACE|OPTION)$) { +if ($request_method ~ ^(TRACE|OPTION)$) { return 405; }