diff --git a/AUTHORS.md b/AUTHORS.md index 60b4c67c..8d859a7a 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -7,12 +7,18 @@ Django Ledger was created by [Miguel Sanda](https://github.com/elarroba). ### Project Maintainers * Miguel Sanda [@elarroba](https://github.com/elarroba) -### Developers & Contributors +### Developers * Miguel Sanda [@elarroba](https://github.com/elarroba) + +### Contributors * Michael Noel [@mnooel](https://github.com/mnooel) * Eric Owuor [@Ericpaul](https://github.com/25-do) +* Pranav P Tulshyan ### Accountants, CPAs & Bookkeepers * Miguel Sanda [@elarroba](https://github.com/elarroba) * Albert Salazar [@Beachwood619](https://github.com/Beachwood619) -* Michael Noel, CPA [@mnooel](https://github.com/mnooel) \ No newline at end of file +* Michael Noel, CPA [@mnooel](https://github.com/mnooel) + +### Documentation Contributors +* Miguel Sanda [@elarroba](https://github.com/elarroba) \ No newline at end of file diff --git a/Contribute.md b/Contribute.md index b78a62bd..844ac31b 100644 --- a/Contribute.md +++ b/Contribute.md @@ -1,23 +1,44 @@ -# Django Ledger Contribution Guidelines - -* UI - * Django Ledger UI is based on the [Bulma](https://bulma.io/) CSS Framework via [WebPack](https://webpack.js.org/). - Any template contributions must follow Bulma's best practices. - * Icons are implemented through [Iconify](https://iconify.design/) and Django Ledger has the built-in template tag - [icon](https://github.com/arrobalytics/django-ledger/blob/5f61251ce3ee8a9b159211a98d8d00c53b5cb942/django_ledger/templatetags/django_ledger.py#L78) - which can be used to render any icon using Iconify. -* JavaScript - * Django Ledger uses [TypeScript](https://www.typescriptlang.org/) to ship JavaScript to the browser. Webpack is used to bundle all CSS/JS into two - javascript files respectively. See [bundle](https://github.com/arrobalytics/django-ledger/tree/develop/django_ledger/static/django_ledger/bundle) - in the static file directory. The build command in the [assets/package.json](https://github.com/arrobalytics/django-ledger/blob/develop/assets/package.json) - file will build styles and javascript and - automatically update the application bundle with the latest compiled version. -* Models - * Changes and contributions to Models are limited to those with proven Django experience. Also, in addition to Django - experience, some accounting and domain knowledge is required. Changes to models must be justified and susbtantiated - with proper accounting best practices. -* Documentation - * All documentation contributions are welcome. [Sphinx](https://github.com/sphinx-doc/sphinx) has been set up to - automatically generate static HTML documentation. -* Unit Tests - * All unit tests contributions are welcome if they are intended to validate program logic and/or accounting logic. \ No newline at end of file +# Contribution Guidelines for Django Ledger + +Thank you for your interest in contributing to Django Ledger. Before submitting your contribution, please review the following guidelines: + +## 1. Contributor License Agreement (CLA) +All contributors must sign our Contributor License Agreement. This agreement ensures that: +- You grant us a perpetual, worldwide, non-exclusive, royalty-free license to use your contributions. +- You confirm that you have the right to grant us these rights. +- You understand that your contributions will be under the project's open-source license. + +## 2. Copyright +- The copyright for Django Ledger is held by the project owner. +- By contributing, you agree that your contributions will be licensed under the same terms. + +## 3. Code Contributions +- Ensure your code adheres to our coding standards and style guide. +- All new code should be accompanied by appropriate tests. +- Update documentation as necessary. + +## 4. Pull Requests +- Submit pull requests against the `develop` branch. +- Clearly describe the problem and solution in your PR description. +- Include any relevant issue numbers. + +## 5. Issue Reporting +- Use the issue tracker to report bugs or suggest enhancements. +- Provide as much detail as possible, including steps to reproduce for bugs. + +## 6. Ownership and Rights +- By contributing to Django Ledger, you acknowledge that the project owner retains the right to use, modify, and distribute your contribution as part of the project. +- The project owner reserves the right to reject any contribution. + +## 7. Code of Conduct +- Adhere to our Code of Conduct in all interactions within the project community. + +## 8. Documentation and Other Contributions +- Contributions to documentation, tutorials, or other non-code assets are also subject to these guidelines. + +## 9. No Warranty +- Contributions are provided "as is" without warranty of any kind. + +By submitting a contribution, you agree to these terms and conditions. The project owner reserves the right to update these guidelines as necessary. + +Thank you for helping improve Django Ledger! diff --git a/Pipfile b/Pipfile index 752c3c3a..29a9b956 100644 --- a/Pipfile +++ b/Pipfile @@ -4,7 +4,7 @@ verify_ssl = true name = "pypi" [packages] -django = ">=2.2" +django = ">=4.2" django-treebeard = ">=4.5.1" ofxtools = ">=0.9.5" markdown = ">=3.4.1" @@ -26,6 +26,8 @@ behave = "*" twine = "*" jupyterlab = "*" pandas = "*" +numpy = "*" + [requires] python_version = "3.12" diff --git a/Pipfile.lock b/Pipfile.lock index 80723104..c7b578d1 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "144d422614b7c1e67533f6fa7a01767a4f90bab17ecde1600f255c901d34664e" + "sha256": "cbee294ae633a07c910ada31b7dbf2f2e302de16a1bdb82d1cbffdf806215500" }, "pipfile-spec": 6, "requires": { @@ -26,12 +26,12 @@ }, "django": { "hashes": [ - "sha256:021ffb7fdab3d2d388bc8c7c2434eb9c1f6f4d09e6119010bbb1694dda286bc2", - "sha256:71603f27dac22a6533fb38d83072eea9ddb4017fead6f67f2562a40402d61c3f" + "sha256:bd7376f90c99f96b643722eee676498706c9fd7dc759f55ebfaf2c08ebcdf4f0", + "sha256:f11aa87ad8d5617171e3f77e1d5d16f004b79a2cf5d2e1d2b97a6a1f8e9ba5ed" ], "index": "pypi", "markers": "python_version >= '3.10'", - "version": "==5.1.1" + "version": "==5.1.2" }, "django-treebeard": { "hashes": [ @@ -44,12 +44,12 @@ }, "faker": { "hashes": [ - "sha256:4294d169255a045990720d6f3fa4134b764a4cdf46ef0d3c7553d2506f1adaa1", - "sha256:e59c01d1e8b8e20a83255ab8232c143cb2af3b4f5ab6a3f5ce495f385ad8ab4c" + "sha256:37b5ab951f7367ea93edb865120e9717a7a649d6a4b223f1e4a47a8a20d9e85f", + "sha256:be0e548352c1be6f6d9c982003848a0d305868f160bb1fb7f945acffc347e676" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==28.4.1" + "version": "==30.6.0" }, "markdown": { "hashes": [ @@ -70,97 +70,92 @@ }, "pillow": { "hashes": [ - "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885", - "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea", - "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df", - "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5", - "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c", - "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d", - "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd", - "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06", - "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908", - "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a", - "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be", - "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0", - "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b", - "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80", - "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a", - "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e", - "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9", - "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696", - "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b", - "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309", - "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e", - "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab", - "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d", - "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060", - "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d", - "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d", - "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4", - "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3", - "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6", - "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb", - "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94", - "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b", - "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496", - "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0", - "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319", - "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b", - "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856", - "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef", - "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680", - "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b", - "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42", - "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e", - "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597", - "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a", - "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8", - "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3", - "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736", - "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da", - "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126", - "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd", - "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5", - "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b", - "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026", - "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b", - "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc", - "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46", - "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2", - "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c", - "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe", - "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984", - "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a", - "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70", - "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca", - "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b", - "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91", - "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3", - "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84", - "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1", - "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5", - "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be", - "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f", - "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc", - "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9", - "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e", - "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141", - "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef", - "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22", - "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27", - "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e", - "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1" + "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7", + "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5", + "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903", + "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2", + "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38", + "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2", + "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9", + "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f", + "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc", + "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8", + "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d", + "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2", + "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316", + "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a", + "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25", + "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd", + "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba", + "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc", + "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273", + "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa", + "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a", + "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b", + "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a", + "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae", + "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291", + "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97", + "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06", + "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904", + "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b", + "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b", + "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8", + "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527", + "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947", + "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb", + "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003", + "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5", + "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f", + "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739", + "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944", + "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830", + "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f", + "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3", + "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4", + "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84", + "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7", + "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6", + "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6", + "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9", + "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de", + "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4", + "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47", + "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd", + "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50", + "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c", + "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086", + "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba", + "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306", + "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699", + "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e", + "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488", + "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa", + "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2", + "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3", + "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9", + "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923", + "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2", + "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790", + "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734", + "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916", + "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1", + "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f", + "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798", + "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb", + "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2", + "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==10.4.0" + "markers": "python_version >= '3.9'", + "version": "==11.0.0" }, "python-dateutil": { "hashes": [ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.9.0.post0" }, "six": { @@ -168,7 +163,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "sqlparse": { @@ -178,6 +173,14 @@ ], "markers": "python_version >= '3.8'", "version": "==0.5.1" + }, + "typing-extensions": { + "hashes": [ + "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" + ], + "markers": "python_version >= '3.8'", + "version": "==4.12.2" } }, "develop": { @@ -191,11 +194,11 @@ }, "anyio": { "hashes": [ - "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94", - "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7" + "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", + "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d" ], - "markers": "python_version >= '3.8'", - "version": "==4.4.0" + "markers": "python_version >= '3.9'", + "version": "==4.6.2.post1" }, "appnope": { "hashes": [ @@ -279,14 +282,6 @@ "markers": "python_version >= '3.8'", "version": "==2.16.0" }, - "backports.tarfile": { - "hashes": [ - "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", - "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991" - ], - "markers": "python_version < '3.12'", - "version": "==1.2.0" - }, "beautifulsoup4": { "hashes": [ "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", @@ -301,7 +296,7 @@ "sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c" ], "index": "pypi", - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.2.6" }, "bleach": { @@ -395,99 +390,114 @@ }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "version": "==3.4.0" }, "comm": { "hashes": [ @@ -499,31 +509,35 @@ }, "debugpy": { "hashes": [ - "sha256:0a1029a2869d01cb777216af8c53cda0476875ef02a2b6ff8b2f2c9a4b04176c", - "sha256:1cd04a73eb2769eb0bfe43f5bfde1215c5923d6924b9b90f94d15f207a402226", - "sha256:28ced650c974aaf179231668a293ecd5c63c0a671ae6d56b8795ecc5d2f48d3c", - "sha256:345d6a0206e81eb68b1493ce2fbffd57c3088e2ce4b46592077a943d2b968ca3", - "sha256:3df6692351172a42af7558daa5019651f898fc67450bf091335aa8a18fbf6f3a", - "sha256:4413b7a3ede757dc33a273a17d685ea2b0c09dbd312cc03f5534a0fd4d40750a", - "sha256:4fbb3b39ae1aa3e5ad578f37a48a7a303dad9a3d018d369bc9ec629c1cfa7408", - "sha256:55919dce65b471eff25901acf82d328bbd5b833526b6c1364bd5133754777a44", - "sha256:5b5c770977c8ec6c40c60d6f58cacc7f7fe5a45960363d6974ddb9b62dbee156", - "sha256:606bccba19f7188b6ea9579c8a4f5a5364ecd0bf5a0659c8a5d0e10dcee3032a", - "sha256:7b0fe36ed9d26cb6836b0a51453653f8f2e347ba7348f2bbfe76bfeb670bfb1c", - "sha256:7e4d594367d6407a120b76bdaa03886e9eb652c05ba7f87e37418426ad2079f7", - "sha256:8f913ee8e9fcf9d38a751f56e6de12a297ae7832749d35de26d960f14280750a", - "sha256:a697beca97dad3780b89a7fb525d5e79f33821a8bc0c06faf1f1289e549743cf", - "sha256:ad84b7cde7fd96cf6eea34ff6c4a1b7887e0fe2ea46e099e53234856f9d99a34", - "sha256:b2112cfeb34b4507399d298fe7023a16656fc553ed5246536060ca7bd0e668d0", - "sha256:b78c1250441ce893cb5035dd6f5fc12db968cc07f91cc06996b2087f7cefdd8e", - "sha256:c0a65b00b7cdd2ee0c2cf4c7335fef31e15f1b7056c7fdbce9e90193e1a8c8cb", - "sha256:c9f7c15ea1da18d2fcc2709e9f3d6de98b69a5b0fff1807fb80bc55f906691f7", - "sha256:db9fb642938a7a609a6c865c32ecd0d795d56c1aaa7a7a5722d77855d5e77f2b", - "sha256:dd3811bd63632bb25eda6bd73bea8e0521794cda02be41fa3160eb26fc29e7ed", - "sha256:e84c276489e141ed0b93b0af648eef891546143d6a48f610945416453a8ad406" - ], - "markers": "python_version >= '3.8'", - "version": "==1.8.5" + "sha256:11ad72eb9ddb436afb8337891a986302e14944f0f755fd94e90d0d71e9100bba", + "sha256:171899588bcd412151e593bd40d9907133a7622cd6ecdbdb75f89d1551df13c2", + "sha256:18b8f731ed3e2e1df8e9cdaa23fb1fc9c24e570cd0081625308ec51c82efe42e", + "sha256:29e1571c276d643757ea126d014abda081eb5ea4c851628b33de0c2b6245b037", + "sha256:2efb84d6789352d7950b03d7f866e6d180284bc02c7e12cb37b489b7083d81aa", + "sha256:2f729228430ef191c1e4df72a75ac94e9bf77413ce5f3f900018712c9da0aaca", + "sha256:45c30aaefb3e1975e8a0258f5bbd26cd40cde9bfe71e9e5a7ac82e79bad64e39", + "sha256:4b908291a1d051ef3331484de8e959ef3e66f12b5e610c203b5b75d2725613a7", + "sha256:4d27d842311353ede0ad572600c62e4bcd74f458ee01ab0dd3a1a4457e7e3706", + "sha256:57b00de1c8d2c84a61b90880f7e5b6deaf4c312ecbde3a0e8912f2a56c4ac9ae", + "sha256:628a11f4b295ffb4141d8242a9bb52b77ad4a63a2ad19217a93be0f77f2c28c9", + "sha256:6a9d9d6d31846d8e34f52987ee0f1a904c7baa4912bf4843ab39dadf9b8f3e0d", + "sha256:6e1c4ffb0c79f66e89dfd97944f335880f0d50ad29525dc792785384923e2211", + "sha256:703c1fd62ae0356e194f3e7b7a92acd931f71fe81c4b3be2c17a7b8a4b546ec2", + "sha256:85ce9c1d0eebf622f86cc68618ad64bf66c4fc3197d88f74bb695a416837dd55", + "sha256:90d93e4f2db442f8222dec5ec55ccfc8005821028982f1968ebf551d32b28907", + "sha256:93176e7672551cb5281577cdb62c63aadc87ec036f0c6a486f0ded337c504596", + "sha256:95fe04a573b8b22896c404365e03f4eda0ce0ba135b7667a1e57bd079793b96b", + "sha256:a6cf2510740e0c0b4a40330640e4b454f928c7b99b0c9dbf48b11efba08a8cda", + "sha256:b12515e04720e9e5c2216cc7086d0edadf25d7ab7e3564ec8b4521cf111b4f8c", + "sha256:b6db2a370e2700557a976eaadb16243ec9c91bd46f1b3bb15376d7aaa7632c81", + "sha256:caf528ff9e7308b74a1749c183d6808ffbedbb9fb6af78b033c28974d9b8831f", + "sha256:cba1d078cf2e1e0b8402e6bda528bf8fda7ccd158c3dba6c012b7897747c41a0", + "sha256:d050a1ec7e925f514f0f6594a1e522580317da31fbda1af71d1530d6ea1f2b40", + "sha256:da8df5b89a41f1fd31503b179d0a84a5fdb752dddd5b5388dbd1ae23cda31ce9", + "sha256:f2f4349a28e3228a42958f8ddaa6333d6f8282d5edaea456070e48609c5983b7" + ], + "markers": "python_version >= '3.8'", + "version": "==1.8.7" }, "decorator": { "hashes": [ @@ -581,11 +595,11 @@ }, "httpcore": { "hashes": [ - "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", - "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5" + "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", + "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f" ], "markers": "python_version >= '3.8'", - "version": "==1.0.5" + "version": "==1.0.6" }, "httpx": { "hashes": [ @@ -597,11 +611,11 @@ }, "idna": { "hashes": [ - "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac", - "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], "markers": "python_version >= '3.6'", - "version": "==3.8" + "version": "==3.10" }, "imagesize": { "hashes": [ @@ -613,11 +627,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1", - "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5" + "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", + "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7" ], "markers": "python_version >= '3.8'", - "version": "==8.4.0" + "version": "==8.5.0" }, "ipykernel": { "hashes": [ @@ -629,11 +643,11 @@ }, "ipython": { "hashes": [ - "sha256:0b99a2dc9f15fd68692e898e5568725c6d49c527d36a9fb5960ffbdeaa82ff7e", - "sha256:f68b3cb8bde357a5d7adc9598d57e22a45dfbea19eb6b98286fa3b288c9cd55c" + "sha256:0d0d15ca1e01faeb868ef56bc7ee5a0de5bd66885735682e8a322ae289a13d1a", + "sha256:530ef1e7bb693724d3cdc37287c80b07ad9b25986c007a53aa1857272dac3f35" ], "markers": "python_version >= '3.10'", - "version": "==8.27.0" + "version": "==8.28.0" }, "isoduration": { "hashes": [ @@ -660,11 +674,11 @@ }, "jaraco.functools": { "hashes": [ - "sha256:3460c74cd0d32bf82b9576bbb3527c4364d5b27a21f5158a62aed6c4b42e23f5", - "sha256:c9d16a3ed4ccb5a889ad8e0b7a343401ee5b2a71cee6ed192d3f68bc351e94e3" + "sha256:70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", + "sha256:ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649" ], "markers": "python_version >= '3.8'", - "version": "==4.0.2" + "version": "==4.1.0" }, "jedi": { "hashes": [ @@ -710,19 +724,19 @@ }, "jsonschema-specifications": { "hashes": [ - "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", - "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" + "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", + "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf" ], - "markers": "python_version >= '3.8'", - "version": "==2023.12.1" + "markers": "python_version >= '3.9'", + "version": "==2024.10.1" }, "jupyter-client": { "hashes": [ - "sha256:2bda14d55ee5ba58552a8c53ae43d215ad9868853489213f37da060ced54d8df", - "sha256:50cbc5c66fd1b8f65ecb66bc490ab73217993632809b6e505687de18e9dea39f" + "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", + "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f" ], "markers": "python_version >= '3.8'", - "version": "==8.6.2" + "version": "==8.6.3" }, "jupyter-core": { "hashes": [ @@ -791,11 +805,11 @@ }, "keyring": { "hashes": [ - "sha256:8d85a1ea5d6db8515b59e1c5d1d1678b03cf7fc8b8dcfb1651e8c4a524eb42ef", - "sha256:8d963da00ccdf06e356acd9bf3b743208878751032d8599c6cc89eb51310ffae" + "sha256:5426f817cf7f6f007ba5ec722b1bcad95a75b27d780343772ad76b17cb47b0bf", + "sha256:b07ebc55f3e8ed86ac81dd31ef14e81ace9dd9c3d4b5d77a6e9a2016d0d71a1b" ], "markers": "python_version >= '3.8'", - "version": "==25.3.0" + "version": "==25.4.1" }, "markdown-it-py": { "hashes": [ @@ -807,69 +821,70 @@ }, "markupsafe": { "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", + "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", + "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", + "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8", + "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", + "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", + "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a", + "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", + "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", + "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6", + "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", + "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", + "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a", + "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8", + "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", + "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", + "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170", + "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132", + "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", + "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", + "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9", + "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", + "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", + "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589", + "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", + "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", + "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", + "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", + "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea", + "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", + "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", + "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b", + "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", + "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b", + "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", + "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", + "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", + "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", + "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", + "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", + "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b", + "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", + "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", + "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", + "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", + "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", + "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25", + "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", + "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", + "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", + "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97", + "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1", + "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd", + "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", + "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a", + "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", + "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca", + "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6", + "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", + "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", + "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.5" + "markers": "python_version >= '3.9'", + "version": "==3.0.1" }, "matplotlib-inline": { "hashes": [ @@ -966,62 +981,63 @@ }, "numpy": { "hashes": [ - "sha256:046356b19d7ad1890c751b99acad5e82dc4a02232013bd9a9a712fddf8eb60f5", - "sha256:0b8cc2715a84b7c3b161f9ebbd942740aaed913584cae9cdc7f8ad5ad41943d0", - "sha256:0d07841fd284718feffe7dd17a63a2e6c78679b2d386d3e82f44f0108c905550", - "sha256:13cc11c00000848702322af4de0147ced365c81d66053a67c2e962a485b3717c", - "sha256:13ce49a34c44b6de5241f0b38b07e44c1b2dcacd9e36c30f9c2fcb1bb5135db7", - "sha256:24c2ad697bd8593887b019817ddd9974a7f429c14a5469d7fad413f28340a6d2", - "sha256:251105b7c42abe40e3a689881e1793370cc9724ad50d64b30b358bbb3a97553b", - "sha256:2ca4b53e1e0b279142113b8c5eb7d7a877e967c306edc34f3b58e9be12fda8df", - "sha256:3269c9eb8745e8d975980b3a7411a98976824e1fdef11f0aacf76147f662b15f", - "sha256:397bc5ce62d3fb73f304bec332171535c187e0643e176a6e9421a6e3eacef06d", - "sha256:3fc5eabfc720db95d68e6646e88f8b399bfedd235994016351b1d9e062c4b270", - "sha256:50a95ca3560a6058d6ea91d4629a83a897ee27c00630aed9d933dff191f170cd", - "sha256:52ac2e48f5ad847cd43c4755520a2317f3380213493b9d8a4c5e37f3b87df504", - "sha256:53e27293b3a2b661c03f79aa51c3987492bd4641ef933e366e0f9f6c9bf257ec", - "sha256:57eb525e7c2a8fdee02d731f647146ff54ea8c973364f3b850069ffb42799647", - "sha256:5889dd24f03ca5a5b1e8a90a33b5a0846d8977565e4ae003a63d22ecddf6782f", - "sha256:59ca673ad11d4b84ceb385290ed0ebe60266e356641428c845b39cd9df6713ab", - "sha256:6435c48250c12f001920f0751fe50c0348f5f240852cfddc5e2f97e007544cbe", - "sha256:6e5a9cb2be39350ae6c8f79410744e80154df658d5bea06e06e0ac5bb75480d5", - "sha256:7be6a07520b88214ea85d8ac8b7d6d8a1839b0b5cb87412ac9f49fa934eb15d5", - "sha256:7c803b7934a7f59563db459292e6aa078bb38b7ab1446ca38dd138646a38203e", - "sha256:7dd86dfaf7c900c0bbdcb8b16e2f6ddf1eb1fe39c6c8cca6e94844ed3152a8fd", - "sha256:8661c94e3aad18e1ea17a11f60f843a4933ccaf1a25a7c6a9182af70610b2313", - "sha256:8ae0fd135e0b157365ac7cc31fff27f07a5572bdfc38f9c2d43b2aff416cc8b0", - "sha256:910b47a6d0635ec1bd53b88f86120a52bf56dcc27b51f18c7b4a2e2224c29f0f", - "sha256:913cc1d311060b1d409e609947fa1b9753701dac96e6581b58afc36b7ee35af6", - "sha256:920b0911bb2e4414c50e55bd658baeb78281a47feeb064ab40c2b66ecba85553", - "sha256:950802d17a33c07cba7fd7c3dcfa7d64705509206be1606f196d179e539111ed", - "sha256:981707f6b31b59c0c24bcda52e5605f9701cb46da4b86c2e8023656ad3e833cb", - "sha256:98ce7fb5b8063cfdd86596b9c762bf2b5e35a2cdd7e967494ab78a1fa7f8b86e", - "sha256:99f4a9ee60eed1385a86e82288971a51e71df052ed0b2900ed30bc840c0f2e39", - "sha256:9a8e06c7a980869ea67bbf551283bbed2856915f0a792dc32dd0f9dd2fb56728", - "sha256:ae8ce252404cdd4de56dcfce8b11eac3c594a9c16c231d081fb705cf23bd4d9e", - "sha256:afd9c680df4de71cd58582b51e88a61feed4abcc7530bcd3d48483f20fc76f2a", - "sha256:b49742cdb85f1f81e4dc1b39dcf328244f4d8d1ded95dea725b316bd2cf18c95", - "sha256:b5613cfeb1adfe791e8e681128f5f49f22f3fcaa942255a6124d58ca59d9528f", - "sha256:bab7c09454460a487e631ffc0c42057e3d8f2a9ddccd1e60c7bb8ed774992480", - "sha256:c8a0e34993b510fc19b9a2ce7f31cb8e94ecf6e924a40c0c9dd4f62d0aac47d9", - "sha256:caf5d284ddea7462c32b8d4a6b8af030b6c9fd5332afb70e7414d7fdded4bfd0", - "sha256:cea427d1350f3fd0d2818ce7350095c1a2ee33e30961d2f0fef48576ddbbe90f", - "sha256:d0cf7d55b1051387807405b3898efafa862997b4cba8aa5dbe657be794afeafd", - "sha256:d10c39947a2d351d6d466b4ae83dad4c37cd6c3cdd6d5d0fa797da56f710a6ae", - "sha256:d2b9cd92c8f8e7b313b80e93cedc12c0112088541dcedd9197b5dee3738c1201", - "sha256:d4c57b68c8ef5e1ebf47238e99bf27657511ec3f071c465f6b1bccbef12d4136", - "sha256:d51fc141ddbe3f919e91a096ec739f49d686df8af254b2053ba21a910ae518bf", - "sha256:e097507396c0be4e547ff15b13dc3866f45f3680f789c1a1301b07dadd3fbc78", - "sha256:e30356d530528a42eeba51420ae8bf6c6c09559051887196599d96ee5f536468", - "sha256:e8d5f8a8e3bc87334f025194c6193e408903d21ebaeb10952264943a985066ca", - "sha256:e8dfa9e94fc127c40979c3eacbae1e61fda4fe71d84869cc129e2721973231ef", - "sha256:f212d4f46b67ff604d11fff7cc62d36b3e8714edf68e44e9760e19be38c03eb0", - "sha256:f7506387e191fe8cdb267f912469a3cccc538ab108471291636a96a54e599556", - "sha256:fac6e277a41163d27dfab5f4ec1f7a83fac94e170665a4a50191b545721c6521", - "sha256:fcd8f556cdc8cfe35e70efb92463082b7f43dd7e547eb071ffc36abc0ca4699b" - ], - "markers": "python_version == '3.11'", - "version": "==2.1.1" + "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8", + "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466", + "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35", + "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c", + "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4", + "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6", + "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0", + "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7", + "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a", + "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a", + "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e", + "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62", + "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2", + "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5", + "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee", + "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe", + "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a", + "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e", + "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf", + "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c", + "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3", + "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86", + "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df", + "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98", + "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d", + "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2", + "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146", + "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550", + "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8", + "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb", + "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e", + "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d", + "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366", + "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0", + "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db", + "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe", + "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426", + "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952", + "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03", + "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f", + "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7", + "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b", + "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17", + "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5", + "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1", + "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142", + "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884", + "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", + "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9", + "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445", + "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1", + "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1", + "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==2.1.2" }, "overrides": { "hashes": [ @@ -1041,39 +1057,52 @@ }, "pandas": { "hashes": [ - "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863", - "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2", - "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1", - "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad", - "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db", - "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76", - "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51", - "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32", - "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08", - "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b", - "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4", - "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921", - "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288", - "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee", - "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0", - "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24", - "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99", - "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151", - "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd", - "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce", - "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57", - "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef", - "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54", - "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a", - "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238", - "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23", - "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772", - "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce", - "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad" + "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", + "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d", + "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5", + "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4", + "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0", + "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32", + "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea", + "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28", + "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f", + "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348", + "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18", + "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468", + "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5", + "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e", + "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", + "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645", + "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", + "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30", + "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3", + "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d", + "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb", + "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3", + "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039", + "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", + "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd", + "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761", + "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659", + "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57", + "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c", + "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c", + "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4", + "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", + "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9", + "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42", + "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2", + "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39", + "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc", + "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698", + "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed", + "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015", + "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24", + "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==2.2.2" + "version": "==2.2.3" }, "pandocfilters": { "hashes": [ @@ -1092,11 +1121,11 @@ }, "parse-type": { "hashes": [ - "sha256:8d94a52e0197fbad63fee8f70df16e6ed689e5e4f105b705c9afa7a30397a5aa", - "sha256:8e99d2f52fab2f0f1f3d68ba9d026060140bf0e53680aada0111fb27b2f0e93a" + "sha256:5e1ec10440b000c3f818006033372939e693a9ec0176f446d9303e4db88489a6", + "sha256:83d41144a82d6b8541127bf212dd76c7f01baff680b498ce8a4d052a7a5bce4c" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.6.3" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1'", + "version": "==0.6.4" }, "parso": { "hashes": [ @@ -1124,27 +1153,27 @@ }, "platformdirs": { "hashes": [ - "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c", - "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617" + "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", + "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb" ], "markers": "python_version >= '3.8'", - "version": "==4.3.2" + "version": "==4.3.6" }, "prometheus-client": { "hashes": [ - "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89", - "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7" + "sha256:4fa6b4dd0ac16d58bb587c04b1caae65b8c5043e85f778f42f5f632f6af2e166", + "sha256:96c83c606b71ff2b0a433c98889d275f51ffec6c5e267de37c7a2b5c9aa9233e" ], "markers": "python_version >= '3.8'", - "version": "==0.20.0" + "version": "==0.21.0" }, "prompt-toolkit": { "hashes": [ - "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10", - "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360" + "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90", + "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.0.47" + "version": "==3.0.48" }, "psutil": { "hashes": [ @@ -1205,7 +1234,7 @@ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.9.0.post0" }, "python-json-logger": { @@ -1218,10 +1247,10 @@ }, "pytz": { "hashes": [ - "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812", - "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319" + "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", + "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725" ], - "version": "==2024.1" + "version": "==2024.2" }, "pyyaml": { "hashes": [ @@ -1455,11 +1484,11 @@ }, "rich": { "hashes": [ - "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc", - "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4" + "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", + "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.8.0" + "markers": "python_full_version >= '3.8.0'", + "version": "==13.9.2" }, "rpds-py": { "hashes": [ @@ -1580,18 +1609,18 @@ }, "setuptools": { "hashes": [ - "sha256:5f4c08aa4d3ebcb57a50c33b1b07e94315d7fc7230f7115e47fc99776c8ce308", - "sha256:95b40ed940a1c67eb70fc099094bd6e99c6ee7c23aa2306f4d2697ba7916f9c6" + "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec", + "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8" ], "markers": "python_version >= '3.8'", - "version": "==74.1.2" + "version": "==75.2.0" }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "sniffio": { @@ -1619,12 +1648,12 @@ }, "sphinx": { "hashes": [ - "sha256:0cce1ddcc4fd3532cf1dd283bc7d886758362c5c1de6598696579ce96d8ffa5b", - "sha256:56173572ae6c1b9a38911786e206a110c9749116745873feae4f9ce88e59391d" + "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2", + "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927" ], "index": "pypi", "markers": "python_version >= '3.10'", - "version": "==8.0.2" + "version": "==8.1.3" }, "sphinxcontrib-applehelp": { "hashes": [ @@ -1733,27 +1762,19 @@ }, "types-python-dateutil": { "hashes": [ - "sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6", - "sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e" + "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d", + "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446" ], "markers": "python_version >= '3.8'", - "version": "==2.9.0.20240906" - }, - "typing-extensions": { - "hashes": [ - "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", - "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" - ], - "markers": "python_version < '3.12'", - "version": "==4.12.2" + "version": "==2.9.0.20241003" }, "tzdata": { "hashes": [ - "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd", - "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252" + "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc", + "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd" ], "markers": "python_version >= '2'", - "version": "==2024.1" + "version": "==2024.2" }, "uri-template": { "hashes": [ @@ -1764,11 +1785,11 @@ }, "urllib3": { "hashes": [ - "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", - "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" + "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" ], "markers": "python_version >= '3.8'", - "version": "==2.2.2" + "version": "==2.2.3" }, "wcwidth": { "hashes": [ @@ -1801,11 +1822,11 @@ }, "zipp": { "hashes": [ - "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064", - "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b" + "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", + "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29" ], "markers": "python_version >= '3.8'", - "version": "==3.20.1" + "version": "==3.20.2" } }, "graphql": { @@ -1907,99 +1928,114 @@ }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "version": "==3.4.0" }, "cryptography": { "hashes": [ @@ -2036,12 +2072,12 @@ }, "django": { "hashes": [ - "sha256:021ffb7fdab3d2d388bc8c7c2434eb9c1f6f4d09e6119010bbb1694dda286bc2", - "sha256:71603f27dac22a6533fb38d83072eea9ddb4017fead6f67f2562a40402d61c3f" + "sha256:bd7376f90c99f96b643722eee676498706c9fd7dc759f55ebfaf2c08ebcdf4f0", + "sha256:f11aa87ad8d5617171e3f77e1d5d16f004b79a2cf5d2e1d2b97a6a1f8e9ba5ed" ], "index": "pypi", "markers": "python_version >= '3.10'", - "version": "==5.1.1" + "version": "==5.1.2" }, "django-filter": { "hashes": [ @@ -2079,11 +2115,11 @@ }, "graphql-core": { "hashes": [ - "sha256:1604f2042edc5f3114f49cac9d77e25863be51b23a54a61a23245cf32f6476f0", - "sha256:acbe2e800980d0e39b4685dd058c2f4042660b89ebca38af83020fd872ff1264" + "sha256:2f150d5096448aa4f8ab26268567bbfeef823769893b39c1a2e1409590939c8a", + "sha256:e671b90ed653c808715645e3998b7ab67d382d55467b7e2978549111bbabf8d5" ], "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==3.2.4" + "version": "==3.2.5" }, "graphql-relay": { "hashes": [ @@ -2095,11 +2131,11 @@ }, "idna": { "hashes": [ - "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac", - "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], "markers": "python_version >= '3.6'", - "version": "==3.8" + "version": "==3.10" }, "jwcrypto": { "hashes": [ @@ -2144,7 +2180,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "sqlparse": { @@ -2172,11 +2208,11 @@ }, "urllib3": { "hashes": [ - "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", - "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" + "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" ], "markers": "python_version >= '3.8'", - "version": "==2.2.2" + "version": "==2.2.3" } }, "pdf": { @@ -2190,147 +2226,148 @@ }, "fonttools": { "hashes": [ - "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122", - "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397", - "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f", - "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d", - "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60", - "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169", - "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8", - "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31", - "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923", - "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2", - "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb", - "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab", - "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb", - "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a", - "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670", - "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8", - "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407", - "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671", - "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88", - "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f", - "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f", - "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0", - "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb", - "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2", - "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d", - "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c", - "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3", - "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719", - "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749", - "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4", - "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f", - "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02", - "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58", - "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1", - "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41", - "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4", - "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb", - "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb", - "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3", - "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d", - "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d", - "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2" - ], - "markers": "python_version >= '3.8'", - "version": "==4.53.1" + "sha256:07e005dc454eee1cc60105d6a29593459a06321c21897f769a281ff2d08939f6", + "sha256:0a911591200114969befa7f2cb74ac148bce5a91df5645443371aba6d222e263", + "sha256:0d1d353ef198c422515a3e974a1e8d5b304cd54a4c2eebcae708e37cd9eeffb1", + "sha256:0e88e3018ac809b9662615072dcd6b84dca4c2d991c6d66e1970a112503bba7e", + "sha256:1d152d1be65652fc65e695e5619e0aa0982295a95a9b29b52b85775243c06556", + "sha256:262705b1663f18c04250bd1242b0515d3bbae177bee7752be67c979b7d47f43d", + "sha256:278913a168f90d53378c20c23b80f4e599dca62fbffae4cc620c8eed476b723e", + "sha256:301540e89cf4ce89d462eb23a89464fef50915255ece765d10eee8b2bf9d75b2", + "sha256:31c32d7d4b0958600eac75eaf524b7b7cb68d3a8c196635252b7a2c30d80e986", + "sha256:357cacb988a18aace66e5e55fe1247f2ee706e01debc4b1a20d77400354cddeb", + "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd", + "sha256:41bb0b250c8132b2fcac148e2e9198e62ff06f3cc472065dff839327945c5882", + "sha256:4aa4817f0031206e637d1e685251ac61be64d1adef111060df84fdcbc6ab6c44", + "sha256:4e10d2e0a12e18f4e2dd031e1bf7c3d7017be5c8dbe524d07706179f355c5dac", + "sha256:5419771b64248484299fa77689d4f3aeed643ea6630b2ea750eeab219588ba20", + "sha256:54471032f7cb5fca694b5f1a0aaeba4af6e10ae989df408e0216f7fd6cdc405d", + "sha256:58974b4987b2a71ee08ade1e7f47f410c367cdfc5a94fabd599c88165f56213a", + "sha256:58d29b9a294573d8319f16f2f79e42428ba9b6480442fa1836e4eb89c4d9d61c", + "sha256:5eb2474a7c5be8a5331146758debb2669bf5635c021aee00fd7c353558fc659d", + "sha256:6e37561751b017cf5c40fce0d90fd9e8274716de327ec4ffb0df957160be3bff", + "sha256:76ae5091547e74e7efecc3cbf8e75200bc92daaeb88e5433c5e3e95ea8ce5aa7", + "sha256:7965af9b67dd546e52afcf2e38641b5be956d68c425bef2158e95af11d229f10", + "sha256:7e3b7d44e18c085fd8c16dcc6f1ad6c61b71ff463636fcb13df7b1b818bd0c02", + "sha256:7ed7ee041ff7b34cc62f07545e55e1468808691dddfd315d51dd82a6b37ddef2", + "sha256:82834962b3d7c5ca98cb56001c33cf20eb110ecf442725dc5fdf36d16ed1ab07", + "sha256:8583e563df41fdecef31b793b4dd3af8a9caa03397be648945ad32717a92885b", + "sha256:8fa92cb248e573daab8d032919623cc309c005086d743afb014c836636166f08", + "sha256:93d458c8a6a354dc8b48fc78d66d2a8a90b941f7fec30e94c7ad9982b1fa6bab", + "sha256:957f669d4922f92c171ba01bef7f29410668db09f6c02111e22b2bce446f3285", + "sha256:9dc080e5a1c3b2656caff2ac2633d009b3a9ff7b5e93d0452f40cd76d3da3b3c", + "sha256:9ef1b167e22709b46bf8168368b7b5d3efeaaa746c6d39661c1b4405b6352e58", + "sha256:a7a310c6e0471602fe3bf8efaf193d396ea561486aeaa7adc1f132e02d30c4b9", + "sha256:ab774fa225238986218a463f3fe151e04d8c25d7de09df7f0f5fce27b1243dbc", + "sha256:ada215fd079e23e060157aab12eba0d66704316547f334eee9ff26f8c0d7b8ab", + "sha256:c39287f5c8f4a0c5a55daf9eaf9ccd223ea59eed3f6d467133cc727d7b943a55", + "sha256:c9c563351ddc230725c4bdf7d9e1e92cbe6ae8553942bd1fb2b2ff0884e8b714", + "sha256:d26732ae002cc3d2ecab04897bb02ae3f11f06dd7575d1df46acd2f7c012a8d8", + "sha256:d3b659d1029946f4ff9b6183984578041b520ce0f8fb7078bb37ec7445806b33", + "sha256:dd9cc95b8d6e27d01e1e1f1fae8559ef3c02c76317da650a19047f249acd519d", + "sha256:e4564cf40cebcb53f3dc825e85910bf54835e8a8b6880d59e5159f0f325e637e", + "sha256:e7d82b9e56716ed32574ee106cabca80992e6bbdcf25a88d97d21f73a0aae664", + "sha256:e8a4b261c1ef91e7188a30571be6ad98d1c6d9fa2427244c545e2fa0a2494dd7", + "sha256:e96bc94c8cda58f577277d4a71f51c8e2129b8b36fd05adece6320dd3d57de8a", + "sha256:ed2f80ca07025551636c555dec2b755dd005e2ea8fbeb99fc5cdff319b70b23b", + "sha256:f5b8a096e649768c2f4233f947cf9737f8dbf8728b90e2771e2497c6e3d21d13", + "sha256:f8e953cc0bddc2beaf3a3c3b5dd9ab7554677da72dfaf46951e193c9653e515a", + "sha256:fda582236fee135d4daeca056c8c88ec5f6f6d88a004a79b84a02547c8f57386", + "sha256:fdb062893fd6d47b527d39346e0c5578b7957dcea6d6a3b6794569370013d9ac" + ], + "markers": "python_version >= '3.8'", + "version": "==4.54.1" }, "fpdf2": { "hashes": [ - "sha256:1f176aea4a1cc0fa1da5c799fce8f8bcfe2e936b9d2298a75514c9efc7528bfa", - "sha256:f364c0d816a5e364eeeda9761cf5c961bae8c946f080cf87fed7f38ab773b318" + "sha256:02f9e81ea5a0ec723c467de392bc6f4c54ea7859857e6fcee46579bd02bd335f", + "sha256:8866161396f942c8f7e3f022c4afb5e671b4d044745d4ed13c5d2ccc16ae5091" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.7.9" + "version": "==2.8.1" }, "pillow": { "hashes": [ - "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885", - "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea", - "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df", - "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5", - "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c", - "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d", - "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd", - "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06", - "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908", - "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a", - "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be", - "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0", - "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b", - "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80", - "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a", - "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e", - "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9", - "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696", - "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b", - "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309", - "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e", - "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab", - "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d", - "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060", - "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d", - "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d", - "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4", - "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3", - "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6", - "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb", - "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94", - "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b", - "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496", - "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0", - "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319", - "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b", - "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856", - "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef", - "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680", - "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b", - "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42", - "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e", - "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597", - "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a", - "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8", - "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3", - "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736", - "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da", - "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126", - "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd", - "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5", - "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b", - "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026", - "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b", - "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc", - "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46", - "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2", - "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c", - "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe", - "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984", - "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a", - "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70", - "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca", - "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b", - "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91", - "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3", - "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84", - "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1", - "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5", - "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be", - "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f", - "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc", - "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9", - "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e", - "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141", - "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef", - "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22", - "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27", - "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e", - "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1" + "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7", + "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5", + "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903", + "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2", + "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38", + "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2", + "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9", + "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f", + "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc", + "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8", + "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d", + "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2", + "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316", + "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a", + "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25", + "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd", + "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba", + "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc", + "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273", + "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa", + "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a", + "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b", + "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a", + "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae", + "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291", + "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97", + "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06", + "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904", + "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b", + "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b", + "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8", + "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527", + "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947", + "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb", + "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003", + "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5", + "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f", + "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739", + "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944", + "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830", + "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f", + "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3", + "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4", + "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84", + "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7", + "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6", + "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6", + "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9", + "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de", + "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4", + "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47", + "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd", + "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50", + "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c", + "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086", + "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba", + "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306", + "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699", + "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e", + "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488", + "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa", + "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2", + "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3", + "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9", + "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923", + "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2", + "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790", + "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734", + "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916", + "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1", + "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f", + "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798", + "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb", + "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2", + "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==10.4.0" + "markers": "python_version >= '3.9'", + "version": "==11.0.0" } } } diff --git a/README.md b/README.md index 0d2cee57..12cfca48 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,48 @@ ![django ledger logo](https://us-east-1.linodeobjects.com/django-ledger/logo/django-ledger-logo@2x.png) -### An Accounting, Bookkeeping & Financial Analysis Engine for the Django Framework. +Here's a more concise and readable version of the Django Ledger README: -Introducing __Django Ledger__, a powerful double entry accounting system designed for financially driven applications -using the [Django Web Framework](https://www.djangoproject.com). Developed by lead developer Miguel Sanda, this system -offers a simplified, high-level API, making it easier for users to navigate the complexities of accounting. +# Django Ledger -If you have prior experience with Django, you'll find this software even more effective. And, for those interested -in contributing, consider joining our new discord channel for further collaboration and discussions. +## A Double Entry Accounting Engine for Django -### Questions? Join our Discord Channel [Here](https://discord.gg/c7PZcbYgrc) +Django Ledger is a powerful financial management system built on the Django Web Framework. It offers a simplified API for handling complex accounting tasks in financially driven applications. -### Documentation +[Join our Discord](https://discord.gg/c7PZcbYgrc) | [Documentation](https://django-ledger.readthedocs.io/en/latest/) | [QuickStart Notebook](https://github.com/arrobalytics/django-ledger/blob/develop/notebooks/QuickStart%20Notebook.ipynb) -Access the latest documentation and QuickStart guide [here](https://django-ledger.readthedocs.io/en/latest/). -Also, you may download the QuickStart Jupyter Notebook -[here](https://github.com/arrobalytics/django-ledger/blob/develop/notebooks/QuickStart%20Notebook.ipynb). +## Key Features -# Main Features +- High-level API +- Double entry accounting +- Hierarchical Chart of Accounts +- Financial statements (Income Statement, Balance Sheet, Cash Flow) +- Purchase Orders, Sales Orders, Bills, and Invoices +- Financial ratio calculations +- Multi-tenancy support +- Ledgers, Journal Entries & Transactions +- OFX & QFX file import +- Closing Entries +- Inventory management +- Unit of Measures +- Bank account information +- Django Admin integration +- Built-in Entity Management UI -- High Level API. -- Double entry accounting system. -- Multiple Hierarchical Chart of Accounts. -- Financial Statements (Income Statement, Balance Sheet & Cash Flow Statement). -- Purchase Orders, Sales Orders (Estimates), Bills and Invoices. -- Automatic financial ratio & insight calculations. -- Multi tenancy (multiple companies/users/clients). -- Self-contained Ledgers, Journal Entries & Transactions. -- Basic OFX & QFX file import. -- Closing Entries. -- Items, lists & inventory management. -- Unit of Measures. -- Bank Accounts Information. -- Django Admin Classes. -- Built In Entity Management UI. +## Getting Involved -## Need a new feature or report a bug? -Feel free to initiate an Issue describing your new feature request. +- **Feature Requests/Bug Reports**: Open an issue in the repository +- **For software customization, advanced features and consulting services**: +[Contact us](https://www.miguelsanda.com/work-with-me/) or email msanda@arrobalytics.com +- **Contribute**: See our [contribution guidelines](https://github.com/arrobalytics/django-ledger/blob/master/Contribute.md) -# Want to contribute? +## Who Should Contribute? -Finance and Accounting is a complicated subject. Django Ledger stands out from other Django projects due to its focus -on providing a developer-friendly accounting engine and a reliable, extensible API for financially driven applications. -The project requires expertise in Python, Django programming, finance, and accounting. In essence, the project is -seeking assistance from individuals with the specific skill set needed to contribute effectively. +We're looking for contributors with: +- Python and Django programming skills +- Finance and accounting expertise +- Interest in developing a robust accounting engine API -The project is actively seeking contributors with financial and/or accounting experience. Prior accounting experience -is a big plus for potential contributors. If you have the relevant experience and want to contribute, feel free to -reach out to me or submit your pull request. - -You can find the contribution guidelines at the specified link. -The project welcomes anyone interested in making a contribution. - -See __[contribution guidelines](https://github.com/arrobalytics/django-ledger/blob/develop/Contribute.md)__. +If you have relevant experience, especially in accounting, we welcome your pull requests or direct contact. # Installation diff --git a/django_ledger/__init__.py b/django_ledger/__init__.py index a9e80dda..d5cecb37 100644 --- a/django_ledger/__init__.py +++ b/django_ledger/__init__.py @@ -1,15 +1,12 @@ """ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. - -Contributions to this module: - * Miguel Sanda """ default_app_config = 'django_ledger.apps.DjangoLedgerConfig' """Django Ledger""" -__version__ = '0.6.4' +__version__ = '0.7.0' __license__ = 'GPLv3 License' __author__ = 'Miguel Sanda' diff --git a/django_ledger/contrib/django_ledger_graphene/accounts/schema.py b/django_ledger/contrib/django_ledger_graphene/accounts/schema.py index 4e60b051..bf2a2890 100644 --- a/django_ledger/contrib/django_ledger_graphene/accounts/schema.py +++ b/django_ledger/contrib/django_ledger_graphene/accounts/schema.py @@ -25,7 +25,7 @@ class Accountlist_Query(graphene.ObjectType): def resolve_all_accounts(self, info, slug_name, **kwargs): if info.context.user.is_authenticated: return AccountModel.objects.for_entity( - entity_slug=slug_name, + entity_model=slug_name, user_model=info.context.user, ).select_related('parent').order_by('code') else: diff --git a/django_ledger/forms/account.py b/django_ledger/forms/account.py index 35e5e71e..e8a00f63 100644 --- a/django_ledger/forms/account.py +++ b/django_ledger/forms/account.py @@ -1,47 +1,49 @@ +""" +Django Ledger created by Miguel Sanda . +Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. + +Contributions to this module: + * Miguel Sanda +""" +from random import randint from typing import Optional -from django.forms import TextInput, Select, ModelForm, ChoiceField, ValidationError, CheckboxInput +from django.forms import TextInput, Select, ModelForm, ChoiceField, ValidationError, CheckboxInput, HiddenInput from django.utils.translation import gettext_lazy as _ from treebeard.forms import MoveNodeForm from django_ledger.io import ACCOUNT_CHOICES_NO_ROOT +from django_ledger.models import ChartOfAccountModel, EntityModel from django_ledger.models.accounts import AccountModel from django_ledger.settings import DJANGO_LEDGER_FORM_INPUT_CLASSES -""" -The account Model has the below forms: All these form have Account Model as their base. - -CreateForm -CreateChildForm -Update Form -""" - class AccountModelCreateForm(ModelForm): """ - AccountModelCreateForm - ====================== - A form for creating and managing account models within the system. Attributes ---------- - ENTITY : Model + ENTITY_MODEL : Model The entity model being used in the form. COA_MODEL : Model The Chart of Account Model being used in the form. - USER_MODEL : Model - The user model being used in the form. - """ - def __init__(self, entity_model, coa_model, user_model, *args, **kwargs): - self.ENTITY = entity_model - self.COA_MODEL = coa_model - self.USER_MODEL = user_model + FORM_ID_SEP = '___' + + def __init__(self, coa_model: ChartOfAccountModel, *args, **kwargs): + self.COA_MODEL: ChartOfAccountModel = coa_model super().__init__(*args, **kwargs) self.fields['role'].choices = ACCOUNT_CHOICES_NO_ROOT self.fields['code'].required = False + self.fields['coa_model'].disabled = True + self.fields['coa_model'].required = False + + self.form_id: str = self.get_form_id() + + def get_form_id(self) -> str: + return f'account-model-create-form-{self.COA_MODEL.slug}{self.FORM_ID_SEP}{randint(100000, 999999)}' def clean_role_default(self): role_default = self.cleaned_data['role_default'] @@ -49,12 +51,8 @@ def clean_role_default(self): return None return role_default - def clean_code(self): - code = self.cleaned_data['code'] - is_code_valid = not self.COA_MODEL.accountmodel_set.filter(code=code).exists() - if not is_code_valid: - raise ValidationError(message=_('Code {} already exists for CoA {}').format(code, self.COA_MODEL.slug)) - return code + def clean_coa_model(self): + return self.COA_MODEL class Meta: model = AccountModel @@ -65,7 +63,8 @@ class Meta: 'role_default', 'balance_type', 'active', - 'active' + 'active', + 'coa_model' ] widgets = { 'code': TextInput(attrs={ @@ -83,6 +82,7 @@ class Meta: 'balance_type': Select(attrs={ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES }), + 'coa_model': HiddenInput() } @@ -101,22 +101,22 @@ class AccountModelUpdateForm(MoveNodeForm): """ _position = ChoiceField(required=True, - label=_("Position"), + label=_('Position'), widget=Select(attrs={ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES })) _ref_node_id = ChoiceField(required=False, - label=_("Relative to"), + label=_('Relative to'), widget=Select(attrs={ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES })) - def __init__(self, entity_model, coa_model, user_model, *args, **kwargs): - self.ENTITY = entity_model - self.COA_MODEL = coa_model - self.USER_MODEL = user_model + + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - # self.fields['_ref_node_id'].choices = self.mk_dropdown_tree_choices() + self.fields['role'].disabled = True + self.fields['coa_model'].disabled = True + @classmethod def mk_dropdown_tree(cls, model, for_node: Optional[AccountModel] = None): @@ -125,15 +125,18 @@ def mk_dropdown_tree(cls, model, for_node: Optional[AccountModel] = None): if not for_node: raise ValidationError(message='Must provide for_node argument.') - options = list() qs = for_node.get_account_move_choice_queryset() - # for node in qs: - # cls.add_subtree(for_node, node, options) return [ (i.uuid, f'{"-" * (i.depth - 1)} {i}') for i in qs ] + def clean_role(self): + return self.instance.role + + def coa_model(self): + return self.instance.coa_model + def clean_role_default(self): role_default = self.cleaned_data['role_default'] if not role_default: @@ -142,8 +145,10 @@ def clean_role_default(self): class Meta: model = AccountModel - exclude = ('depth', 'numchild', 'path', 'balance_type', 'role') + exclude = ('depth', 'numchild', 'path', 'balance_type') widgets = { + 'role': HiddenInput(), + 'coa_model': HiddenInput(), 'parent': Select(attrs={ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES }), diff --git a/django_ledger/forms/bank_account.py b/django_ledger/forms/bank_account.py index 8fa1bd71..e314b1bc 100644 --- a/django_ledger/forms/bank_account.py +++ b/django_ledger/forms/bank_account.py @@ -13,9 +13,10 @@ def __init__(self, *args, entity_slug, user_model, **kwargs): super().__init__(*args, **kwargs) self.ENTITY_SLUG = entity_slug self.USER_MODEL = user_model - account_qs = AccountModel.objects.for_entity_available( + account_qs = AccountModel.objects.for_entity( user_model=self.USER_MODEL, - entity_slug=self.ENTITY_SLUG).filter( + entity_model=self.ENTITY_SLUG + ).available().filter( role__exact=ASSET_CA_CASH) self.fields['cash_account'].queryset = account_qs diff --git a/django_ledger/forms/bill.py b/django_ledger/forms/bill.py index c2d8cee7..cc9bb4f0 100644 --- a/django_ledger/forms/bill.py +++ b/django_ledger/forms/bill.py @@ -6,25 +6,20 @@ from django_ledger.io.roles import ASSET_CA_CASH, ASSET_CA_PREPAID, LIABILITY_CL_ACC_PAYABLE from django_ledger.models import (ItemModel, AccountModel, BillModel, ItemTransactionModel, - VendorModel, EntityUnitModel) + VendorModel, EntityUnitModel, EntityModel) from django_ledger.settings import DJANGO_LEDGER_FORM_INPUT_CLASSES class BillModelCreateForm(ModelForm): - def __init__(self, *args, entity_slug, user_model, **kwargs): + def __init__(self, *args, entity_model: EntityModel, **kwargs): super().__init__(*args, **kwargs) - self.ENTITY_SLUG = entity_slug - self.USER_MODEL = user_model - self.BILL_MODEL: BillModel = self.instance + self.ENTITY_MODEL = entity_model self.get_vendor_queryset() self.get_accounts_queryset() def get_vendor_queryset(self): if 'vendor' in self.fields: - vendor_qs = VendorModel.objects.for_entity( - user_model=self.USER_MODEL, - entity_slug=self.ENTITY_SLUG - ) + vendor_qs = self.ENTITY_MODEL.vendormodel_set.active() self.fields['vendor'].queryset = vendor_qs def get_accounts_queryset(self): @@ -34,14 +29,7 @@ def get_accounts_queryset(self): 'prepaid_account' in self.fields, 'unearned_account' in self.fields, ]): - account_qs = AccountModel.objects.for_bill( - user_model=self.USER_MODEL, - entity_slug=self.ENTITY_SLUG - ) - - # forcing evaluation of qs to cache results for fields... (avoids multiple database queries) - len(account_qs) - + account_qs = self.ENTITY_MODEL.default_coa.accountmodel_set.all().for_bill() self.fields['cash_account'].queryset = account_qs.filter(role__exact=ASSET_CA_CASH) self.fields['prepaid_account'].queryset = account_qs.filter(role__exact=ASSET_CA_PREPAID) self.fields['unearned_account'].queryset = account_qs.filter(role__exact=LIABILITY_CL_ACC_PAYABLE) @@ -107,11 +95,11 @@ class BaseBillModelUpdateForm(BillModelCreateForm): def __init__(self, *args, - entity_slug, + entity_model, user_model, **kwargs): - super().__init__(entity_slug=entity_slug, user_model=user_model, *args, **kwargs) - self.ENTITY_SLUG = entity_slug + super().__init__(entity_model=entity_model, *args, **kwargs) + self.ENTITY_MODEL = entity_model self.USER_MODEL = user_model self.BILL_MODEL: BillModel = self.instance @@ -120,7 +108,7 @@ def save(self, commit=True): self.BILL_MODEL.update_state() self.instance.migrate_state( user_model=self.USER_MODEL, - entity_slug=self.ENTITY_SLUG, + entity_slug=self.ENTITY_MODEL.slug, raise_exception=False ) super().save(commit=commit) @@ -226,6 +214,10 @@ class Meta(BaseBillModelUpdateForm.Meta): class BillItemTransactionForm(ModelForm): + # def __init__(self, entity_unit_qs, *args, **kwargs): + # super().__init__(self, *args, **kwargs) + # self.fields['entity_unit'].queryset = entity_unit_qs + def clean(self): cleaned_data = super(BillItemTransactionForm, self).clean() itemtxs_model: ItemTransactionModel = self.instance @@ -262,28 +254,24 @@ class Meta: class BaseBillItemTransactionFormset(BaseModelFormSet): def __init__(self, *args, - entity_slug, + entity_model: EntityModel, bill_model: BillModel, - user_model, **kwargs): super().__init__(*args, **kwargs) - self.USER_MODEL = user_model self.BILL_MODEL = bill_model - self.ENTITY_SLUG = entity_slug - - items_qs = ItemModel.objects.for_bill( - entity_slug=self.ENTITY_SLUG, - user_model=self.USER_MODEL - ) + self.ENTITY_MODEL = entity_model + self.queryset = self.BILL_MODEL.itemtransactionmodel_set.select_related( + 'item_model', + 'po_model', + 'bill_model' + ).order_by('-total_amount') - unit_qs = EntityUnitModel.objects.for_entity( - entity_slug=self.ENTITY_SLUG, - user_model=self.USER_MODEL - ) + self.items_qs = self.ENTITY_MODEL.itemmodel_set.bills() + self.entity_unit_qs = self.ENTITY_MODEL.entityunitmodel_set.all() for form in self.forms: - form.fields['item_model'].queryset = items_qs - form.fields['entity_unit'].queryset = unit_qs + form.fields['item_model'].queryset = self.items_qs + form.fields['entity_unit'].queryset = self.entity_unit_qs if not self.BILL_MODEL.can_edit_items(): form.fields['item_model'].disabled = True diff --git a/django_ledger/forms/customer.py b/django_ledger/forms/customer.py index 15825f49..a39ed332 100644 --- a/django_ledger/forms/customer.py +++ b/django_ledger/forms/customer.py @@ -37,7 +37,7 @@ class Meta: 'hidden' ] help_texts = { - 'sales_tax_rate': _('Example: 3.50% should be entered as 0.0035') + 'sales_tax_rate': _('Example: 3.50% should be entered as 0.035') } widgets = { 'customer_name': TextInput(attrs={ diff --git a/django_ledger/forms/data_import.py b/django_ledger/forms/data_import.py index 759370f5..0fbf4f7d 100644 --- a/django_ledger/forms/data_import.py +++ b/django_ledger/forms/data_import.py @@ -130,10 +130,10 @@ def __init__(self, *args, entity_slug, user_model, exclude_account=None, **kwarg self.IMPORT_DISABLED = not exclude_account self.CASH_ACCOUNT = exclude_account - account_model_qs = AccountModel.objects.for_entity_available( + account_model_qs = AccountModel.objects.for_entity( user_model=self.USER_MODEL, - entity_slug=self.ENTITY_SLUG - ).order_by('role', 'name') + entity_model=self.ENTITY_SLUG + ).available().order_by('role', 'name') unit_model_qs = EntityUnitModel.objects.for_entity( user_model=self.USER_MODEL, diff --git a/django_ledger/forms/estimate.py b/django_ledger/forms/estimate.py index a9848c2d..86846276 100644 --- a/django_ledger/forms/estimate.py +++ b/django_ledger/forms/estimate.py @@ -27,7 +27,7 @@ def get_customer_queryset(self): return CustomerModel.objects.for_entity( entity_slug=self.ENTITY_SLUG, user_model=self.USER_MODEL - ) + ).active() class Meta: model = EstimateModel diff --git a/django_ledger/forms/invoice.py b/django_ledger/forms/invoice.py index de0d2883..b59dc2f0 100644 --- a/django_ledger/forms/invoice.py +++ b/django_ledger/forms/invoice.py @@ -31,7 +31,7 @@ def get_customer_queryset(self): customer_qs = CustomerModel.objects.for_entity( user_model=self.USER_MODEL, entity_slug=self.ENTITY_SLUG - ) + ).active() self.fields['customer'].queryset = customer_qs def get_accounts_queryset(self): @@ -41,13 +41,11 @@ def get_accounts_queryset(self): 'prepaid_account' in self.fields, 'unearned_account' in self.fields, ]): - account_qs = AccountModel.objects.for_invoice( - user_model=self.USER_MODEL, - entity_slug=self.ENTITY_SLUG - ) - # forcing evaluation of qs to cache results for fields... (avoids multiple database queries) - len(account_qs) + account_qs = AccountModel.objects.for_entity( + user_model=self.USER_MODEL, + entity_model=self.ENTITY_SLUG + ).for_invoice() self.fields['cash_account'].queryset = account_qs.filter(role__exact=ASSET_CA_CASH) self.fields['prepaid_account'].queryset = account_qs.filter(role__exact=ASSET_CA_RECEIVABLES) diff --git a/django_ledger/forms/item.py b/django_ledger/forms/item.py index bce10e4c..d531a9f1 100644 --- a/django_ledger/forms/item.py +++ b/django_ledger/forms/item.py @@ -46,10 +46,12 @@ def __init__(self, entity_slug: str, user_model, *args, **kwargs): self.USER_MODEL = user_model super().__init__(*args, **kwargs) - accounts_qs = AccountModel.objects.with_roles( - roles=self.PRODUCT_OR_SERVICE_ROLES, - entity_slug=self.ENTITY_SLUG, - user_model=self.USER_MODEL).active() + accounts_qs = AccountModel.objects.for_entity( + entity_model=self.ENTITY_SLUG, + user_model=self.USER_MODEL + ).with_roles( + roles=self.PRODUCT_OR_SERVICE_ROLES + ).active() # caches the QS for filtering... len(accounts_qs) @@ -139,10 +141,12 @@ def __init__(self, entity_slug: str, user_model, *args, **kwargs): self.USER_MODEL = user_model super().__init__(*args, **kwargs) - accounts_qs = AccountModel.objects.with_roles( + accounts_qs = AccountModel.objects.for_entity( + entity_model=self.ENTITY_SLUG, + user_model=self.USER_MODEL + ).with_roles( roles=self.SERVICE_ROLES, - entity_slug=self.ENTITY_SLUG, - user_model=self.USER_MODEL).active() + ).active() # caches the QS for filtering... len(accounts_qs) @@ -224,10 +228,12 @@ def __init__(self, entity_slug: str, user_model, *args, **kwargs): self.USER_MODEL = user_model super().__init__(*args, **kwargs) - accounts_qs = AccountModel.objects.with_roles( - roles=GROUP_EXPENSES, - entity_slug=self.ENTITY_SLUG, - user_model=self.USER_MODEL).active() + accounts_qs = AccountModel.objects.for_entity( + entity_model=self.ENTITY_SLUG, + user_model=self.USER_MODEL + ).with_roles( + roles=GROUP_EXPENSES + ).active() self.fields['expense_account'].queryset = accounts_qs.filter(role__in=GROUP_EXPENSES) @@ -295,6 +301,7 @@ class Meta(ExpenseItemCreateForm.Meta): 'sku', 'default_amount', 'expense_account', + 'is_active' ] @@ -306,10 +313,12 @@ def __init__(self, entity_slug: str, user_model, *args, **kwargs): self.USER_MODEL = user_model super().__init__(*args, **kwargs) - accounts_qs = AccountModel.objects.with_roles( - roles=[ASSET_CA_INVENTORY], - entity_slug=self.ENTITY_SLUG, - user_model=self.USER_MODEL).active() + accounts_qs = AccountModel.objects.for_entity( + entity_model=self.ENTITY_SLUG, + user_model=self.USER_MODEL + ).with_roles( + roles=[ASSET_CA_INVENTORY] + ).active() self.fields['inventory_account'].queryset = accounts_qs if 'uom' in self.fields: diff --git a/django_ledger/forms/transactions.py b/django_ledger/forms/transactions.py index 711609ec..ae02dfd4 100644 --- a/django_ledger/forms/transactions.py +++ b/django_ledger/forms/transactions.py @@ -51,10 +51,10 @@ def __init__(self, *args, entity_slug, user_model, ledger_pk, je_model=None, **k self.LEDGER_PK = ledger_pk self.ENTITY_SLUG = entity_slug - account_qs = AccountModel.objects.for_entity_available( + account_qs = AccountModel.objects.for_entity( user_model=self.USER_MODEL, - entity_slug=self.ENTITY_SLUG - ).order_by('code') + entity_model=self.ENTITY_SLUG + ).available().order_by('code') for form in self.forms: form.fields['account'].queryset = account_qs diff --git a/django_ledger/io/io_core.py b/django_ledger/io/io_core.py index 519d0cbb..ee31ea2b 100644 --- a/django_ledger/io/io_core.py +++ b/django_ledger/io/io_core.py @@ -757,7 +757,6 @@ def digest(self, by_unit=by_unit ) - # idea: change digest() name to something else? maybe aggregate, calculate?... io_state = roles_mgr.digest() if any([ diff --git a/django_ledger/io/io_middleware.py b/django_ledger/io/io_middleware.py index 0e9de6c6..a9ff4b40 100644 --- a/django_ledger/io/io_middleware.py +++ b/django_ledger/io/io_middleware.py @@ -451,11 +451,16 @@ def net_cash(self): bal for act, bal in self.IO_DATA[self.CFS_DIGEST_KEY]['net_cash_by_activity'].items() ]) + def net_income(self): + group_balances = self.IO_DATA[AccountGroupIOMiddleware.GROUP_BALANCE_KEY] + self.IO_DATA[self.CFS_DIGEST_KEY]['net_income'] = group_balances['GROUP_CFS_NET_INCOME'] + def digest(self): self.IO_DATA[self.CFS_DIGEST_KEY] = dict() self.check_io_digest() self.operating() self.financing() self.investing() + self.net_income() self.net_cash() return self.IO_DATA diff --git a/django_ledger/migrations/0017_alter_accountmodel_unique_together_and_more.py b/django_ledger/migrations/0017_alter_accountmodel_unique_together_and_more.py new file mode 100644 index 00000000..5f692e35 --- /dev/null +++ b/django_ledger/migrations/0017_alter_accountmodel_unique_together_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 5.1.1 on 2024-10-09 19:40 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_ledger', '0016_remove_accountmodel_django_ledg_coa_mod_e19964_idx_and_more'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='accountmodel', + unique_together=set(), + ), + migrations.AlterField( + model_name='accountmodel', + name='coa_model', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='django_ledger.chartofaccountmodel', verbose_name='Chart of Accounts'), + ), + migrations.AddConstraint( + model_name='accountmodel', + constraint=models.UniqueConstraint(fields=('coa_model', 'code'), name='unique_code_for_coa_model', violation_error_message='Account codes must be unique for each Chart of Accounts Model.'), + ), + migrations.AddConstraint( + model_name='accountmodel', + constraint=models.UniqueConstraint(fields=('coa_model', 'role', 'role_default'), name='only_one_account_assigned_as_default_for_role', violation_error_message='Only one default account for role permitted.'), + ), + ] diff --git a/django_ledger/models/accounts.py b/django_ledger/models/accounts.py index 3d681fa3..44a11693 100644 --- a/django_ledger/models/accounts.py +++ b/django_ledger/models/accounts.py @@ -2,14 +2,8 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - * Pranav P Tulshyan - - AccountModel ------------ - The AccountModel is a fundamental component of the Django Ledger system, responsible for categorizing and organizing financial transactions related to an entity's assets, liabilities, and equity. @@ -60,18 +54,19 @@ from django.core.exceptions import ValidationError from django.db import models -from django.db.models import Q +from django.db.models import Q, F, UniqueConstraint from django.db.models.signals import pre_save from django.urls import reverse from django.utils.translation import gettext_lazy as _ from treebeard.mp_tree import MP_Node, MP_NodeManager, MP_NodeQuerySet -from django_ledger.io.io_core import get_localdate -from django_ledger.io.roles import (ACCOUNT_ROLE_CHOICES, BS_ROLES, GROUP_INVOICE, GROUP_BILL, validate_roles, - GROUP_ASSETS, - GROUP_LIABILITIES, GROUP_CAPITAL, GROUP_INCOME, GROUP_EXPENSES, GROUP_COGS, - ROOT_GROUP, BS_BUCKETS, ROOT_ASSETS, ROOT_LIABILITIES, - ROOT_CAPITAL, ROOT_INCOME, ROOT_EXPENSES, ROOT_COA, VALID_PARENTS) +from django_ledger.io.roles import ( + ACCOUNT_ROLE_CHOICES, BS_ROLES, GROUP_INVOICE, GROUP_BILL, validate_roles, + GROUP_ASSETS, GROUP_LIABILITIES, GROUP_CAPITAL, GROUP_INCOME, GROUP_EXPENSES, GROUP_COGS, + ROOT_GROUP, BS_BUCKETS, ROOT_ASSETS, ROOT_LIABILITIES, + ROOT_CAPITAL, ROOT_INCOME, ROOT_EXPENSES, ROOT_COA, VALID_PARENTS, + ROLES_ORDER_ALL +) from django_ledger.models.mixins import CreateUpdateMixIn from django_ledger.models.utils import lazy_loader from django_ledger.settings import DJANGO_LEDGER_ACCOUNT_CODE_GENERATE, DJANGO_LEDGER_ACCOUNT_CODE_USE_PREFIX @@ -155,11 +150,17 @@ def with_roles(self, roles: Union[List, str]): AccountModelQuerySet A QuerySet of accounts filtered by the provided roles. """ + roles = validate_roles(roles) if isinstance(roles, str): roles = [roles] roles = validate_roles(roles) return self.filter(role__in=roles) + def with_codes(self, codes: Union[List, str]): + if isinstance(codes, str): + codes = [codes] + return self.filter(code__in=codes) + def expenses(self): """ Retrieve a queryset containing expenses filtered by specified roles. @@ -200,36 +201,6 @@ def not_coa_root(self): """ return self.exclude(role__in=ROOT_GROUP) - def for_entity(self, entity_slug, user_model): - """ - Parameters - ---------- - entity_slug : str - The slug identifier for the entity. - user_model : UserModel - The user model instance to use for filtering. - - Returns - ------- - AccountModelQuerySet - A Django QuerySet filtered by the specified entity and user permissions, ordered by 'code'. - """ - if isinstance(self, lazy_loader.get_entity_model()): - return self.filter( - Q(coa_model__entity=entity_slug) & - ( - Q(coa_model__entity__admin=user_model) | - Q(coa_model__entity__managers__in=[user_model]) - ) - ).order_by('code') - return self.filter( - Q(coa_model__entity__slug__exact=entity_slug) & - ( - Q(coa_model__entity__admin=user_model) | - Q(coa_model__entity__managers__in=[user_model]) - ) - ).order_by('code') - def gb_bs_role(self): """ Groups accounts by Balance Sheet Bucket and then further groups them by role. @@ -241,10 +212,14 @@ def gb_bs_role(self): and the second element is a list of tuples where each sub-tuple contains a role display and a list of accounts that fall into that role within the BS bucket. """ - accounts_gb = list((r, list(gb)) for r, gb in groupby(self, key=lambda acc: acc.get_bs_bucket())) + accounts_gb = list( + (r, sorted(list(gb), key=lambda acc: ROLES_ORDER_ALL.index(acc.role))) for r, gb in + groupby(self, key=lambda acc: acc.get_bs_bucket()) + ) return [ (bsr, [ - (r, list(l)) for r, l in groupby(gb, key=lambda a: a.get_role_display()) + (r, sorted(list(l), key=lambda acc: acc.code)) for r, l in + groupby(gb, key=lambda a: a.get_role_display()) ]) for bsr, gb in accounts_gb ] @@ -270,9 +245,47 @@ def can_transact(self): A QuerySet containing the filtered results. """ return self.filter( - Q(locked=False) & Q(active=True) + Q(locked=False) & + Q(active=True) & + Q(coa_model__active=True) + ) + + def available(self): + return self.filter( + Q(locked=False) & + Q(active=True) & + Q(coa_model__active=True) ) + def for_bill(self): + """ + Retrieves only available and unlocked AccountModels for a specific EntityModel, + specifically for the creation and management of Bills. Roles within the 'GROUP_BILL' + context include: ASSET_CA_CASH, ASSET_CA_PREPAID, and LIABILITY_CL_ACC_PAYABLE. + + Returns + ------- + AccountModelQuerySet + A QuerySet of the requested EntityModel's chart of accounts. + """ + return self.available().filter(role__in=GROUP_BILL) + + def for_invoice(self): + """ + Retrieves available and unlocked AccountModels for a specific EntityModel, specifically for the creation + and management of Invoices. + + This method ensures that only relevant accounts are pulled, as defined under the roles in `GROUP_INVOICE`. + These roles include: ASSET_CA_CASH, ASSET_CA_RECEIVABLES, and LIABILITY_CL_DEFERRED_REVENUE. + + Returns + ------- + AccountModelQuerySet + A QuerySet containing the AccountModels relevant for the specified EntityModel and the roles defined + in `GROUP_INVOICE`. + """ + return self.available().filter(role__in=GROUP_INVOICE) + class AccountModelManager(MP_NodeManager): """ @@ -295,7 +308,12 @@ def get_queryset(self) -> AccountModelQuerySet: return AccountModelQuerySet( self.model, using=self._db - ).order_by('path').select_related('coa_model') + ).order_by('path').select_related( + 'coa_model').annotate( + _coa_slug=F('coa_model__slug'), + _coa_active=F('coa_model__active'), + _entity_slug=F('coa_model__entity__slug'), + ) def for_user(self, user_model) -> AccountModelQuerySet: """ @@ -318,235 +336,54 @@ def for_user(self, user_model) -> AccountModelQuerySet: Q(coa_model__entity__managers__in=[user_model]) ) - # todo: search for uses and pass EntityModel whenever possible. def for_entity( self, user_model, - entity_slug, - coa_slug: Optional[str] = None, - select_coa_model: bool = True + entity_model, + coa_slug: Optional[str] = None ) -> AccountModelQuerySet: """ - Retrieves accounts associated with the specified EntityModel. + Retrieve accounts associated with a specified EntityModel and Chart of Accounts. Parameters ---------- - user_model: User - The Django User Model making the request to check for permissions. - entity_slug: Union[EntityModel, str] - The EntityModel instance or its slug to filter accounts by. If a slug is provided and `coa_slug` is None, - an additional - database query will be executed to determine the default Chart of Accounts. - coa_slug: Optional[str], default=None - The slug of the specific Chart of Accounts to use. If None, the default Chart of Accounts is selected. - select_coa_model: bool, default=True - If True, prefetches the CoA Model information in the QuerySet. + user_model : User + The Django User instance initiating the request. Used to check for required permissions. + entity_model : Union[EntityModel, str] + An instance of EntityModel or its slug. This determines the entity whose accounts are being retrieved. + A database query will be carried out to identify the default Chart of Accounts. + coa_slug : Optional[str], default=None + The slug for a specific Chart of Accounts to be used. If None, the default Chart of Accounts will be selected. Returns ------- AccountModelQuerySet A QuerySet containing accounts associated with the specified EntityModel and Chart of Accounts. + + Raises + ------ + AccountModelValidationError + If the entity_model is neither an instance of EntityModel nor a string. """ qs = self.for_user(user_model) - if select_coa_model: - qs = qs.select_related('coa_model') - EntityModel = lazy_loader.get_entity_model() - if isinstance(entity_slug, EntityModel): - entity_model = entity_slug + + if isinstance(entity_model, EntityModel): + entity_model = entity_model qs = qs.filter(coa_model__entity=entity_model) - elif isinstance(entity_slug, str): - qs = qs.filter(coa_model__entity__slug__exact=entity_slug) + elif isinstance(entity_model, str): + qs = qs.filter(coa_model__entity__slug__exact=entity_model) else: - raise AccountModelValidationError(message='Must pass an instance of EntityModel or String for entity_slug.') - - if coa_slug: - qs = qs.filter(coa_model__slug__exact=coa_slug) - return qs.order_by('coa_model') - - def for_entity_available(self, user_model, entity_slug, coa_slug: Optional[str] = None) -> AccountModelQuerySet: - """ - Retrieve available and unlocked AccountModels for a specific EntityModel. - - This method filters AccountModels associated with the specified EntityModel - that are active, not locked, and have an active Chart of Accounts. - - Parameters - ---------- - user_model: User - The Django User Model instance making the request, used to validate permissions. - - entity_slug: EntityModel or str - The EntityModel instance or its slug to pull accounts from. If entity_slug is passed - and coa_slug is None, an additional database query will be performed to determine - the default Chart of Accounts. - - coa_slug: str, optional - The specific Chart of Accounts to use. If None, the default Chart of Accounts will be pulled. + raise AccountModelValidationError( + message='Must pass an instance of EntityModel or String for entity_slug.' + ) - Returns - ------- - AccountModelQuerySet - A QuerySet containing available and unlocked AccountModels for the specified EntityModel and Chart of Accounts. - """ - qs = self.for_entity( - user_model=user_model, - entity_slug=entity_slug, - coa_slug=coa_slug) return qs.filter( - Q(active=True) & - Q(locked=False) & - Q(coa_model__active=True) + coa_model__slug__exact=coa_slug + ) if coa_slug else qs.filter( + coa_model__slug__exact=F('coa_model__entity__default_coa__slug') ) - def with_roles(self, roles: Union[list, str], entity_slug, user_model) -> AccountModelQuerySet: - """ - Retrieve accounts based on specific roles. - - This method filters accounts associated with a given role or a list of roles. For example, if you need to - find all accounts under the "asset_ppe_build" role, which includes all buildings fixed assets, this method - can be used. - - Parameters - ---------- - entity_slug: EntityModel or str - The EntityModel instance or its slug to fetch accounts from. If only the slug is provided and coa_slug is - not specified, an additional database query will be performed to determine the default chart of accounts. - user_model: User - The Django User model instance making the request to ensure appropriate permissions are checked. - roles: list or str - Accepts either a single role as a string or a list of roles. Refer to io.roles.py for a comprehensive - list of roles. - - Returns - ------- - AccountModelQuerySet - A QuerySet of accounts filtered by the specified roles. - """ - roles = validate_roles(roles) - if isinstance(roles, str): - roles = [roles] - qs = self.for_entity(entity_slug=entity_slug, user_model=user_model) - return qs.filter(role__in=roles) - - def with_roles_available(self, roles: Union[list, str], - entity_slug, - user_model, - coa_slug: Optional[str]) -> AccountModelQuerySet: - """ - Retrieve available and unlocked AccountModels for a specified EntityModel and list of roles. - - Parameters - ---------- - roles : Union[list, str] - A single role as a string or a list of roles. - entity_slug : Union[str, 'EntityModel'] - The EntityModel object or its slug. If a slug is provided and `coa_slug` is None, an additional - database query will be executed to fetch the default Chart of Accounts. - user_model : 'UserModel' - The Django UserModel instance making the request, used to check permissions. - coa_slug : Optional[str], default None - The specific Chart of Accounts slug. If None, the default Chart of Accounts will be used. - This parameter assists in identifying the complete Chart of Accounts for the EntityModel. - - Returns - ------- - AccountModelQuerySet - A QuerySet containing available and unlocked AccountModel instances for the specified - EntityModel and roles. - """ - - if isinstance(roles, str): - roles = [roles] - roles = validate_roles(roles) - qs = self.for_entity_available(entity_slug=entity_slug, user_model=user_model) - return qs.filter(role__in=roles) - - def coa_roots(self, user_model, entity_slug, coa_slug) -> AccountModelQuerySet: - """ - Retrieves the root accounts of a specified Code of Accounts (CoA). - - Parameters - ---------- - user_model: object - The Django User model instance requesting the data, used for permission checking. - entity_slug: Union[EntityModel, str] - The entity or its slug from which to fetch accounts. If a slug is provided and `coa_slug` is None, - an additional database query is performed to determine the default Code of Accounts. - coa_slug: Optional[str] - The specific chart of accounts to retrieve. If None, the default chart of accounts for the entity - will be used. This is crucial for identifying the complete set of accounts for a given entity. - - Returns - ------- - AccountModelQuerySet - A queryset of root accounts for the specified Code of Accounts. - """ - qs = self.for_entity(user_model=user_model, entity_slug=entity_slug, coa_slug=coa_slug) - return qs.is_coa_root() - - def for_invoice(self, user_model, entity_slug: str, coa_slug: Optional[str] = None) -> AccountModelQuerySet: - """ - Retrieves available and unlocked AccountModels for a specific EntityModel, specifically for the creation - and management of Invoices. - - This method ensures that only relevant accounts are pulled, as defined under the roles in `GROUP_INVOICE`. - These roles include: ASSET_CA_CASH, ASSET_CA_RECEIVABLES, and LIABILITY_CL_DEFERRED_REVENUE. - - Parameters - ---------- - user_model: User - The Django User Model instance requesting access. It is used to check the necessary permissions. - - entity_slug: Union[EntityModel, str] - Specifies the EntityModel or its slug to pull accounts from. If a slug is provided and `coa_slug` is `None`, - the method will perform an additional database query to determine the default chart of accounts. - - coa_slug: Optional[str], default=None - Explicitly specifies which chart of accounts to use. If `None`, the method will default to using - the EntityModel's default chart of accounts. - - Returns - ------- - AccountModelQuerySet - A QuerySet containing the AccountModels relevant for the specified EntityModel and the roles defined - in `GROUP_INVOICE`. - """ - qs = self.for_entity_available( - user_model=user_model, - entity_slug=entity_slug, - coa_slug=coa_slug) - return qs.filter(role__in=GROUP_INVOICE) - - def for_bill(self, user_model, entity_slug, coa_slug: Optional[str] = None) -> AccountModelQuerySet: - """ - Retrieves only available and unlocked AccountModels for a specific EntityModel, - specifically for the creation and management of Bills. Roles within the 'GROUP_BILL' - context include: ASSET_CA_CASH, ASSET_CA_PREPAID, and LIABILITY_CL_ACC_PAYABLE. - - Parameters - ---------- - user_model : Django User Model - The Django User Model that is making the request, used to check for permissions. - - entity_slug : Union[EntityModel, str] - The EntityModel or EntityModel slug from which to pull accounts. If given a slug and coa_slug - is None, an additional database query will be made to determine the default chart of accounts. - - coa_slug : Optional[str] - The specific chart of accounts to use. If None, it will default to the EntityModel's default chart of accounts. - - Returns - ------- - AccountModelQuerySet - A QuerySet of the requested EntityModel's chart of accounts. - """ - qs = self.for_entity_available( - user_model=user_model, - entity_slug=entity_slug, - coa_slug=coa_slug) - return qs.filter(role__in=GROUP_BILL) - def account_code_validator(value: str): if not value.isalnum(): @@ -596,7 +433,6 @@ class AccountModelAbstract(MP_Node, CreateUpdateMixIn): active = models.BooleanField(default=False, verbose_name=_('Active')) coa_model = models.ForeignKey('django_ledger.ChartOfAccountModel', on_delete=models.CASCADE, - editable=False, verbose_name=_('Chart of Accounts')) objects = AccountModelManager() node_order_by = ['uuid'] @@ -606,9 +442,17 @@ class Meta: ordering = ['-created'] verbose_name = _('Account') verbose_name_plural = _('Accounts') - unique_together = [ - ('coa_model', 'code'), - ('coa_model', 'role', 'role_default') + constraints = [ + UniqueConstraint( + fields=('coa_model', 'code'), + name='unique_code_for_coa_model', + violation_error_message=_('Account codes must be unique for each Chart of Accounts Model.') + ), + UniqueConstraint( + fields=('coa_model', 'role', 'role_default'), + name='only_one_account_assigned_as_default_for_role', + violation_error_message=_('Only one default account for role permitted.') + ) ] indexes = [ models.Index(fields=['role']), @@ -628,6 +472,17 @@ def __str__(self): x5=self.code ) + @property + def coa_slug(self): + try: + return getattr(self, '_coa_slug') + except AttributeError: + return self.coa_model.slug + + @property + def entity_slug(self): + return getattr(self, '_entity_slug') + @classmethod def create_account(cls, name: str, @@ -838,6 +693,13 @@ def is_locked(self) -> bool: """ return self.locked is True + def is_coa_active(self) -> bool: + try: + return getattr(self, '_coa_active') + except AttributeError: + pass + return self.coa_model.active + def can_activate(self): """ Determines if the object can be activated. @@ -866,6 +728,46 @@ def can_deactivate(self): self.active is True ]) + def can_lock(self): + return all([ + self.locked is False + ]) + + def can_unlock(self): + return all([ + self.locked is True + ]) + + def lock(self, commit: bool = True, raise_exception: bool = True, **kwargs): + if not self.can_lock(): + if raise_exception: + raise AccountModelValidationError( + message=_(f'Cannot lock account {self.code}: {self.name}. Active: {self.is_active()}') + ) + return + + self.locked = True + if commit: + self.save(update_fields=[ + 'locked', + 'updated' + ]) + + def unlock(self, commit: bool = True, raise_exception: bool = True, **kwargs): + if not self.can_unlock(): + if raise_exception: + raise AccountModelValidationError( + message=_(f'Cannot unlock account {self.code}: {self.name}. Active: {self.is_active()}') + ) + return + + self.locked = False + if commit: + self.save(update_fields=[ + 'locked', + 'updated' + ]) + def activate(self, commit: bool = True, raise_exception: bool = True, **kwargs): """ Checks if the Account Model instance can be activated, then Activates the AccountModel instance. @@ -936,9 +838,8 @@ def can_transact(self) -> bool: 3. The entity itself must be active. """ return all([ - self.coa_model.is_active(), - not self.is_locked(), - self.is_active() + self.is_coa_active(), + not self.is_locked() ]) def get_code_prefix(self) -> str: @@ -1072,16 +973,75 @@ def generate_random_code(self): ri = randint(10000, 99999) return f'{prefix}{ri}' - def get_absolute_url(self): + # URLS... + def get_absolute_url(self) -> str: return reverse( - viewname='django_ledger:account-detail-year', + viewname='django_ledger:account-detail', kwargs={ 'account_pk': self.uuid, - 'entity_slug': self.coa_model.entity.slug, - 'year': get_localdate().year + 'entity_slug': self.entity_slug, + 'coa_slug': self.coa_slug } ) + def get_update_url(self) -> str: + return reverse( + viewname='django_ledger:account-update', + kwargs={ + 'account_pk': self.uuid, + 'entity_slug': self.entity_slug, + 'coa_slug': self.coa_slug + } + ) + + def get_action_deactivate_url(self) -> str: + return reverse( + viewname='django_ledger:account-action-deactivate', + kwargs={ + 'account_pk': self.uuid, + 'entity_slug': self.entity_slug, + 'coa_slug': self.coa_slug + } + ) + + def get_action_activate_url(self) -> str: + return reverse( + viewname='django_ledger:account-action-activate', + kwargs={ + 'account_pk': self.uuid, + 'entity_slug': self.entity_slug, + 'coa_slug': self.coa_slug + } + ) + + def get_action_lock_url(self) -> str: + return reverse( + viewname='django_ledger:account-action-lock', + kwargs={ + 'account_pk': self.uuid, + 'entity_slug': self.entity_slug, + 'coa_slug': self.coa_slug + } + ) + + def get_action_unlock_url(self) -> str: + return reverse( + viewname='django_ledger:account-action-unlock', + kwargs={ + 'account_pk': self.uuid, + 'entity_slug': self.entity_slug, + 'coa_slug': self.coa_slug + } + ) + + def get_coa_account_list_url(self) -> str: + return reverse( + viewname='django_ledger:account-list', + kwargs={ + 'entity_slug': self.entity_slug, + 'coa_slug': self.coa_slug + }) + def clean(self): if not self.code and DJANGO_LEDGER_ACCOUNT_CODE_GENERATE: self.code = self.generate_random_code() diff --git a/django_ledger/models/bank_account.py b/django_ledger/models/bank_account.py index fe9186fd..fa978354 100644 --- a/django_ledger/models/bank_account.py +++ b/django_ledger/models/bank_account.py @@ -2,10 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - * Pranav P Tulshyan - A Bank Account refers to the financial institution which holds financial assets for the EntityModel. A bank account usually holds cash, which is a Current Asset. Transactions may be imported using the open financial format specification OFX into a staging area for final disposition into the EntityModel ledger. diff --git a/django_ledger/models/bill.py b/django_ledger/models/bill.py index 652978aa..e2b256a9 100644 --- a/django_ledger/models/bill.py +++ b/django_ledger/models/bill.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - This module implements the BillModel, which represents an Invoice received from a Supplier/Vendor, on which the Vendor states the amount owed by the recipient for the purposes of supplying goods and/or services. In addition to tracking the bill amount, it tracks the paid and due amount. diff --git a/django_ledger/models/closing_entry.py b/django_ledger/models/closing_entry.py index 4ea80a9c..5d2a3e6c 100644 --- a/django_ledger/models/closing_entry.py +++ b/django_ledger/models/closing_entry.py @@ -1,9 +1,6 @@ """ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. - -Contributions to this module: - * Miguel Sanda """ from datetime import datetime, time diff --git a/django_ledger/models/coa.py b/django_ledger/models/coa.py index 682147b9..db45d132 100644 --- a/django_ledger/models/coa.py +++ b/django_ledger/models/coa.py @@ -2,12 +2,8 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - * Pranav P Tulshyan - Chart Of Accounts -_________________ +----------------- A Chart of Accounts (CoA) is a crucial collection of logically grouped accounts within a ChartOfAccountModel, forming the backbone of financial statements. The CoA includes various account roles such as cash, accounts receivable, @@ -29,7 +25,7 @@ from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError from django.db import models -from django.db.models import Q +from django.db.models import Q, F from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -66,6 +62,12 @@ class ChartOfAccountModelManager(models.Manager): to the ChartOfAccountModel. """ + def get_queryset(self): + qs = super().get_queryset() + return qs.annotate( + _entity_slug=F('entity__slug') + ) + def for_user(self, user_model) -> ChartOfAccountModelQuerySet: """ Fetches a QuerySet of ChartOfAccountModel that the UserModel as access to. May include ChartOfAccountModel from @@ -157,6 +159,14 @@ def __str__(self): return f'{self.name} ({self.slug})' return self.slug + @property + def entity_slug(self) -> str: + try: + # from QS annotation... + return getattr(self, '_entity_slug') + except AttributeError: + return self.entity.slug + def get_coa_root_accounts_qs(self) -> AccountModelQuerySet: """ Retrieves the root accounts in the chart of accounts. @@ -563,23 +573,6 @@ def mark_as_default(self, commit: bool = False, raise_exception: bool = False, * ] ) - def mark_as_default_url(self) -> str: - """ - Returns the URL to mark the current Chart of Accounts instances as Default for the EntityModel. - - Returns - ------- - str - The URL as a String. - """ - return reverse( - viewname='django_ledger:coa-action-mark-as-default', - kwargs={ - 'entity_slug': self.entity.slug, - 'coa_slug': self.slug - } - ) - def can_activate(self) -> bool: """ Check if the ChartOffAccountModel instance can be activated. @@ -630,23 +623,6 @@ def mark_as_active(self, commit: bool = False, raise_exception: bool = False, ** 'updated' ]) - def mark_as_active_url(self) -> str: - """ - Returns the URL to mark the current Chart of Accounts instances as active. - - Returns - ------- - str - The URL as a String. - """ - return reverse( - viewname='django_ledger:coa-action-mark-as-active', - kwargs={ - 'entity_slug': self.entity.slug, - 'coa_slug': self.slug - } - ) - def mark_as_inactive(self, commit: bool = False, raise_exception: bool = False, **kwargs): """ Marks the current Chart of Accounts as Active. @@ -674,6 +650,41 @@ def mark_as_inactive(self, commit: bool = False, raise_exception: bool = False, 'updated' ]) + # URLS.... + def mark_as_default_url(self) -> str: + """ + Returns the URL to mark the current Chart of Accounts instances as Default for the EntityModel. + + Returns + ------- + str + The URL as a String. + """ + return reverse( + viewname='django_ledger:coa-action-mark-as-default', + kwargs={ + 'entity_slug': self.entity_slug, + 'coa_slug': self.slug + } + ) + + def mark_as_active_url(self) -> str: + """ + Returns the URL to mark the current Chart of Accounts instances as active. + + Returns + ------- + str + The URL as a String. + """ + return reverse( + viewname='django_ledger:coa-action-mark-as-active', + kwargs={ + 'entity_slug': self.entity_slug, + 'coa_slug': self.slug + } + ) + def mark_as_inactive_url(self) -> str: """ Returns the URL to mark the current Chart of Accounts instances as inactive. @@ -686,7 +697,7 @@ def mark_as_inactive_url(self) -> str: return reverse( viewname='django_ledger:coa-action-mark-as-inactive', kwargs={ - 'entity_slug': self.entity.slug, + 'entity_slug': self.entity_slug, 'coa_slug': self.slug } ) @@ -695,7 +706,7 @@ def get_coa_list_url(self): return reverse( viewname='django_ledger:coa-list', kwargs={ - 'entity_slug': self.entity.slug + 'entity_slug': self.entity_slug } ) @@ -703,26 +714,26 @@ def get_absolute_url(self) -> str: return reverse( viewname='django_ledger:coa-detail', kwargs={ - 'coa_slug': self.slug, - 'entity_slug': self.entity.slug + 'entity_slug': self.entity_slug, + 'coa_slug': self.slug } ) def get_account_list_url(self): return reverse( - viewname='django_ledger:account-list-coa', + viewname='django_ledger:account-list', kwargs={ - 'entity_slug': self.entity.slug, + 'entity_slug': self.entity_slug, 'coa_slug': self.slug } ) def get_create_coa_account_url(self): return reverse( - viewname='django_ledger:account-create-coa', + viewname='django_ledger:account-create', kwargs={ 'coa_slug': self.slug, - 'entity_slug': self.entity.slug + 'entity_slug': self.entity_slug } ) diff --git a/django_ledger/models/customer.py b/django_ledger/models/customer.py index f247cb1c..f3737642 100644 --- a/django_ledger/models/customer.py +++ b/django_ledger/models/customer.py @@ -2,10 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - * Pranav P Tulshyan - A Customer refers to the person or entity that buys product and services. When issuing Invoices, a Customer must be created before it can be assigned to the InvoiceModel. Only customers who are active can be assigned to new Invoices. """ diff --git a/django_ledger/models/data_import.py b/django_ledger/models/data_import.py index 94d27375..74eed99f 100644 --- a/django_ledger/models/data_import.py +++ b/django_ledger/models/data_import.py @@ -1,9 +1,6 @@ """ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. - -Contributions to this module: -Miguel Sanda """ from decimal import Decimal diff --git a/django_ledger/models/entity.py b/django_ledger/models/entity.py index 32c3b092..26833d2c 100644 --- a/django_ledger/models/entity.py +++ b/django_ledger/models/entity.py @@ -2,16 +2,13 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - * Pranav P Tulshyan ptulshyan77@gmail.com<> - The EntityModel represents the Company, Corporation, Legal Entity, Enterprise or Person that engage and operate as a business. EntityModels can be created as part of a parent/child model structure to accommodate complex corporate structures where certain entities may be owned by other entities and may also generate consolidated financial statements. + Another use case of parent/child model structures is the coordination and authorization of inter-company transactions -across multiple related entities. The EntityModel encapsulates all LedgerModel, JournalEntryModel and TransactionModel which is the core structure of -Django Ledger in order to track and produce all financials. +across multiple related entities. The EntityModel encapsulates all LedgerModel, JournalEntryModel and TransactionModel +which is the core structure of Django Ledger in order to track and produce all financials. The EntityModel must be assigned an Administrator at creation, and may have optional Managers that will have the ability to operate on such EntityModel. @@ -36,7 +33,7 @@ from django.core.exceptions import ValidationError, ObjectDoesNotExist from django.core.validators import MinValueValidator from django.db import models -from django.db.models import Q +from django.db.models import Q, F from django.db.models.signals import pre_save from django.urls import reverse from django.utils.text import slugify @@ -113,8 +110,14 @@ class EntityModelManager(MP_NodeManager): def get_queryset(self): """Sets the custom queryset as the default.""" - qs = EntityModelQuerySet(self.model, using=self._db).order_by('path') - return qs.order_by('path').select_related('admin', 'default_coa') + qs = EntityModelQuerySet( + self.model, + using=self._db).order_by('path') + return qs.order_by('path').select_related( + 'admin', + 'default_coa').annotate( + _default_coa_slug=F('default_coa__slug'), + ) def for_user(self, user_model, authorized_superuser: bool = False): """ @@ -421,6 +424,9 @@ def get_fy_for_date(self, dt: Union[date, datetime], as_str: bool = False) -> Un class EntityModelClosingEntryMixIn: + """ + Closing Entries provide + """ def validate_closing_entry_model(self, closing_entry_model, closing_date: Optional[date] = None): if isinstance(self, EntityModel): @@ -519,7 +525,6 @@ def get_closing_entry_queryset_for_fiscal_year(self, fiscal_year: int): return self.get_closing_entry_queryset_for_date(closing_date=closing_date) # ----> Create Closing Entries <---- - def create_closing_entry_for_date(self, closing_date: date, closing_entry_model=None, @@ -578,7 +583,6 @@ def get_closing_entry_cache_key_for_fiscal_year(self, fiscal_year: int) -> str: return f'closing_entry_{end_dt_str}_{self.uuid}' # ----> Closing Entry Caching Month < ----- - def get_closing_entry_cache_for_date(self, closing_date: date, cache_name: str = 'default', @@ -801,6 +805,13 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._CLOSING_ENTRY_DATES: Optional[List[date]] = None + @property + def default_coa_slug(self): + try: + return getattr(self, '_default_coa_slug') + except AttributeError: + return self.default_coa.slug + # ## Logging ### def get_logger_name(self): return f'EntityModel {self.uuid}' @@ -1272,7 +1283,10 @@ def get_all_accounts(self, active: bool = True, order_by: Optional[Tuple[str]] = def get_coa_accounts(self, coa_model: Optional[Union[ChartOfAccountModel, UUID, str]] = None, active: bool = True, - order_by: Optional[Tuple] = ('code',)) -> AccountModelQuerySet: + locked: bool = False, + order_by: Optional[Tuple] = ('code',), + return_coa_model: bool = False, + ) -> Union[AccountModelQuerySet, Tuple[ChartOfAccountModel, AccountModelQuerySet]]: """ Fetches the AccountModelQuerySet for a specific ChartOfAccountModel. @@ -1282,6 +1296,8 @@ def get_coa_accounts(self, The ChartOfAccountsModel UUID, model instance or slug to pull accounts from. If None, will use default CoA. active: bool Selects only active accounts. + locked: bool + Selects only locked accounts. order_by: list of strings. Optional list of fields passed to the order_by QuerySet method. @@ -1294,9 +1310,9 @@ def get_coa_accounts(self, if not coa_model: coa_model = self.default_coa elif isinstance(coa_model, UUID): - coa_model = self.chartofaccountmodel_set.get(uuid__exact=coa_model) + coa_model = self.chartofaccountmodel_set.select_related('entity').get(uuid__exact=coa_model) elif isinstance(coa_model, str): - coa_model = self.chartofaccountmodel_set.get(slug__exact=coa_model) + coa_model = self.chartofaccountmodel_set.select_related('entity').get(slug__exact=coa_model) elif isinstance(coa_model, ChartOfAccountModel): self.validate_chart_of_accounts_for_entity(coa_model=coa_model) else: @@ -1309,9 +1325,14 @@ def get_coa_accounts(self, if active: account_model_qs = account_model_qs.active() + if locked: + account_model_qs = account_model_qs.locked() + if order_by: account_model_qs = account_model_qs.order_by(*order_by) + if return_coa_model: + return coa_model, account_model_qs return account_model_qs def get_default_coa_accounts(self, @@ -1694,11 +1715,12 @@ def create_bill(self, account_model_qs = self.get_coa_accounts(coa_model=coa_model, active=True) - account_model_qs = account_model_qs.with_roles(roles=[ - roles_module.ASSET_CA_CASH, - roles_module.ASSET_CA_PREPAID, - roles_module.LIABILITY_CL_ACC_PAYABLE - ]).is_role_default() + account_model_qs = account_model_qs.with_roles( + roles=[ + roles_module.ASSET_CA_CASH, + roles_module.ASSET_CA_PREPAID, + roles_module.LIABILITY_CL_ACC_PAYABLE + ]).is_role_default() # evaluates the queryset... len(account_model_qs) @@ -1803,11 +1825,12 @@ def create_invoice(self, raise EntityModelValidationError('CustomerModel must be an instance of CustomerModel, UUID or str.') account_model_qs = self.get_coa_accounts(coa_model=coa_model, active=True) - account_model_qs = account_model_qs.with_roles(roles=[ - roles_module.ASSET_CA_CASH, - roles_module.ASSET_CA_RECEIVABLES, - roles_module.LIABILITY_CL_DEFERRED_REVENUE - ]).is_role_default() + account_model_qs = account_model_qs.with_roles( + roles=[ + roles_module.ASSET_CA_CASH, + roles_module.ASSET_CA_RECEIVABLES, + roles_module.LIABILITY_CL_DEFERRED_REVENUE + ]).is_role_default() # evaluates the queryset... len(account_model_qs) @@ -1998,7 +2021,9 @@ def create_bank_account(self, raise EntityModelValidationError( _(f'Invalid Account Type: choices are {BankAccountModel.VALID_ACCOUNT_TYPES}')) account_model_qs = self.get_coa_accounts(coa_model=coa_model, active=True) - account_model_qs = account_model_qs.with_roles(roles=roles_module.ASSET_CA_CASH).is_role_default() + account_model_qs = account_model_qs.with_roles( + roles=roles_module.ASSET_CA_CASH + ).is_role_default() bank_account_model = BankAccountModel( name=name, entity_model=self, @@ -2154,11 +2179,12 @@ def create_item_product(self, raise EntityModelValidationError(f'Invalid UnitOfMeasureModel for entity {self.slug}...') account_model_qs = self.get_coa_accounts(coa_model=coa_model, active=True) - account_model_qs = account_model_qs.with_roles(roles=[ - roles_module.ASSET_CA_INVENTORY, - roles_module.COGS, - roles_module.INCOME_OPERATIONAL - ]).is_role_default() + account_model_qs = account_model_qs.with_roles( + roles=[ + roles_module.ASSET_CA_INVENTORY, + roles_module.COGS, + roles_module.INCOME_OPERATIONAL + ]).is_role_default() # evaluates the queryset... len(account_model_qs) @@ -2229,10 +2255,11 @@ def create_item_service(self, raise EntityModelValidationError(f'Invalid UnitOfMeasureModel for entity {self.slug}...') account_model_qs = self.get_coa_accounts(coa_model=coa_model, active=True) - account_model_qs = account_model_qs.with_roles(roles=[ - roles_module.COGS, - roles_module.INCOME_OPERATIONAL - ]).is_role_default() + account_model_qs = account_model_qs.with_roles( + roles=[ + roles_module.COGS, + roles_module.INCOME_OPERATIONAL + ]).is_role_default() # evaluates the queryset... len(account_model_qs) @@ -2308,7 +2335,9 @@ def create_item_expense(self, raise EntityModelValidationError(f'Invalid UnitOfMeasureModel for entity {self.slug}...') account_model_qs = self.get_coa_accounts(coa_model=coa_model, active=True) - account_model_qs = account_model_qs.with_roles(roles=roles_module.EXPENSE_OPERATIONAL) + account_model_qs = account_model_qs.with_roles( + roles=roles_module.EXPENSE_OPERATIONAL + ) if not expense_account: expense_account = account_model_qs.is_role_default().get() elif isinstance(expense_account, UUID): @@ -2407,7 +2436,9 @@ def create_item_inventory(self, raise EntityModelValidationError(f'Invalid UnitOfMeasureModel for entity {self.slug}...') account_model_qs = self.get_coa_accounts(coa_model=coa_model, active=True) - account_model_qs = account_model_qs.with_roles(roles=roles_module.ASSET_CA_INVENTORY) + account_model_qs = account_model_qs.with_roles( + roles=roles_module.ASSET_CA_INVENTORY + ) if not inventory_account: inventory_account = account_model_qs.is_role_default().get() elif isinstance(inventory_account, UUID): @@ -2627,7 +2658,9 @@ def deposit_capital(self, ROLES_NEEDED.append(roles_module.EQUITY_CAPITAL) account_model_qs = self.get_coa_accounts(coa_model=coa_model) - account_model_qs = account_model_qs.with_roles(roles=ROLES_NEEDED).is_role_default() + account_model_qs = account_model_qs.with_roles( + roles=ROLES_NEEDED + ).is_role_default() if not cash_account or not capital_account: if cash_account or capital_account: diff --git a/django_ledger/models/estimate.py b/django_ledger/models/estimate.py index 5d77d00b..8dcf7680 100644 --- a/django_ledger/models/estimate.py +++ b/django_ledger/models/estimate.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - The EstimateModel provides the means to estimate customer requests, jobs or quotes that may ultimately be considered contracts, if approved. The EstimateModels will estimate revenues and costs associated with a specific scope of work which is documented using ItemTransactionModels. @@ -140,12 +137,6 @@ def for_entity(self, entity_slug: Union[EntityModel, str], user_model): user_model Logged in and authenticated django UserModel instance. - Examples - -------- - >>> request_user = request.user - >>> slug = kwargs['entity_slug'] # may come from request kwargs - >>> bill_model_qs = EstimateModel.objects.for_entity(user_model=request_user, entity_slug=slug) - Returns ------- EstimateModelQuerySet diff --git a/django_ledger/models/invoice.py b/django_ledger/models/invoice.py index 5e00126b..79c211b9 100644 --- a/django_ledger/models/invoice.py +++ b/django_ledger/models/invoice.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - This module implements the InvoiceModel, which represents the Sales Invoice/ Sales Invoice/ Tax Invoice/ Proof of Sale which the :func:`EntityModel ` issues to its customers for the supply of goods or services. The model manages all the Sales Invoices which are issued by the :func:`EntityModel diff --git a/django_ledger/models/items.py b/django_ledger/models/items.py index d2d55cec..cc476a27 100644 --- a/django_ledger/models/items.py +++ b/django_ledger/models/items.py @@ -2,10 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - * Pranav P Tulshyan - The Items refer to the additional detail provided to Bills, Invoices, Purchase Orders and Estimates for the purposes of documenting a breakdown of materials, labor, equipment, and other resources used for the purposes of the business operations. @@ -389,7 +385,10 @@ def for_bill(self, entity_slug, user_model): ItemModelQuerySet A Filtered ItemModelQuerySet. """ - qs = self.for_entity_active(entity_slug=entity_slug, user_model=user_model) + qs = self.for_entity_active( + entity_slug=entity_slug, + user_model=user_model + ) return qs.filter( ( Q(is_product_or_service=False) & @@ -527,7 +526,6 @@ class ItemModelAbstract(CreateUpdateMixIn): uuid = models.UUIDField(default=uuid4, editable=False, primary_key=True) name = models.CharField(max_length=100, verbose_name=_('Item Name')) - # todo: rename this and remove 'id' from it. item_id = models.CharField(max_length=50, blank=True, null=True, verbose_name=_('Internal ID')) item_number = models.CharField(max_length=30, editable=False, verbose_name=_('Item Number')) item_role = models.CharField(max_length=10, choices=ITEM_ROLE_CHOICES, null=True, blank=True) diff --git a/django_ledger/models/journal_entry.py b/django_ledger/models/journal_entry.py index 3cbfab96..b7d6f771 100644 --- a/django_ledger/models/journal_entry.py +++ b/django_ledger/models/journal_entry.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - A Journal Entry (JE) is the foundation of all double entry accounting and financial data of any EntityModel. A JE encapsulates a collection of TransactionModel, which must contain two transactions at a minimum. Each transaction must perform a DEBIT or a CREDIT to an AccountModel. The JE Model performs additional validation to make sure that @@ -37,7 +34,7 @@ from django.core.exceptions import FieldError, ObjectDoesNotExist, ValidationError from django.db import models, transaction, IntegrityError -from django.db.models import Q, Sum, QuerySet, F +from django.db.models import Q, Sum, QuerySet, F, Manager from django.db.models.functions import Coalesce from django.db.models.signals import pre_save from django.urls import reverse @@ -144,7 +141,7 @@ def unlocked(self): return self.filter(locked=False) -class JournalEntryModelManager(models.Manager): +class JournalEntryModelManager(Manager): """ A custom defined Journal Entry Model Manager that supports additional complex initial Queries based on the EntityModel and authenticated UserModel. diff --git a/django_ledger/models/ledger.py b/django_ledger/models/ledger.py index c594c6c0..8cc62c65 100644 --- a/django_ledger/models/ledger.py +++ b/django_ledger/models/ledger.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - The LedgerModel is the heart of Django Ledger. It is a self-contained unit of accounting that implements a double-entry accounting system capable of creating and managing transactions into the ledger and producing any financial statements. In essence, an EntityModel is made of a collection of LedgerModels that drive the whole bookkeeping process. diff --git a/django_ledger/models/mixins.py b/django_ledger/models/mixins.py index 5c5a5946..16e645f1 100644 --- a/django_ledger/models/mixins.py +++ b/django_ledger/models/mixins.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - This module implements the different model MixIns used on different Django Ledger Models to implement common functionality. """ diff --git a/django_ledger/models/purchase_order.py b/django_ledger/models/purchase_order.py index 2f0c49dd..1ba7c5a7 100644 --- a/django_ledger/models/purchase_order.py +++ b/django_ledger/models/purchase_order.py @@ -2,10 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - * Pranav P Tulshyan - A purchase order is a commercial source document that is issued by a business purchasing department when placing an order with its vendors or suppliers. The document indicates the details on the items that are to be purchased, such as the types of goods, quantity, and price. In simple terms, it is the contract drafted by the buyer when purchasing goods diff --git a/django_ledger/models/signals.py b/django_ledger/models/signals.py index 0c3a6794..2c836a86 100644 --- a/django_ledger/models/signals.py +++ b/django_ledger/models/signals.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - The signals module provide the means to notify listeners about important events or states in the models, such as a ledger model being posted or a bill status changing. """ diff --git a/django_ledger/models/transactions.py b/django_ledger/models/transactions.py index ff0b9f61..55ec8e66 100644 --- a/django_ledger/models/transactions.py +++ b/django_ledger/models/transactions.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - The TransactionModel is the lowest accounting level where financial information is recorded. Every transaction with a financial implication must be part of a JournalEntryModel, which encapsulates a collection of TransactionModels. Transaction models cannot exist without being part of a validated JournalEntryModel. Orphan TransactionModels are not @@ -24,7 +21,7 @@ from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator from django.db import models -from django.db.models import Q, QuerySet, F +from django.db.models import Q, QuerySet, Manager from django.db.models.signals import pre_save from django.utils.translation import gettext_lazy as _ @@ -209,7 +206,7 @@ def is_closing_entry(self): return self.filter(journal_entry__is_closing_entry=True) -class TransactionModelManager(models.Manager): +class TransactionModelManager(Manager): """ A manager class for the TransactionModel. """ diff --git a/django_ledger/models/unit.py b/django_ledger/models/unit.py index 4b511da7..91fe5880 100644 --- a/django_ledger/models/unit.py +++ b/django_ledger/models/unit.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - An EntityUnit is a logical, user-defined grouping which is assigned to JournalEntryModels to help segregate business operations into separate components. Examples of business units may include Departments (i.e. Human Resources, IT, etc.) office locations, a real estate property, or any other label relevant to the business. diff --git a/django_ledger/models/utils.py b/django_ledger/models/utils.py index 28677964..a8634cfe 100644 --- a/django_ledger/models/utils.py +++ b/django_ledger/models/utils.py @@ -1,9 +1,6 @@ """ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. - -Contributions to this module: - * Miguel Sanda """ from django.apps import apps diff --git a/django_ledger/models/vendor.py b/django_ledger/models/vendor.py index 51e42ea1..4b9fe2f3 100644 --- a/django_ledger/models/vendor.py +++ b/django_ledger/models/vendor.py @@ -2,9 +2,6 @@ Django Ledger created by Miguel Sanda . Copyright© EDMA Group Inc licensed under the GPLv3 Agreement. -Contributions to this module: - * Miguel Sanda - A Vendor refers to the person or entity that provides products and services to the business for a fee. Vendors are an integral part of the billing process as they are the providers of goods and services for the business. diff --git a/django_ledger/templates/django_ledger/account/account_create.html b/django_ledger/templates/django_ledger/account/account_create.html index cbb554e9..02f744d8 100644 --- a/django_ledger/templates/django_ledger/account/account_create.html +++ b/django_ledger/templates/django_ledger/account/account_create.html @@ -13,12 +13,12 @@

{{ coa_model.name }}

-
+ {% csrf_token %} {{ form.as_p }} Back + href="{{ coa_model.get_account_list_url }}">Back
diff --git a/django_ledger/templates/django_ledger/account/account_update.html b/django_ledger/templates/django_ledger/account/account_update.html index ede2f8ab..3758f453 100644 --- a/django_ledger/templates/django_ledger/account/account_update.html +++ b/django_ledger/templates/django_ledger/account/account_update.html @@ -18,7 +18,7 @@

{{ account }}

{{ form.as_p }} Back + href="{{ coa_model.get_account_list_url }}">Back diff --git a/django_ledger/templates/django_ledger/account/tags/account_txs_table.html b/django_ledger/templates/django_ledger/account/tags/account_txs_table.html index 77a01929..2d84a8b8 100644 --- a/django_ledger/templates/django_ledger/account/tags/account_txs_table.html +++ b/django_ledger/templates/django_ledger/account/tags/account_txs_table.html @@ -32,6 +32,7 @@ diff --git a/django_ledger/templates/django_ledger/bills/bill_detail.html b/django_ledger/templates/django_ledger/bills/bill_detail.html index 6a20d1e6..4a5ebbfa 100644 --- a/django_ledger/templates/django_ledger/bills/bill_detail.html +++ b/django_ledger/templates/django_ledger/bills/bill_detail.html @@ -29,7 +29,7 @@

{% trans 'Cash Account' %}: - {{ bill.cash_account.code }}

{% currency_symbol %}{{ bill.get_amount_cash | absolute | currency_format }}

@@ -40,7 +40,7 @@

{% trans 'Prepaid Account' %}: - {{ bill.prepaid_account.code }}

@@ -50,7 +50,7 @@

{% trans 'Accounts Payable' %}: - {{ bill.unearned_account.code }}

diff --git a/django_ledger/templates/django_ledger/expense/tags/expense_item_table.html b/django_ledger/templates/django_ledger/expense/tags/expense_item_table.html index 26d5ce83..39c9934b 100644 --- a/django_ledger/templates/django_ledger/expense/tags/expense_item_table.html +++ b/django_ledger/templates/django_ledger/expense/tags/expense_item_table.html @@ -9,6 +9,7 @@ {% trans 'Item' %} {% trans 'UOM' %} {% trans 'Expense Account' %} + {% trans 'Is Active' %} {% trans 'Actions' %} @@ -19,6 +20,12 @@ {{ expense_item.name }} {{ expense_item.uom }} {{ expense_item.expense_account }} + + {% if expense_item.is_active %} + {% icon 'bi:check-circle-fill' 24 %} + {% else %} + {% icon 'healthicons:no' 24 %} + {% endif %}