From a13a0755f73535bcfddce845466bf75e130b528a Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Tue, 25 Nov 2025 15:11:11 -0500 Subject: [PATCH 1/9] feat: update changelog with prose processing --- .pre-commit-config.yaml | 8 + CHANGELOG.md | 1546 ++++++++++++++++++++++++++++++--------- 2 files changed, 1193 insertions(+), 361 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d34c77ef..71b7430d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -60,6 +60,14 @@ repos: - id: codespell additional_dependencies: - tomli + exclude: > + (?x)^( + CHANGELOG.md| + .*\.lock| + .*\.pyc| + \.tox + \.mypy_cache + )$ - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.15.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7398ab24..df2372f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,57 +1,400 @@ -# CHANGELOG +# Changelog +This changelog was automatically generated from GitHub releases and pull requests. + +## [v15.10.0] - 2025-09-10 + +### Release Notes + +## v15.10.0 (2025-09-10) + +### Bug Fixes + +- Dates control ([`b04a9bb`](https://github.com/agritheory/check_run/commit/b04a9bb81ec0cbf5f0170d4e5836f8bdad86a68f)) + +- Mandatory field ([`bb35197`](https://github.com/agritheory/check_run/commit/bb35197a74bed207c52b55f8fb37f5246b86b6dc)) + +- Naming and precise dates to test edge cases ([`c7de096`](https://github.com/agritheory/check_run/commit/c7de0969c1d28f2053e63416ea5e8c22dbb1ec8d)) + +- Numer to number ([`47c445e`](https://github.com/agritheory/check_run/commit/47c445e0d946fea4591d609af6ac11061a766e29)) + +- Posting_date moved ([`f9c49dd`](https://github.com/agritheory/check_run/commit/f9c49dd4ae59606f8993333e4930e743558f29a9)) + +- Posting_date str to obj ([`74a7fa8`](https://github.com/agritheory/check_run/commit/74a7fa80105e358ab132d5acd6c7309e54c82cff)) + +- Reduce the Paid Amount field by the discount ([`f6da84c`](https://github.com/agritheory/check_run/commit/f6da84cb92ee1908c8beafa8f52e539678484b06)) + +- Show discount and due_date format ([`5ba1567`](https://github.com/agritheory/check_run/commit/5ba156720c99ae57ac9ba3178b5298553ac76d85)) + +### Chores + +- Yarn.lock ignored ([`177e0b3`](https://github.com/agritheory/check_run/commit/177e0b33470059d354b7156ff44ba1eb07b4133f)) + +### Features + +- Calculate_payment_term_discount ([`46d1c98`](https://github.com/agritheory/check_run/commit/46d1c98d16f91376094db74b3f662ecabdc0078d)) + +- Discount applied on submit ([`e35a6c2`](https://github.com/agritheory/check_run/commit/e35a6c21ac1455705eccd081e84aed98afcdb7bf)) + +- Discounts test data ([`48fa6a5`](https://github.com/agritheory/check_run/commit/48fa6a53cef798bb955770a9fbd7675c0e3a5340)) + +- Payment Discount Account field ([`dd60801`](https://github.com/agritheory/check_run/commit/dd60801c50f26c2146e90724d2d1038e19cfe555)) + +- Tests discounts ([`eaa35ea`](https://github.com/agritheory/check_run/commit/eaa35ea58325acdc562f79bbc9a33b04c402e7cd)) + +--- + +**Detailed Changes**: [v15.9.1...v15.10.0](https://github.com/agritheory/check_run/compare/v15.9.1...v15.10.0) + + +### Changes from Pull Requests + +Added a new field for Payment Discount Account in Check Run Settings. Fixed an issue where valid payment term discounts were not applied to invoices. + _Source: PR #373_ + +## [v15.9.1] - 2025-08-18 + +### Release Notes + +## v15.9.1 (2025-08-18) + +### Bug Fixes + +- Disallow save until table renders (#380) (#381) ([#381](https://github.com/agritheory/check_run/pull/381), [`71afea9`](https://github.com/agritheory/check_run/commit/71afea9712d2fcf1c33ee17f39f1e5afa52374bf)) + +--- + +**Detailed Changes**: [v15.9.0...v15.9.1](https://github.com/agritheory/check_run/compare/v15.9.0...v15.9.1) + + +### Changes from Pull Requests + +Fixed an issue where saving was allowed before the table rendered. Corrected the mode of payment summary. + _Source: PR #381_ + +Added a new action to generate changelogs automatically. This simplifies tracking updates and improvements in the project. + _Source: PR #375_ + +## [v15.9.0] - 2025-07-10 + +### Release Notes + +## v15.9.0 (2025-07-10) + +### Features + +- Add amount to positive pay (#369) (#371) ([#371](https://github.com/agritheory/check_run/pull/371), [`8f7168c`](https://github.com/agritheory/check_run/commit/8f7168c4320cf9ac3252453278870062078c71e9)) + +--- + +**Detailed Changes**: [v15.8.0...v15.9.0](https://github.com/agritheory/check_run/compare/v15.8.0...v15.9.0) + + +### Changes from Pull Requests + +Added amount field to positive pay feature. + _Source: PR #371_ + +Backported issue 355 to version 15. Fixed issues with on_hold status and added tests for check_run functionality. + _Source: PR #362_ + +## [v15.8.0] - 2025-06-24 + +### Release Notes + +## v15.8.0 (2025-06-24) + +### Features + +- Backport issue_355 (#361) ([#361](https://github.com/agritheory/check_run/pull/361), [`925bb23`](https://github.com/agritheory/check_run/commit/925bb231f112ab2799ddc5e35e99682b5c3ba402)) + +--- + +**Detailed Changes**: [v15.7.4...v15.8.0](https://github.com/agritheory/check_run/compare/v15.7.4...v15.8.0) + + +### Changes from Pull Requests + +Backported issue 355 to version 15. Updated check run settings and fixed issues in CheckRun.vue component. + _Source: PR #361_ + +## [v15.7.4] - 2025-06-22 + +### Release Notes + +## v15.7.4 (2025-06-22) + +### Bug Fixes + +- Ensure that on-hold invoices are not preselected for payment (#358) (#360) ([#360](https://github.com/agritheory/check_run/pull/360), [`554b755`](https://github.com/agritheory/check_run/commit/554b755be3fbea77ff73fb08633ac27c6b862b0b)) + +--- + +**Detailed Changes**: [v15.7.3...v15.7.4](https://github.com/agritheory/check_run/compare/v15.7.3...v15.7.4) + + +### Changes from Pull Requests + +Fixed an issue where on-hold invoices were being preselected for payment. This ensures a smoother and more accurate billing process for users. + _Source: PR #360_ + +## [v15.7.3] - 2025-06-18 + +### Release Notes + +## v15.7.3 (2025-06-18) + +### Bug Fixes + +- Use correct keyword argument for v15 (#356) ([#356](https://github.com/agritheory/check_run/pull/356), [`8c429e8`](https://github.com/agritheory/check_run/commit/8c429e8b379810745a74a5331173c2e81a3c139e)) + +--- + +**Detailed Changes**: [v15.7.2...v15.7.3](https://github.com/agritheory/check_run/compare/v15.7.2...v15.7.3) + + +### Changes from Pull Requests + +Fixed an issue where the wrong keyword argument was used for v15, ensuring compatibility and functionality. + _Source: PR #356_ + +## [v15.7.2] - 2025-06-11 + +### Release Notes + +## v15.7.2 (2025-06-11) + +### Bug Fixes + +- Filters mop (#341) ([#352](https://github.com/agritheory/check_run/pull/352), [`bac67ba`](https://github.com/agritheory/check_run/commit/bac67ba96df124333805152b130a561ebe2ecfa4)) + +--- + +**Detailed Changes**: [v15.7.1...v15.7.2](https://github.com/agritheory/check_run/compare/v15.7.1...v15.7.2) + + +### Changes from Pull Requests + +Fixed an issue with filters in the application. Added new pay filter options. + _Source: PR #352_ + +## [v15.7.1] - 2025-06-11 + +### Release Notes + +## v15.7.1 (2025-06-11) + +### Bug Fixes + +- Backport-335-to-version-15 ([#344](https://github.com/agritheory/check_run/pull/344), [`b155a6c`](https://github.com/agritheory/check_run/commit/b155a6c77703b9bc68191c681dee4acb07dd715e)) + +--- + +**Detailed Changes**: [v15.7.0...v15.7.1](https://github.com/agritheory/check_run/compare/v15.7.0...v15.7.1) + + +### Changes from Pull Requests + +Fixed an issue that caused problems in version 15. Improved linting and updated JavaScript configuration files for better performance. + _Source: PR #344_ + +## [v15.7.0] - 2025-06-11 + +### Release Notes + +## v15.7.0 (2025-06-11) + +### Features + +- Base Example Voucher MICR print format off Payment Entry ([#351](https://github.com/agritheory/check_run/pull/351), [`bb874e4`](https://github.com/agritheory/check_run/commit/bb874e4fcf038c2656143842c52c5ee0e1bd8d99)) + +--- + +**Detailed Changes**: [v15.6.0...v15.7.0](https://github.com/agritheory/check_run/compare/v15.6.0...v15.7.0) + + +### Changes from Pull Requests + +Added a new MICR print format for Payment Entries in Example Vouchers. This update addresses issue #348 and improves the clarity and functionality of payment documents. + _Source: PR #351_ + +## [v15.6.0] - 2025-06-11 + +### Release Notes + +## v15.6.0 (2025-06-11) + +### Features + +- Check run settings quick entry override ([#350](https://github.com/agritheory/check_run/pull/350), [`e778743`](https://github.com/agritheory/check_run/commit/e778743dfc25adeafadfcedb6d8216a087e649b9)) + +--- + +**Detailed Changes**: [v15.5.0...v15.6.0](https://github.com/agritheory/check_run/compare/v15.5.0...v15.6.0) + + +### Changes from Pull Requests + +Bank Account and Payable Account fields now preload their values correctly. The Payable Account field also filters properly. + _Source: PR #350_ + +## [v15.5.0] - 2025-06-11 + +### Release Notes + +## v15.5.0 (2025-06-11) + +### Features + +- Add setting to automatically attach positive pay to Check Run ([#347](https://github.com/agritheory/check_run/pull/347), [`9cc13df`](https://github.com/agritheory/check_run/commit/9cc13df7e29366b1e424d1a432d591519b33c2f6)) + +--- + +**Detailed Changes**: [v15.4.0...v15.5.0](https://github.com/agritheory/check_run/compare/v15.4.0...v15.5.0) + + +### Changes from Pull Requests + +Added an option to automatically attach Positive Pay to Check Runs. This feature was backported from a newer version to ensure compatibility and functionality in `version-15`. + _Source: PR #347_ + +## [v15.4.0] - 2025-05-29 + +### Release Notes + +## v15.4.0 (2025-05-29) + +### Chores + +- Bp ([#327](https://github.com/agritheory/check_run/pull/327), [`3426dd8`](https://github.com/agritheory/check_run/commit/3426dd8ab48bfc64c229122ff0f0473fe5898fb0)) + +- Fix merge ([#306](https://github.com/agritheory/check_run/pull/306), [`c8e8317`](https://github.com/agritheory/check_run/commit/c8e8317677c43f64f42db4c8516fab20ed74cc42)) + +### Features + +- Add permissioned signature API ([#339](https://github.com/agritheory/check_run/pull/339), [`5f0d019`](https://github.com/agritheory/check_run/commit/5f0d019b0a9e8d71caf93ca613d2e4aa20695b2d)) + +### Testing + +- Backport posting date config tests, add pytest-order ([#311](https://github.com/agritheory/check_run/pull/311), [`eb1f540`](https://github.com/agritheory/check_run/commit/eb1f540a1753b671cc38cbb8be5879c9aa936a9a)) + +--- + +**Detailed Changes**: [v15.3.1...v15.4.0](https://github.com/agritheory/check_run/compare/v15.3.1...v15.4.0) + + +### Changes from Pull Requests + +Added permissioned signature API for enhanced security and control. + _Source: PR #339_ + +Updated approval workflow for RFPs. Fixed issues in check run settings and documentation. + _Source: PR #327_ + +Handling keydown events now supported. Fixed issues with asset caching and user experience. + _Source: PR #319_ + +Added permission checks for custom buttons and process check run API. Updated documentation on permissions. + _Source: PR #312_ + +Backported new posting date config tests and added pytest-order markers. Fixed issues related to test organization in `version-15`. + _Source: PR #311_ + +In Check Run Settings, the Company, Bank Account, and Payable Account fields are now mandatory. This ensures that all necessary information is provided during checks, preventing errors in processing payments. + _Source: PR #306_ + +## [v15.3.1] - 2025-04-15 + +### Release Notes ## v15.3.1 (2025-04-15) ### Bug Fixes -- Remove unnecessary self typing ([#296](https://github.com/agritheory/check_run/pull/296), - [`c5ca969`](https://github.com/agritheory/check_run/commit/c5ca96919a6131b9e86631f49abc6d2b1ffc61ff)) +- Remove unnecessary self typing ([#296](https://github.com/agritheory/check_run/pull/296), [`c5ca969`](https://github.com/agritheory/check_run/commit/c5ca96919a6131b9e86631f49abc6d2b1ffc61ff)) Co-authored-by: Rohan Bansal Co-authored-by: Tyler Matteson +--- + +**Detailed Changes**: [v15.3.0...v15.3.1](https://github.com/agritheory/check_run/compare/v15.3.0...v15.3.1) + + +### Changes from Pull Requests + +Removed unnecessary self typing in codebase. Fixed potential issues related to type inference by IDEs. + _Source: PR #296_ + +Ports config posting date feature to version-15. Fixed issues with node action/cache and pre-commit configuration. Updated documentation for settings. + _Source: PR #301_ + +## [v15.3.0] - 2025-04-15 + +### Release Notes ## v15.3.0 (2025-04-15) ### Features -- Make Posting Date read only if Set Payment Entry Posting Date == Use Todays Date" (#303) - ([#309](https://github.com/agritheory/check_run/pull/309), - [`88c0863`](https://github.com/agritheory/check_run/commit/88c0863ceaa5f43924bb4d17b0e8e960c98e988a)) +- Make Posting Date read only if Set Payment Entry Posting Date == Use Todays Date" (#303) ([#309](https://github.com/agritheory/check_run/pull/309), [`88c0863`](https://github.com/agritheory/check_run/commit/88c0863ceaa5f43924bb4d17b0e8e960c98e988a)) (cherry picked from commit 61a43b32978927982369fa88afc85abc249ac910) Co-authored-by: Francisco Roldán +--- + +**Detailed Changes**: [v15.2.1...v15.3.0](https://github.com/agritheory/check_run/compare/v15.2.1...v15.3.0) + + +### Changes from Pull Requests + +Make Posting Date read only if Set Payment Entry Posting Date is set to 'Use Today's Date'. This change ensures that users cannot manually edit the posting date when it is automatically determined. + _Source: PR #309_ + +## [v15.2.1] - 2025-04-01 + +### Release Notes ## v15.2.1 (2025-04-01) ### Bug Fixes -- Respect settings date config (#298) ([#299](https://github.com/agritheory/check_run/pull/299), - [`fcb2ab5`](https://github.com/agritheory/check_run/commit/fcb2ab574fa35e4a3fa507186f17112d258e9404)) +- Respect settings date config (#298) ([#299](https://github.com/agritheory/check_run/pull/299), [`fcb2ab5`](https://github.com/agritheory/check_run/commit/fcb2ab574fa35e4a3fa507186f17112d258e9404)) (cherry picked from commit 8edbbffd1a8787102a30bce37ae9917c62c5f5d7) Co-authored-by: Tyler Matteson +--- + +**Detailed Changes**: [v15.2.0...v15.2.1](https://github.com/agritheory/check_run/compare/v15.2.0...v15.2.1) + + +### Changes from Pull Requests + +Fixed an issue where settings date config was not being respected. This update ensures that the system now correctly applies the configured date settings. + _Source: PR #299_ + +## [v15.2.0] - 2025-01-28 + +### Release Notes ## v15.2.0 (2025-01-28) ### Continuous Integration -- Backport config (#271) ([#272](https://github.com/agritheory/check_run/pull/272), - [`db40e9f`](https://github.com/agritheory/check_run/commit/db40e9f69444da2857be322a82851210c7a23e1f)) +- Backport config (#271) ([#272](https://github.com/agritheory/check_run/pull/272), [`db40e9f`](https://github.com/agritheory/check_run/commit/db40e9f69444da2857be322a82851210c7a23e1f)) -Co-authored-by: Tyler Matteson (cherry picked from commit - 438efdea82cc67cbeeb5df59c237e0450721d263) +Co-authored-by: Tyler Matteson + +(cherry picked from commit 438efdea82cc67cbeeb5df59c237e0450721d263) Co-authored-by: Myuddin Khatri <53251406+MyuddinKhatri@users.noreply.github.com> -- Change backport config (#273) ([#275](https://github.com/agritheory/check_run/pull/275), - [`48eebf7`](https://github.com/agritheory/check_run/commit/48eebf7efd5071ced8b9299862afe28652b4288d)) +- Change backport config (#273) ([#275](https://github.com/agritheory/check_run/pull/275), [`48eebf7`](https://github.com/agritheory/check_run/commit/48eebf7efd5071ced8b9299862afe28652b4288d)) (cherry picked from commit 76fc626c6fa697cfd914ddef26e2c6b4ed3ba8c8) @@ -59,8 +402,7 @@ Co-authored-by: Myuddin Khatri <53251406+MyuddinKhatri@users.noreply.github.com> ### Features -- Add MICR Encoding Print Format and docs ([#282](https://github.com/agritheory/check_run/pull/282), - [`2b9f51a`](https://github.com/agritheory/check_run/commit/2b9f51a6145ee3c474c5949b75a12a346b15f359)) +- Add MICR Encoding Print Format and docs ([#282](https://github.com/agritheory/check_run/pull/282), [`2b9f51a`](https://github.com/agritheory/check_run/commit/2b9f51a6145ee3c474c5949b75a12a346b15f359)) * feat: add print format applying MICR Encoding font @@ -68,577 +410,1059 @@ Co-authored-by: Myuddin Khatri <53251406+MyuddinKhatri@users.noreply.github.com> * docs: add MICR Encoding print format +--- -## v15.1.2 (2024-07-18) +**Detailed Changes**: [v15.1.2...v15.2.0](https://github.com/agritheory/check_run/compare/v15.1.2...v15.2.0) -### Bug Fixes -- Serialize null transactions(v15) ([#262](https://github.com/agritheory/check_run/pull/262), - [`5e13ec7`](https://github.com/agritheory/check_run/commit/5e13ec7514b78ce6d2596ed5c640e4f2c1d9bada)) +### Changes from Pull Requests -* fix: serialize null transactions(v15) +Added MICR Encoding print format for checks. Updated documentation with rendering caveats. + _Source: PR #282_ -* fix: remove ci jobs dependency +Added a new GitHub Action to print diff formats, improving readability and usability. + _Source: PR #284_ +Updated backport configuration to streamline the process. Removed old configuration file and updated workflow for better automation. + _Source: PR #275_ -## v15.1.1 (2024-05-29) +This update includes new configuration files for continuous integration backporting. Users can now benefit from automated backport processes, enhancing efficiency and reducing manual errors in version management. + _Source: PR #272_ -### Bug Fixes +## [v15.1.2] - 2024-07-18 -- Bankaccount => bank typing ([#247](https://github.com/agritheory/check_run/pull/247), - [`da77cc3`](https://github.com/agritheory/check_run/commit/da77cc329e28d95f84783d98dbd204addb39d0e8)) +### Release Notes -### Continuous Integration +# v15.1.2 (2024-07-18) -- Add conftest file updated for json ([#228](https://github.com/agritheory/check_run/pull/228), - [`dc306c3`](https://github.com/agritheory/check_run/commit/dc306c3364ac9ecb2d02003137284a138340ef42)) +## Fix -- Remove cypress, fix hrms install, conform - ([#221](https://github.com/agritheory/check_run/pull/221), - [`f6b629b`](https://github.com/agritheory/check_run/commit/f6b629b7876a14795f39dc6d853ea5b7f8722098)) +* fix: serialize null transactions(v15) (#262) -* ci: remove cypress, fix hrms install, conform +* fix: serialize null transactions(v15) -* ci: fix mypy error +* fix: remove ci jobs dependency ([`5e13ec7`](https://github.com/agritheory/check_run/commit/5e13ec7514b78ce6d2596ed5c640e4f2c1d9bada)) -### Testing +## Unknown -- Add tests, remove cypress ([#238](https://github.com/agritheory/check_run/pull/238), - [`c20ed6e`](https://github.com/agritheory/check_run/commit/c20ed6e23fc744f0718dd85665f407c134bb7a56)) +* Allow or Disallow stand-alone debit note in check run -- Version 15 (#257) +* allow or disallow standalone debit note -## v15.1.0 (2024-03-18) +* test cases changes' ([`e0707df`](https://github.com/agritheory/check_run/commit/e0707df4fba64ac63e9fd4d36627c792748db292)) -### Features +* Fix payment schedule outstanding v15 (#254) -- Add v15 to release config - ([`41e329d`](https://github.com/agritheory/check_run/commit/41e329d5f58b8d2c1550a334495fe2c57ff0bc5b)) +* fix: fix payment schedule outstanding -- Release version-15 - ([`6cd1a27`](https://github.com/agritheory/check_run/commit/6cd1a2788dc6597b3236d867b2dfd3f047dd4d6f)) +* test: assert parent doc amount matches -- Update init version - ([`f53307b`](https://github.com/agritheory/check_run/commit/f53307bbdd631b1e2dd869cb2c3a7892d9acc870)) +* tests: fix matching error message -- Version-15 - ([`0f2cd0a`](https://github.com/agritheory/check_run/commit/0f2cd0ada07d1cb3e13ebe5325a0b9d6ab2e3876)) +* feat: on_cancel hook and tests +* feat: minor changes, add precision (#253) -## v15.0.0 (2024-03-05) +* fix: isort, JE generation issue -### Continuous Integration +--------- -- Add frappe black to CI ([#214](https://github.com/agritheory/check_run/pull/214), - [`771e57c`](https://github.com/agritheory/check_run/commit/771e57c166f6516c4a518d5960ff1371b254b038)) +Co-authored-by: Francisco Roldán <franciscoproldan@gmail.com> ([`624f36e`](https://github.com/agritheory/check_run/commit/624f36ebf195e734795216cdc790b0b1112ee802)) -* ci: add frappe black to CI +### Changes from Pull Requests -* chore: black, flake8 +Fixed an issue where null transactions were not being serialized correctly. Removed unnecessary CI jobs dependency. + _Source: PR #262_ +Users can now allow or disallow standalone debit notes in check runs. This change includes updated settings and test cases for better functionality. + _Source: PR #257_ -## v14.11.5 (2024-02-06) +## [v14.11.7] - 2024-06-29 -### Bug Fixes +### Release Notes -- Disallow mop selection on submitted doc, fix indicator - ([#207](https://github.com/agritheory/check_run/pull/207), - [`0429e48`](https://github.com/agritheory/check_run/commit/0429e484c38227ac0f4136f94d128d5ef26580f9)) +# v14.11.7 (2024-06-29) -- Onchanges of mode_of_payment make enable to save form - ([#206](https://github.com/agritheory/check_run/pull/206), - [`0b4bff0`](https://github.com/agritheory/check_run/commit/0b4bff0d5de5e76d6e0127e53081775a8056554b)) +## Fix -Co-authored-by: viralpatel15 +* fix: clean up and upgrade dependencies in v14 (#259) ([`ae18154`](https://github.com/agritheory/check_run/commit/ae181546d750bf2c6a3f5e2308f0721f75d8eb74)) +## [v14.11.6] - 2024-06-29 -## v14.11.4 (2024-01-22) +### Release Notes -### Bug Fixes +# v14.11.6 (2024-06-29) -- Always include payment term for purchase invoice - ([#197](https://github.com/agritheory/check_run/pull/197), - [`1156621`](https://github.com/agritheory/check_run/commit/1156621b4b80f0e7a5cc3f7c10076910305ad29b)) +## Ci -* ci: update app name in path string check +* ci: track overrides for Payment Entry (#248) ([`fc3d902`](https://github.com/agritheory/check_run/commit/fc3d9028a46f6cf31ff0c96cfc87a29f83a37c7a)) -* fix: add PI payment term in Pmt Entry outside a Check Run +## Fix -* tests: add manual payment entry to test payment term +* fix: File preview (#256) -* docs: update for Payment Entry payment term customizations +* fix: File preview +* feat: refactor to jQuery -## v14.11.3 (2024-01-18) +--------- -### Bug Fixes +Co-authored-by: Tyler Matteson <tyler@agritheory.com> ([`061be4e`](https://github.com/agritheory/check_run/commit/061be4ed28531be1b6f4fed5cb07bec8295a4699)) -- Add docstatus check first before fetching supplier MOP - ([#195](https://github.com/agritheory/check_run/pull/195), - [`9691364`](https://github.com/agritheory/check_run/commit/9691364f52248e4dfd2c79eaa89bdaba41c5d148)) +## Unknown +* Secondary Print Format (#209) -## v14.11.2 (2024-01-18) +* fix: customization on split payment entry -### Bug Fixes +* changes to remove pre-commit error -- Remove validation ([#194](https://github.com/agritheory/check_run/pull/194), - [`efda8ae`](https://github.com/agritheory/check_run/commit/efda8ae0f58ce272eae7888a0dd867a7ede4c792)) +* changes to remove pre-commit error +* new print format Secondery sample -## v14.11.1 (2024-01-18) +* rename print format -### Bug Fixes +* on header check number added -- Payment terms validation ([#192](https://github.com/agritheory/check_run/pull/192), - [`036177d`](https://github.com/agritheory/check_run/commit/036177d6e4b82455e90e9e9d5d58e60f58845749)) +* cheque number added +* set print format -## v14.11.0 (2024-01-08) +* payment currency added -### Features +* print format changes -- Filter check run settings print format to only show enabled and Payment Entry formats - ([#186](https://github.com/agritheory/check_run/pull/186), - [`fc0f7d7`](https://github.com/agritheory/check_run/commit/fc0f7d776f83f8bc8b3b194b0362de3e27aa1baa)) +* comma saperated on bothe tablec +* commit to solve linter test -## v14.10.0 (2023-12-14) +* secondary print format with same attechment -### Features +* change field name in print format -- Ignore PI where debit not has been issued - ([#181](https://github.com/agritheory/check_run/pull/181), - [`e085e96`](https://github.com/agritheory/check_run/commit/e085e9675a70c81fdc560e2341472d345c92ee70)) +* split pdf in two attechment +* comment to run lint -## v14.9.0 (2023-12-12) +* fix: customization on split payment entry -### Bug Fixes +* fix:resolve conflict -- Empty string values to NULL in queries - ([`75ab1c9`](https://github.com/agritheory/check_run/commit/75ab1c96629b0e2220dd30555a1498ddd2561291)) +* fix: resolve conflict -### Documentation +* Check PDF name changes -- Update settings section - ([`b9b15f8`](https://github.com/agritheory/check_run/commit/b9b15f8ac16494d53399ccd7ab3f823fd1545620)) +--------- -### Features +Co-authored-by: viralpatel15 <viralkansodiya167@gmail.com> ([`9eda182`](https://github.com/agritheory/check_run/commit/9eda182dccd211090ce7f4c84399c1e863758ad4)) -- Add fallbacks for mode of payment per source document type - ([`12f9160`](https://github.com/agritheory/check_run/commit/12f916000dbb96db2a1ea3474b55d226a7a1cb5a)) +* Fix payment schedule outstanding (#251) +* fix: fix payment schedule outstanding -## v14.8.4 (2023-12-11) +* test: assert parent doc amount matches -### Bug Fixes +* tests: fix matching error message -- Only fetch check number on "pay" payment types - ([#179](https://github.com/agritheory/check_run/pull/179), - [`1b6dd48`](https://github.com/agritheory/check_run/commit/1b6dd488a6cf921c4497737f47d27627f19e510f)) +* feat: on_cancel hook and tests +* feat: minor changes, add precision (#253) -## v14.8.3 (2023-12-11) +--------- -### Bug Fixes +Co-authored-by: Francisco Roldán <franciscoproldan@gmail.com> ([`46a084a`](https://github.com/agritheory/check_run/commit/46a084a3cf862e06bbd3a0b9c81ecd5e6a683d07)) -- Mode of payment summary ([#176](https://github.com/agritheory/check_run/pull/176), - [`40fd4ee`](https://github.com/agritheory/check_run/commit/40fd4ee3057f9808944258b9d7807522827f17a6)) +* Allow and Disallow setting to create stand-alone debit note (#232) -* fix: mode of payment summary +* Seetng added for stand-alon credit note -* wip: refactor reactivity for performance +* remove field from check run settings -* feat: improved reactivity +* custom field Allow stand-alone debit notes? -* style: prettify code +* correct the spelling mistake -* fix: move built files to dist folder / ignored by git +* move setting from company level to check run settings level ---------- +* reformat by pre-commit -Co-authored-by: Tyler Matteson +* chore: prettier -Co-authored-by: agritheory +* chore: remove old linters +* chore: fix checkout GHA depth from forks -## v14.8.2 (2023-09-22) +* ci: fix python version -### Bug Fixes +* test: add test for excluding purchase invoice return -- Required_apps ([#162](https://github.com/agritheory/check_run/pull/162), - [`31b5297`](https://github.com/agritheory/check_run/commit/31b52975839424f9a9bfbded6cc03c241dcb44cd)) +--------- -* fix: required_apps +Co-authored-by: Tyler Matteson <tyler@agritheory.com> ([`f76ad3a`](https://github.com/agritheory/check_run/commit/f76ad3acc971ff59fe8ffd0332a5339ac8f84b62)) +* Add documentation and tests for returns (#222) -## v14.8.1 (2023-09-14) +* docs: add screen shot and explanation around returns -### Bug Fixes +* test: add return test -- Customizations leaks, module specificity - ([#161](https://github.com/agritheory/check_run/pull/161), - [`ce6b9fc`](https://github.com/agritheory/check_run/commit/ce6b9fc2a79e9a1beea4f514b3c52d4fd442da50)) +* ci: replace cypress with pytest tests -### Continuous Integration +* ci: add pytest dependency ([`48bd0c2`](https://github.com/agritheory/check_run/commit/48bd0c274429cd8f1bb034d551f99bb23277056e)) -- Update release action user and email ([#155](https://github.com/agritheory/check_run/pull/155), - [`a3cfc97`](https://github.com/agritheory/check_run/commit/a3cfc975aac95696b943ecbd809a00cab6159ffd)) +* Staging (#220) +* fix: add supplier bank field (#219) -## v14.8.0 (2023-09-08) +was removed previously in error -### Features +* remove irrelevant code (#217) -- Add read_only decorator - ([`c7bb83c`](https://github.com/agritheory/check_run/commit/c7bb83ceba8fcfd291b6198ff1ee8b92edf1abca)) +--------- +Co-authored-by: ViralKansodiya-Fosserp <141210323+viralkansodiya@users.noreply.github.com> ([`cf8e1fe`](https://github.com/agritheory/check_run/commit/cf8e1fe1cc4f1aa5915a0f91e42c2a3ba5c39fdb)) -## v14.7.0 (2023-09-07) +### Changes from Pull Requests -### Bug Fixes +Fixed issues with payment schedule outstanding. Added new tests and hooks for better functionality. + _Source: PR #254_ -- Move bank validation out of override class into hook - ([#142](https://github.com/agritheory/check_run/pull/142), - [`f07ad5a`](https://github.com/agritheory/check_run/commit/f07ad5a1c4a9b7e424ad534ec40731f26f6feb0c)) +## [v15.1.1] - 2024-05-29 -- Only increment if check number is numeric - ([#139](https://github.com/agritheory/check_run/pull/139), - [`079aa52`](https://github.com/agritheory/check_run/commit/079aa52bf013e13d3350848ef011b74b99b64bf1)) +### Release Notes -- Skip check on draft check runs with no transactions (v14) - ([#148](https://github.com/agritheory/check_run/pull/148), - [`dadd084`](https://github.com/agritheory/check_run/commit/dadd084c26f50de4e9dff1f360a8d73bbb37e250)) +# v15.1.1 (2024-05-29) -Resolution for `TypeError: the JSON object must be str, bytes or bytearray, not NoneType` when draft - check run has no transactions. +## Ci -### Continuous Integration +* ci: add conftest file updated for json (#228) ([`dc306c3`](https://github.com/agritheory/check_run/commit/dc306c3364ac9ecb2d02003137284a138340ef42)) -- Migrate to python semantic release ([#133](https://github.com/agritheory/check_run/pull/133), - [`d37bca6`](https://github.com/agritheory/check_run/commit/d37bca61505e99476e6fb857fbd36dacc932918a)) +* ci: remove cypress, fix hrms install, conform (#221) -* ci: migrate to python semantic release +* ci: remove cypress, fix hrms install, conform -* ci: add version variable file +* ci: fix mypy error ([`f6b629b`](https://github.com/agritheory/check_run/commit/f6b629b7876a14795f39dc6d853ea5b7f8722098)) -* ci: update remote name +## Fix -### Features +* fix: bankaccount => bank typing (#247) ([`da77cc3`](https://github.com/agritheory/check_run/commit/da77cc329e28d95f84783d98dbd204addb39d0e8)) -- Disallow cancellation of source documents selected for payment in draft CRs (#126) - ([#143](https://github.com/agritheory/check_run/pull/143), - [`bddc888`](https://github.com/agritheory/check_run/commit/bddc8884167c9e3381f519914a278a29fdf345f1)) +## Test +* test: add tests, remove cypress (#238) ([`c20ed6e`](https://github.com/agritheory/check_run/commit/c20ed6e23fc744f0718dd85665f407c134bb7a56)) -## v14.6.0 (2023-07-28) +## Unknown -### Bug Fixes +* Grant file download access for multiple downloads only to specific roles (#237) -- Add on hold fixes to query builder - ([`a1e3114`](https://github.com/agritheory/check_run/commit/a1e3114e78b3894af61b40d46276c6dd6c0d92d3)) +* ach file download access -- Broken translation string in csv ([#122](https://github.com/agritheory/check_run/pull/122), - [`9c2ded2`](https://github.com/agritheory/check_run/commit/9c2ded22846e0753a0ed4a7732781fb205a47df4)) +* replace super class validate -- Mop ignore keypress if input is focused - ([`e073c09`](https://github.com/agritheory/check_run/commit/e073c09a5ed26e61b34a44419f85a939781b1409)) +* chore: prettier -- Remove check_digit argument in ACH generation - ([#66](https://github.com/agritheory/check_run/pull/66), - [`8476235`](https://github.com/agritheory/check_run/commit/8476235f380cfcea81309bd703667f6ff047663d)) +* ci: remove old linters -- Remove undeclared variable reference - ([`6a36c84`](https://github.com/agritheory/check_run/commit/6a36c84c6b3f8b8497ca7bae9e8db24e1e939228)) +--------- -- Show purchase returns in check run ([#131](https://github.com/agritheory/check_run/pull/131), - [`b1cd85b`](https://github.com/agritheory/check_run/commit/b1cd85b42284a3ea38aa1c703d1f2ae714ab7f6a)) +Co-authored-by: Tyler Matteson <tyler@agritheory.com> ([`160f609`](https://github.com/agritheory/check_run/commit/160f6090b3e3061f12c8f9649c4755bb358a8f70)) -### Chores +### Changes from Pull Requests -- Fix account names ([#99](https://github.com/agritheory/check_run/pull/99), - [`7946bdf`](https://github.com/agritheory/check_run/commit/7946bdfb4bb4f7ba96a4939ff36f449bc108fa10)) +Fixed a typo in the code: changed "bankaccount" to "bank". This change improves readability and consistency. + _Source: PR #247_ -### Continuous Integration +#216: Grant file download access for multiple downloads only to specific roles. Fixed old linters and updated code formatting. + _Source: PR #237_ -- Fix release CI - ([`9c954d5`](https://github.com/agritheory/check_run/commit/9c954d5e6259a3c257036ea066e07e08afb93181)) +Added new tests for check runs and removed old Cypress files. + _Source: PR #238_ -- Fix release correctly on V14 also - ([`3ff2d65`](https://github.com/agritheory/check_run/commit/3ff2d65dece13db5e8e40b96fbe0ecd8aed4f0be)) +Added an updated `conftest.py` file that now uses JSON references instead of TXT. This change enhances configuration management and flexibility in tests. + _Source: PR #228_ -- Remove registry from package.json - ([`607db96`](https://github.com/agritheory/check_run/commit/607db9619e75740c419e01c622ee51374e53aecf)) +Removed Cypress for UI tests, fixed HRMS installation issues, and added a pytest workflow. + _Source: PR #221_ -- Update installation and workflows - ([`23c4f83`](https://github.com/agritheory/check_run/commit/23c4f838e51882b6f7db6ded58735b18e4f9a0c5)) +## [v15.1.0] - 2024-03-18 -### Documentation +### Release Notes -- Add translations page - ([`6e9c977`](https://github.com/agritheory/check_run/commit/6e9c9778b25aaa8d2bd8dc77ae87c341fbb1bc23)) +# v15.1.0 (2024-03-18) -### Features +## Feature -- Add Canadian DFI Routing Number validation for bank - ([`b4d9df9`](https://github.com/agritheory/check_run/commit/b4d9df97bc1705bd5c622d46bb88e4d7795f8b3d)) +* feat: add v15 to release config ([`41e329d`](https://github.com/agritheory/check_run/commit/41e329d5f58b8d2c1550a334495fe2c57ff0bc5b)) -- Add Canadian/GB English translations - ([`1e86c00`](https://github.com/agritheory/check_run/commit/1e86c00beb396499e7ece0eccb0902ab4e3188b0)) +* feat: update init version ([`f53307b`](https://github.com/agritheory/check_run/commit/f53307bbdd631b1e2dd869cb2c3a7892d9acc870)) -- Add logic for handling on-hold invoices, setting for automatic release and docs - ([`da93c1d`](https://github.com/agritheory/check_run/commit/da93c1d04a58b18d9c098f3661bd731c6761d783)) +* feat: release version-15 ([`6cd1a27`](https://github.com/agritheory/check_run/commit/6cd1a2788dc6597b3236d867b2dfd3f047dd4d6f)) -- Add validate when processing, enable on_update_after_submit hook - ([#115](https://github.com/agritheory/check_run/pull/115), - [`d58a106`](https://github.com/agritheory/check_run/commit/d58a106bd295c4811ff0722ca0ade7d29a711c34)) +* feat: version-15 ([`0f2cd0a`](https://github.com/agritheory/check_run/commit/0f2cd0ada07d1cb3e13ebe5325a0b9d6ab2e3876)) -- Check payment entries for cancelled or paid invoices before submitting - ([#108](https://github.com/agritheory/check_run/pull/108), - [`adbca4d`](https://github.com/agritheory/check_run/commit/adbca4df65c3599a213ddebacd9a269d8a2462a1)) +## [v14.11.5] - 2024-02-06 -- Custom immediate origin value in settings ([#76](https://github.com/agritheory/check_run/pull/76), - [`813be9e`](https://github.com/agritheory/check_run/commit/813be9e299c2ba42f1bc0de11fabd03d1ab2f0fb)) +### Release Notes -* feat: custom immediate origin value in settings +# v14.11.5 (2024-02-06) -* style: prettify code +## Fix ---------- +* fix: disallow mop selection on submitted doc, fix indicator (#207) ([`0429e48`](https://github.com/agritheory/check_run/commit/0429e484c38227ac0f4136f94d128d5ef26580f9)) -Co-authored-by: agritheory +* fix: onchanges of mode_of_payment make enable to save form (#206) -- Fix lookup for non-existient bank account info, improve UX - ([`4ef8a91`](https://github.com/agritheory/check_run/commit/4ef8a91ed769798d9569edc770ac4bd81a709b14)) +Co-authored-by: viralpatel15 <viralkansodiya167@gmail.com> ([`0b4bff0`](https://github.com/agritheory/check_run/commit/0b4bff0d5de5e76d6e0127e53081775a8056554b)) -- Port timeout fix to v14 ([#62](https://github.com/agritheory/check_run/pull/62), - [`6f50230`](https://github.com/agritheory/check_run/commit/6f50230a8713c16f1818ba8450abc18cc2535322)) +## Unknown -* feat: port timeout fix to v14 +* Override a function to improve error msg (#205) -* fix: indent +* Allocated ammount validation override for msg improvement -* chore: prettier formatting +* comment add -* style: prettify code +* add a comment on function + +* Refactor: Rename 'uniq_vouchers' to 'unique_vouchers' in payment_entry.py --------- -Co-authored-by: agritheory +Co-authored-by: viralpatel15 <viralkansodiya167@gmail.com> ([`80fa4cf`](https://github.com/agritheory/check_run/commit/80fa4cf564b8f437eaccfc042af10c23b54b895b)) -- Split checks by address - ([`b32f0c9`](https://github.com/agritheory/check_run/commit/b32f0c991ba91a8377e87673977a4b651a4f6970)) +* Remove paid document on Process check run (#202) -- Update translations to capture button text - ([`ccc4b67`](https://github.com/agritheory/check_run/commit/ccc4b6779c869a9786e7f67ded1c09333383439a)) +* class name has been change -- Validate docstatus of selected invoices still saved/submitted - ([#44](https://github.com/agritheory/check_run/pull/44), - [`78b3e25`](https://github.com/agritheory/check_run/commit/78b3e2580e200ce60211ed44d20651f68546eeae)) +* fix: remove paid invoice and changes related to manually paid case -* feat: validate docstatus of selected invoices still saved/submitted +* changes to remove class name changes ([`43cc33e`](https://github.com/agritheory/check_run/commit/43cc33ee6f192271b5c10b5c1efea7c09b17375f)) -* refactor: moved validation code for cancelled transactions to function +* class name has been changed (#201) ([`8d46b53`](https://github.com/agritheory/check_run/commit/8d46b535748949e1d5467b05f69abc6d68dc077b)) -### Testing -- Add on hold invoice to test data - ([`6867d42`](https://github.com/agritheory/check_run/commit/6867d428c77fb096125d17e1e0382a92aabceaa0)) +## [v14.11.4] - 2024-01-22 -- Add payment terms to test data - ([`8b4073e`](https://github.com/agritheory/check_run/commit/8b4073eaf7b0016fe7a4e1bd0c014af818d5477c)) +### Release Notes -- Fix net 14 days - ([`3acea48`](https://github.com/agritheory/check_run/commit/3acea48f68560ca417b1d05cd9153635e9cc6c2e)) +# v14.11.4 (2024-01-22) +## Fix -## v14.0.0 (2022-12-30) +* fix: always include payment term for purchase invoice (#197) -### Bug Fixes +* ci: update app name in path string check -- Add bank account to payment entry form - ([`3316d61`](https://github.com/agritheory/check_run/commit/3316d61fcce6b5de35cc029c52a9a1e57a507102)) +* fix: add PI payment term in Pmt Entry outside a Check Run + +* tests: add manual payment entry to test payment term -- Change employee party field so payment entry can properly link to it - ([`5f96753`](https://github.com/agritheory/check_run/commit/5f96753e1a27304565c59c39c150112b65aba50d)) +* docs: update for Payment Entry payment term customizations ([`1156621`](https://github.com/agritheory/check_run/commit/1156621b4b80f0e7a5cc3f7c10076910305ad29b)) -- Checkrun rerender on document change - ([`eabf8a5`](https://github.com/agritheory/check_run/commit/eabf8a55e9d2bd01fffdfbc6a24e41f8391a3981)) -- Company name in correct header field of NACHA file - ([`1e50281`](https://github.com/agritheory/check_run/commit/1e502816a1ade9badd5e0b727857847e4e194c55)) +## [v14.11.3] - 2024-01-18 -- Conform demo mode of payment types to docs recommendations - ([`44cb68c`](https://github.com/agritheory/check_run/commit/44cb68c3f5ce79f863ea79b988c3fca3a639481d)) +### Release Notes -- Don't trigger settings change for check run creation - ([`a672f46`](https://github.com/agritheory/check_run/commit/a672f467a1b3ceda3eb725e4bf605ecbc82933aa)) +# v14.11.3 (2024-01-18) -- Field name and type issues when creating NACHA file - ([`7ded221`](https://github.com/agritheory/check_run/commit/7ded221b633e6330520508d497f4ce6c49cede78)) +## Fix -- Include built JS - ([`12492b8`](https://github.com/agritheory/check_run/commit/12492b8573985470f5339ef37f71fd8c951da9e2)) +* fix: add docstatus check first before fetching supplier MOP (#195) ([`9691364`](https://github.com/agritheory/check_run/commit/9691364f52248e4dfd2c79eaa89bdaba41c5d148)) -- Line height and checkbox alignment - ([`232fff6`](https://github.com/agritheory/check_run/commit/232fff641db11dc821051154788ffbd35e4760e5)) -- Remove check PDF on confirm print - ([`c2d0db9`](https://github.com/agritheory/check_run/commit/c2d0db949f51dc6e232785212212fc12ab4189f5)) +## [v14.11.2] - 2024-01-18 -- Reorder Supplier json to show bank account field in form - ([#12](https://github.com/agritheory/check_run/pull/12), - [`5d05e38`](https://github.com/agritheory/check_run/commit/5d05e38f4004f5f36735e43b1a229a46b4762c48)) +### Release Notes -- Set fields in test script expense claim generation - ([`3152aac`](https://github.com/agritheory/check_run/commit/3152aac10b283aa92fdbd3f8e44a010b1d15b09c)) +# v14.11.2 (2024-01-18) -- Update installation guide link - ([`bbc0a0e`](https://github.com/agritheory/check_run/commit/bbc0a0e47a64227ede7207803beac5e428ee45fe)) +## Fix -### Chores +* fix: remove validation (#194) ([`efda8ae`](https://github.com/agritheory/check_run/commit/efda8ae0f58ce272eae7888a0dd867a7ede4c792)) -- Conform capitalization - ([`b66019f`](https://github.com/agritheory/check_run/commit/b66019f402af8b4ca740565316da452b363806b7)) -- Use awesomplete z-index number / 1 - ([`1b19e30`](https://github.com/agritheory/check_run/commit/1b19e304be1b3ade913f965d3d6cabafccb47a4d)) +## [v14.11.1] - 2024-01-18 -### Documentation +### Release Notes -- Add ACH generation infoand screen shot - ([`2501cee`](https://github.com/agritheory/check_run/commit/2501cee0c8e19547febf500ccd952791960b2ab1)) +# v14.11.1 (2024-01-18) -- Add and re-order config section - ([`c0ac8e5`](https://github.com/agritheory/check_run/commit/c0ac8e5da2d000a3170c40f617035493262247c3)) +## Fix -- Add directory structure, index, and photo assets - ([`cf4e5d9`](https://github.com/agritheory/check_run/commit/cf4e5d9e1641b8e747326634716ae088d80a45cb)) +* fix: payment terms validation (#192) ([`036177d`](https://github.com/agritheory/check_run/commit/036177d6e4b82455e90e9e9d5d58e60f58845749)) -- Add docs for example data and print format - ([`9f6761b`](https://github.com/agritheory/check_run/commit/9f6761b4a0dfd3093a33447e3d4e6e5158b9f38d)) +## Unknown -- Add docs for example format; disable format - ([`6fcf639`](https://github.com/agritheory/check_run/commit/6fcf639a50acd3d5c0f753b381d1e96a46f49562)) +* Optionally validate if check number has been used already (#189) -- Add docs link - ([`a264a21`](https://github.com/agritheory/check_run/commit/a264a21aabe82ea6686710098125790c22079f27)) +* feat: add "validate unique check number" setting -- Add employee configuration image - ([`fc4db1c`](https://github.com/agritheory/check_run/commit/fc4db1cae998baf8e65812a6c75024e05cc83e62)) +* feat: Optionally validate if check number has been used already -- Add install instructions to readme - ([`e055a03`](https://github.com/agritheory/check_run/commit/e055a03a7a6d305e1fe75660378fb646f8aed091)) +* feat: Optionally validate if check number has been used already -- Add placeholder docs, start configuration - ([`f3b6210`](https://github.com/agritheory/check_run/commit/f3b6210e43e00741791ef9693597c05fa3a1e6b3)) +* fix: tabulation ([`e374b97`](https://github.com/agritheory/check_run/commit/e374b9797985a9842541335cba3bfb40f9e74bfd)) -- Add Positive Pay screen shot - ([`eaa596d`](https://github.com/agritheory/check_run/commit/eaa596dd172dd0dc7a672f99a9da507f76581a94)) +* File preview in check run (#182) -- Add positive pay, links to index - ([`ade8adb`](https://github.com/agritheory/check_run/commit/ade8adbf5b1f462ba4a90230b30feddbae34eea3)) +* feat: file preview -- Add print confirmation screen shot - ([`0b9ee06`](https://github.com/agritheory/check_run/commit/0b9ee062469f620f99556c0ec062e3ce9063ad06)) +* feat: improvement -- Add settings docs and screen shots - ([`c56f917`](https://github.com/agritheory/check_run/commit/c56f917f291ed9941592a4c26d558c9cf3bcf075)) +* feat: file preview treshold -- Add supplier config image and update text - ([`06989a6`](https://github.com/agritheory/check_run/commit/06989a623fe5d787299c76d8b7933bc0c517ff96)) +* fix: refactor filters to work with prettier, also fix rendering bug -- Change 'todo' to 'coming soon' - ([`be8af10`](https://github.com/agritheory/check_run/commit/be8af10e82751d513aa10e163d5363bef6c341cb)) +--------- + +Co-authored-by: Tyler Matteson <tyler@agritheory.com> ([`1e8cd26`](https://github.com/agritheory/check_run/commit/1e8cd268786cb8dcea94bb7f279643a48570aa77)) -- Edit config information - ([`eabf6d0`](https://github.com/agritheory/check_run/commit/eabf6d0f74f33ec1ab9198645b85a76d6536defd)) +* Validate customizations (#166) -- Edit permissions information - ([`472abfc`](https://github.com/agritheory/check_run/commit/472abfca6a632ad50a2c24d0e66e2fffe7baafe1)) +* fix: validate customizations -- Flatten directory structure - ([`900fd2f`](https://github.com/agritheory/check_run/commit/900fd2f4af7dfc0822ad7962bcebd43c52281214)) +* Per supplier invoices per voucher (#165) -- Minor formatting - ([`d1bf1f5`](https://github.com/agritheory/check_run/commit/d1bf1f571874f916421540d0af7b19f106f3e6d4)) +* feat: allow per-supplier override for number of invoices per voucher -- Move installation instructions to doc page, link to that in README - ([`427f4ae`](https://github.com/agritheory/check_run/commit/427f4ae4d77d4a72275278da74b45c357fe39803)) +* docs: add docs for per supplier invoices per voucher -- Restructure index and update links - ([`b423605`](https://github.com/agritheory/check_run/commit/b423605480909fe525aa70271b93c99b62190074)) +* Quick Check (#172) -- Spacing edits - ([`ce4ec3a`](https://github.com/agritheory/check_run/commit/ce4ec3a91fa9ce5841d3a86704d7f878c3a704e3)) +* feat: quick check poc -- Update config with mop type - ([`8e26dc9`](https://github.com/agritheory/check_run/commit/8e26dc9b8b9575d65c4abc529be9c183132d7247)) +* fix: add additional filters in check run settings and also in check run quick entry -- Update configuration with images - ([`a2ca105`](https://github.com/agritheory/check_run/commit/a2ca1056ab7d24b79fc6e3034f9f89c58332b5d8)) +* docs: quick check and payment entry customization docs -- Update developer installation instructions - ([`6f16336`](https://github.com/agritheory/check_run/commit/6f16336bb8b3ac9bdc98ca2637d4e987515e3538)) +* fix: validate customizations -- Update for v14 Payment Ledger and install requirements - ([`af2ebf3`](https://github.com/agritheory/check_run/commit/af2ebf3aeef0ba66bd4545cfe906e9fb4fbb6901)) +* chore: prettier ([`6fd59cb`](https://github.com/agritheory/check_run/commit/6fd59cb5dea2f7b7e84387796c18ebd83ad18442)) -- Update image - ([`55e0be1`](https://github.com/agritheory/check_run/commit/55e0be170f3b375dfec8861dbce913bc9a3bf68c)) +* Add workflow for voided check (#187) -- Update screen shot - ([`42b3e16`](https://github.com/agritheory/check_run/commit/42b3e16b3da18e0df17b3ce46cd565536f9ef212)) +* feat: voided check -- Update screen shots and information - ([`6aabb43`](https://github.com/agritheory/check_run/commit/6aabb43086e071e55e2b380fe358286bca8f45f6)) +* style: prettify code -- Use tip component in docs - ([`94551f7`](https://github.com/agritheory/check_run/commit/94551f7e99d2ace5069ec4aeed04a0cd8e2d797d)) +* fix: rename workflow -### Features +* chore: remove list JS, use workflow instead + +* chore: tab spacing + +--------- + +Co-authored-by: fproldan <fproldan@users.noreply.github.com> +Co-authored-by: Tyler Matteson <tyler@agritheory.com> ([`a84c566`](https://github.com/agritheory/check_run/commit/a84c5667edafa09b876a17f80661f0ced65a796e)) -- Ach integration - ([`b3864c7`](https://github.com/agritheory/check_run/commit/b3864c76e710e0499b72eb619c4ec6987a8618df)) -- Add example print format - ([`0d316c1`](https://github.com/agritheory/check_run/commit/0d316c178612f893e9e8e67a4599baa3a4a8f6ac)) +## [v14.11.0] - 2024-01-08 -- Add files for employee and suppleir bank account obfuscation - ([`f7ada06`](https://github.com/agritheory/check_run/commit/f7ada0650d035cadbe1d059c92c51947c5b119f5)) +### Release Notes -- Add mop alert - ([`ba6029a`](https://github.com/agritheory/check_run/commit/ba6029a6ccf843acd70393a505fc1ff885cba206)) +# v14.11.0 (2024-01-08) -- Add more permissions topics - ([`3f61a25`](https://github.com/agritheory/check_run/commit/3f61a2522348dfeb08e2f3f12901981b91df1083)) +## Feature -- Add positive pay report - ([`128b5d6`](https://github.com/agritheory/check_run/commit/128b5d6fda4013a58930b7f426c9e676552dfb8e)) +* feat: Filter check run settings print format to only show enabled and Payment Entry formats (#186) ([`fc0f7d7`](https://github.com/agritheory/check_run/commit/fc0f7d776f83f8bc8b3b194b0362de3e27aa1baa)) -- Allow normal cusomtization workflow with multiple installed apps - ([`1001b75`](https://github.com/agritheory/check_run/commit/1001b75a24564ba139bc3d6ab2a9873b419bb320)) +## Unknown -- Check run settings - ([`26c560d`](https://github.com/agritheory/check_run/commit/26c560db8fffb9dd73d6d403c1015f7eb8da2328)) +* patch: update outsanting in old payment schedule entries (#183) ([`a9e3e8b`](https://github.com/agritheory/check_run/commit/a9e3e8b1685cdad2c243e6c383ad0563f31f5c27)) -- Convert raw sql statements to use query builder - ([`a457067`](https://github.com/agritheory/check_run/commit/a457067f5235972d521c2061a925f1856c37a513)) -- Expand permissions - ([`e02c6cd`](https://github.com/agritheory/check_run/commit/e02c6cd4526a962023933e96040478ce9b7a93bb)) +## [v14.10.0] - 2023-12-14 + +### Release Notes + +# v14.10.0 (2023-12-14) + +## Feature + +* feat: ignore PI where debit not has been issued (#181) ([`e085e96`](https://github.com/agritheory/check_run/commit/e085e9675a70c81fdc560e2341472d345c92ee70)) + + +## [v14.9.0] - 2023-12-12 + +### Release Notes + +# v14.9.0 (2023-12-12) + +## Documentation + +* docs: update settings section ([`b9b15f8`](https://github.com/agritheory/check_run/commit/b9b15f8ac16494d53399ccd7ab3f823fd1545620)) + +## Feature + +* feat: add fallbacks for mode of payment per source document type ([`12f9160`](https://github.com/agritheory/check_run/commit/12f916000dbb96db2a1ea3474b55d226a7a1cb5a)) + +## Fix + +* fix: empty string values to NULL in queries ([`75ab1c9`](https://github.com/agritheory/check_run/commit/75ab1c96629b0e2220dd30555a1498ddd2561291)) + +## Unknown + +* Merge pull request #180 from agritheory/default_mode_of_payment_settings + +feat: add fallbacks for mode of payment per source document type ([`c609603`](https://github.com/agritheory/check_run/commit/c6096038c1363e14a2ba7abb29f2cf73d25ce860)) + + +## [v14.8.4] - 2023-12-11 + +### Release Notes + +# v14.8.4 (2023-12-11) + +## Fix + +* fix: only fetch check number on "pay" payment types (#179) ([`1b6dd48`](https://github.com/agritheory/check_run/commit/1b6dd488a6cf921c4497737f47d27627f19e510f)) + + +## [v14.8.3] - 2023-12-11 + +### Release Notes + +# v14.8.3 (2023-12-11) + +## Fix + +* fix: mode of payment summary (#176) + +* fix: mode of payment summary + +* wip: refactor reactivity for performance + +* feat: improved reactivity + +* style: prettify code + +* fix: move built files to dist folder / ignored by git + +--------- + +Co-authored-by: Tyler Matteson <tyler@agritheory.com> +Co-authored-by: agritheory <agritheory@users.noreply.github.com> ([`40fd4ee`](https://github.com/agritheory/check_run/commit/40fd4ee3057f9808944258b9d7807522827f17a6)) + +## Unknown + +* Draft: Paid Invoices appearing in the Check Run (#171) + +* wip: add correct setup data to remove payment terms bug + +* fix: paid invoices showing in check run + +* fix: add payment schedule validation in payment entry + +* docs: add purchase invoice payment term considerations + +--------- + +Co-authored-by: Heather Kusmierz <heather.kusmierz@gmail.com> ([`bbb66d6`](https://github.com/agritheory/check_run/commit/bbb66d6b79fd2719b8ba6d691f73302a58362e4d)) + +* Quick Check (#172) + +* feat: quick check poc + +* fix: add additional filters in check run settings and also in check run quick entry + +* docs: quick check and payment entry customization docs ([`37a39a1`](https://github.com/agritheory/check_run/commit/37a39a17f490e6e3d173707e36cd4467116f4e3b)) + +* Per supplier invoices per voucher (#165) + +* feat: allow per-supplier override for number of invoices per voucher + +* docs: add docs for per supplier invoices per voucher ([`567762c`](https://github.com/agritheory/check_run/commit/567762c67c9cbbc89e57f345beca61a64e28961a)) + + +## [v14.8.2] - 2023-09-22 + +### Release Notes + +# v14.8.2 (2023-09-22) + +## Fix + +* fix: required_apps (#162) + +* fix: required_apps + +* fix: required_apps ([`31b5297`](https://github.com/agritheory/check_run/commit/31b52975839424f9a9bfbded6cc03c241dcb44cd)) + + +## [v14.8.1] - 2023-09-14 + +### Release Notes + +# v14.8.1 (2023-09-14) + +## Ci + +* ci: update release action user and email (#155) ([`a3cfc97`](https://github.com/agritheory/check_run/commit/a3cfc975aac95696b943ecbd809a00cab6159ffd)) + +## Fix + +* fix: customizations leaks, module specificity (#161) ([`ce6b9fc`](https://github.com/agritheory/check_run/commit/ce6b9fc2a79e9a1beea4f514b3c52d4fd442da50)) + +## Unknown + +* Port preview to V14 (#153) + +* File Preview (#140) + +* wip: file preview + +* feat: preview in check run, allow to preview in non submittable documents + +* feat: WIP payables attachment report + +* feat: wip preview of attachments + +* style: prettify code + +* feat: close with space + +* fix: do not open sidebar in check run + +* wip: multiple attachments in check run + +* fix: merge + +* style: prettify code + +* fix: df-preview-wrapper-fw + +* feat: improve code + +* feat: improve code + +* feat: columns + +--------- + +Co-authored-by: Tyler Matteson <tyler@agritheory.com> +Co-authored-by: fproldan <fproldan@users.noreply.github.com> + +* feat: use query builder in payables attachments report' + +* fix: build + +* fix: add remove btn + +* style: prettify code + +--------- + +Co-authored-by: Tyler Matteson <tyler@agritheory.com> +Co-authored-by: fproldan <fproldan@users.noreply.github.com> ([`78d2666`](https://github.com/agritheory/check_run/commit/78d2666c2c9b92831b90ee1c647737ef79375a44)) + + +## [v14.8.0] - 2023-09-08 + +### Release Notes + +# v14.8.0 (2023-09-08) + +## Feature + +* feat: add read_only decorator ([`c7bb83c`](https://github.com/agritheory/check_run/commit/c7bb83ceba8fcfd291b6198ff1ee8b92edf1abca)) + +## Unknown + +* Merge pull request #150 from agritheory/read_only + +feat: add read_only decorator ([`73d459d`](https://github.com/agritheory/check_run/commit/73d459d616b5190ba85ebe67c115f29cae2d11ba)) + +* Merge branch 'version-14' into read_only ([`aaca764`](https://github.com/agritheory/check_run/commit/aaca76471cb95480aef1a62459ae296767dafcd2)) + +* Setup mypy (#149) + +* chore: add typing + +* ci: add mypy to pre-commit and CI + +--------- + +Co-authored-by: Heather Kusmierz <heather.kusmierz@gmail.com> ([`5831fb8`](https://github.com/agritheory/check_run/commit/5831fb85f3b08e76f486c3b01fb671b3dba06225)) + + +## [v14.7.0] - 2023-09-07 + +### Release Notes + +# v14.7.0 (2023-09-07) + +## Ci + +* ci: migrate to python semantic release (#133) + +* ci: migrate to python semantic release + +* ci: add version variable file + +* ci: update remote name ([`d37bca6`](https://github.com/agritheory/check_run/commit/d37bca61505e99476e6fb857fbd36dacc932918a)) + +## Feature + +* feat: disallow cancellation of source documents selected for payment in draft CRs (#126) (#143) ([`bddc888`](https://github.com/agritheory/check_run/commit/bddc8884167c9e3381f519914a278a29fdf345f1)) + +## Fix + +* fix: skip check on draft check runs with no transactions (v14) (#148) + +Resolution for `TypeError: the JSON object must be str, bytes or bytearray, not NoneType` when draft check run has no transactions. ([`dadd084`](https://github.com/agritheory/check_run/commit/dadd084c26f50de4e9dff1f360a8d73bbb37e250)) + +* fix: move bank validation out of override class into hook (#142) ([`f07ad5a`](https://github.com/agritheory/check_run/commit/f07ad5a1c4a9b7e424ad534ec40731f26f6feb0c)) + +* fix: only increment if check numer is numeric (#139) ([`079aa52`](https://github.com/agritheory/check_run/commit/079aa52bf013e13d3350848ef011b74b99b64bf1)) + +## Unknown + +* Show the quantity and amount of each Mode of Payment (#141) + +* feat: mode of payment summary component + +* feat: add number_of_invoices_per_voucher to check + +* feat: currency format + +* chore: fix setup, run formatters against repo + +* fix: html formatting + +* feat: reactive + +* feat: only update when draft + +* feat: improvement + +* feat: sort mop + +* fix: slight refactor, 'account' => 'Account' + +--------- + +Co-authored-by: Tyler Matteson <tyler@agritheory.com> ([`a0471a3`](https://github.com/agritheory/check_run/commit/a0471a3304c9610e8be3794599561c7872209e07)) + +* Use payment schedule as basis for due date and amount in purchase invoice query (#144) + +* feat: use payment schedule as basis for due date and amount in purchase invoices + +* docs: update setup script path + +* fix: typo, add missing query column + +--------- + +Co-authored-by: Heather Kusmierz <heather.kusmierz@gmail.com> ([`4ccba65`](https://github.com/agritheory/check_run/commit/4ccba65818350bf256fa6d25d730ba2abfe36788)) + +* Query Builder fixes (#145) + +* fix: refactor frappe.db.sql to query builder for outstanding + +* fix: refactor postive pay to query builder + +* chore: remove print statement + +* fix: update comparison operator + +--------- + +Co-authored-by: Heather Kusmierz <heather.kusmierz@gmail.com> ([`e00e476`](https://github.com/agritheory/check_run/commit/e00e4768b4634716b417c6798123b44399ef7d2d)) + +* Update originating dfi id (#135) + +According to the NACHA Dev Guide, Originating DFI Identification is supposed to be "The routing number of the DFI originating the entries within the batch." + +Co-authored-by: Trusted Computer <75872475+trustedcomputer@users.noreply.github.com> ([`f16bb24`](https://github.com/agritheory/check_run/commit/f16bb2468231a8221e302109060dee79aa476838)) + + +## [v13.3.3] - 2023-09-07 + +### Release Notes + +# v13.3.3 (2023-09-07) + +## Fix + +* fix: skip check on draft check runs with no transactions (#147) + +Resolution for `TypeError: the JSON object must be str, bytes or bytearray, not NoneType` when draft check run has no transactions. ([`b3821cb`](https://github.com/agritheory/check_run/commit/b3821cb7332414ce5049a2f9bf355cd4f9e4ae1e)) + + +## [v13.3.2] - 2023-09-07 + +### Release Notes + +# v13.3.2 (2023-09-07) + +## Ci + +* ci: migrate to python semantic release (#134) + +* ci: migrate to python semantic release + +* ci: add version variable file + +* ci: update remote name ([`404edf3`](https://github.com/agritheory/check_run/commit/404edf35cae2180a02a45be875fcb54ef7e92cef)) + +## Fix + +* fix: only increment if check numer is numeric (#138) ([`30679db`](https://github.com/agritheory/check_run/commit/30679db1985fcc0a41238d8860a17c019b751d98)) + +## Unknown + +* File Preview (#140) + +* wip: file preview + +* feat: preview in check run, allow to preview in non submittable documents + +* feat: WIP payables attachment report + +* feat: wip preview of attachments + +* style: prettify code + +* feat: close with space + +* fix: do not open sidebar in check run + +* wip: multiple attachments in check run + +* fix: merge + +* style: prettify code + +* fix: df-preview-wrapper-fw + +* feat: improve code + +* feat: improve code + +* feat: columns + +--------- + +Co-authored-by: Tyler Matteson <tyler@agritheory.com> +Co-authored-by: fproldan <fproldan@users.noreply.github.com> ([`a698431`](https://github.com/agritheory/check_run/commit/a698431b7ac850b5dc4203ecbb8c65ada0f0a152)) + + +## [v13.3.1] - 2023-08-03 + +### Release Notes + +## What's Changed +* trans: add error message to translations by @HKuz in https://github.com/agritheory/check_run/pull/128 + + +## [v14.6.0] - 2023-08-03 + +### Release Notes + +## What's Changed +* feat: validate docstatus of selected invoices still saved/submitted by @HKuz in https://github.com/agritheory/check_run/pull/44 +* Port recent version-13 changes by @HKuz in https://github.com/agritheory/check_run/pull/50 +* feat: Canadian regionalization by @HKuz in https://github.com/agritheory/check_run/pull/45 +* V14 on hold invoice by @agritheory in https://github.com/agritheory/check_run/pull/55 +* Bank account lookup fix by @agritheory in https://github.com/agritheory/check_run/pull/59 +* Bank account lookup fix by @agritheory in https://github.com/agritheory/check_run/pull/61 +* feat: port timeout fix to v14 by @agritheory in https://github.com/agritheory/check_run/pull/62 +* V14 timeout fix by @agritheory in https://github.com/agritheory/check_run/pull/64 +* fix: remove check_digit argument in ACH generation by @agritheory in https://github.com/agritheory/check_run/pull/66 +* V14 party lookup by @agritheory in https://github.com/agritheory/check_run/pull/68 +* [v14] handle errors in background queue by @agritheory in https://github.com/agritheory/check_run/pull/72 +* feat: custom immediate origin value in settings by @agritheory in https://github.com/agritheory/check_run/pull/76 +* ci: fix release CI by @agritheory in https://github.com/agritheory/check_run/pull/85 +* V14 ci by @agritheory in https://github.com/agritheory/check_run/pull/87 +* The hook jenv is deprecated New variable is jinja by @alibaig4u in https://github.com/agritheory/check_run/pull/90 +* chore: fix account names by @HKuz in https://github.com/agritheory/check_run/pull/99 +* V14 ports by @agritheory in https://github.com/agritheory/check_run/pull/98 +* Pre-processing validation by @agritheory in https://github.com/agritheory/check_run/pull/108 +* V14 pre process validation by @agritheory in https://github.com/agritheory/check_run/pull/113 +* feat: add validate when processing, enable on_update_after_submit hook by @HKuz in https://github.com/agritheory/check_run/pull/115 +* fix: broken translation string in csv by @HKuz in https://github.com/agritheory/check_run/pull/122 +* fix: show purchase returns in check run by @agritheory in https://github.com/agritheory/check_run/pull/131 +* trans: add error message to translations by @HKuz in https://github.com/agritheory/check_run/pull/129 + +## New Contributors +* @alibaig4u made their first contribution in https://github.com/agritheory/check_run/pull/90 + +**Full Changelog**: https://github.com/agritheory/check_run/compare/v14.0.0...v14.6.0 + +## [v14.5.1] - 2023-07-28 + +### Release Notes + +## [14.5.1](https://github.com/agritheory/check_run/compare/v14.5.0...v14.5.1) (2023-07-28) + + +### Bug Fixes + +* show purchase returns in list ([#130](https://github.com/agritheory/check_run/issues/130)) ([c504828](https://github.com/agritheory/check_run/commit/c504828c1bbe1552e9a3cc87f87082c5f89dae7b)) + + + + + +## [v14.5.0] - 2023-07-24 + +### Release Notes + +# [14.5.0](https://github.com/agritheory/check_run/compare/v14.4.0...v14.5.0) (2023-07-24) + + +### Features + +* migrate validation to doc_events from doctype override ([#127](https://github.com/agritheory/check_run/issues/127)) ([45c9598](https://github.com/agritheory/check_run/commit/45c959834a60d57148b4443e902f25c2c56a30ff)), closes [#126](https://github.com/agritheory/check_run/issues/126) [#126](https://github.com/agritheory/check_run/issues/126) + + + + + +## [v14.4.0] - 2023-07-24 + +### Release Notes + +# [14.4.0](https://github.com/agritheory/check_run/compare/v14.3.2...v14.4.0) (2023-07-24) + + +### Features + +* disallow cancellation of source documents selected for payment in draft CRs ([#126](https://github.com/agritheory/check_run/issues/126)) ([329c41c](https://github.com/agritheory/check_run/commit/329c41c9d1470a97deaa45b7972c9e6818c8aa3b)) + + + + + +## [v14.3.2] - 2023-07-19 + +### Release Notes + +## [14.3.2](https://github.com/agritheory/check_run/compare/v14.3.1...v14.3.2) (2023-07-19) + + +### Bug Fixes + +* broken translation string in csv ([#121](https://github.com/agritheory/check_run/issues/121)) ([e3c87b4](https://github.com/agritheory/check_run/commit/e3c87b415fe54e94562cc712948b44d33b0d8519)) + + + + + +## [v14.3.1] - 2023-06-11 + +### Release Notes + +## [14.3.1](https://github.com/agritheory/check_run/compare/v14.3.0...v14.3.1) (2023-06-11) + + +### Bug Fixes + +* add check for expense claim in pre-process validation ([#112](https://github.com/agritheory/check_run/issues/112)) ([1503fa9](https://github.com/agritheory/check_run/commit/1503fa9cad5e7e0a74614a2dcd63eea1797024cc)) + + + + + +## [v14.3.0] - 2023-06-11 + +### Release Notes + +# [14.3.0](https://github.com/agritheory/check_run/compare/v14.2.2...v14.3.0) (2023-06-11) + + +### Features + +* add validate when processing, enable on_update_after_submit hook ([#111](https://github.com/agritheory/check_run/issues/111)) ([2e87a26](https://github.com/agritheory/check_run/commit/2e87a260035cfd81466cb0206f8d718a2d107551)) + + + + + +## [v14.2.2] - 2023-05-12 + +### Release Notes + +## [14.2.2](https://github.com/agritheory/check_run/compare/v14.2.1...v14.2.2) (2023-05-12) + + +### Bug Fixes + +* reprint button text color ([#103](https://github.com/agritheory/check_run/issues/103)) ([7101284](https://github.com/agritheory/check_run/commit/7101284f5007723877d312efa753b9c16a6efb2e)) + + + + + +## [V13.3.0] - 2023-04-21 + +### Release Notes + +## What's Changed +* Code style by @agritheory in https://github.com/agritheory/check_run/pull/96 +* Fix process check run by @agritheory in https://github.com/agritheory/check_run/pull/97 + + +**Full Changelog**: https://github.com/agritheory/check_run/compare/v13.2.2...V13.3.0 + +## [v13.2.2] - 2023-04-17 + +### Release Notes + +## What's Changed +* Use Posting Date for Effective Entry Date by @put3r-r00t3r in https://github.com/agritheory/check_run/pull/89 + + +**Full Changelog**: https://github.com/agritheory/check_run/compare/v13.2.1...v13.2.2 + +## [v13.2.1] - 2023-04-17 + +### Release Notes + +## What's Changed +* fix: check for docstatus instead of status by @agritheory in https://github.com/agritheory/check_run/pull/93 + + +**Full Changelog**: https://github.com/agritheory/check_run/compare/v13.2.0...v13.2.1 + +## [v13.1.0] - 2023-04-03 + +### Release Notes + +# [14.1.0](https://github.com/agritheory/check_run/compare/v14.0.0...v14.1.0) (2023-04-03) + + +### Bug Fixes + +* address PR requests ([084fb22](https://github.com/agritheory/check_run/commit/084fb2253b62908440df0d3b4993eb4b1f0d376b)) +* company name in correct header field of NACHA file ([81afb09](https://github.com/agritheory/check_run/commit/81afb09c3b1d3e34774d67dc7e838ff2b69900ee)) +* don't raise exception on bank account lookup, better UX ([#60](https://github.com/agritheory/check_run/issues/60)) ([1d5d018](https://github.com/agritheory/check_run/commit/1d5d018c9e1703b41ee568482f9fb0f57f2d4c62)) +* fallbacks and length limitations for discretionary data ([f783951](https://github.com/agritheory/check_run/commit/f7839517f043fa811ab030b92608826e4bbb0f0e)) +* MOP ignore keypress if input is focused ([8d2d697](https://github.com/agritheory/check_run/commit/8d2d6975973041e07616fb6704b72ffe3655cd04)) +* release ([8a8ec06](https://github.com/agritheory/check_run/commit/8a8ec062f263d49a9bcd7487af6f5de9372fcde1)) +* release ([#82](https://github.com/agritheory/check_run/issues/82)) ([9b32e9b](https://github.com/agritheory/check_run/commit/9b32e9b036f0ff16d21d65ba96851bc8d03e8c5a)) +* remove check PDF on confirm print ([4b96835](https://github.com/agritheory/check_run/commit/4b96835d8415bd0e9b2a9bf07a90a2e450559573)) +* remove mimesis import ([bdbadea](https://github.com/agritheory/check_run/commit/bdbadea1759c0cf4ad469677606704dbf02bf078)) +* test release ([f5cd245](https://github.com/agritheory/check_run/commit/f5cd245154802b1c4c78b4dcce47677064ec7ddb)) +* validate if there are any transactions before validating them ([2aa94a7](https://github.com/agritheory/check_run/commit/2aa94a7306db4107d7e15ddd33767169f52a06b7)) + + +### Features -- Initialize App - ([`cf39bb7`](https://github.com/agritheory/check_run/commit/cf39bb7679becd8a39c9ad20ea1aa7603a93ca52)) +* add Canadian regionalization for v-13 ([5cbd277](https://github.com/agritheory/check_run/commit/5cbd277c7979e54c545e04c415dd2f836a3c6dd4)) +* add example print format ([521bff5](https://github.com/agritheory/check_run/commit/521bff50d3f1e4f5d141ef12f6ed05663d2c070a)) +* add field for immediate origin ([#75](https://github.com/agritheory/check_run/issues/75)) ([531b307](https://github.com/agritheory/check_run/commit/531b3077316af0fdfcef5cfd4ece04bc29b95493)) +* add logic for handling on-hold invoices, setting for automatic release and docs ([63bd16e](https://github.com/agritheory/check_run/commit/63bd16eaf6aa1b2f9f4738ad0f860c731e84d721)) +* add more detail to cancelled document validation error message ([6a99349](https://github.com/agritheory/check_run/commit/6a9934956d7f62cfc5b286e8ab06c621b15071b8)) +* add omit origin ach setting ([b72901e](https://github.com/agritheory/check_run/commit/b72901e0a6bf806c012a91bbba28ee765efecac0)) +* increment check number from payment ([#70](https://github.com/agritheory/check_run/issues/70)) ([00706ff](https://github.com/agritheory/check_run/commit/00706ff8c17a20f99ddff53beb62e450ff09eb5c)) +* look up party on PE submission to avoid renaming problems ([#67](https://github.com/agritheory/check_run/issues/67)) ([4cdf7de](https://github.com/agritheory/check_run/commit/4cdf7de5d648bcd37cb19ce67d899804f7107ad3)) +* split checks by address ([f091550](https://github.com/agritheory/check_run/commit/f09155050ea8a64ee7fdb3ba8f3596eb936fd871)) +* validate docstatus of selected invoices in Check Run still saved/submitted ([9bf5605](https://github.com/agritheory/check_run/commit/9bf56054041c341fc23c4cdf0a9449ca32ef8ba5)) -- Key nav - ([`ae5bb24`](https://github.com/agritheory/check_run/commit/ae5bb245c807ea6fd812cc60f9e13ab1bd4726da)) -- Port to version-14 - ([`cb8f9a5`](https://github.com/agritheory/check_run/commit/cb8f9a5b8cb508acc64ab0c9e36d835a9dd18a8d)) -- Update SQL to use filter.bank_account in query - ([`fa3580b`](https://github.com/agritheory/check_run/commit/fa3580b1ea7c2ba742047e9aa81a11b22e65fae3)) -- Use variables to respect dark mode - ([`b0bb4ae`](https://github.com/agritheory/check_run/commit/b0bb4ae7ddceda28ff51a7b72a21290c3e7f2d88)) From 94c87c193ec5e695c0d7c3b0f3bb07209eb353d5 Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Sat, 21 Feb 2026 17:09:40 -0500 Subject: [PATCH 2/9] chore: update pyproject and precommit --- .github/workflows/overrides.yml | 20 + .pre-commit-config.yaml | 87 +- .prettierrc.js | 3 + CHANGELOG.md | 3 + README.md | 3 + check_run/__init__.py | 3 + check_run/check_run/custom/bank.json | 113 +- check_run/check_run/custom/bank_account.json | 317 +-- check_run/check_run/custom/employee.json | 320 ++- .../check_run/custom/mode_of_payment.json | 49 +- check_run/check_run/custom/payment_entry.json | 113 +- .../check_run/custom/purchase_invoice.json | 114 +- check_run/check_run/custom/supplier.json | 459 ++-- check_run/check_run/doctype/__init__.py | 2 + .../check_run/doctype/check_run/__init__.py | 2 + .../doctype/check_run/check_run_list.js | 3 + .../doctype/check_run_settings/__init__.py | 2 + check_run/check_run/print_format/__init__.py | 2 + .../print_format/example_voucher/__init__.py | 2 + .../example_voucher_micr/__init__.py | 2 + check_run/check_run/report/__init__.py | 2 + .../report/payables_attachments/__init__.py | 2 + .../check_run/report/positive_pay/__init__.py | 2 + check_run/config/__init__.py | 2 + check_run/config/desktop.py | 3 + check_run/config/docs.py | 3 + check_run/customize.py | 461 ++-- check_run/hooks.py | 3 + check_run/overrides/__init__.py | 2 + check_run/patches/patch_payment_schedule.py | 37 +- .../patches/patch_voided_check_workflow.py | 3 + check_run/public/js/check_run.bundle.js | 3 + .../js/check_run/check_run_quick_entry.js | 3 + .../check_run_settings_quick_entry.js | 3 + check_run/public/js/custom/employee_custom.js | 3 + check_run/public/js/custom/file_preview.js | 3 + .../public/js/custom/payment_entry_custom.js | 3 + check_run/public/js/custom/supplier_custom.js | 3 + check_run/public/js/vite.config.js | 3 + check_run/tests/conftest.py | 3 + check_run/tests/fixtures.py | 493 ++-- check_run/tests/setup.py | 2076 +++++++++-------- docs/achgeneration.md | 8 + docs/configuration.md | 5 + docs/exampledata.md | 8 + docs/exampleprint.md | 8 + docs/index.md | 8 + docs/installationguide.md | 8 + docs/payment_entry.md | 34 +- docs/permissions.md | 8 + docs/positivepay.md | 8 + docs/renderpdfsequence.md | 8 + docs/settings.md | 5 + docs/translations.md | 8 + poetry.lock | 1037 ++++++++ pyproject.toml | 95 +- setup.py | 3 + 57 files changed, 3453 insertions(+), 2533 deletions(-) create mode 100644 .github/workflows/overrides.yml create mode 100644 poetry.lock diff --git a/.github/workflows/overrides.yml b/.github/workflows/overrides.yml new file mode 100644 index 00000000..a57726d2 --- /dev/null +++ b/.github/workflows/overrides.yml @@ -0,0 +1,20 @@ +name: Track Overrides + +on: + pull_request: + branches: + - version-14 + - version-15 + +jobs: + track_overrides: + runs-on: ubuntu-latest + name: Track Overrides + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Track Overrides + uses: agritheory/test_utils/actions/track_overrides@main + with: + app: check_run diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 71b7430d..8c61e732 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,15 +9,24 @@ repos: - id: trailing-whitespace files: 'check_run.*' exclude: '.*json$|.*txt$|.*csv|.*md|.*svg' + - id: check-yaml - id: no-commit-to-branch - args: ['--branch', 'version-15'] + args: ['--branch', 'version-15', '--branch', 'version-16'] - id: check-merge-conflict - id: check-ast - id: check-json - id: check-toml - - id: check-yaml - id: debug-statements + - repo: https://github.com/codespell-project/codespell + rev: v2.4.1 + hooks: + - id: codespell + args: ["--ignore-words-list", "notin"] + exclude: 'yarn.lock|poetry.lock' + additional_dependencies: + - tomli + - repo: https://github.com/asottile/pyupgrade rev: v3.19.1 hooks: @@ -28,62 +37,42 @@ repos: rev: 951ccf4d5bb0d692b457a5ebc4215d755618eb68 hooks: - id: black - args: ['--line-length', '99'] - - - repo: local - hooks: - - id: prettier - name: prettier - entry: npx prettier -w . --config .prettierrc.js --ignore-path .prettierignore - language: system - - - repo: https://github.com/PyCQA/isort - rev: 6.0.1 - hooks: - - id: isort - - - repo: https://github.com/PyCQA/autoflake - rev: v2.3.1 - hooks: - - id: autoflake - args: [--remove-all-unused-imports, --in-place] - repo: https://github.com/PyCQA/flake8 - rev: 7.1.2 + rev: 7.2.0 hooks: - id: flake8 additional_dependencies: ['flake8-bugbear'] - - repo: https://github.com/codespell-project/codespell - rev: v2.3.0 - hooks: - - id: codespell - additional_dependencies: - - tomli - exclude: > - (?x)^( - CHANGELOG.md| - .*\.lock| - .*\.pyc| - \.tox - \.mypy_cache - )$ - - - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.15.0 + - repo: https://github.com/agritheory/test_utils + rev: v1.15.4 hooks: - - id: mypy - exclude: ^tests/ - args: ['--install-types', '--non-interactive', '--ignore-missing-imports'] + - id: update_pre_commit_config + - id: validate_frappe_project + - id: validate_copyright + files: '\.(js|ts|py|md)$' + args: ['--app', 'check_run'] + - id: bylines + exclude: 'README.md|CHANGELOG.md' + - id: clean_customized_doctypes + args: ['--app', 'check_run'] + - id: validate_customizations + - id: patch_linters + args: ['--app', 'check_run'] + - id: track_overrides + args: ['--directory', '.', '--app', 'check_run', '--base-branch', 'version-15'] - - repo: local + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.1.0 hooks: - - id: validate_customizations - always_run: true - name: .github/validate_customizations.py - entry: python .github/validate_customizations.py - language: system - types: [python] + - id: prettier + types_or: [javascript, vue, scss] + exclude: | + (?x)^( + .*node_modules.*| + check_run/public/dist/.*| + check_run/public/js/lib/.* + )$ ci: autoupdate_schedule: weekly diff --git a/.prettierrc.js b/.prettierrc.js index eeb2d4e4..46352c01 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + module.exports = { arrowParens: 'avoid', bracketSameLine: true, diff --git a/CHANGELOG.md b/CHANGELOG.md index df2372f6..32e2eb47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ + + # Changelog This changelog was automatically generated from GitHub releases and pull requests. diff --git a/README.md b/README.md index 7a20cd62..a83aa240 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ + + ## Check Run ### License diff --git a/check_run/__init__.py b/check_run/__init__.py index 9bc73dde..133f0a0b 100644 --- a/check_run/__init__.py +++ b/check_run/__init__.py @@ -1 +1,4 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + __version__ = "15.10.0" diff --git a/check_run/check_run/custom/bank.json b/check_run/check_run/custom/bank.json index bea0a573..8d9f0d2e 100644 --- a/check_run/check_run/custom/bank.json +++ b/check_run/check_run/custom/bank.json @@ -1,69 +1,46 @@ { - "custom_fields": [ - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-08-07 15:07:53.297493", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Bank", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "aba_number", - "fieldtype": "Data", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 4, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "column_break_1", - "label": "ABA Number", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-08-07 15:07:53.297493", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Bank-aba_number", - "no_copy": 0, - "non_negative": 0, - "options": null, - "owner": "Administrator", - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - } - ], - "custom_perms": [], - "doctype": "Bank", - "property_setters": [], - "sync_on_migrate": 1 -} + "custom_fields": [ + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Bank", + "fetch_if_empty": 0, + "fieldname": "aba_number", + "fieldtype": "Data", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 4, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "column_break_1", + "label": "ABA Number", + "length": 0, + "module": "Check Run", + "name": "Bank-aba_number", + "no_copy": 0, + "non_negative": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0 + } + ], + "doctype": "Bank", + "property_setters": [], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/check_run/check_run/custom/bank_account.json b/check_run/check_run/custom/bank_account.json index e6ab9c34..29f7050b 100644 --- a/check_run/check_run/custom/bank_account.json +++ b/check_run/check_run/custom/bank_account.json @@ -1,191 +1,128 @@ { - "custom_fields": [ - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 11:20:02.666689", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Bank Account", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "check_number", - "fieldtype": "Data", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 10, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "company", - "label": "Last Used Check Number", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-06-30 11:20:02.666689", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Bank Account-check_number", - "no_copy": 0, - "non_negative": 0, - "options": null, - "owner": "Administrator", - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 1, - "unique": 0, - "width": null - }, - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-08-07 14:55:42.859002", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Bank Account", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "company_ach_id", - "fieldtype": "Data", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 10, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "check_number", - "label": "Company ACH ID", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-08-07 14:55:42.859002", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Bank Account-company_ach_id", - "no_copy": 0, - "non_negative": 0, - "options": null, - "owner": "Administrator", - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 1, - "unique": 0, - "width": null - }, - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2023-10-11 15:03:16.705933", - "default": "1", - "depends_on": null, - "description": "Allow Quick Check Payment Entries to be made against this Bank Account. This fetches the Bank Account into the Payment Entry automatically.", - "docstatus": 0, - "dt": "Bank Account", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "allow_quick_check", - "fieldtype": "Check", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 8, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "is_company_account", - "is_system_generated": 0, - "is_virtual": 0, - "label": "Allow Quick Check", - "length": 0, - "mandatory_depends_on": null, - "modified": "2023-10-11 15:22:30.742925", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Bank Account-allow_quick_check", - "no_copy": 0, - "non_negative": 0, - "options": null, - "owner": "Administrator", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "sort_options": 0, - "translatable": 0, - "unique": 0, - "width": null - } - ], - "custom_perms": [], - "doctype": "Bank Account", - "property_setters": [], - "sync_on_migrate": 1 -} + "custom_fields": [ + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Bank Account", + "fetch_if_empty": 0, + "fieldname": "check_number", + "fieldtype": "Data", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 10, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "company", + "label": "Last Used Check Number", + "length": 0, + "module": "Check Run", + "name": "Bank Account-check_number", + "no_copy": 0, + "non_negative": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 1, + "unique": 0 + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Bank Account", + "fetch_if_empty": 0, + "fieldname": "company_ach_id", + "fieldtype": "Data", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 10, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "check_number", + "label": "Company ACH ID", + "length": 0, + "module": "Check Run", + "name": "Bank Account-company_ach_id", + "no_copy": 0, + "non_negative": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 1, + "unique": 0 + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "1", + "description": "Allow Quick Check Payment Entries to be made against this Bank Account. This fetches the Bank Account into the Payment Entry automatically.", + "dt": "Bank Account", + "fetch_if_empty": 0, + "fieldname": "allow_quick_check", + "fieldtype": "Check", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 8, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "is_company_account", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Allow Quick Check", + "length": 0, + "module": "Check Run", + "name": "Bank Account-allow_quick_check", + "no_copy": 0, + "non_negative": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0 + } + ], + "doctype": "Bank Account", + "property_setters": [], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/check_run/check_run/custom/employee.json b/check_run/check_run/custom/employee.json index ebed6781..4ff2d830 100644 --- a/check_run/check_run/custom/employee.json +++ b/check_run/check_run/custom/employee.json @@ -1,189 +1,133 @@ { - "custom_fields": [ - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 11:20:02.666689", - "default": null, - "depends_on": null, - "description": "Show Bank Account Number", - "docstatus": 0, - "dt": "Employee", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "bank_account", - "fieldtype": "Password", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 69, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "bank", - "is_system_generated": 0, - "is_virtual": 0, - "label": "Bank Account", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-06-30 11:20:02.666689", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Employee-bank_account", - "no_copy": 0, - "non_negative": 0, - "options": null, - "owner": "Administrator", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - }, - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 11:20:02.666689", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Employee", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "mode_of_payment", - "fieldtype": "Link", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 53, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "salary_mode", - "is_system_generated": 0, - "is_virtual": 0, - "label": "Mode of Payment", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-06-30 11:20:02.666689", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Employee-mode_of_payment", - "no_copy": 0, - "non_negative": 0, - "options": "Mode of Payment", - "owner": "Administrator", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - }, - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 11:20:02.666689", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Employee", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "bank", - "fieldtype": "Link", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 68, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "mode_of_payment", - "is_system_generated": 0, - "is_virtual": 0, - "label": "Bank", - "length": 0, - "mandatory_depends_on": null, - "modified": "2023-02-28 11:18:22.590359", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Employee-bank", - "no_copy": 0, - "non_negative": 0, - "options": "Bank", - "owner": "Administrator", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - } - ], - "custom_perms": [], - "doctype": "Employee", - "links": [], - "property_setters": [], - "sync_on_migrate": 1 -} + "custom_fields": [ + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "description": "Show Bank Account Number", + "dt": "Employee", + "fetch_if_empty": 0, + "fieldname": "bank_account", + "fieldtype": "Password", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 69, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "bank", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Bank Account", + "length": 0, + "module": "Check Run", + "name": "Employee-bank_account", + "no_copy": 0, + "non_negative": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Employee", + "fetch_if_empty": 0, + "fieldname": "mode_of_payment", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 53, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "salary_mode", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Mode of Payment", + "length": 0, + "module": "Check Run", + "name": "Employee-mode_of_payment", + "no_copy": 0, + "non_negative": 0, + "options": "Mode of Payment", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Employee", + "fetch_if_empty": 0, + "fieldname": "bank", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 68, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "mode_of_payment", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Bank", + "length": 0, + "module": "Check Run", + "name": "Employee-bank", + "no_copy": 0, + "non_negative": 0, + "options": "Bank", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0 + } + ], + "doctype": "Employee", + "property_setters": [], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/check_run/check_run/custom/mode_of_payment.json b/check_run/check_run/custom/mode_of_payment.json index 1be9d68d..74f7e9e9 100644 --- a/check_run/check_run/custom/mode_of_payment.json +++ b/check_run/check_run/custom/mode_of_payment.json @@ -1,33 +1,18 @@ { - "custom_fields": [], - "custom_perms": [], - "doctype": "Mode of Payment", - "property_setters": [ - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "creation": "2022-08-05 13:10:55.278054", - "default_value": null, - "doc_type": "Mode of Payment", - "docstatus": 0, - "doctype_or_field": "DocField", - "field_name": "type", - "idx": 0, - "modified": "2022-08-05 13:10:55.278054", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Mode of Payment-type-options", - "owner": "Administrator", - "parent": null, - "parentfield": null, - "parenttype": null, - "property": "options", - "property_type": "Text", - "row_name": null, - "value": "Cash\nBank\nGeneral\nPhone\nElectronic" - } - ], - "sync_on_migrate": 1 -} + "custom_fields": [], + "doctype": "Mode of Payment", + "property_setters": [ + { + "doc_type": "Mode of Payment", + "doctype_or_field": "DocField", + "field_name": "type", + "idx": 0, + "module": "Check Run", + "name": "Mode of Payment-type-options", + "property": "options", + "property_type": "Text", + "value": "Cash\nBank\nGeneral\nPhone\nElectronic" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/check_run/check_run/custom/payment_entry.json b/check_run/check_run/custom/payment_entry.json index 3df21d4b..60b018c5 100644 --- a/check_run/check_run/custom/payment_entry.json +++ b/check_run/check_run/custom/payment_entry.json @@ -1,69 +1,46 @@ { - "custom_fields": [ - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 15:30:29.886371", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Payment Entry", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "check_run", - "fieldtype": "Data", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 5, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "payment_order_status", - "label": "Check Run", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-06-30 11:20:02.666689", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Payment Entry-check_run", - "no_copy": 0, - "non_negative": 0, - "options": null, - "owner": "Administrator", - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 1, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - } - ], - "custom_perms": [], - "doctype": "Payment Entry", - "property_setters": [], - "sync_on_migrate": 1 -} + "custom_fields": [ + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Payment Entry", + "fetch_if_empty": 0, + "fieldname": "check_run", + "fieldtype": "Data", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 5, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "payment_order_status", + "label": "Check Run", + "length": 0, + "module": "Check Run", + "name": "Payment Entry-check_run", + "no_copy": 0, + "non_negative": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0 + } + ], + "doctype": "Payment Entry", + "property_setters": [], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/check_run/check_run/custom/purchase_invoice.json b/check_run/check_run/custom/purchase_invoice.json index 0c36646f..33fa44e0 100644 --- a/check_run/check_run/custom/purchase_invoice.json +++ b/check_run/check_run/custom/purchase_invoice.json @@ -1,69 +1,47 @@ { - "custom_fields": [ - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 11:20:02.666689", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Purchase Invoice", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "supplier_default_mode_of_payment", - "fieldtype": "Link", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 23, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "bill_no", - "label": "Supplier Default Mode of Payment", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-06-30 11:20:02.666689", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Purchase Invoice-supplier_default_mode_of_payment", - "no_copy": 0, - "non_negative": 0, - "options": "Mode of Payment", - "owner": "Administrator", - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - } - ], - "custom_perms": [], - "doctype": "Purchase Invoice", - "property_setters": [], - "sync_on_migrate": 1 -} + "custom_fields": [ + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Purchase Invoice", + "fetch_if_empty": 0, + "fieldname": "supplier_default_mode_of_payment", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 23, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "bill_no", + "label": "Supplier Default Mode of Payment", + "length": 0, + "module": "Check Run", + "name": "Purchase Invoice-supplier_default_mode_of_payment", + "no_copy": 0, + "non_negative": 0, + "options": "Mode of Payment", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0 + } + ], + "doctype": "Purchase Invoice", + "property_setters": [], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/check_run/check_run/custom/supplier.json b/check_run/check_run/custom/supplier.json index 81e193ed..276394eb 100644 --- a/check_run/check_run/custom/supplier.json +++ b/check_run/check_run/custom/supplier.json @@ -1,274 +1,187 @@ { - "custom_fields": [ - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 11:20:02.666689", - "default": null, - "depends_on": "", - "description": "Show Bank Account Number", - "docstatus": 0, - "dt": "Supplier", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "bank_account", - "fieldtype": "Password", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 62, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "release_date", - "is_system_generated": 0, - "is_virtual": 0, - "label": "Bank Account", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-06-30 11:20:02.666689", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Supplier-bank_account", - "no_copy": 0, - "non_negative": 0, - "options": null, - "owner": "Administrator", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "sort_options": 0, - "translatable": 0, - "unique": 0, - "width": null - }, - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 11:20:02.666689", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Supplier", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "bank", - "fieldtype": "Link", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 33, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "cb_21", - "label": "Bank", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-06-30 11:20:02.666689", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Supplier-bank", - "no_copy": 0, - "non_negative": 0, - "options": "Bank", - "owner": "Administrator", - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - }, - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2022-06-30 11:20:02.666689", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Supplier", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "supplier_default_mode_of_payment", - "fieldtype": "Link", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 15, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "payment_terms", - "is_system_generated": 0, - "is_virtual": 0, - "label": "Supplier Default Mode of Payment", - "length": 0, - "mandatory_depends_on": null, - "modified": "2022-06-30 11:20:02.666689", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Supplier-supplier_default_mode_of_payment", - "no_copy": 0, - "non_negative": 0, - "options": "Mode of Payment", - "owner": "Administrator", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "sort_options": 0, - "translatable": 0, - "unique": 0, - "width": null - }, - { - "_assign": null, - "_comments": null, - "_liked_by": null, - "_user_tags": null, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "creation": "2023-09-27 14:04:57.166489", - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "dt": "Supplier", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "number_of_invoices_per_check_voucher", - "fieldtype": "Int", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "idx": 15, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "supplier_default_mode_of_payment", - "is_system_generated": 0, - "is_virtual": 0, - "label": "Number of Invoices Per Check Voucher", - "length": 0, - "mandatory_depends_on": null, - "modified": "2023-09-27 14:05:17.695804", - "modified_by": "Administrator", - "module": "Check Run", - "name": "Supplier-number_of_invoices_per_check_voucher", - "no_copy": 0, - "non_negative": 0, - "options": null, - "owner": "Administrator", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "sort_options": 0, - "translatable": 0, - "unique": 0, - "width": null - } - ], - "custom_perms": [], - "doctype": "Supplier", - "links": [ - { - "creation": "2013-01-10 16:34:11", - "custom": 0, - "docstatus": 0, - "group": "Allowed Items", - "hidden": 0, - "idx": 1, - "is_child_table": 0, - "link_doctype": "Party Specific Item", - "link_fieldname": "party", - "modified": "2023-09-14 19:51:06.084944", - "modified_by": "Administrator", - "name": "22db288d07", - "owner": "Administrator", - "parent": "Supplier", - "parent_doctype": null, - "parentfield": "links", - "parenttype": "DocType", - "table_fieldname": null - } - ], - "property_setters": [], - "sync_on_migrate": 1 -} + "custom_fields": [ + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "description": "Show Bank Account Number", + "dt": "Supplier", + "fetch_if_empty": 0, + "fieldname": "bank_account", + "fieldtype": "Password", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 62, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "release_date", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Bank Account", + "length": 0, + "module": "Check Run", + "name": "Supplier-bank_account", + "no_copy": 0, + "non_negative": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Supplier", + "fetch_if_empty": 0, + "fieldname": "bank", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 33, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "cb_21", + "label": "Bank", + "length": 0, + "module": "Check Run", + "name": "Supplier-bank", + "no_copy": 0, + "non_negative": 0, + "options": "Bank", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Supplier", + "fetch_if_empty": 0, + "fieldname": "supplier_default_mode_of_payment", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 15, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "payment_terms", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Supplier Default Mode of Payment", + "length": 0, + "module": "Check Run", + "name": "Supplier-supplier_default_mode_of_payment", + "no_copy": 0, + "non_negative": 0, + "options": "Mode of Payment", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": null, + "dt": "Supplier", + "fetch_if_empty": 0, + "fieldname": "number_of_invoices_per_check_voucher", + "fieldtype": "Int", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 15, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "supplier_default_mode_of_payment", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Number of Invoices Per Check Voucher", + "length": 0, + "module": "Check Run", + "name": "Supplier-number_of_invoices_per_check_voucher", + "no_copy": 0, + "non_negative": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0 + } + ], + "doctype": "Supplier", + "links": [ + { + "custom": 0, + "group": "Allowed Items", + "hidden": 0, + "idx": 1, + "is_child_table": 0, + "link_doctype": "Party Specific Item", + "link_fieldname": "party", + "name": "22db288d07" + } + ], + "property_setters": [], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/check_run/check_run/doctype/__init__.py b/check_run/check_run/doctype/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/doctype/__init__.py +++ b/check_run/check_run/doctype/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/check_run/doctype/check_run/__init__.py b/check_run/check_run/doctype/check_run/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/doctype/check_run/__init__.py +++ b/check_run/check_run/doctype/check_run/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/check_run/doctype/check_run/check_run_list.js b/check_run/check_run/doctype/check_run/check_run_list.js index 45455f7d..ce12422b 100644 --- a/check_run/check_run/doctype/check_run/check_run_list.js +++ b/check_run/check_run/doctype/check_run/check_run_list.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + frappe.listview_settings['Check Run'] = { add_fields: ['status'], hide_name_column: true, diff --git a/check_run/check_run/doctype/check_run_settings/__init__.py b/check_run/check_run/doctype/check_run_settings/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/doctype/check_run_settings/__init__.py +++ b/check_run/check_run/doctype/check_run_settings/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/check_run/print_format/__init__.py b/check_run/check_run/print_format/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/print_format/__init__.py +++ b/check_run/check_run/print_format/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/check_run/print_format/example_voucher/__init__.py b/check_run/check_run/print_format/example_voucher/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/print_format/example_voucher/__init__.py +++ b/check_run/check_run/print_format/example_voucher/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/check_run/print_format/example_voucher_micr/__init__.py b/check_run/check_run/print_format/example_voucher_micr/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/print_format/example_voucher_micr/__init__.py +++ b/check_run/check_run/print_format/example_voucher_micr/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/check_run/report/__init__.py b/check_run/check_run/report/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/report/__init__.py +++ b/check_run/check_run/report/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/check_run/report/payables_attachments/__init__.py b/check_run/check_run/report/payables_attachments/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/report/payables_attachments/__init__.py +++ b/check_run/check_run/report/payables_attachments/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/check_run/report/positive_pay/__init__.py b/check_run/check_run/report/positive_pay/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/check_run/report/positive_pay/__init__.py +++ b/check_run/check_run/report/positive_pay/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/config/__init__.py b/check_run/config/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/config/__init__.py +++ b/check_run/config/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/config/desktop.py b/check_run/config/desktop.py index dfe4ffdc..b322fdb3 100644 --- a/check_run/config/desktop.py +++ b/check_run/config/desktop.py @@ -1,3 +1,6 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + from frappe import _ diff --git a/check_run/config/docs.py b/check_run/config/docs.py index a2410663..a3ecdf51 100644 --- a/check_run/config/docs.py +++ b/check_run/config/docs.py @@ -1,3 +1,6 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + """ Configuration for docs """ diff --git a/check_run/customize.py b/check_run/customize.py index c3c55422..6c36b13f 100644 --- a/check_run/customize.py +++ b/check_run/customize.py @@ -1,229 +1,232 @@ -import json -from pathlib import Path - -import frappe - - -def load_customizations(): - customizations_directory = ( - Path().cwd().parent / "apps" / "check_run" / "check_run" / "check_run" / "custom" - ) - files = list(customizations_directory.glob("**/*.json")) - for file in files: - customizations = json.loads(Path(file).read_text()) - for field in customizations.get("custom_fields"): - if field.get("module") != "Check Run": - continue - existing_field = frappe.get_value("Custom Field", field.get("name")) - custom_field = ( - frappe.get_doc("Custom Field", field.get("name")) - if existing_field - else frappe.new_doc("Custom Field") - ) - field.pop("modified") - {custom_field.set(key, value) for key, value in field.items()} - custom_field.flags.ignore_permissions = True - custom_field.flags.ignore_version = True - custom_field.save() - for prop in customizations.get("property_setters"): - if prop.get("module") != "Check Run": - continue - property_setter = frappe.get_doc( - { - "name": prop.get("name"), - "doctype": "Property Setter", - "doctype_or_field": prop.get("doctype_or_field"), - "doc_type": prop.get("doc_type"), - "field_name": prop.get("field_name"), - "property": prop.get("property"), - "value": prop.get("value"), - "property_type": prop.get("property_type"), - } - ) - property_setter.flags.ignore_permissions = True - property_setter.insert() - - -def add_workflow_for_voided_check(): - - workflow_actions = [ - { - "docstatus": 0, - "doctype": "Workflow Action Master", - "name": "Submit", - "workflow_action_name": "Submit", - }, - { - "docstatus": 0, - "doctype": "Workflow Action Master", - "name": "Void", - "workflow_action_name": "Void", - }, - { - "docstatus": 0, - "doctype": "Workflow Action Master", - "name": "Cancel", - "workflow_action_name": "Cancel", - }, - { - "docstatus": 0, - "doctype": "Workflow Action Master", - "name": "Save", - "workflow_action_name": "Save", - }, - ] - - for action in workflow_actions: - if not frappe.db.exists("Workflow Action Master", action["name"]): - act = frappe.new_doc("Workflow Action Master") - act.update(action) - act.insert() - - workflow_states = [ - { - "docstatus": 0, - "icon": "", - "name": "Submitted", - "style": "Primary", - "workflow_state_name": "Submitted", - }, - { - "docstatus": 0, - "icon": "", - "name": "Voided", - "style": "Inverse", - "workflow_state_name": "Voided", - }, - { - "docstatus": 0, - "doctype": "Workflow State", - "icon": "", - "name": "Cancelled", - "style": "Inverse", - "workflow_state_name": "Cancelled", - }, - { - "docstatus": 0, - "doctype": "Workflow State", - "icon": "", - "name": "Draft", - "style": "Warning", - "workflow_state_name": "Draft", - }, - ] - - for state in workflow_states: - if not frappe.db.exists("Workflow State", state["name"]): - ws = frappe.new_doc("Workflow State") - ws.update(state) - ws.insert() - - workflow_data = { - "docstatus": 0, - "doctype": "Workflow", - "document_type": "Payment Entry", - "is_active": 0, - "name": "Void Payment Entry", - "override_status": 0, - "send_email_alert": 0, - "states": [ - { - "allow_edit": "Accounts User", - "doc_status": "0", - "is_optional_state": 0, - "parent": "Payment Entry", - "parentfield": "states", - "parenttype": "Workflow", - "state": "Draft", - }, - { - "allow_edit": "Accounts User", - "doc_status": "1", - "is_optional_state": 0, - "parent": "Payment Entry", - "parentfield": "states", - "parenttype": "Workflow", - "state": "Submitted", - }, - { - "allow_edit": "Accounts User", - "doc_status": "2", - "is_optional_state": 0, - "parent": "Payment Entry", - "parentfield": "states", - "parenttype": "Workflow", - "state": "Cancelled", - }, - { - "allow_edit": "Accounts User", - "doc_status": "2", - "is_optional_state": 0, - "parent": "Payment Entry", - "parentfield": "states", - "parenttype": "Workflow", - "state": "Voided", - "update_field": "status", - "update_value": "Voided", - }, - ], - "transitions": [ - { - "action": "Save", - "allow_self_approval": 1, - "allowed": "Accounts User", - "next_state": "Draft", - "parent": "Payment Entry", - "parentfield": "transitions", - "parenttype": "Workflow", - "state": "Draft", - }, - { - "action": "Submit", - "allow_self_approval": 1, - "allowed": "Accounts User", - "next_state": "Submitted", - "parent": "Payment Entry", - "parentfield": "transitions", - "parenttype": "Workflow", - "state": "Draft", - }, - { - "action": "Cancel", - "allow_self_approval": 1, - "allowed": "Accounts User", - "next_state": "Cancelled", - "parent": "Payment Entry", - "parentfield": "transitions", - "parenttype": "Workflow", - "state": "Submitted", - }, - { - "action": "Void", - "allow_self_approval": 1, - "allowed": "Accounts User", - "next_state": "Voided", - "parent": "Payment Entry", - "parentfield": "transitions", - "parenttype": "Workflow", - "state": "Submitted", - }, - ], - "workflow_name": "Voidable Payment Entry", - "workflow_state_field": "status", - } - if not frappe.db.exists("Workflow", workflow_data["workflow_name"]): - workflow = frappe.new_doc("Workflow") - workflow.update(workflow_data) - workflow.insert() - - -def after_install(): - if not frappe.db.exists("File", "Home/Check Run"): - try: - cr_folder = frappe.new_doc("File") - cr_folder.update({"file_name": "Check Run", "is_folder": True, "folder": "Home"}) - cr_folder.save() - except Exception as e: - pass - - add_workflow_for_voided_check() +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + +import json +from pathlib import Path + +import frappe + + +def load_customizations(): + customizations_directory = ( + Path().cwd().parent / "apps" / "check_run" / "check_run" / "check_run" / "custom" + ) + files = list(customizations_directory.glob("**/*.json")) + for file in files: + customizations = json.loads(Path(file).read_text()) + for field in customizations.get("custom_fields"): + if field.get("module") != "Check Run": + continue + existing_field = frappe.get_value("Custom Field", field.get("name")) + custom_field = ( + frappe.get_doc("Custom Field", field.get("name")) + if existing_field + else frappe.new_doc("Custom Field") + ) + field.pop("modified") + {custom_field.set(key, value) for key, value in field.items()} + custom_field.flags.ignore_permissions = True + custom_field.flags.ignore_version = True + custom_field.save() + for prop in customizations.get("property_setters"): + if prop.get("module") != "Check Run": + continue + property_setter = frappe.get_doc( + { + "name": prop.get("name"), + "doctype": "Property Setter", + "doctype_or_field": prop.get("doctype_or_field"), + "doc_type": prop.get("doc_type"), + "field_name": prop.get("field_name"), + "property": prop.get("property"), + "value": prop.get("value"), + "property_type": prop.get("property_type"), + } + ) + property_setter.flags.ignore_permissions = True + property_setter.insert() + + +def add_workflow_for_voided_check(): + + workflow_actions = [ + { + "docstatus": 0, + "doctype": "Workflow Action Master", + "name": "Submit", + "workflow_action_name": "Submit", + }, + { + "docstatus": 0, + "doctype": "Workflow Action Master", + "name": "Void", + "workflow_action_name": "Void", + }, + { + "docstatus": 0, + "doctype": "Workflow Action Master", + "name": "Cancel", + "workflow_action_name": "Cancel", + }, + { + "docstatus": 0, + "doctype": "Workflow Action Master", + "name": "Save", + "workflow_action_name": "Save", + }, + ] + + for action in workflow_actions: + if not frappe.db.exists("Workflow Action Master", action["name"]): + act = frappe.new_doc("Workflow Action Master") + act.update(action) + act.insert() + + workflow_states = [ + { + "docstatus": 0, + "icon": "", + "name": "Submitted", + "style": "Primary", + "workflow_state_name": "Submitted", + }, + { + "docstatus": 0, + "icon": "", + "name": "Voided", + "style": "Inverse", + "workflow_state_name": "Voided", + }, + { + "docstatus": 0, + "doctype": "Workflow State", + "icon": "", + "name": "Cancelled", + "style": "Inverse", + "workflow_state_name": "Cancelled", + }, + { + "docstatus": 0, + "doctype": "Workflow State", + "icon": "", + "name": "Draft", + "style": "Warning", + "workflow_state_name": "Draft", + }, + ] + + for state in workflow_states: + if not frappe.db.exists("Workflow State", state["name"]): + ws = frappe.new_doc("Workflow State") + ws.update(state) + ws.insert() + + workflow_data = { + "docstatus": 0, + "doctype": "Workflow", + "document_type": "Payment Entry", + "is_active": 0, + "name": "Void Payment Entry", + "override_status": 0, + "send_email_alert": 0, + "states": [ + { + "allow_edit": "Accounts User", + "doc_status": "0", + "is_optional_state": 0, + "parent": "Payment Entry", + "parentfield": "states", + "parenttype": "Workflow", + "state": "Draft", + }, + { + "allow_edit": "Accounts User", + "doc_status": "1", + "is_optional_state": 0, + "parent": "Payment Entry", + "parentfield": "states", + "parenttype": "Workflow", + "state": "Submitted", + }, + { + "allow_edit": "Accounts User", + "doc_status": "2", + "is_optional_state": 0, + "parent": "Payment Entry", + "parentfield": "states", + "parenttype": "Workflow", + "state": "Cancelled", + }, + { + "allow_edit": "Accounts User", + "doc_status": "2", + "is_optional_state": 0, + "parent": "Payment Entry", + "parentfield": "states", + "parenttype": "Workflow", + "state": "Voided", + "update_field": "status", + "update_value": "Voided", + }, + ], + "transitions": [ + { + "action": "Save", + "allow_self_approval": 1, + "allowed": "Accounts User", + "next_state": "Draft", + "parent": "Payment Entry", + "parentfield": "transitions", + "parenttype": "Workflow", + "state": "Draft", + }, + { + "action": "Submit", + "allow_self_approval": 1, + "allowed": "Accounts User", + "next_state": "Submitted", + "parent": "Payment Entry", + "parentfield": "transitions", + "parenttype": "Workflow", + "state": "Draft", + }, + { + "action": "Cancel", + "allow_self_approval": 1, + "allowed": "Accounts User", + "next_state": "Cancelled", + "parent": "Payment Entry", + "parentfield": "transitions", + "parenttype": "Workflow", + "state": "Submitted", + }, + { + "action": "Void", + "allow_self_approval": 1, + "allowed": "Accounts User", + "next_state": "Voided", + "parent": "Payment Entry", + "parentfield": "transitions", + "parenttype": "Workflow", + "state": "Submitted", + }, + ], + "workflow_name": "Voidable Payment Entry", + "workflow_state_field": "status", + } + if not frappe.db.exists("Workflow", workflow_data["workflow_name"]): + workflow = frappe.new_doc("Workflow") + workflow.update(workflow_data) + workflow.insert() + + +def after_install(): + if not frappe.db.exists("File", "Home/Check Run"): + try: + cr_folder = frappe.new_doc("File") + cr_folder.update({"file_name": "Check Run", "is_folder": True, "folder": "Home"}) + cr_folder.save() + except Exception as e: + pass + + add_workflow_for_voided_check() diff --git a/check_run/hooks.py b/check_run/hooks.py index cfef59d0..e3553ca5 100644 --- a/check_run/hooks.py +++ b/check_run/hooks.py @@ -1,3 +1,6 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + from . import __version__ as app_version # noqa: F401 app_name = "check_run" diff --git a/check_run/overrides/__init__.py b/check_run/overrides/__init__.py index e69de29b..ea2ab3f3 100644 --- a/check_run/overrides/__init__.py +++ b/check_run/overrides/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt diff --git a/check_run/patches/patch_payment_schedule.py b/check_run/patches/patch_payment_schedule.py index fb67ac03..091aeba5 100644 --- a/check_run/patches/patch_payment_schedule.py +++ b/check_run/patches/patch_payment_schedule.py @@ -1,17 +1,20 @@ -import frappe - - -def execute(): - pts = frappe.db.sql( - """ - SELECT `tabPayment Schedule`.parent, `tabPayment Schedule`.name - FROM `tabPayment Schedule`, `tabPurchase Invoice` - WHERE `tabPayment Schedule`.outstanding > 0.0 - AND `tabPayment Schedule`.parent = `tabPurchase Invoice`.name - AND `tabPurchase Invoice`.status = 'Paid' - """, - as_dict=True, - ) - - for ps in pts: - frappe.db.set_value("Payment Schedule", ps.name, "outstanding", 0.0) +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + +import frappe + + +def execute(): + pts = frappe.db.sql( + """ + SELECT `tabPayment Schedule`.parent, `tabPayment Schedule`.name + FROM `tabPayment Schedule`, `tabPurchase Invoice` + WHERE `tabPayment Schedule`.outstanding > 0.0 + AND `tabPayment Schedule`.parent = `tabPurchase Invoice`.name + AND `tabPurchase Invoice`.status = 'Paid' + """, + as_dict=True, + ) + + for ps in pts: + frappe.db.set_value("Payment Schedule", ps.name, "outstanding", 0.0) diff --git a/check_run/patches/patch_voided_check_workflow.py b/check_run/patches/patch_voided_check_workflow.py index 0740c4b7..3330d473 100644 --- a/check_run/patches/patch_voided_check_workflow.py +++ b/check_run/patches/patch_voided_check_workflow.py @@ -1,3 +1,6 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + from check_run.customize import add_workflow_for_voided_check diff --git a/check_run/public/js/check_run.bundle.js b/check_run/public/js/check_run.bundle.js index f439da52..64b736c0 100644 --- a/check_run/public/js/check_run.bundle.js +++ b/check_run/public/js/check_run.bundle.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + import './check_run/check_run_quick_entry.js' import './check_run/check_run_settings_quick_entry.js' import './custom/file_preview.js' diff --git a/check_run/public/js/check_run/check_run_quick_entry.js b/check_run/public/js/check_run/check_run_quick_entry.js index 9f046616..1a4d1b48 100644 --- a/check_run/public/js/check_run/check_run_quick_entry.js +++ b/check_run/public/js/check_run/check_run_quick_entry.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + frappe.provide('check_run') frappe.provide('frappe.ui.form') diff --git a/check_run/public/js/check_run/check_run_settings_quick_entry.js b/check_run/public/js/check_run/check_run_settings_quick_entry.js index 221549d4..8688b779 100644 --- a/check_run/public/js/check_run/check_run_settings_quick_entry.js +++ b/check_run/public/js/check_run/check_run_settings_quick_entry.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + frappe.provide('check_run') frappe.provide('frappe.ui.form') diff --git a/check_run/public/js/custom/employee_custom.js b/check_run/public/js/custom/employee_custom.js index 5a19feb3..7015bee6 100644 --- a/check_run/public/js/custom/employee_custom.js +++ b/check_run/public/js/custom/employee_custom.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + frappe.ui.form.on('Employee', { onload_post_render: frm => { frm.fields_dict.bank_account.$wrapper diff --git a/check_run/public/js/custom/file_preview.js b/check_run/public/js/custom/file_preview.js index 21bc07d7..6ffabcb4 100644 --- a/check_run/public/js/custom/file_preview.js +++ b/check_run/public/js/custom/file_preview.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + frappe.provide('frappe.ui.form') $(document).on('page-change', function (e) { diff --git a/check_run/public/js/custom/payment_entry_custom.js b/check_run/public/js/custom/payment_entry_custom.js index a630f7f9..4ac71578 100644 --- a/check_run/public/js/custom/payment_entry_custom.js +++ b/check_run/public/js/custom/payment_entry_custom.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + frappe.ui.form.on('Payment Entry', { mode_of_payment: frm => { get_next_check_number(frm) diff --git a/check_run/public/js/custom/supplier_custom.js b/check_run/public/js/custom/supplier_custom.js index 2d77cedc..38b23d1f 100644 --- a/check_run/public/js/custom/supplier_custom.js +++ b/check_run/public/js/custom/supplier_custom.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + frappe.ui.form.on('Supplier', { onload_post_render: frm => { frm.fields_dict.bank_account.$wrapper diff --git a/check_run/public/js/vite.config.js b/check_run/public/js/vite.config.js index c7deb3a3..f5650627 100644 --- a/check_run/public/js/vite.config.js +++ b/check_run/public/js/vite.config.js @@ -1,3 +1,6 @@ +// Copyright (c) 2026, AgriTheory and contributors +// For license information, please see license.txt + import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { getProxyOptions } from 'frappe-ui/src/utils/vite-dev-server' diff --git a/check_run/tests/conftest.py b/check_run/tests/conftest.py index 214c2a1b..e87c2c60 100644 --- a/check_run/tests/conftest.py +++ b/check_run/tests/conftest.py @@ -1,3 +1,6 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + import json from pathlib import Path from unittest.mock import MagicMock diff --git a/check_run/tests/fixtures.py b/check_run/tests/fixtures.py index b8d9707f..602eaf49 100644 --- a/check_run/tests/fixtures.py +++ b/check_run/tests/fixtures.py @@ -1,245 +1,248 @@ -suppliers = [ - ( - "Exceptional Grid", - "Electricity", - "ACH/EFT", - 150.00, - "Net 14", - { - "address_line1": "2 Cosmo Point", - "city": "Summerville", - "state": "MA", - "country": "United States", - "pincode": "34791", - }, - ), - ( - "Liu & Loewen Accountants LLP", - "Accounting Services", - None, - 500.00, - "Net 30", - { - "address_line1": "138 Wanda Square", - "city": "Chino", - "state": "ME", - "country": "United States", - "pincode": "90953", - }, - ), - ( - "Mare Digitalis", - "Cloud Services", - "Credit Card", - 200.00, - "Due on Receipt", - { - "address_line1": "1000 Toll Plaza Tunnel Alley", - "city": "Joplin", - "state": "CT", - "country": "United States", - "pincode": "51485", - }, - ), - ( - "AgriTheory", - "ERPNext Consulting", - "Check", - 1000.00, - "Net 14", - { - "address_line1": "1293 Bannan Road", - "city": "New Brighton", - "state": "NH", - "country": "United States", - "pincode": "55932", - }, - ), - ( - "HIJ Telecom, Inc", - "Internet Services", - "Check", - 150.00, - "Net 30", - { - "address_line1": "955 Winding Highway", - "city": "Glassboro", - "state": "NY", - "country": "United States", - "pincode": "28026", - }, - ), - ( - "Sphere Cellular", - "Phone Services", - "ACH/EFT", - 250.00, - "", - { - "address_line1": "1198 Carpenter Road", - "city": "Rolla", - "state": "VT", - "country": "United States", - "pincode": "94286", - }, - ), - ( - "Cooperative Ag Finance", - "Financial Services", - "Bank Draft", - 5000.00, - "Net 30", - { - "address_line1": "629 Loyola Landing", - "city": "Warner Robins", - "state": "CT", - "country": "United States", - "pincode": "28989", - }, - ), - ( - "Tireless Equipment Rental, Inc", - "Equipment Rental", - "Check", - 30000.00, - "18 Month Rental Agreement", - { - "address_line1": "385 Crespi Road", - "city": "Garfield", - "state": "VT", - "country": "United States", - "pincode": "28327", - }, - ), -] - -tax_authority = [ - ( - "Local Tax Authority", - "Payroll Taxes", - None, - 0.00, - "Due on Receipt", - { - "address_line1": "18 Spooner Stravenue", - "city": "Danbury", - "state": "RI", - "country": "United States", - "pincode": "07165", - }, - ), -] - -employees = [ - ("Wilmer Larson", "Male", "1977-03-06", "2019-04-12", "20 Gaven Path", "Spokane", "NV", "66308"), - ( - "Shanel Finley", - "Female", - "1984-04-23", - "2019-07-04", - "1070 Ulloa Green", - "DeKalb", - "PA", - "30474", - ), - ( - "Camellia Phelps", - "Female", - "1980-07-06", - "2019-07-28", - "787 Sotelo Arcade", - "Stockton", - "CO", - "14860", - ), - ( - "Michale Mitchell", - "Male", - "1984-06-29", - "2020-01-12", - "773 Icehouse Road", - "West Sacramento", - "VT", - "24355", - ), - ( - "Sharilyn Romero", - "Female", - "1998-04-22", - "2020-03-20", - "432 Dudley Ranch", - "Clovis", - "WA", - "97159", - ), - ( - "Doug Buckley", - "Male", - "1979-06-18", - "2020-09-08", - "771 Battery Caulfield Motorway", - "Yonkers", - "VT", - "38125", - ), - ( - "Margarito Wallace", - "Male", - "1991-08-17", - "2020-11-01", - "639 Brook Park", - "Terre Haute", - "OR", - "41704", - ), - ( - "Mckenzie Ashley", - "Female", - "1997-09-13", - "2021-02-22", - "1119 Hunter Glen", - "Ormond Beach", - "MD", - "30864", - ), - ( - "Merrie Oliver", - "Other", - "1979-11-08", - "2021-03-11", - "267 Vega Freeway", - "West Palm Beach", - "FL", - "24411", - ), - ( - "Naoma Blake", - "Female", - "1987-07-10", - "2021-06-21", - "649 Conrad Road", - "Thousand Oaks", - "CT", - "97929", - ), - ( - "Donnell Fry", - "Male", - "1994-07-27", - "2021-06-24", - "504 Starr King Canyon", - "Norwalk", - "OR", - "46845", - ), - ( - "Shalanda Peterson", - "Female", - "1999-10-04", - "2021-08-01", - "109 Seventh Parkway", - "Urbana", - "DE", - "55975", - ), -] +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + +suppliers = [ + ( + "Exceptional Grid", + "Electricity", + "ACH/EFT", + 150.00, + "Net 14", + { + "address_line1": "2 Cosmo Point", + "city": "Summerville", + "state": "MA", + "country": "United States", + "pincode": "34791", + }, + ), + ( + "Liu & Loewen Accountants LLP", + "Accounting Services", + None, + 500.00, + "Net 30", + { + "address_line1": "138 Wanda Square", + "city": "Chino", + "state": "ME", + "country": "United States", + "pincode": "90953", + }, + ), + ( + "Mare Digitalis", + "Cloud Services", + "Credit Card", + 200.00, + "Due on Receipt", + { + "address_line1": "1000 Toll Plaza Tunnel Alley", + "city": "Joplin", + "state": "CT", + "country": "United States", + "pincode": "51485", + }, + ), + ( + "AgriTheory", + "ERPNext Consulting", + "Check", + 1000.00, + "Net 14", + { + "address_line1": "1293 Bannan Road", + "city": "New Brighton", + "state": "NH", + "country": "United States", + "pincode": "55932", + }, + ), + ( + "HIJ Telecom, Inc", + "Internet Services", + "Check", + 150.00, + "Net 30", + { + "address_line1": "955 Winding Highway", + "city": "Glassboro", + "state": "NY", + "country": "United States", + "pincode": "28026", + }, + ), + ( + "Sphere Cellular", + "Phone Services", + "ACH/EFT", + 250.00, + "", + { + "address_line1": "1198 Carpenter Road", + "city": "Rolla", + "state": "VT", + "country": "United States", + "pincode": "94286", + }, + ), + ( + "Cooperative Ag Finance", + "Financial Services", + "Bank Draft", + 5000.00, + "Net 30", + { + "address_line1": "629 Loyola Landing", + "city": "Warner Robins", + "state": "CT", + "country": "United States", + "pincode": "28989", + }, + ), + ( + "Tireless Equipment Rental, Inc", + "Equipment Rental", + "Check", + 30000.00, + "18 Month Rental Agreement", + { + "address_line1": "385 Crespi Road", + "city": "Garfield", + "state": "VT", + "country": "United States", + "pincode": "28327", + }, + ), +] + +tax_authority = [ + ( + "Local Tax Authority", + "Payroll Taxes", + None, + 0.00, + "Due on Receipt", + { + "address_line1": "18 Spooner Stravenue", + "city": "Danbury", + "state": "RI", + "country": "United States", + "pincode": "07165", + }, + ), +] + +employees = [ + ("Wilmer Larson", "Male", "1977-03-06", "2019-04-12", "20 Gaven Path", "Spokane", "NV", "66308"), + ( + "Shanel Finley", + "Female", + "1984-04-23", + "2019-07-04", + "1070 Ulloa Green", + "DeKalb", + "PA", + "30474", + ), + ( + "Camellia Phelps", + "Female", + "1980-07-06", + "2019-07-28", + "787 Sotelo Arcade", + "Stockton", + "CO", + "14860", + ), + ( + "Michale Mitchell", + "Male", + "1984-06-29", + "2020-01-12", + "773 Icehouse Road", + "West Sacramento", + "VT", + "24355", + ), + ( + "Sharilyn Romero", + "Female", + "1998-04-22", + "2020-03-20", + "432 Dudley Ranch", + "Clovis", + "WA", + "97159", + ), + ( + "Doug Buckley", + "Male", + "1979-06-18", + "2020-09-08", + "771 Battery Caulfield Motorway", + "Yonkers", + "VT", + "38125", + ), + ( + "Margarito Wallace", + "Male", + "1991-08-17", + "2020-11-01", + "639 Brook Park", + "Terre Haute", + "OR", + "41704", + ), + ( + "Mckenzie Ashley", + "Female", + "1997-09-13", + "2021-02-22", + "1119 Hunter Glen", + "Ormond Beach", + "MD", + "30864", + ), + ( + "Merrie Oliver", + "Other", + "1979-11-08", + "2021-03-11", + "267 Vega Freeway", + "West Palm Beach", + "FL", + "24411", + ), + ( + "Naoma Blake", + "Female", + "1987-07-10", + "2021-06-21", + "649 Conrad Road", + "Thousand Oaks", + "CT", + "97929", + ), + ( + "Donnell Fry", + "Male", + "1994-07-27", + "2021-06-24", + "504 Starr King Canyon", + "Norwalk", + "OR", + "46845", + ), + ( + "Shalanda Peterson", + "Female", + "1999-10-04", + "2021-08-01", + "109 Seventh Parkway", + "Urbana", + "DE", + "55975", + ), +] diff --git a/check_run/tests/setup.py b/check_run/tests/setup.py index 7f65ff2a..bf4b6729 100644 --- a/check_run/tests/setup.py +++ b/check_run/tests/setup.py @@ -1,1029 +1,1047 @@ -import datetime -import types - -import frappe -from erpnext.accounts.doctype.account.account import update_account_number -from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import make_debit_note -from erpnext.setup.utils import enable_all_roles_and_domains, set_defaults_for_tests -from frappe.desk.page.setup_wizard.setup_wizard import setup_complete -from frappe.utils.data import add_days, flt - -from check_run.tests.fixtures import employees, suppliers, tax_authority - - -def before_test(): - frappe.clear_cache() - today = frappe.utils.getdate() - setup_complete( - { - "currency": "USD", - "full_name": "Administrator", - "company_name": "Chelsea Fruit Co", - "timezone": "America/New_York", - "company_abbr": "CFC", - "domains": ["Distribution"], - "country": "United States", - "fy_start_date": today.replace(month=1, day=1).isoformat(), - "fy_end_date": today.replace(month=12, day=31).isoformat(), - "language": "english", - "company_tagline": "Chelsea Fruit Co", - "email": "support@agritheory.dev", - "password": "admin", - "chart_of_accounts": "Standard with Numbers", - "bank_account": "Primary Checking", - } - ) - enable_all_roles_and_domains() - set_defaults_for_tests() - frappe.db.commit() - create_test_data() - for modu in frappe.get_all("Module Onboarding"): - frappe.db.set_value("Module Onboarding", modu, "is_complete", 1) - frappe.set_value("Website Settings", "Website Settings", "home_page", "login") - - -def create_test_data(): - today = frappe.utils.getdate() - setup_accounts() - settings = frappe._dict( - { - "day": today.replace(month=1, day=1), - "company": frappe.defaults.get_defaults().get("company"), - "company_account": frappe.get_value( - "Account", - { - "account_type": "Bank", - "company": frappe.defaults.get_defaults().get("company"), - "is_group": 0, - }, - ), - } - ) - create_company_address(settings) - create_bank_and_bank_account(settings) - create_payment_terms_templates(settings) - create_suppliers(settings) - create_items(settings) - create_invoices(settings) - config_expense_claim(settings) - create_employees(settings) - create_expense_claim(settings) - for month in range(1, 13): - settings.day = settings.day.replace(month=month) - create_payroll_journal_entry(settings) - create_manual_payment_entry(settings) - - -def create_company_address(settings): - company_address = frappe.new_doc("Address") - company_address.title = settings.company - company_address.address_type = "Office" - company_address.address_line1 = "67C Sweeny Street" - company_address.city = "Chelsea" - company_address.state = "MA" - company_address.pincode = "89077" - company_address.is_your_company_address = True - company_address.append("links", {"link_doctype": "Company", "link_name": settings.company}) - company_address.save() - - -def create_bank_and_bank_account(settings): - if not frappe.db.exists("Mode of Payment", "ACH/EFT"): - mop = frappe.new_doc("Mode of Payment") - mop.mode_of_payment = "ACH/EFT" - mop.enabled = 1 - mop.type = "Electronic" - mop.append( - "accounts", {"company": settings.company, "default_account": settings.company_account} - ) - mop.save() - - wire_transfer = frappe.get_doc("Mode of Payment", "Wire Transfer") - wire_transfer.type = "General" - wire_transfer.append( - "accounts", {"company": settings.company, "default_account": settings.company_account} - ) - wire_transfer.save() - - credit_card = frappe.get_doc("Mode of Payment", "Credit Card") - credit_card.type = "General" - credit_card.append( - "accounts", {"company": settings.company, "default_account": settings.company_account} - ) - credit_card.save() - - bank_draft = frappe.get_doc("Mode of Payment", "Bank Draft") - bank_draft.type = "General" - bank_draft.append( - "accounts", {"company": settings.company, "default_account": settings.company_account} - ) - bank_draft.save() - - check_mop = frappe.get_doc("Mode of Payment", "Check") - check_mop.type = "Bank" - check_mop.append( - "accounts", {"company": settings.company, "default_account": settings.company_account} - ) - check_mop.save() - - if not frappe.db.exists("Bank", "Local Bank"): - bank = frappe.new_doc("Bank") - bank.bank_name = "Local Bank" - bank.aba_number = "07200091" - bank.save() - - if not frappe.db.exists("Bank Account", "Primary Checking - Local Bank"): - bank_account = frappe.new_doc("Bank Account") - bank_account.account_name = "Primary Checking" - bank_account.bank = bank.name - bank_account.is_default = 1 - bank_account.is_company_account = 1 - bank_account.company = settings.company - bank_account.account = settings.company_account - bank_account.check_number = 2500 - bank_account.company_ach_id = "1381655417" - bank_account.bank_account_no = "072000915" - bank_account.branch_code = "07200091" - bank_account.save() - - doc = frappe.new_doc("Journal Entry") - doc.posting_date = settings.day - doc.voucher_type = "Opening Entry" - doc.company = settings.company - opening_balance = 50000.00 - doc.append( - "accounts", {"account": settings.company_account, "debit_in_account_currency": opening_balance} - ) - retained_earnings = frappe.get_value( - "Account", {"account_name": "Retained Earnings", "company": settings.company} - ) - doc.append( - "accounts", {"account": retained_earnings, "credit_in_account_currency": opening_balance} - ) - doc.save() - doc.submit() - - -def setup_accounts(): - frappe.rename_doc( - "Account", "1000 - Application of Funds (Assets) - CFC", "1000 - Assets - CFC", force=True - ) - frappe.rename_doc( - "Account", "2000 - Source of Funds (Liabilities) - CFC", "2000 - Liabilities - CFC", force=True - ) - frappe.rename_doc( - "Account", "1310 - Debtors - CFC", "1310 - Accounts Receivable - CFC", force=True - ) - frappe.rename_doc( - "Account", "2110 - Creditors - CFC", "2110 - Accounts Payable - CFC", force=True - ) - update_account_number("1110 - Cash - CFC", "Petty Cash", account_number="1110") - update_account_number("Primary Checking - CFC", "Primary Checking", account_number="1201") - - -def create_payment_terms_templates(settings): - if not frappe.db.exists("Payment Terms Template", "Net 30"): - pt = frappe.new_doc("Payment Term") - pt.payment_term_name = "Net 30" - pt.due_date_based_on = "Day(s) after invoice date" - pt.invoice_portion = 100 - pt.credit_days = 30 - pt.save() - doc = frappe.new_doc("Payment Terms Template") - doc.template_name = pt.name - doc.append( - "terms", - { - "payment_term": pt.name, - "invoice_portion": pt.invoice_portion, - "due_date_based_on": pt.due_date_based_on, - "credit_days": pt.credit_days, - }, - ) - doc.save() - if not frappe.db.exists("Payment Terms Template", "Due on Receipt"): - pt = frappe.new_doc("Payment Term") - pt.payment_term_name = "Due on Receipt" - pt.due_date_based_on = "Day(s) after invoice date" - pt.invoice_portion = 100 - pt.credit_days = 0 - pt.save() - doc = frappe.new_doc("Payment Terms Template") - doc.template_name = pt.name - doc.append( - "terms", - { - "payment_term": pt.name, - "invoice_portion": pt.invoice_portion, - "due_date_based_on": pt.due_date_based_on, - "credit_days": pt.credit_days, - }, - ) - doc.save() - if not frappe.db.exists("Payment Terms Template", "Net 14"): - pt = frappe.new_doc("Payment Term") - pt.payment_term_name = "Net 14" - pt.due_date_based_on = "Day(s) after invoice date" - pt.invoice_portion = 100 - pt.credit_days = 14 - pt.save() - doc = frappe.new_doc("Payment Terms Template") - doc.template_name = pt.name - doc.append( - "terms", - { - "payment_term": pt.name, - "invoice_portion": pt.invoice_portion, - "due_date_based_on": pt.due_date_based_on, - "credit_days": pt.credit_days, - }, - ) - doc.save() - - if not frappe.db.exists("Payment Terms Template", "18 Month Rental Agreement"): - doc = frappe.new_doc("Payment Terms Template") - doc.template_name = "18 Month Rental Agreement" - for month in range(0, 18): - pt = frappe.new_doc("Payment Term") - pt.payment_term_name = f"Rental Installment {month+1}" - pt.due_date_based_on = "Month(s) after the end of the invoice month" - pt.invoice_portion = 5.555555555555556 - pt.credit_months = month - pt.save() - doc.append( - "terms", - { - "payment_term": pt.name, - "invoice_portion": pt.invoice_portion, - "due_date_based_on": pt.due_date_based_on, - "credit_months": pt.credit_months, - }, - ) - doc.save() - - if not frappe.db.exists("Payment Terms Template", "2% 10 Net 30"): - doc = frappe.new_doc("Payment Terms Template") - doc.template_name = "2% 10 Net 30" - - pt = frappe.new_doc("Payment Term") - pt.payment_term_name = "2% 10 Net 30" - pt.due_date_based_on = "Day(s) after the end of the invoice month" - pt.discount_validity_based_on = "Day(s) after the end of the invoice month" - pt.invoice_portion = 100 - pt.credit_days = 30 - pt.discount_type = "Percentage" - pt.discount = 2.0 - pt.discount_validity = 10 - pt.save() - doc.append( - "terms", - { - "payment_term": pt.name, - "invoice_portion": pt.invoice_portion, - "due_date_based_on": pt.due_date_based_on, - "credit_days": pt.credit_days, - }, - ) - doc.save() - - if not frappe.db.exists("Payment Terms Template", "$20 10 Net 30"): - doc = frappe.new_doc("Payment Terms Template") - doc.template_name = "$20 10 Net 30" - - pt = frappe.new_doc("Payment Term") - pt.payment_term_name = "$20 10 Net 30" - pt.due_date_based_on = "Day(s) after the end of the invoice month" - pt.discount_validity_based_on = "Day(s) after the end of the invoice month" - pt.invoice_portion = 100 - pt.credit_days = 30 - pt.discount_type = "Amount" - pt.discount = 20.0 - pt.discount_validity = 10 - pt.save() - doc.append( - "terms", - { - "payment_term": pt.name, - "invoice_portion": pt.invoice_portion, - "due_date_based_on": pt.due_date_based_on, - "credit_days": pt.credit_days, - }, - ) - doc.save() - - # Payment term with "Day(s) after invoice date" for discount validity - if not frappe.db.exists("Payment Terms Template", "2% 10 Net 30 - Invoice Date"): - doc = frappe.new_doc("Payment Terms Template") - doc.template_name = "2% 10 Net 30 - Invoice Date" - - pt = frappe.new_doc("Payment Term") - pt.payment_term_name = "2% 10 Net 30 - Invoice Date" - pt.due_date_based_on = "Day(s) after invoice date" - pt.discount_validity_based_on = "Day(s) after invoice date" - pt.invoice_portion = 100 - pt.credit_days = 30 - pt.discount_type = "Percentage" - pt.discount = 2.0 - pt.discount_validity = 10 - pt.save() - doc.append( - "terms", - { - "payment_term": pt.name, - "invoice_portion": pt.invoice_portion, - "due_date_based_on": pt.due_date_based_on, - "credit_days": pt.credit_days, - }, - ) - doc.save() - - # Payment term with "Month(s) after the end of the invoice month" for discount validity - if not frappe.db.exists("Payment Terms Template", "3% Net 30"): - doc = frappe.new_doc("Payment Terms Template") - doc.template_name = "3% Net 30" - - pt = frappe.new_doc("Payment Term") - pt.payment_term_name = "3% Net 30" - pt.due_date_based_on = "Month(s) after the end of the invoice month" - pt.discount_validity_based_on = "Month(s) after the end of the invoice month" - pt.invoice_portion = 100 - pt.credit_months = 1 - pt.discount_type = "Percentage" - pt.discount = 3.0 - pt.discount_validity = 1 - pt.save() - doc.append( - "terms", - { - "payment_term": pt.name, - "invoice_portion": pt.invoice_portion, - "due_date_based_on": pt.due_date_based_on, - "credit_months": pt.credit_months, - }, - ) - doc.save() - - -def create_suppliers(settings): - addresses = frappe._dict({}) - for supplier in suppliers + tax_authority: - biz = frappe.new_doc("Supplier") - biz.supplier_name = supplier[0] - biz.supplier_group = "Services" - biz.country = "United States" - biz.supplier_default_mode_of_payment = supplier[2] - if biz.supplier_default_mode_of_payment == "ACH/EFT": - biz.bank = "Local Bank" - biz.bank_account = "123456789" - biz.currency = "USD" - biz.default_price_list = "Standard Buying" - biz.payment_terms = supplier[4] - if supplier[0] == "Tireless Equipment Rental, Inc": - biz.number_of_invoices_per_check_voucher = 1 - biz.save() - - addr = frappe.new_doc("Address") - addr.address_title = f"{supplier[0]} - {supplier[5]['city']}" - addr.address_type = "Billing" - addr.address_line1 = supplier[5]["address_line1"] - addr.city = supplier[5]["city"] - addr.state = supplier[5]["state"] - addr.country = supplier[5]["country"] - addr.pincode = supplier[5]["pincode"] - addr.append("links", {"link_doctype": "Supplier", "link_name": supplier[0]}) - addr.save() - - addr = frappe.new_doc("Address") - addr.address_type = "Billing" - addr.address_title = "HIJ Telecom - Burlingame" - addr.address_line1 = "167 Auto Terrace" - addr.city = "Burlingame" - addr.state = "ME" - addr.country = "United States" - addr.pincode = "79749" - addr.append("links", {"link_doctype": "Supplier", "link_name": "HIJ Telecom, Inc"}) - addr.save() - - -def create_items(settings): - for supplier in suppliers + tax_authority: - item = frappe.new_doc("Item") - item.item_code = item.item_name = supplier[1] - item.item_group = "Services" - item.stock_uom = "Nos" - item.maintain_stock = 0 - item.is_sales_item, item.is_sub_contracted_item, item.include_item_in_manufacturing = 0, 0, 0 - item.grant_commission = 0 - item.is_purchase_item = 1 - item.append("supplier_items", {"supplier": supplier[0]}) - item.append( - "item_defaults", - {"company": settings.company, "default_warehouse": "", "default_supplier": supplier[0]}, - ) - item.save() - - -def create_invoices(settings): - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = settings.day - pi.supplier = "Tireless Equipment Rental, Inc" - pi.append( - "items", - { - "item_code": "Equipment Rental", - "rate": 30000.00, - "qty": 1, - }, - ) - pi.payment_terms = "18 Month Rental Agreement" - pi.save() - pi.submit() - - # first month - already paid - for supplier in suppliers: - if supplier[0].startswith("Tireless"): - continue - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = settings.day - pi.supplier = supplier[0] - pi.append( - "items", - { - "item_code": supplier[1], - "rate": supplier[3], - "qty": 1, - }, - ) - pi.save() - pi.submit() - # two electric meters / test invoice aggregation - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = settings.day - pi.supplier = suppliers[0][0] - pi.append( - "items", - { - "item_code": suppliers[0][1], - "rate": 75.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - # two phone bills / test address splitting - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = settings.day - pi.supplier = suppliers[4][0] - pi.append( - "items", - { - "item_code": suppliers[4][1], - "rate": 122.50, - "qty": 1, - }, - ) - pi.supplier_address = "HIJ Telecom - Burlingame-Billing" - pi.save() - pi.submit() - - # second month - unpaid - next_day = settings.day + datetime.timedelta(days=31) - - for supplier in suppliers: - if supplier[0].startswith("Tireless"): - continue - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = next_day - pi.supplier = supplier[0] - pi.append( - "items", - { - "item_code": supplier[1], - "rate": supplier[3], - "qty": 1, - }, - ) - if supplier[0].startswith("Sphere"): - pi.payment_terms_template = None - pi.save() - pi.submit() - # two electric meters / test invoice aggregation - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = next_day - pi.supplier = suppliers[0][0] - pi.append( - "items", - { - "item_code": suppliers[0][1], - "rate": 75.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - # two phone bills / test address splitting - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = settings.day - pi.supplier = suppliers[4][0] - pi.append( - "items", - { - "item_code": suppliers[4][1], - "rate": 122.50, - "qty": 1, - }, - ) - pi.supplier_address = "HIJ Telecom - Burlingame-Billing" - pi.save() - pi.submit() - - # test on-hold invoice - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = settings.day - pi.supplier = suppliers[1][0] - pi.append( - "items", - { - "item_code": suppliers[1][1], - "rate": 4000.00, - "qty": 1, - }, - ) - pi.on_hold = 1 - pi.release_date = settings.day + datetime.timedelta(days=60) - pi.hold_comment = "Testing for on hold invoices" - pi.validate_release_date = types.MethodType( - validate_release_date, pi - ) # allow date to be backdated for testing - pi.save() - pi.submit() - - spi = frappe.get_value( - "Purchase Invoice", - {"supplier": "Cooperative Ag Finance"}, - order_by="posting_date DESC", - ) - rpi = make_debit_note(spi) - rpi.return_against = ( - None # this approach isn't best practice but it allows us to see a negative PI in the check run - ) - rpi.items[0].rate = 500 - rpi.save() - rpi.submit() - - # has discount - recent date to qualify for discount - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = datetime.date.today() - datetime.timedelta(days=7) - pi.supplier = suppliers[3][0] - pi.payment_terms_template = "2% 10 Net 30" - pi.append( - "items", - { - "item_code": suppliers[1][1], - "rate": 200.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - # has discount - amount based discount - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = datetime.date.today() - datetime.timedelta(days=5) - pi.supplier = suppliers[3][0] - pi.payment_terms_template = "$20 10 Net 30" - pi.append( - "items", - { - "item_code": suppliers[1][1], - "rate": 120.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - # hasn't discount - too old - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = datetime.date.today() - datetime.timedelta(days=45) - pi.supplier = suppliers[3][0] - pi.payment_terms_template = "2% 10 Net 30" - pi.append( - "items", - { - "item_code": suppliers[1][1], - "rate": 300.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - # Case last day of discount validity (Day(s) after invoice date) - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = datetime.date.today() - datetime.timedelta(days=10) # Exactly 10 days ago - pi.supplier = suppliers[2][0] - pi.payment_terms_template = "2% 10 Net 30 - Invoice Date" - pi.append( - "items", - { - "item_code": suppliers[2][1], - "rate": 500.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - # Case first day discount expires (Day(s) after invoice date) - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = datetime.date.today() - datetime.timedelta(days=11) # discount expired - pi.supplier = suppliers[2][0] - pi.payment_terms_template = "2% 10 Net 30 - Invoice Date" - pi.append( - "items", - { - "item_code": suppliers[2][1], - "rate": 400.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - # Case "Month(s) after the end of the invoice month" - first_of_month = datetime.date.today().replace(day=1) - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = first_of_month - datetime.timedelta(days=5) # Previous month - pi.supplier = suppliers[1][0] - pi.payment_terms_template = "3% Net 30" - pi.append( - "items", - { - "item_code": suppliers[1][1], - "rate": 250.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - # Case amount-based discount - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = datetime.date.today() - datetime.timedelta(days=5) - pi.supplier = suppliers[0][0] - pi.payment_terms_template = "$20 10 Net 30" - pi.append( - "items", - { - "item_code": suppliers[0][1], - "rate": 100.00, - "qty": 1, - }, - ) - pi.save() - pi.submit() - - -def validate_release_date(self): - pass - - -def config_expense_claim(settings): - try: - travel_expense_account = frappe.get_value( - "Account", {"account_name": "Travel Expenses", "company": settings.company} - ) - travel = frappe.get_doc("Expense Claim Type", "Travel") - travel.append( - "accounts", {"company": settings.company, "default_account": travel_expense_account} - ) - travel.save() - except Exception as e: - pass - - payroll_payable = frappe.db.get_value( - "Account", {"account_name": "Payroll Payable", "company": settings.company} - ) - if payroll_payable: - frappe.db.set_value("Account", payroll_payable, "account_type", "Payable") - - if frappe.db.exists("Account", {"account_name": "Payroll Taxes", "company": settings.company}): - return - pta = frappe.new_doc("Account") - pta.account_name = "Payroll Taxes" - pta.account_number = ( - max( - int(a.account_number or 1) - for a in frappe.get_all("Account", {"is_group": 0}, ["account_number"]) - ) - + 1 - ) - pta.account_type = "Expense Account" - pta.company = settings.company - pta.parent_account = frappe.get_value( - "Account", {"account_name": "Indirect Expenses", "company": settings.company} - ) - pta.save() - - -def create_employees(settings): - for employee_number, employee in enumerate(employees, start=10): - emp = frappe.new_doc("Employee") - emp.first_name = employee[0].split(" ")[0] - emp.last_name = employee[0].split(" ")[1] - emp.employment_type = "Full-time" - emp.company = settings.company - emp.status = "Active" - emp.gender = employee[1] - emp.date_of_birth = employee[2] - emp.date_of_joining = employee[3] - emp.mode_of_payment = "Check" if employee_number % 3 == 0 else "ACH/EFT" - emp.mode_of_payment = "Cash" if employee_number == 10 else emp.mode_of_payment - emp.mode_of_payment = None if employee_number % 4 == 0 else emp.mode_of_payment - emp.expense_approver = "Administrator" - if emp.mode_of_payment == "ACH/EFT": - emp.bank = "Local Bank" - emp.bank_account = f"{employee_number}12345" - emp.save() - - -def create_expense_claim(settings): - cost_center = frappe.get_value("Company", settings.company, "cost_center") - payable_acct = frappe.get_value("Company", settings.company, "default_payable_account") - # first month - paid - ec = frappe.new_doc("Expense Claim") - ec.employee = "HR-EMP-00002" - ec.expense_approver = "Administrator" - ec.approval_status = "Approved" - ec.append( - "expenses", - { - "expense_date": settings.day, - "expense_type": "Travel", - "amount": 50.0, - "sanctioned_amount": 50.0, - "cost_center": cost_center, - }, - ) - ec.posting_date = settings.day - ec.company = settings.company - ec.payable_account = payable_acct - ec.save() - ec.submit() - # second month - open - next_day = settings.day + datetime.timedelta(days=31) - - ec = frappe.new_doc("Expense Claim") - ec.employee = "HR-EMP-00002" - ec.expense_approver = "Administrator" - ec.approval_status = "Approved" - ec.append( - "expenses", - { - "expense_date": next_day, - "expense_type": "Travel", - "amount": 50.0, - "sanctioned_amount": 50.0, - "cost_center": cost_center, - }, - ) - ec.posting_date = next_day - ec.company = settings.company - ec.payable_account = payable_acct - ec.save() - ec.submit() - # two expense claims to test aggregation - ec = frappe.new_doc("Expense Claim") - ec.employee = "HR-EMP-00002" - ec.expense_approver = "Administrator" - ec.approval_status = "Approved" - ec.append( - "expenses", - { - "expense_date": next_day, - "expense_type": "Travel", - "amount": 50.0, - "sanctioned_amount": 50.0, - "cost_center": cost_center, - }, - ) - ec.posting_date = next_day - ec.company = settings.company - ec.payable_account = payable_acct - ec.save() - ec.submit() - - -def create_payroll_journal_entry(settings): - emps = frappe.get_list("Employee", {"company": settings.company}) - cost_center = frappe.get_value("Company", settings.company, "cost_center") - payroll_account = frappe.get_value( - "Account", {"company": settings.company, "account_name": "Payroll Payable", "is_group": 0} - ) - salary_account = frappe.get_value( - "Account", {"company": settings.company, "account_name": "Salary", "is_group": 0} - ) - payroll_expense = frappe.get_value( - "Account", {"company": settings.company, "account_name": "Payroll Taxes", "is_group": 0} - ) - payable_account = frappe.get_value("Company", settings.company, "default_payable_account") - je = frappe.new_doc("Journal Entry") - je.entry_type = "Journal Entry" - je.company = settings.company - je.due_date = je.posting_date = settings.day - total_payroll = 0.0 - for idx, emp in enumerate(emps): - employee_name = frappe.get_value( - "Employee", {"company": settings.company, "name": emp.name}, "employee_name" - ) - je.append( - "accounts", - { - "account": payroll_account, - "bank_account": frappe.get_value("Bank Account", {"account": settings.company_account}), - "party_type": "Employee", - "party": emp.name, - "cost_center": cost_center, - "account_currency": "USD", - "credit": 1000.00, - "credit_in_account_currency": 1000.00, - "debit": 0.00, - "debit_in_account_currency": 0.00, - "user_remark": employee_name + " Paycheck", - "idx": idx + 2, - }, - ) - total_payroll += 1000.00 - je.append( - "accounts", - { - "account": salary_account, - "cost_center": cost_center, - "account_currency": "USD", - "credit": 0.00, - "credit_in_account_currency": 0.00, - "debit": total_payroll, - "debit_in_account_currency": total_payroll, - "idx": 1, - }, - ) - je.append( - "accounts", - { - "account": payroll_expense, - "cost_center": cost_center, - "account_currency": "USD", - "credit": 0.00, - "credit_in_account_currency": 0.00, - "debit": total_payroll * 0.15, - "debit_in_account_currency": total_payroll * 0.15, - }, - ) - je.append( - "accounts", - { - "account": payable_account, - "cost_center": cost_center, - "party_type": "Supplier", - "party": tax_authority[0][0], - "account_currency": "USD", - "credit": total_payroll * 0.15, - "credit_in_account_currency": total_payroll * 0.15, - "debit": 0.00, - "debit_in_account_currency": 0.0, - }, - ) - je.save() - je.submit() - - -""" -Set in check run settings -check_run.test_setup.example_post_processing_hook -""" - - -def example_post_processing_hook(check_run, settings, nacha) -> str: - # check_run: "CheckRun", settings: "CheckRun Settings", nacha: "NACHAFile" # noqa: F722 - b = "$$AAPAACH0094[TEST[NL$$\n" - a = str(nacha) - return b + a - - -def create_extra_invoices(settings): - day = settings.day - for next_day in range(0, 365): - _day = settings.day + datetime.timedelta(days=next_day) - print(_day) - if _day.weekday in (5, 6): - continue - - for supplier in suppliers: - if supplier[0].startswith("Tireless"): - continue - if frappe.get_value("Purchase Invoice", {"posting_date": _day, "supplier": supplier[0]}): - continue - pi = frappe.new_doc("Purchase Invoice") - pi.company = settings.company - pi.set_posting_time = 1 - pi.posting_date = _day - pi.supplier = supplier[0] - pi.append( - "items", - { - "item_code": supplier[1], - "rate": supplier[3], - "qty": 1, - }, - ) - pi.save() - pi.submit() - - -def create_manual_payment_entry(settings): - frappe.db.commit() - party = "Cooperative Ag Finance" - to_pay = 1000.00 - docs = frappe.get_all( - "Purchase Invoice", - {"supplier": party, "grand_total": [">=", to_pay]}, - order_by="name ASC", - limit=1, - ) - pi = frappe.get_doc("Purchase Invoice", docs[0]) - # pi = frappe.get_doc( - # "Purchase Invoice", - # {"supplier": party, "grand_total": [">=", 5000], "posting_date": ["<=", settings.day]} - # ) # posting date filter not working in runtime - pe = frappe.new_doc("Payment Entry") - pe.payment_type = "Pay" - pe.posting_date = add_days(settings.day, 2) - pe.mode_of_payment = "Bank Draft" - pe.company = settings.company - pe.bank_account = frappe.get_value("Bank Account", {"account": settings.company_account}) - pe.paid_from = settings.company_account - pe.paid_to = frappe.get_value( - "Account", {"company": settings.company, "name": ["like", "%Accounts Payable%"]} - ) - pe.paid_to_account_currency = frappe.get_value( - "Account", settings.company_account, "account_currency" - ) - pe.paid_from_account_currency = pe.paid_to_account_currency - pe.reference_no = "via Bank Draft " + str(pe.posting_date) - pe.reference_date = pe.posting_date - pe.party_type = "Supplier" - pe.party = party - pe.paid_amount = to_pay - - pe.append( - "references", - { - "reference_doctype": pi.doctype, - "reference_name": pi.name, - "due_date": pi.due_date, - "total_amount": flt(pi.grand_total), - "outstanding_amount": flt(pi.outstanding_amount), - "allocated_amount": to_pay, - }, - ) - pe.received_amount = to_pay - pe.base_received_amount = to_pay - pe.paid_amount = to_pay - pe.base_paid_amount = to_pay - pe.base_grand_total = to_pay - - pe.save() - pe.submit() +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + +import datetime +import types + +import frappe +from erpnext.accounts.doctype.account.account import update_account_number +from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import make_debit_note +from erpnext.setup.utils import enable_all_roles_and_domains, set_defaults_for_tests +from frappe.desk.page.setup_wizard.setup_wizard import setup_complete +from frappe.utils.data import add_days, flt + +from check_run.tests.fixtures import employees, suppliers, tax_authority + + +def before_test(): + frappe.clear_cache() + today = frappe.utils.getdate() + setup_complete( + { + "currency": "USD", + "full_name": "Administrator", + "company_name": "Chelsea Fruit Co", + "timezone": "America/New_York", + "company_abbr": "CFC", + "domains": ["Distribution"], + "country": "United States", + "fy_start_date": today.replace(month=1, day=1).isoformat(), + "fy_end_date": today.replace(month=12, day=31).isoformat(), + "language": "english", + "company_tagline": "Chelsea Fruit Co", + "email": "support@agritheory.dev", + "password": "admin", + "chart_of_accounts": "Standard with Numbers", + "bank_account": "Primary Checking", + } + ) + enable_all_roles_and_domains() + set_defaults_for_tests() + frappe.db.commit() + create_test_data() + for modu in frappe.get_all("Module Onboarding"): + frappe.db.set_value("Module Onboarding", modu, "is_complete", 1) + frappe.set_value("Website Settings", "Website Settings", "home_page", "login") + + +def create_test_data(): + setup_accounts() + settings = frappe._dict( + { + "day": frappe.utils.getdate().replace(month=1, day=1), + "company": frappe.defaults.get_defaults().get("company"), + "company_account": frappe.get_value( + "Account", + { + "account_type": "Bank", + "company": frappe.defaults.get_defaults().get("company"), + "is_group": 0, + }, + ), + } + ) + create_company_address(settings) + create_previous_fiscal_year(settings) + create_bank_and_bank_account(settings) + create_payment_terms_templates(settings) + create_suppliers(settings) + create_items(settings) + create_invoices(settings) + config_expense_claim(settings) + create_employees(settings) + create_expense_claim(settings) + for month in range(1, 13): + settings.day = settings.day.replace(month=month) + create_payroll_journal_entry(settings) + create_manual_payment_entry(settings) + + +def create_company_address(settings): + company_address = frappe.new_doc("Address") + company_address.title = settings.company + company_address.address_type = "Office" + company_address.address_line1 = "67C Sweeny Street" + company_address.city = "Chelsea" + company_address.state = "MA" + company_address.pincode = "89077" + company_address.is_your_company_address = True + company_address.append("links", {"link_doctype": "Company", "link_name": settings.company}) + company_address.save() + + +def create_previous_fiscal_year(settings): + if frappe.db.exists("Fiscal Year", str(settings.day.year - 1)): + return + current_fiscal_year = frappe.get_doc("Fiscal Year", str(settings.day.year)) + previous_fiscal_year = frappe.new_doc("Fiscal Year") + previous_fiscal_year.year_start_date = current_fiscal_year.year_start_date.replace( + year=current_fiscal_year.year_start_date.year - 1 + ) + previous_fiscal_year.year_end_date = current_fiscal_year.year_end_date.replace( + year=current_fiscal_year.year_end_date.year - 1 + ) + previous_fiscal_year.year = previous_fiscal_year.year_start_date.year + previous_fiscal_year.save() + + +def create_bank_and_bank_account(settings): + if not frappe.db.exists("Mode of Payment", "ACH/EFT"): + mop = frappe.new_doc("Mode of Payment") + mop.mode_of_payment = "ACH/EFT" + mop.enabled = 1 + mop.type = "Electronic" + mop.append( + "accounts", {"company": settings.company, "default_account": settings.company_account} + ) + mop.save() + + wire_transfer = frappe.get_doc("Mode of Payment", "Wire Transfer") + wire_transfer.type = "General" + wire_transfer.append( + "accounts", {"company": settings.company, "default_account": settings.company_account} + ) + wire_transfer.save() + + credit_card = frappe.get_doc("Mode of Payment", "Credit Card") + credit_card.type = "General" + credit_card.append( + "accounts", {"company": settings.company, "default_account": settings.company_account} + ) + credit_card.save() + + bank_draft = frappe.get_doc("Mode of Payment", "Bank Draft") + bank_draft.type = "General" + bank_draft.append( + "accounts", {"company": settings.company, "default_account": settings.company_account} + ) + bank_draft.save() + + check_mop = frappe.get_doc("Mode of Payment", "Check") + check_mop.type = "Bank" + check_mop.append( + "accounts", {"company": settings.company, "default_account": settings.company_account} + ) + check_mop.save() + + if not frappe.db.exists("Bank", "Local Bank"): + bank = frappe.new_doc("Bank") + bank.bank_name = "Local Bank" + bank.aba_number = "07200091" + bank.save() + + if not frappe.db.exists("Bank Account", "Primary Checking - Local Bank"): + bank_account = frappe.new_doc("Bank Account") + bank_account.account_name = "Primary Checking" + bank_account.bank = bank.name + bank_account.is_default = 1 + bank_account.is_company_account = 1 + bank_account.company = settings.company + bank_account.account = settings.company_account + bank_account.check_number = 2500 + bank_account.company_ach_id = "1381655417" + bank_account.bank_account_no = "072000915" + bank_account.branch_code = "07200091" + bank_account.save() + + doc = frappe.new_doc("Journal Entry") + doc.posting_date = settings.day + doc.voucher_type = "Opening Entry" + doc.company = settings.company + opening_balance = 50000.00 + doc.append( + "accounts", {"account": settings.company_account, "debit_in_account_currency": opening_balance} + ) + retained_earnings = frappe.get_value( + "Account", {"account_name": "Retained Earnings", "company": settings.company} + ) + doc.append( + "accounts", {"account": retained_earnings, "credit_in_account_currency": opening_balance} + ) + doc.save() + doc.submit() + + +def setup_accounts(): + frappe.rename_doc( + "Account", "1000 - Application of Funds (Assets) - CFC", "1000 - Assets - CFC", force=True + ) + frappe.rename_doc( + "Account", "2000 - Source of Funds (Liabilities) - CFC", "2000 - Liabilities - CFC", force=True + ) + frappe.rename_doc( + "Account", "1310 - Debtors - CFC", "1310 - Accounts Receivable - CFC", force=True + ) + frappe.rename_doc( + "Account", "2110 - Creditors - CFC", "2110 - Accounts Payable - CFC", force=True + ) + update_account_number("1110 - Cash - CFC", "Petty Cash", account_number="1110") + update_account_number("Primary Checking - CFC", "Primary Checking", account_number="1201") + + +def create_payment_terms_templates(settings): + if not frappe.db.exists("Payment Terms Template", "Net 30"): + pt = frappe.new_doc("Payment Term") + pt.payment_term_name = "Net 30" + pt.due_date_based_on = "Day(s) after invoice date" + pt.invoice_portion = 100 + pt.credit_days = 30 + pt.save() + doc = frappe.new_doc("Payment Terms Template") + doc.template_name = pt.name + doc.append( + "terms", + { + "payment_term": pt.name, + "invoice_portion": pt.invoice_portion, + "due_date_based_on": pt.due_date_based_on, + "credit_days": pt.credit_days, + }, + ) + doc.save() + if not frappe.db.exists("Payment Terms Template", "Due on Receipt"): + pt = frappe.new_doc("Payment Term") + pt.payment_term_name = "Due on Receipt" + pt.due_date_based_on = "Day(s) after invoice date" + pt.invoice_portion = 100 + pt.credit_days = 0 + pt.save() + doc = frappe.new_doc("Payment Terms Template") + doc.template_name = pt.name + doc.append( + "terms", + { + "payment_term": pt.name, + "invoice_portion": pt.invoice_portion, + "due_date_based_on": pt.due_date_based_on, + "credit_days": pt.credit_days, + }, + ) + doc.save() + if not frappe.db.exists("Payment Terms Template", "Net 14"): + pt = frappe.new_doc("Payment Term") + pt.payment_term_name = "Net 14" + pt.due_date_based_on = "Day(s) after invoice date" + pt.invoice_portion = 100 + pt.credit_days = 14 + pt.save() + doc = frappe.new_doc("Payment Terms Template") + doc.template_name = pt.name + doc.append( + "terms", + { + "payment_term": pt.name, + "invoice_portion": pt.invoice_portion, + "due_date_based_on": pt.due_date_based_on, + "credit_days": pt.credit_days, + }, + ) + doc.save() + + if not frappe.db.exists("Payment Terms Template", "18 Month Rental Agreement"): + doc = frappe.new_doc("Payment Terms Template") + doc.template_name = "18 Month Rental Agreement" + for month in range(0, 18): + pt = frappe.new_doc("Payment Term") + pt.payment_term_name = f"Rental Installment {month+1}" + pt.due_date_based_on = "Month(s) after the end of the invoice month" + pt.invoice_portion = 5.555555555555556 + pt.credit_months = month + pt.save() + doc.append( + "terms", + { + "payment_term": pt.name, + "invoice_portion": pt.invoice_portion, + "due_date_based_on": pt.due_date_based_on, + "credit_months": pt.credit_months, + }, + ) + doc.save() + + if not frappe.db.exists("Payment Terms Template", "2% 10 Net 30"): + doc = frappe.new_doc("Payment Terms Template") + doc.template_name = "2% 10 Net 30" + + pt = frappe.new_doc("Payment Term") + pt.payment_term_name = "2% 10 Net 30" + pt.due_date_based_on = "Day(s) after the end of the invoice month" + pt.discount_validity_based_on = "Day(s) after the end of the invoice month" + pt.invoice_portion = 100 + pt.credit_days = 30 + pt.discount_type = "Percentage" + pt.discount = 2.0 + pt.discount_validity = 10 + pt.save() + doc.append( + "terms", + { + "payment_term": pt.name, + "invoice_portion": pt.invoice_portion, + "due_date_based_on": pt.due_date_based_on, + "credit_days": pt.credit_days, + }, + ) + doc.save() + + if not frappe.db.exists("Payment Terms Template", "$20 10 Net 30"): + doc = frappe.new_doc("Payment Terms Template") + doc.template_name = "$20 10 Net 30" + + pt = frappe.new_doc("Payment Term") + pt.payment_term_name = "$20 10 Net 30" + pt.due_date_based_on = "Day(s) after the end of the invoice month" + pt.discount_validity_based_on = "Day(s) after the end of the invoice month" + pt.invoice_portion = 100 + pt.credit_days = 30 + pt.discount_type = "Amount" + pt.discount = 20.0 + pt.discount_validity = 10 + pt.save() + doc.append( + "terms", + { + "payment_term": pt.name, + "invoice_portion": pt.invoice_portion, + "due_date_based_on": pt.due_date_based_on, + "credit_days": pt.credit_days, + }, + ) + doc.save() + + # Payment term with "Day(s) after invoice date" for discount validity + if not frappe.db.exists("Payment Terms Template", "2% 10 Net 30 - Invoice Date"): + doc = frappe.new_doc("Payment Terms Template") + doc.template_name = "2% 10 Net 30 - Invoice Date" + + pt = frappe.new_doc("Payment Term") + pt.payment_term_name = "2% 10 Net 30 - Invoice Date" + pt.due_date_based_on = "Day(s) after invoice date" + pt.discount_validity_based_on = "Day(s) after invoice date" + pt.invoice_portion = 100 + pt.credit_days = 30 + pt.discount_type = "Percentage" + pt.discount = 2.0 + pt.discount_validity = 10 + pt.save() + doc.append( + "terms", + { + "payment_term": pt.name, + "invoice_portion": pt.invoice_portion, + "due_date_based_on": pt.due_date_based_on, + "credit_days": pt.credit_days, + }, + ) + doc.save() + + # Payment term with "Month(s) after the end of the invoice month" for discount validity + if not frappe.db.exists("Payment Terms Template", "3% Net 30"): + doc = frappe.new_doc("Payment Terms Template") + doc.template_name = "3% Net 30" + + pt = frappe.new_doc("Payment Term") + pt.payment_term_name = "3% Net 30" + pt.due_date_based_on = "Month(s) after the end of the invoice month" + pt.discount_validity_based_on = "Month(s) after the end of the invoice month" + pt.invoice_portion = 100 + pt.credit_months = 1 + pt.discount_type = "Percentage" + pt.discount = 3.0 + pt.discount_validity = 1 + pt.save() + doc.append( + "terms", + { + "payment_term": pt.name, + "invoice_portion": pt.invoice_portion, + "due_date_based_on": pt.due_date_based_on, + "credit_months": pt.credit_months, + }, + ) + doc.save() + + +def create_suppliers(settings): + addresses = frappe._dict({}) + for supplier in suppliers + tax_authority: + biz = frappe.new_doc("Supplier") + biz.supplier_name = supplier[0] + biz.supplier_group = "Services" + biz.country = "United States" + biz.supplier_default_mode_of_payment = supplier[2] + if biz.supplier_default_mode_of_payment == "ACH/EFT": + biz.bank = "Local Bank" + biz.bank_account = "123456789" + biz.currency = "USD" + biz.default_price_list = "Standard Buying" + biz.payment_terms = supplier[4] + if supplier[0] == "Tireless Equipment Rental, Inc": + biz.number_of_invoices_per_check_voucher = 1 + biz.save() + + addr = frappe.new_doc("Address") + addr.address_title = f"{supplier[0]} - {supplier[5]['city']}" + addr.address_type = "Billing" + addr.address_line1 = supplier[5]["address_line1"] + addr.city = supplier[5]["city"] + addr.state = supplier[5]["state"] + addr.country = supplier[5]["country"] + addr.pincode = supplier[5]["pincode"] + addr.append("links", {"link_doctype": "Supplier", "link_name": supplier[0]}) + addr.save() + + addr = frappe.new_doc("Address") + addr.address_type = "Billing" + addr.address_title = "HIJ Telecom - Burlingame" + addr.address_line1 = "167 Auto Terrace" + addr.city = "Burlingame" + addr.state = "ME" + addr.country = "United States" + addr.pincode = "79749" + addr.append("links", {"link_doctype": "Supplier", "link_name": "HIJ Telecom, Inc"}) + addr.save() + + +def create_items(settings): + for supplier in suppliers + tax_authority: + item = frappe.new_doc("Item") + item.item_code = item.item_name = supplier[1] + item.item_group = "Services" + item.stock_uom = "Nos" + item.maintain_stock = 0 + item.is_sales_item, item.is_sub_contracted_item, item.include_item_in_manufacturing = 0, 0, 0 + item.grant_commission = 0 + item.is_purchase_item = 1 + item.append("supplier_items", {"supplier": supplier[0]}) + item.append( + "item_defaults", + {"company": settings.company, "default_warehouse": "", "default_supplier": supplier[0]}, + ) + item.save() + + +def create_invoices(settings): + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = settings.day + pi.supplier = "Tireless Equipment Rental, Inc" + pi.append( + "items", + { + "item_code": "Equipment Rental", + "rate": 30000.00, + "qty": 1, + }, + ) + pi.payment_terms = "18 Month Rental Agreement" + pi.save() + pi.submit() + + # first month - already paid + for supplier in suppliers: + if supplier[0].startswith("Tireless"): + continue + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = settings.day + pi.supplier = supplier[0] + pi.append( + "items", + { + "item_code": supplier[1], + "rate": supplier[3], + "qty": 1, + }, + ) + pi.save() + pi.submit() + # two electric meters / test invoice aggregation + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = settings.day + pi.supplier = suppliers[0][0] + pi.append( + "items", + { + "item_code": suppliers[0][1], + "rate": 75.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + # two phone bills / test address splitting + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = settings.day + pi.supplier = suppliers[4][0] + pi.append( + "items", + { + "item_code": suppliers[4][1], + "rate": 122.50, + "qty": 1, + }, + ) + pi.supplier_address = "HIJ Telecom - Burlingame-Billing" + pi.save() + pi.submit() + + # second month - unpaid + next_day = settings.day + datetime.timedelta(days=31) + + for supplier in suppliers: + if supplier[0].startswith("Tireless"): + continue + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = next_day + pi.supplier = supplier[0] + pi.append( + "items", + { + "item_code": supplier[1], + "rate": supplier[3], + "qty": 1, + }, + ) + if supplier[0].startswith("Sphere"): + pi.payment_terms_template = None + pi.save() + pi.submit() + # two electric meters / test invoice aggregation + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = next_day + pi.supplier = suppliers[0][0] + pi.append( + "items", + { + "item_code": suppliers[0][1], + "rate": 75.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + # two phone bills / test address splitting + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = settings.day + pi.supplier = suppliers[4][0] + pi.append( + "items", + { + "item_code": suppliers[4][1], + "rate": 122.50, + "qty": 1, + }, + ) + pi.supplier_address = "HIJ Telecom - Burlingame-Billing" + pi.save() + pi.submit() + + # test on-hold invoice + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = settings.day + pi.supplier = suppliers[1][0] + pi.append( + "items", + { + "item_code": suppliers[1][1], + "rate": 4000.00, + "qty": 1, + }, + ) + pi.on_hold = 1 + pi.release_date = settings.day + datetime.timedelta(days=60) + pi.hold_comment = "Testing for on hold invoices" + pi.validate_release_date = types.MethodType( + validate_release_date, pi + ) # allow date to be backdated for testing + pi.save() + pi.submit() + + spi = frappe.get_value( + "Purchase Invoice", + {"supplier": "Cooperative Ag Finance"}, + order_by="posting_date DESC", + ) + rpi = make_debit_note(spi) + rpi.return_against = ( + None # this approach isn't best practice but it allows us to see a negative PI in the check run + ) + rpi.items[0].rate = 500 + rpi.save() + rpi.submit() + + # has discount - recent date to qualify for discount + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = datetime.date.today() - datetime.timedelta(days=7) + pi.supplier = suppliers[3][0] + pi.payment_terms_template = "2% 10 Net 30" + pi.append( + "items", + { + "item_code": suppliers[1][1], + "rate": 200.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + # has discount - amount based discount + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = datetime.date.today() - datetime.timedelta(days=5) + pi.supplier = suppliers[3][0] + pi.payment_terms_template = "$20 10 Net 30" + pi.append( + "items", + { + "item_code": suppliers[1][1], + "rate": 120.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + # hasn't discount - too old + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = datetime.date.today() - datetime.timedelta(days=45) + pi.supplier = suppliers[3][0] + pi.payment_terms_template = "2% 10 Net 30" + pi.append( + "items", + { + "item_code": suppliers[1][1], + "rate": 300.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + # Case last day of discount validity (Day(s) after invoice date) + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = datetime.date.today() - datetime.timedelta(days=10) # Exactly 10 days ago + pi.supplier = suppliers[2][0] + pi.payment_terms_template = "2% 10 Net 30 - Invoice Date" + pi.append( + "items", + { + "item_code": suppliers[2][1], + "rate": 500.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + # Case first day discount expires (Day(s) after invoice date) + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = datetime.date.today() - datetime.timedelta(days=11) # discount expired + pi.supplier = suppliers[2][0] + pi.payment_terms_template = "2% 10 Net 30 - Invoice Date" + pi.append( + "items", + { + "item_code": suppliers[2][1], + "rate": 400.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + # Case "Month(s) after the end of the invoice month" + first_of_month = datetime.date.today().replace(day=1) + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = first_of_month - datetime.timedelta(days=5) # Previous month + pi.supplier = suppliers[1][0] + pi.payment_terms_template = "3% Net 30" + pi.append( + "items", + { + "item_code": suppliers[1][1], + "rate": 250.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + # Case amount-based discount + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = datetime.date.today() - datetime.timedelta(days=5) + pi.supplier = suppliers[0][0] + pi.payment_terms_template = "$20 10 Net 30" + pi.append( + "items", + { + "item_code": suppliers[0][1], + "rate": 100.00, + "qty": 1, + }, + ) + pi.save() + pi.submit() + + +def validate_release_date(self): + pass + + +def config_expense_claim(settings): + try: + travel_expense_account = frappe.get_value( + "Account", {"account_name": "Travel Expenses", "company": settings.company} + ) + travel = frappe.get_doc("Expense Claim Type", "Travel") + travel.append( + "accounts", {"company": settings.company, "default_account": travel_expense_account} + ) + travel.save() + except Exception as e: + pass + + payroll_payable = frappe.db.get_value( + "Account", {"account_name": "Payroll Payable", "company": settings.company} + ) + if payroll_payable: + frappe.db.set_value("Account", payroll_payable, "account_type", "Payable") + + if frappe.db.exists("Account", {"account_name": "Payroll Taxes", "company": settings.company}): + return + pta = frappe.new_doc("Account") + pta.account_name = "Payroll Taxes" + pta.account_number = ( + max( + int(a.account_number or 1) + for a in frappe.get_all("Account", {"is_group": 0}, ["account_number"]) + ) + + 1 + ) + pta.account_type = "Expense Account" + pta.company = settings.company + pta.parent_account = frappe.get_value( + "Account", {"account_name": "Indirect Expenses", "company": settings.company} + ) + pta.save() + + +def create_employees(settings): + for employee_number, employee in enumerate(employees, start=10): + emp = frappe.new_doc("Employee") + emp.first_name = employee[0].split(" ")[0] + emp.last_name = employee[0].split(" ")[1] + emp.employment_type = "Full-time" + emp.company = settings.company + emp.status = "Active" + emp.gender = employee[1] + emp.date_of_birth = employee[2] + emp.date_of_joining = employee[3] + emp.mode_of_payment = "Check" if employee_number % 3 == 0 else "ACH/EFT" + emp.mode_of_payment = "Cash" if employee_number == 10 else emp.mode_of_payment + emp.mode_of_payment = None if employee_number % 4 == 0 else emp.mode_of_payment + emp.expense_approver = "Administrator" + if emp.mode_of_payment == "ACH/EFT": + emp.bank = "Local Bank" + emp.bank_account = f"{employee_number}12345" + emp.save() + + +def create_expense_claim(settings): + cost_center = frappe.get_value("Company", settings.company, "cost_center") + payable_acct = frappe.get_value("Company", settings.company, "default_payable_account") + # first month - paid + ec = frappe.new_doc("Expense Claim") + ec.employee = "HR-EMP-00002" + ec.expense_approver = "Administrator" + ec.approval_status = "Approved" + ec.append( + "expenses", + { + "expense_date": settings.day, + "expense_type": "Travel", + "amount": 50.0, + "sanctioned_amount": 50.0, + "cost_center": cost_center, + }, + ) + ec.posting_date = settings.day + ec.company = settings.company + ec.payable_account = payable_acct + ec.save() + ec.submit() + # second month - open + next_day = settings.day + datetime.timedelta(days=31) + + ec = frappe.new_doc("Expense Claim") + ec.employee = "HR-EMP-00002" + ec.expense_approver = "Administrator" + ec.approval_status = "Approved" + ec.append( + "expenses", + { + "expense_date": next_day, + "expense_type": "Travel", + "amount": 50.0, + "sanctioned_amount": 50.0, + "cost_center": cost_center, + }, + ) + ec.posting_date = next_day + ec.company = settings.company + ec.payable_account = payable_acct + ec.save() + ec.submit() + # two expense claims to test aggregation + ec = frappe.new_doc("Expense Claim") + ec.employee = "HR-EMP-00002" + ec.expense_approver = "Administrator" + ec.approval_status = "Approved" + ec.append( + "expenses", + { + "expense_date": next_day, + "expense_type": "Travel", + "amount": 50.0, + "sanctioned_amount": 50.0, + "cost_center": cost_center, + }, + ) + ec.posting_date = next_day + ec.company = settings.company + ec.payable_account = payable_acct + ec.save() + ec.submit() + + +def create_payroll_journal_entry(settings): + emps = frappe.get_list("Employee", {"company": settings.company}) + cost_center = frappe.get_value("Company", settings.company, "cost_center") + payroll_account = frappe.get_value( + "Account", {"company": settings.company, "account_name": "Payroll Payable", "is_group": 0} + ) + salary_account = frappe.get_value( + "Account", {"company": settings.company, "account_name": "Salary", "is_group": 0} + ) + payroll_expense = frappe.get_value( + "Account", {"company": settings.company, "account_name": "Payroll Taxes", "is_group": 0} + ) + payable_account = frappe.get_value("Company", settings.company, "default_payable_account") + je = frappe.new_doc("Journal Entry") + je.entry_type = "Journal Entry" + je.company = settings.company + je.due_date = je.posting_date = settings.day + total_payroll = 0.0 + for idx, emp in enumerate(emps): + employee_name = frappe.get_value( + "Employee", {"company": settings.company, "name": emp.name}, "employee_name" + ) + je.append( + "accounts", + { + "account": payroll_account, + "bank_account": frappe.get_value("Bank Account", {"account": settings.company_account}), + "party_type": "Employee", + "party": emp.name, + "cost_center": cost_center, + "account_currency": "USD", + "credit": 1000.00, + "credit_in_account_currency": 1000.00, + "debit": 0.00, + "debit_in_account_currency": 0.00, + "user_remark": employee_name + " Paycheck", + "idx": idx + 2, + }, + ) + total_payroll += 1000.00 + je.append( + "accounts", + { + "account": salary_account, + "cost_center": cost_center, + "account_currency": "USD", + "credit": 0.00, + "credit_in_account_currency": 0.00, + "debit": total_payroll, + "debit_in_account_currency": total_payroll, + "idx": 1, + }, + ) + je.append( + "accounts", + { + "account": payroll_expense, + "cost_center": cost_center, + "account_currency": "USD", + "credit": 0.00, + "credit_in_account_currency": 0.00, + "debit": total_payroll * 0.15, + "debit_in_account_currency": total_payroll * 0.15, + }, + ) + je.append( + "accounts", + { + "account": payable_account, + "cost_center": cost_center, + "party_type": "Supplier", + "party": tax_authority[0][0], + "account_currency": "USD", + "credit": total_payroll * 0.15, + "credit_in_account_currency": total_payroll * 0.15, + "debit": 0.00, + "debit_in_account_currency": 0.0, + }, + ) + je.save() + je.submit() + + +""" +Set in check run settings +check_run.test_setup.example_post_processing_hook +""" + + +def example_post_processing_hook(check_run, settings, nacha) -> str: + # check_run: "CheckRun", settings: "CheckRun Settings", nacha: "NACHAFile" # noqa: F722 + b = "$$AAPAACH0094[TEST[NL$$\n" + a = str(nacha) + return b + a + + +def create_extra_invoices(settings): + day = settings.day + for next_day in range(0, 365): + _day = settings.day + datetime.timedelta(days=next_day) + print(_day) + if _day.weekday in (5, 6): + continue + + for supplier in suppliers: + if supplier[0].startswith("Tireless"): + continue + if frappe.get_value("Purchase Invoice", {"posting_date": _day, "supplier": supplier[0]}): + continue + pi = frappe.new_doc("Purchase Invoice") + pi.company = settings.company + pi.set_posting_time = 1 + pi.posting_date = _day + pi.supplier = supplier[0] + pi.append( + "items", + { + "item_code": supplier[1], + "rate": supplier[3], + "qty": 1, + }, + ) + pi.save() + pi.submit() + + +def create_manual_payment_entry(settings): + frappe.db.commit() + party = "Cooperative Ag Finance" + to_pay = 1000.00 + docs = frappe.get_all( + "Purchase Invoice", + {"supplier": party, "grand_total": [">=", to_pay]}, + order_by="name ASC", + limit=1, + ) + pi = frappe.get_doc("Purchase Invoice", docs[0]) + # pi = frappe.get_doc( + # "Purchase Invoice", + # {"supplier": party, "grand_total": [">=", 5000], "posting_date": ["<=", settings.day]} + # ) # posting date filter not working in runtime + pe = frappe.new_doc("Payment Entry") + pe.payment_type = "Pay" + pe.posting_date = add_days(settings.day, 2) + pe.mode_of_payment = "Bank Draft" + pe.company = settings.company + pe.bank_account = frappe.get_value("Bank Account", {"account": settings.company_account}) + pe.paid_from = settings.company_account + pe.paid_to = frappe.get_value( + "Account", {"company": settings.company, "name": ["like", "%Accounts Payable%"]} + ) + pe.paid_to_account_currency = frappe.get_value( + "Account", settings.company_account, "account_currency" + ) + pe.paid_from_account_currency = pe.paid_to_account_currency + pe.reference_no = "via Bank Draft " + str(pe.posting_date) + pe.reference_date = pe.posting_date + pe.party_type = "Supplier" + pe.party = party + pe.paid_amount = to_pay + + pe.append( + "references", + { + "reference_doctype": pi.doctype, + "reference_name": pi.name, + "due_date": pi.due_date, + "total_amount": flt(pi.grand_total), + "outstanding_amount": flt(pi.outstanding_amount), + "allocated_amount": to_pay, + }, + ) + pe.received_amount = to_pay + pe.base_received_amount = to_pay + pe.paid_amount = to_pay + pe.base_paid_amount = to_pay + pe.base_grand_total = to_pay + + pe.save() + pe.submit() diff --git a/docs/achgeneration.md b/docs/achgeneration.md index dbbbf8d1..39bd9330 100644 --- a/docs/achgeneration.md +++ b/docs/achgeneration.md @@ -1,5 +1,13 @@ + + # ACH Generation + + + For electronic bank transfers, banking institutions require specifically-formatted plain-text files to encode all necessary information. This includes data about the type of payment, the parties, their bank accounts, and payment amounts. These files conform to Automated Clearing House (ACH) standards, which is an electronic-funds transfer system run by the National Automated Clearing House Association (NACHA). ACH files are intended to represent electronic inter-bank transactions. A Check Run will automatically generate this on demand, but only if the run includes payments using an "Electronic" Mode of Payment. See the [configuration page](./configuration.md) for details on how to set the `Mode of Payment` `type` field to mark it as an electronic bank transfer. diff --git a/docs/configuration.md b/docs/configuration.md index 1e8833b6..86921c07 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -3,6 +3,11 @@ For license information, please see license.txt--> # Configuration + + + ## Banks and Bank Accounts The Check Run feature requires at least one `Bank` and `Bank Account` defined for the Company. These can be set up under `Accounting > Bank` and `Accounting > Bank Account`, respectively. diff --git a/docs/exampledata.md b/docs/exampledata.md index 02945182..971f6179 100644 --- a/docs/exampledata.md +++ b/docs/exampledata.md @@ -1,5 +1,13 @@ + + # Using the Example Data to Experiment with Check Run + + + The Check Run application comes with a `test_setup.py` script that is completely optional to use. If you execute the script, it populates your ERPNext site with demo business data for a fictitious company called Chelsea Fruit Co. The data enable you to experiment with and test the Check Run application's functionality before installing the app into your ERPNext site. It's recommended to install the demo data into its own site to avoid potential interference with the configuration or data in your organization's ERPNext site. diff --git a/docs/exampleprint.md b/docs/exampleprint.md index b6733525..59292a50 100644 --- a/docs/exampleprint.md +++ b/docs/exampleprint.md @@ -1,5 +1,13 @@ + + # Example Print Format: Voucher Check + + + To take advantage of Check Run's check printing functionality, you'll need to set up a print format in ERPNext. Print formats are as unique as the organizations using ERPNext, so a voucher check print format serves as an example template. It can be a starting point from which to customize to suit your needs. The example print format included with this application can be found in the Print Format List under Example Voucher. It is disabled by default. diff --git a/docs/index.md b/docs/index.md index 56f0dd6f..ce9aacaf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,13 @@ + + # Check Run Documentation + + + The Check Run application extends ERPNext[^1] with several payables-related utilities. These include Check Run (a single-page payment mechanism), check printing, and a bank-friendly report. The Check Run feature collects all outstanding payables for a given company and account head. It defaults to returning payables up to the current date, but this can be adjusted as needed. The user then selects the invoices to pay and the payment method. On submission, the form creates payment entries that post against the specified bank account, and gives the user the option to print checks. diff --git a/docs/installationguide.md b/docs/installationguide.md index 97cee03a..daf8d9db 100644 --- a/docs/installationguide.md +++ b/docs/installationguide.md @@ -1,5 +1,13 @@ + + # Check Run Installation Guide + + + ## Developer Setup First, set up a new bench and substitute a path to the python version to use. Python should be 3.8 latest for V13 and 3.10 latest for V14. These instructions use [pyenv](https://github.com/pyenv/pyenv) for managing environments. diff --git a/docs/payment_entry.md b/docs/payment_entry.md index 5ba15e25..35ab030e 100644 --- a/docs/payment_entry.md +++ b/docs/payment_entry.md @@ -1,13 +1,21 @@ -# Payment Entry -## Auto-Increment Check Number -The Check Run application will automatically fetch and increment check numbers, the latest number is stored in the Bank Account doctype. Both Mode of Payment and Company Bank Account are required fields to fetch the data. As long as the number provided is an integer it will save it to the linked Bank Account record. - -## Quick Check -This setting on Bank Account automatically fetches the Bank Account into the Payment Entry. This allows for paying a single Purchase Invoice with the normal Create => Payment workflow without selecting any additional information. - -![Screen shot showing Bank Account Settings](./assets/BankAccount.png) - -## Additional Customizations -Check Run takes the opinion that there is no scenario where it it appropriate to cut a check without providing a reference document. Payment References has been customized to be required unless the Payment Entry is of type 'Internal Transfer'. - -Since the Purchase Invoices displayed in a Check Run are automatically split by their Payment Terms (if the invoice has a defined Payment Schedule), it's important that a Payment Entry for a portion of an invoice made outside of a Check Run properly links a Payment Reference to a Payment Term. Check Run includes a validation that attempts to fill this in, and warns the user to review. For more information, refer to the "Considerations for Purchase Invoices with Payment Schedules" section on the [Settings page](./settings.md). + + +# Payment Entry + + + +## Auto-Increment Check Number +The Check Run application will automatically fetch and increment check numbers, the latest number is stored in the Bank Account doctype. Both Mode of Payment and Company Bank Account are required fields to fetch the data. As long as the number provided is an integer it will save it to the linked Bank Account record. + +## Quick Check +This setting on Bank Account automatically fetches the Bank Account into the Payment Entry. This allows for paying a single Purchase Invoice with the normal Create => Payment workflow without selecting any additional information. + +![Screen shot showing Bank Account Settings](./assets/BankAccount.png) + +## Additional Customizations +Check Run takes the opinion that there is no scenario where it it appropriate to cut a check without providing a reference document. Payment References has been customized to be required unless the Payment Entry is of type 'Internal Transfer'. + +Since the Purchase Invoices displayed in a Check Run are automatically split by their Payment Terms (if the invoice has a defined Payment Schedule), it's important that a Payment Entry for a portion of an invoice made outside of a Check Run properly links a Payment Reference to a Payment Term. Check Run includes a validation that attempts to fill this in, and warns the user to review. For more information, refer to the "Considerations for Purchase Invoices with Payment Schedules" section on the [Settings page](./settings.md). diff --git a/docs/permissions.md b/docs/permissions.md index 17b52d08..ba360cc6 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -1,5 +1,13 @@ + + # Default Permissions and Workflow + + + It's strongly recommended that you set system permissions to limit which users can see and execute a Check Run. The only permission the application enforces is that a user must have a permission level in ERPNext to create payment entries in order to perform a Check Run. Additionally, only the first user to access a draft Check Run doctype can edit it. See the [ERPNext documentation page](https://docs.erpnext.com/docs/v13/user/manual/en/setting-up/users-and-permissions) for more information about user and role permissions. diff --git a/docs/positivepay.md b/docs/positivepay.md index c095d8c9..7c6bc721 100644 --- a/docs/positivepay.md +++ b/docs/positivepay.md @@ -1,5 +1,13 @@ + + # Positive Pay Report + + + The Check Run application includes a new Positive Pay report. This report generates a bank-friendly summary of check payments for a given bank account and period. To access the report, type "Report Positive Pay" into the AwesomeBar. Enter the bank account, start date, and end date. The report will display a table showing the check date, check number, and party name for all checks against the bank account within the specified time period. diff --git a/docs/renderpdfsequence.md b/docs/renderpdfsequence.md index f46ebca5..d1bacbe8 100644 --- a/docs/renderpdfsequence.md +++ b/docs/renderpdfsequence.md @@ -1,5 +1,13 @@ + + # Render PDF Sequence + + + After a Check Run has been submitted, it will begin rendering the Checks it needs to print. Even on powerful systems it can take several minutes to render checks. The Check Run creates a new Folder in the File Manager for PDFs. These will be linked to the Check Run but removed when the user confirms they have printed correctly. ![Screen shot showing options to "Confirm Print" if the Checks printed properly, or "Re-Print Checks" if not.](./assets/PrintConfirmation.png) \ No newline at end of file diff --git a/docs/settings.md b/docs/settings.md index 5bd74765..be93e475 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -3,6 +3,11 @@ For license information, please see license.txt--> # Check Run Settings + + + A `Check Run Setting` entry determines the behavior in a Check Run for a specific bank account/payable account combination. You will need to confirm separate settings for every bank account-payable account combination that you plan to use in a Check Run. ![Screen shot of the Check Run Settings listview with two entries - one for the Local Bank and Payroll Payable combination and the other for the Local Bank and Accounts Payable combination.](./assets/SettingsList.png) diff --git a/docs/translations.md b/docs/translations.md index c33e24a3..4f627d30 100644 --- a/docs/translations.md +++ b/docs/translations.md @@ -1,5 +1,13 @@ + + # Translations + + + The Check Run application currently offers a Canadian regionalization. To utilize this feature, Canadian users should select the "English (United Kingdom)" (`en-GB`) language option under their user settings. Contributions for other translations are welcome. diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..d841c82e --- /dev/null +++ b/poetry.lock @@ -0,0 +1,1037 @@ +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. + +[[package]] +name = "atnacha" +version = "0.1.0" +description = "NACHA file generation" +optional = false +python-versions = ">=3.10,<4.0" +groups = ["main"] +files = [] +develop = false + +[package.source] +type = "git" +url = "https://github.com/AgriTheory/atnacha.git" +reference = "HEAD" +resolved_reference = "df4286860dd5d6f611a79f033b77fa9f4362063a" + +[[package]] +name = "cffi" +version = "2.0.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "platform_python_implementation != \"PyPy\"" +files = [ + {file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"}, + {file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb"}, + {file = "cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a"}, + {file = "cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"}, + {file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"}, + {file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"}, + {file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"}, + {file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"}, + {file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"}, + {file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"}, + {file = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"}, + {file = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"}, + {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"}, + {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"}, + {file = "cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"}, + {file = "cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"}, + {file = "cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"}, + {file = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"}, + {file = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"}, + {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"}, + {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"}, + {file = "cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"}, + {file = "cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"}, + {file = "cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"}, + {file = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"}, + {file = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"}, + {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"}, + {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"}, + {file = "cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"}, + {file = "cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"}, + {file = "cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"}, + {file = "cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"}, + {file = "cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322"}, + {file = "cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a"}, + {file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"}, + {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}, +] + +[package.dependencies] +pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, + {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, + {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] +markers = "sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coverage" +version = "7.13.4" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415"}, + {file = "coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9"}, + {file = "coverage-7.13.4-cp310-cp310-win32.whl", hash = "sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf"}, + {file = "coverage-7.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95"}, + {file = "coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053"}, + {file = "coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9"}, + {file = "coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9"}, + {file = "coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f"}, + {file = "coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f"}, + {file = "coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459"}, + {file = "coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0"}, + {file = "coverage-7.13.4-cp312-cp312-win32.whl", hash = "sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246"}, + {file = "coverage-7.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126"}, + {file = "coverage-7.13.4-cp312-cp312-win_arm64.whl", hash = "sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d"}, + {file = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}, + {file = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}, + {file = "coverage-7.13.4-cp313-cp313-win32.whl", hash = "sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}, + {file = "coverage-7.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}, + {file = "coverage-7.13.4-cp313-cp313-win_arm64.whl", hash = "sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}, + {file = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}, + {file = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}, + {file = "coverage-7.13.4-cp313-cp313t-win32.whl", hash = "sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}, + {file = "coverage-7.13.4-cp313-cp313t-win_amd64.whl", hash = "sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}, + {file = "coverage-7.13.4-cp313-cp313t-win_arm64.whl", hash = "sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}, + {file = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}, + {file = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}, + {file = "coverage-7.13.4-cp314-cp314-win32.whl", hash = "sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}, + {file = "coverage-7.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}, + {file = "coverage-7.13.4-cp314-cp314-win_arm64.whl", hash = "sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}, + {file = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}, + {file = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}, + {file = "coverage-7.13.4-cp314-cp314t-win32.whl", hash = "sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}, + {file = "coverage-7.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}, + {file = "coverage-7.13.4-cp314-cp314t-win_arm64.whl", hash = "sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}, + {file = "coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}, + {file = "coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli ; python_full_version <= \"3.11.0a6\""] + +[[package]] +name = "cryptography" +version = "46.0.5" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.8" +groups = ["main"] +files = [ + {file = "cryptography-46.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731"}, + {file = "cryptography-46.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82"}, + {file = "cryptography-46.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1"}, + {file = "cryptography-46.0.5-cp311-abi3-win32.whl", hash = "sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48"}, + {file = "cryptography-46.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4"}, + {file = "cryptography-46.0.5-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663"}, + {file = "cryptography-46.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826"}, + {file = "cryptography-46.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d"}, + {file = "cryptography-46.0.5-cp314-cp314t-win32.whl", hash = "sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a"}, + {file = "cryptography-46.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4"}, + {file = "cryptography-46.0.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c"}, + {file = "cryptography-46.0.5-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4"}, + {file = "cryptography-46.0.5-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9"}, + {file = "cryptography-46.0.5-cp38-abi3-win32.whl", hash = "sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72"}, + {file = "cryptography-46.0.5-cp38-abi3-win_amd64.whl", hash = "sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7"}, + {file = "cryptography-46.0.5.tar.gz", hash = "sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d"}, +] + +[package.dependencies] +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} +typing-extensions = {version = ">=4.13.2", markers = "python_full_version < \"3.11.0\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.5)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +markers = "python_version == \"3.10\"" +files = [ + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "iniconfig" +version = "2.3.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, + {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, +] + +[[package]] +name = "librt" +version = "0.8.1" +description = "Mypyc runtime library" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "platform_python_implementation != \"PyPy\"" +files = [ + {file = "librt-0.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc"}, + {file = "librt-0.8.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7"}, + {file = "librt-0.8.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6"}, + {file = "librt-0.8.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0"}, + {file = "librt-0.8.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b"}, + {file = "librt-0.8.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6"}, + {file = "librt-0.8.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71"}, + {file = "librt-0.8.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7"}, + {file = "librt-0.8.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05"}, + {file = "librt-0.8.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891"}, + {file = "librt-0.8.1-cp310-cp310-win32.whl", hash = "sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7"}, + {file = "librt-0.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2"}, + {file = "librt-0.8.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd"}, + {file = "librt-0.8.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965"}, + {file = "librt-0.8.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da"}, + {file = "librt-0.8.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0"}, + {file = "librt-0.8.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e"}, + {file = "librt-0.8.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3"}, + {file = "librt-0.8.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac"}, + {file = "librt-0.8.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596"}, + {file = "librt-0.8.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99"}, + {file = "librt-0.8.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe"}, + {file = "librt-0.8.1-cp311-cp311-win32.whl", hash = "sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb"}, + {file = "librt-0.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b"}, + {file = "librt-0.8.1-cp311-cp311-win_arm64.whl", hash = "sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9"}, + {file = "librt-0.8.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a"}, + {file = "librt-0.8.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9"}, + {file = "librt-0.8.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb"}, + {file = "librt-0.8.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d"}, + {file = "librt-0.8.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7"}, + {file = "librt-0.8.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440"}, + {file = "librt-0.8.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9"}, + {file = "librt-0.8.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972"}, + {file = "librt-0.8.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921"}, + {file = "librt-0.8.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0"}, + {file = "librt-0.8.1-cp312-cp312-win32.whl", hash = "sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a"}, + {file = "librt-0.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444"}, + {file = "librt-0.8.1-cp312-cp312-win_arm64.whl", hash = "sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d"}, + {file = "librt-0.8.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35"}, + {file = "librt-0.8.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583"}, + {file = "librt-0.8.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c"}, + {file = "librt-0.8.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04"}, + {file = "librt-0.8.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363"}, + {file = "librt-0.8.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0"}, + {file = "librt-0.8.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012"}, + {file = "librt-0.8.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb"}, + {file = "librt-0.8.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b"}, + {file = "librt-0.8.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d"}, + {file = "librt-0.8.1-cp313-cp313-win32.whl", hash = "sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a"}, + {file = "librt-0.8.1-cp313-cp313-win_amd64.whl", hash = "sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79"}, + {file = "librt-0.8.1-cp313-cp313-win_arm64.whl", hash = "sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0"}, + {file = "librt-0.8.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f"}, + {file = "librt-0.8.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c"}, + {file = "librt-0.8.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc"}, + {file = "librt-0.8.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c"}, + {file = "librt-0.8.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3"}, + {file = "librt-0.8.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14"}, + {file = "librt-0.8.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7"}, + {file = "librt-0.8.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6"}, + {file = "librt-0.8.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071"}, + {file = "librt-0.8.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78"}, + {file = "librt-0.8.1-cp314-cp314-win32.whl", hash = "sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023"}, + {file = "librt-0.8.1-cp314-cp314-win_amd64.whl", hash = "sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730"}, + {file = "librt-0.8.1-cp314-cp314-win_arm64.whl", hash = "sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3"}, + {file = "librt-0.8.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1"}, + {file = "librt-0.8.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee"}, + {file = "librt-0.8.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7"}, + {file = "librt-0.8.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040"}, + {file = "librt-0.8.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e"}, + {file = "librt-0.8.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732"}, + {file = "librt-0.8.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624"}, + {file = "librt-0.8.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4"}, + {file = "librt-0.8.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382"}, + {file = "librt-0.8.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994"}, + {file = "librt-0.8.1-cp314-cp314t-win32.whl", hash = "sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a"}, + {file = "librt-0.8.1-cp314-cp314t-win_amd64.whl", hash = "sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4"}, + {file = "librt-0.8.1-cp314-cp314t-win_arm64.whl", hash = "sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61"}, + {file = "librt-0.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac"}, + {file = "librt-0.8.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed"}, + {file = "librt-0.8.1-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd"}, + {file = "librt-0.8.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851"}, + {file = "librt-0.8.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128"}, + {file = "librt-0.8.1-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac"}, + {file = "librt-0.8.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551"}, + {file = "librt-0.8.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5"}, + {file = "librt-0.8.1-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6"}, + {file = "librt-0.8.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed"}, + {file = "librt-0.8.1-cp39-cp39-win32.whl", hash = "sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc"}, + {file = "librt-0.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7"}, + {file = "librt-0.8.1.tar.gz", hash = "sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73"}, +] + +[[package]] +name = "mypy" +version = "1.19.1" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec"}, + {file = "mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b"}, + {file = "mypy-1.19.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6"}, + {file = "mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74"}, + {file = "mypy-1.19.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1"}, + {file = "mypy-1.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac"}, + {file = "mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288"}, + {file = "mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab"}, + {file = "mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6"}, + {file = "mypy-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331"}, + {file = "mypy-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925"}, + {file = "mypy-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042"}, + {file = "mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1"}, + {file = "mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e"}, + {file = "mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2"}, + {file = "mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8"}, + {file = "mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a"}, + {file = "mypy-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13"}, + {file = "mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250"}, + {file = "mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b"}, + {file = "mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e"}, + {file = "mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef"}, + {file = "mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75"}, + {file = "mypy-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd"}, + {file = "mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1"}, + {file = "mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718"}, + {file = "mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b"}, + {file = "mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045"}, + {file = "mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957"}, + {file = "mypy-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f"}, + {file = "mypy-1.19.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3"}, + {file = "mypy-1.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a"}, + {file = "mypy-1.19.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67"}, + {file = "mypy-1.19.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e"}, + {file = "mypy-1.19.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376"}, + {file = "mypy-1.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24"}, + {file = "mypy-1.19.1-py3-none-any.whl", hash = "sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247"}, + {file = "mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba"}, +] + +[package.dependencies] +librt = {version = ">=0.6.2", markers = "platform_python_implementation != \"PyPy\""} +mypy_extensions = ">=1.0.0" +pathspec = ">=0.9.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing_extensions = ">=4.6.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, +] + +[[package]] +name = "packaging" +version = "26.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, +] + +[[package]] +name = "pathspec" +version = "1.0.4" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"}, + {file = "pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645"}, +] + +[package.extras] +hyperscan = ["hyperscan (>=0.7)"] +optional = ["typing-extensions (>=4)"] +re2 = ["google-re2 (>=1.1)"] +tests = ["pytest (>=9)", "typing-extensions (>=4.15)"] + +[[package]] +name = "pdfminer-six" +version = "20251230" +description = "PDF parser and analyzer" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "pdfminer_six-20251230-py3-none-any.whl", hash = "sha256:9ff2e3466a7dfc6de6fd779478850b6b7c2d9e9405aa2a5869376a822771f485"}, + {file = "pdfminer_six-20251230.tar.gz", hash = "sha256:e8f68a14c57e00c2d7276d26519ea64be1b48f91db1cdc776faa80528ca06c1e"}, +] + +[package.dependencies] +charset-normalizer = ">=2.0.0" +cryptography = ">=36.0.0" + +[package.extras] +image = ["Pillow"] + +[[package]] +name = "pdfplumber" +version = "0.11.9" +description = "Plumb a PDF for detailed information about each char, rectangle, and line." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pdfplumber-0.11.9-py3-none-any.whl", hash = "sha256:33ec5580959ba524e9100138746e090879504c42955df1b8a997604dd326c443"}, + {file = "pdfplumber-0.11.9.tar.gz", hash = "sha256:481224b678b2bbdbf376e2c39bf914144eef7c3d301b4a28eebf0f7f6109d6dc"}, +] + +[package.dependencies] +"pdfminer.six" = "20251230" +Pillow = ">=9.1" +pypdfium2 = ">=4.18.0" + +[[package]] +name = "pillow" +version = "12.1.1" +description = "Python Imaging Library (fork)" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0"}, + {file = "pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4"}, + {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e"}, + {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff"}, + {file = "pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40"}, + {file = "pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23"}, + {file = "pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9"}, + {file = "pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32"}, + {file = "pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b"}, + {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5"}, + {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d"}, + {file = "pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c"}, + {file = "pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563"}, + {file = "pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80"}, + {file = "pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052"}, + {file = "pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0"}, + {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3"}, + {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35"}, + {file = "pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a"}, + {file = "pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6"}, + {file = "pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6"}, + {file = "pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60"}, + {file = "pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717"}, + {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a"}, + {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029"}, + {file = "pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b"}, + {file = "pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1"}, + {file = "pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a"}, + {file = "pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da"}, + {file = "pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13"}, + {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf"}, + {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524"}, + {file = "pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986"}, + {file = "pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c"}, + {file = "pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642"}, + {file = "pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd"}, + {file = "pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e"}, + {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0"}, + {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb"}, + {file = "pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f"}, + {file = "pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15"}, + {file = "pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f"}, + {file = "pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8"}, + {file = "pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586"}, + {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce"}, + {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8"}, + {file = "pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36"}, + {file = "pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b"}, + {file = "pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e"}, + {file = "pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +test-arrow = ["arro3-compute", "arro3-core", "nanoarrow", "pyarrow"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma (>=5)", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] +xmp = ["defusedxml"] + +[[package]] +name = "pluggy" +version = "1.6.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["coverage", "pytest", "pytest-benchmark"] + +[[package]] +name = "pycparser" +version = "3.0" +description = "C parser in Python" +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "platform_python_implementation != \"PyPy\" and implementation_name != \"PyPy\"" +files = [ + {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, + {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, +] + +[[package]] +name = "pygments" +version = "2.19.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, + {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pypdfium2" +version = "5.5.0" +description = "Python bindings to PDFium" +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "pypdfium2-5.5.0-py3-none-android_23_arm64_v8a.whl", hash = "sha256:414f0b4aef7413e04df7355043fb752f2efb6f9777e04fd880d302612dacf89f"}, + {file = "pypdfium2-5.5.0-py3-none-android_23_armeabi_v7a.whl", hash = "sha256:126ff8b131d12f16ce96b3e85b7f413e5073212be06b571f157fe11ad221c274"}, + {file = "pypdfium2-5.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0770bd3f0be5c68443fc4017e43b1b1fe8f36877481cab70fd29b68b2c362e1b"}, + {file = "pypdfium2-5.5.0-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:5ab41a3b9953d9be44be35c36a2340f1d67c602db98a0d6f70006610871ae43a"}, + {file = "pypdfium2-5.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2492a22c3126a004cee2fa208ea4aa03ede2c7e205d05814934ab18f83d073e9"}, + {file = "pypdfium2-5.5.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:83ff93e08b1fadb00040564e2eccc99147fc1a632ba5daff745126b373d78446"}, + {file = "pypdfium2-5.5.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7e85de3332bedf8e5f157c248063b4eaf968660e1e490353b6e581d9f96a4c6"}, + {file = "pypdfium2-5.5.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e258365f34b6e334bb415e44dd9b1ee78a6e525bf854a1e74af67af7ede7555b"}, + {file = "pypdfium2-5.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bec21d833404ca771f02fa5cefb0b73e2148f05cbdb3b5b9989bdd51d9b5cbac"}, + {file = "pypdfium2-5.5.0-py3-none-manylinux_2_27_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1dd6ccbe1b5e2e778e8b021e47f9485b4fd42eaa6c9bdda2631641724e1fcc04"}, + {file = "pypdfium2-5.5.0-py3-none-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:da3eada345570cec5e34872d1472d4ac542f0e650ccdb6c2eac08ae1a5f07c82"}, + {file = "pypdfium2-5.5.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a087fb4088c7433fd3d78833dbe42cfb66df3d5ac98e3edf66110520fb33c0f0"}, + {file = "pypdfium2-5.5.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e6418cdc500ef85a90319f9bc7f1c54fc133460379f509429403225d8a4c157f"}, + {file = "pypdfium2-5.5.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:8f7b66eedfac26eb2df4b00936e081b0a1c76fb8ee1c12639d85c2e73b0769ef"}, + {file = "pypdfium2-5.5.0-py3-none-musllinux_1_2_ppc64le.whl", hash = "sha256:faea3246591ce2ea6218cd06679071275e3c65f11c3f5c9091eb7fb07610af6a"}, + {file = "pypdfium2-5.5.0-py3-none-musllinux_1_2_riscv64.whl", hash = "sha256:aba26d404b51a9de3d3e80c867a95c71abf1c79552001ae22707451e59186b3d"}, + {file = "pypdfium2-5.5.0-py3-none-musllinux_1_2_s390x.whl", hash = "sha256:e0fa8f81679e6e71f26806f4db853571ee6435dc3bde7a46acdd182ef886a5b9"}, + {file = "pypdfium2-5.5.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ee22df3376d350eeb64d2002a1071e3a02c0d874c557a3cd8229a8fc572cdaac"}, + {file = "pypdfium2-5.5.0-py3-none-win32.whl", hash = "sha256:ec62a00223d1222d2f35c0866dd79cdc24da070738544cdf51b17d332d4a7389"}, + {file = "pypdfium2-5.5.0-py3-none-win_amd64.whl", hash = "sha256:15c32fbeebb5198afa785dd03e98906ebb4eded9ef8862e10f833c37b4a18786"}, + {file = "pypdfium2-5.5.0-py3-none-win_arm64.whl", hash = "sha256:f618af0884c16c768539c44933a255039131dbbf39d68eded020da4f14958d73"}, + {file = "pypdfium2-5.5.0.tar.gz", hash = "sha256:3283c61f54c3c546d140da201ef48a51c18b0ad54293091a010029ac13ece23a"}, +] + +[[package]] +name = "pytest" +version = "8.4.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}, + {file = "pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}, +] + +[package.dependencies] +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} +iniconfig = ">=1" +packaging = ">=20" +pluggy = ">=1.5,<2" +pygments = ">=2.7.2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pytest-order" +version = "1.3.0" +description = "pytest plugin to run your tests in a specific order" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "pytest_order-1.3.0-py3-none-any.whl", hash = "sha256:2cd562a21380345dd8d5774aa5fd38b7849b6ee7397ca5f6999bbe6e89f07f6e"}, + {file = "pytest_order-1.3.0.tar.gz", hash = "sha256:51608fec3d3ee9c0adaea94daa124a5c4c1d2bb99b00269f098f414307f23dde"}, +] + +[package.dependencies] +pytest = {version = ">=6.2.4", markers = "python_version >= \"3.10\""} + +[[package]] +name = "tomli" +version = "2.4.0" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "python_full_version <= \"3.11.0a6\"" +files = [ + {file = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"}, + {file = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"}, + {file = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"}, + {file = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"}, + {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"}, + {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"}, + {file = "tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"}, + {file = "tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"}, + {file = "tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"}, + {file = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"}, + {file = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"}, + {file = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"}, + {file = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"}, + {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"}, + {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"}, + {file = "tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"}, + {file = "tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"}, + {file = "tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"}, + {file = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"}, + {file = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"}, + {file = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"}, + {file = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"}, + {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"}, + {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"}, + {file = "tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"}, + {file = "tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"}, + {file = "tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"}, + {file = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"}, + {file = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"}, + {file = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"}, + {file = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"}, + {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"}, + {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"}, + {file = "tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"}, + {file = "tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"}, + {file = "tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"}, + {file = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"}, + {file = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"}, + {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"}, + {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"}, + {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"}, + {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"}, + {file = "tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"}, + {file = "tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"}, + {file = "tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"}, + {file = "tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"}, + {file = "tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +description = "Backported and Experimental Type Hints for Python 3.9+" +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +files = [ + {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, + {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, +] +markers = {main = "python_version == \"3.10\""} + +[metadata] +lock-version = "2.1" +python-versions = "^3.10" +content-hash = "a4dafb3f7359fbc6aaaf9df9036d32f35d586e62e5c5c7627a5b1af5049ee370" diff --git a/pyproject.toml b/pyproject.toml index 4ddf7b10..115c7821 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,23 +1,39 @@ [project] name = "check_run" +version = "15.10.0" +description = "Payables utility for ERPNext" authors = [ { name = "AgriTheory", email = "support@agritheory.dev"} ] -description = "Payables utility for ERPNext" -requires-python = ">=3.10" readme = "README.md" -dynamic = ["version"] -dependencies = [ - "atnacha @ git+https://github.com/AgriTheory/atnacha.git@main#egg=atnacha", - "mypy", - "pytest", - "pdfplumber", - "pytest-order" -] +requires-python = ">=3.10" +dynamic = ["dependencies"] + +[tool.poetry.dependencies] +python = "^3.10" +atnacha = { git = "https://github.com/AgriTheory/atnacha.git" } +pdfplumber = "*" + +[tool.poetry.group.dev.dependencies] +pytest = "^8.2.2" +pytest-cov = "^5.0.0" +pytest-order = "^1.2.1" +mypy = "^1.10.0" [build-system] -requires = ["flit_core >=3.4,<4"] -build-backend = "flit_core.buildapi" +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.bench.frappe-dependencies] +frappe = ">=15.0.0,<16.0.0" +erpnext = ">=15.0.0,<16.0.0" +hrms = ">=15.0.0,<16.0.0" + +[tool.codespell] +skip = "CHANGELOG.md" + +[tool.pytest.ini_options] +addopts = "-s --disable-warnings" [tool.black] line-length = 99 @@ -32,60 +48,11 @@ ensure_newline_before_comments = true indent = "\t" [tool.semantic_release] -assets = [] -commit_message = "{version}\n\nAutomatically generated by python-semantic-release" -commit_parser = "angular" -logging_use_named_masks = false -major_on_zero = true -tag_format = "v{version}" +version_toml = ["pyproject.toml:project.version"] version_variables = [ - "check_run/__init__.py:__version__", - "pyproject.toml:version" + "check_run/__init__.py:__version__" ] +build_command = "echo 1" [tool.semantic_release.branches.version] match = "version-(14|15)" -prerelease = false - -[tool.semantic_release.changelog] -template_dir = "templates" -changelog_file = "CHANGELOG.md" -exclude_commit_patterns = [] - -[tool.semantic_release.changelog.environment] -block_start_string = "{%" -block_end_string = "%}" -variable_start_string = "{{" -variable_end_string = "}}" -comment_start_string = "{#" -comment_end_string = "#}" -trim_blocks = false -lstrip_blocks = false -newline_sequence = "\n" -keep_trailing_newline = false -extensions = [] -autoescape = true - -[tool.semantic_release.commit_author] -env = "GIT_COMMIT_AUTHOR" -default = "semantic-release " - -[tool.semantic_release.commit_parser_options] -allowed_tags = ["build", "chore", "ci", "docs", "feat", "fix", "perf", "style", "refactor", "test"] -minor_tags = ["feat"] -patch_tags = ["fix", "perf"] - -[tool.semantic_release.remote] -name = "origin" -type = "github" -ignore_token_for_push = false - -[tool.semantic_release.remote.token] -env = "GH_TOKEN" - -[tool.semantic_release.publish] -dist_glob_patterns = ["dist/*"] -upload_to_vcs_release = true - -[tool.codespell] -skip = "yarn.lock" diff --git a/setup.py b/setup.py index 55bd3082..e9aa5b91 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,6 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + from setuptools import setup name = "check_run" From 3694a0f338c59369fc6cb27ad6dc7920c90034b5 Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Sat, 21 Feb 2026 19:45:07 -0500 Subject: [PATCH 3/9] chore: update pyproject and precommit --- docs/achgeneration.md | 2 +- docs/configuration.md | 2 +- docs/exampledata.md | 2 +- docs/exampleprint.md | 2 +- docs/index.md | 2 +- docs/installationguide.md | 2 +- docs/payment_entry.md | 2 +- docs/permissions.md | 2 +- docs/positivepay.md | 2 +- docs/renderpdfsequence.md | 2 +- docs/settings.md | 2 +- docs/translations.md | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/achgeneration.md b/docs/achgeneration.md index 39bd9330..b71501da 100644 --- a/docs/achgeneration.md +++ b/docs/achgeneration.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # ACH Generation diff --git a/docs/configuration.md b/docs/configuration.md index 86921c07..c0db2525 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Configuration diff --git a/docs/exampledata.md b/docs/exampledata.md index 971f6179..b2979982 100644 --- a/docs/exampledata.md +++ b/docs/exampledata.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Using the Example Data to Experiment with Check Run diff --git a/docs/exampleprint.md b/docs/exampleprint.md index 59292a50..b56790b0 100644 --- a/docs/exampleprint.md +++ b/docs/exampleprint.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Example Print Format: Voucher Check diff --git a/docs/index.md b/docs/index.md index 36de7bd3..192298e5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Check Run Documentation diff --git a/docs/installationguide.md b/docs/installationguide.md index daf8d9db..b574cb26 100644 --- a/docs/installationguide.md +++ b/docs/installationguide.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Check Run Installation Guide diff --git a/docs/payment_entry.md b/docs/payment_entry.md index 35ab030e..482f1ff0 100644 --- a/docs/payment_entry.md +++ b/docs/payment_entry.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Payment Entry ## Auto-Increment Check Number diff --git a/docs/permissions.md b/docs/permissions.md index 5b0964b2..19e9d686 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Default Permissions and Workflow diff --git a/docs/positivepay.md b/docs/positivepay.md index 7c6bc721..569a4af4 100644 --- a/docs/positivepay.md +++ b/docs/positivepay.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Positive Pay Report diff --git a/docs/renderpdfsequence.md b/docs/renderpdfsequence.md index d1bacbe8..794bd250 100644 --- a/docs/renderpdfsequence.md +++ b/docs/renderpdfsequence.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Render PDF Sequence diff --git a/docs/settings.md b/docs/settings.md index be93e475..2847813f 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Check Run Settings diff --git a/docs/translations.md b/docs/translations.md index 4f627d30..f948c536 100644 --- a/docs/translations.md +++ b/docs/translations.md @@ -4,7 +4,7 @@ For license information, please see license.txt--> # Translations From d0fdb6e0ec35cc1c82d9d4fb14eeb14b774d670e Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Sat, 21 Feb 2026 20:01:07 -0500 Subject: [PATCH 4/9] fix: move customize to install --- check_run/hooks.py | 2 +- check_run/install.py | 189 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 check_run/install.py diff --git a/check_run/hooks.py b/check_run/hooks.py index 3214c53a..fca4d6a5 100644 --- a/check_run/hooks.py +++ b/check_run/hooks.py @@ -70,7 +70,7 @@ # ------------ # before_install = "check_run.install.before_install" -after_install = "check_run.customize.after_install" +after_install = "check_run.install.after_install" # after_migrate = "check_run.customize.load_customizations" # Uninstallation diff --git a/check_run/install.py b/check_run/install.py new file mode 100644 index 00000000..e491c13d --- /dev/null +++ b/check_run/install.py @@ -0,0 +1,189 @@ +# Copyright (c) 2026, AgriTheory and contributors +# For license information, please see license.txt + +import frappe + + +def add_workflow_for_voided_check(): + + workflow_actions = [ + { + "docstatus": 0, + "doctype": "Workflow Action Master", + "name": "Submit", + "workflow_action_name": "Submit", + }, + { + "docstatus": 0, + "doctype": "Workflow Action Master", + "name": "Void", + "workflow_action_name": "Void", + }, + { + "docstatus": 0, + "doctype": "Workflow Action Master", + "name": "Cancel", + "workflow_action_name": "Cancel", + }, + { + "docstatus": 0, + "doctype": "Workflow Action Master", + "name": "Save", + "workflow_action_name": "Save", + }, + ] + + for action in workflow_actions: + if not frappe.db.exists("Workflow Action Master", action["name"]): + act = frappe.new_doc("Workflow Action Master") + act.update(action) + act.insert() + + workflow_states = [ + { + "docstatus": 0, + "icon": "", + "name": "Submitted", + "style": "Primary", + "workflow_state_name": "Submitted", + }, + { + "docstatus": 0, + "icon": "", + "name": "Voided", + "style": "Inverse", + "workflow_state_name": "Voided", + }, + { + "docstatus": 0, + "doctype": "Workflow State", + "icon": "", + "name": "Cancelled", + "style": "Inverse", + "workflow_state_name": "Cancelled", + }, + { + "docstatus": 0, + "doctype": "Workflow State", + "icon": "", + "name": "Draft", + "style": "Warning", + "workflow_state_name": "Draft", + }, + ] + + for state in workflow_states: + if not frappe.db.exists("Workflow State", state["name"]): + ws = frappe.new_doc("Workflow State") + ws.update(state) + ws.insert() + + workflow_data = { + "docstatus": 0, + "doctype": "Workflow", + "document_type": "Payment Entry", + "is_active": 0, + "name": "Void Payment Entry", + "override_status": 0, + "send_email_alert": 0, + "states": [ + { + "allow_edit": "Accounts User", + "doc_status": "0", + "is_optional_state": 0, + "parent": "Payment Entry", + "parentfield": "states", + "parenttype": "Workflow", + "state": "Draft", + }, + { + "allow_edit": "Accounts User", + "doc_status": "1", + "is_optional_state": 0, + "parent": "Payment Entry", + "parentfield": "states", + "parenttype": "Workflow", + "state": "Submitted", + }, + { + "allow_edit": "Accounts User", + "doc_status": "2", + "is_optional_state": 0, + "parent": "Payment Entry", + "parentfield": "states", + "parenttype": "Workflow", + "state": "Cancelled", + }, + { + "allow_edit": "Accounts User", + "doc_status": "2", + "is_optional_state": 0, + "parent": "Payment Entry", + "parentfield": "states", + "parenttype": "Workflow", + "state": "Voided", + "update_field": "status", + "update_value": "Voided", + }, + ], + "transitions": [ + { + "action": "Save", + "allow_self_approval": 1, + "allowed": "Accounts User", + "next_state": "Draft", + "parent": "Payment Entry", + "parentfield": "transitions", + "parenttype": "Workflow", + "state": "Draft", + }, + { + "action": "Submit", + "allow_self_approval": 1, + "allowed": "Accounts User", + "next_state": "Submitted", + "parent": "Payment Entry", + "parentfield": "transitions", + "parenttype": "Workflow", + "state": "Draft", + }, + { + "action": "Cancel", + "allow_self_approval": 1, + "allowed": "Accounts User", + "next_state": "Cancelled", + "parent": "Payment Entry", + "parentfield": "transitions", + "parenttype": "Workflow", + "state": "Submitted", + }, + { + "action": "Void", + "allow_self_approval": 1, + "allowed": "Accounts User", + "next_state": "Voided", + "parent": "Payment Entry", + "parentfield": "transitions", + "parenttype": "Workflow", + "state": "Submitted", + }, + ], + "workflow_name": "Voidable Payment Entry", + "workflow_state_field": "status", + } + if not frappe.db.exists("Workflow", workflow_data["workflow_name"]): + workflow = frappe.new_doc("Workflow") + workflow.update(workflow_data) + workflow.insert() + + +def after_install(): + if not frappe.db.exists("File", "Home/Check Run"): + try: + cr_folder = frappe.new_doc("File") + cr_folder.update({"file_name": "Check Run", "is_folder": True, "folder": "Home"}) + cr_folder.save() + except Exception as e: + pass + + add_workflow_for_voided_check() From ee149d0d41d79ad167afb27dd7575b0cb5e53557 Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Sat, 21 Feb 2026 20:37:20 -0500 Subject: [PATCH 5/9] chore: update pyproject and precommit --- .github/helper/install.sh | 1 + pyproject.toml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/.github/helper/install.sh b/.github/helper/install.sh index 2279fe91..34baf40f 100644 --- a/.github/helper/install.sh +++ b/.github/helper/install.sh @@ -46,6 +46,7 @@ bench get-app check_run "${GITHUB_WORKSPACE}" --skip-assets printf '%s\n' 'frappe' 'erpnext' 'hrms' 'check_run' > ~/frappe-bench/sites/apps.txt bench setup requirements --python +bench setup requirements --dev bench use test_site bench start &> bench_run_logs.txt & diff --git a/pyproject.toml b/pyproject.toml index 9ff8f438..825e1f5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,11 @@ frappe = ">=15.0.0,<16.0.0" erpnext = ">=15.0.0,<16.0.0" hrms = ">=15.0.0,<16.0.0" +[tool.bench.dev-dependencies] +pytest = "~=8.2.2" +pytest-cov = "~=5.0.0" +pytest-order = "~=1.2.1" + [tool.codespell] skip = "CHANGELOG.md" From 07e7495b8742ce4ec659f561aab25ce88fdab752 Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Sat, 21 Feb 2026 21:11:44 -0500 Subject: [PATCH 6/9] chore update pyproject and precommit --- .github/workflows/code-duplication.yml | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/code-duplication.yml diff --git a/.github/workflows/code-duplication.yml b/.github/workflows/code-duplication.yml new file mode 100644 index 00000000..d70489ee --- /dev/null +++ b/.github/workflows/code-duplication.yml @@ -0,0 +1,29 @@ +name: Code Duplication + +on: + push: + branches: ["*"] + pull_request: + branches: ["*"] + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + duplication: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-node@v4 + with: + node-version: '18' + + - uses: agritheory/test_utils/actions/code_duplication@main + with: + max_clones: 60 + max_percentage: 5.0 From 4b2f2730ea48b40f603bd7991b631210d24a1d20 Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Sat, 21 Feb 2026 21:40:47 -0500 Subject: [PATCH 7/9] chore: update pyproject and precommit --- .pre-commit-config.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8c61e732..d8a43730 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: additional_dependencies: ['flake8-bugbear'] - repo: https://github.com/agritheory/test_utils - rev: v1.15.4 + rev: v1.16.0 hooks: - id: update_pre_commit_config - id: validate_frappe_project @@ -61,6 +61,8 @@ repos: args: ['--app', 'check_run'] - id: track_overrides args: ['--directory', '.', '--app', 'check_run', '--base-branch', 'version-15'] + - id: check_code_duplication + args: ['--max-clones', '60', '--max-percentage', '5.0'] - repo: https://github.com/pre-commit/mirrors-prettier rev: v3.1.0 From 58ab1f8a1581c72ffec29f4bb1472e54bd8f948d Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Mon, 23 Feb 2026 10:04:14 -0500 Subject: [PATCH 8/9] chore: update pyproject and precommit, note flase positive on duplication --- .github/validate_customizations.py | 166 ------------------ .pre-commit-config.yaml | 2 +- .../js/check_run/check_run_quick_entry.js | 2 + .../check_run_settings_quick_entry.js | 6 +- 4 files changed, 8 insertions(+), 168 deletions(-) delete mode 100644 .github/validate_customizations.py diff --git a/.github/validate_customizations.py b/.github/validate_customizations.py deleted file mode 100644 index 502a8257..00000000 --- a/.github/validate_customizations.py +++ /dev/null @@ -1,166 +0,0 @@ -import json -import pathlib -import sys - - -def scrub(txt: str) -> str: - """Returns sluggified string. e.g. `Sales Order` becomes `sales_order`.""" - return txt.replace(" ", "_").replace("-", "_").lower() - - -def unscrub(txt: str) -> str: - """Returns titlified string. e.g. `sales_order` becomes `Sales Order`.""" - return txt.replace("_", " ").replace("-", " ").title() - - -def get_customized_doctypes(): - apps_dir = pathlib.Path(__file__).resolve().parent.parent.parent - apps_order = pathlib.Path(__file__).resolve().parent.parent.parent.parent / "sites" / "apps.txt" - apps_order = apps_order.read_text().split("\n") - customized_doctypes = {} - for _app_dir in apps_order: - app_dir = (apps_dir / _app_dir).resolve() - if not app_dir.is_dir(): - continue - modules = (app_dir / _app_dir / "modules.txt").read_text().split("\n") - for module in modules: - if not (app_dir / _app_dir / scrub(module) / "custom").exists(): - continue - for custom_file in list((app_dir / _app_dir / scrub(module) / "custom").glob("**/*.json")): - if custom_file.stem in customized_doctypes: - customized_doctypes[custom_file.stem].append(custom_file.resolve()) - else: - customized_doctypes[custom_file.stem] = [custom_file.resolve()] - - return dict(sorted(customized_doctypes.items())) - - -def validate_module(customized_doctypes, set_module=False): - exceptions = [] - app_dir = pathlib.Path(__file__).resolve().parent.parent - this_app = app_dir.stem - for doctype, customize_files in customized_doctypes.items(): - for customize_file in customize_files: - if not this_app == customize_file.parent.parent.parent.parent.stem: - continue - module = customize_file.parent.parent.stem - file_contents = json.loads(customize_file.read_text()) - if file_contents.get("custom_fields"): - for custom_field in file_contents.get("custom_fields"): - if set_module: - custom_field["module"] = unscrub(module) - continue - if not custom_field.get("module"): - exceptions.append( - f"Custom Field for {custom_field.get('dt')} in {this_app} '{custom_field.get('fieldname')}' does not have a module key" - ) - continue - elif custom_field.get("module") != unscrub(module): - exceptions.append( - f"Custom Field for {custom_field.get('dt')} in {this_app} '{custom_field.get('fieldname')}' has module key ({custom_field.get('module')}) associated with another app" - ) - continue - if file_contents.get("property_setters"): - for ps in file_contents.get("property_setters"): - if set_module: - ps["module"] = unscrub(module) - continue - if not ps.get("module"): - exceptions.append( - f"Property Setter for {ps.get('doc_type')} in {this_app} '{ps.get('property')}' on {ps.get('field_name')} does not have a module key" - ) - continue - elif ps.get("module") != unscrub(module): - exceptions.append( - f"Property Setter for {ps.get('doc_type')} in {this_app} '{ps.get('property')}' on {ps.get('field_name')} has module key ({ps.get('module')}) associated with another app" - ) - continue - if set_module: - with customize_file.open("w", encoding="UTF-8") as target: - json.dump(file_contents, target, sort_keys=True, indent=2) - - return exceptions - - -def validate_no_custom_perms(customized_doctypes): - exceptions = [] - this_app = pathlib.Path(__file__).resolve().parent.parent.stem - for doctype, customize_files in customized_doctypes.items(): - for customize_file in customize_files: - if not this_app == customize_file.parent.parent.parent.parent.stem: - continue - file_contents = json.loads(customize_file.read_text()) - if file_contents.get("custom_perms"): - exceptions.append(f"Customization for {doctype} in {this_app} contains custom permissions") - return exceptions - - -def validate_duplicate_customizations(customized_doctypes): - exceptions = [] - common_fields = {} - common_property_setters = {} - app_dir = pathlib.Path(__file__).resolve().parent.parent - this_app = app_dir.stem - for doctype, customize_files in customized_doctypes.items(): - if len(customize_files) == 1: - continue - common_fields[doctype] = {} - common_property_setters[doctype] = {} - for customize_file in customize_files: - module = customize_file.parent.parent.stem - app = customize_file.parent.parent.parent.parent.stem - file_contents = json.loads(customize_file.read_text()) - if file_contents.get("custom_fields"): - fields = [cf.get("fieldname") for cf in file_contents.get("custom_fields")] - common_fields[doctype][module] = fields - if file_contents.get("property_setters"): - ps = [ps.get("name") for ps in file_contents.get("property_setters")] - common_property_setters[doctype][module] = ps - - for doctype, module_and_fields in common_fields.items(): - if this_app not in module_and_fields.keys(): - continue - this_modules_fields = module_and_fields.pop(this_app) - for module, fields in module_and_fields.items(): - for field in fields: - if field in this_modules_fields: - exceptions.append( - f"Custom Field for {unscrub(doctype)} in {this_app} '{field}' also appears in customizations for {module}" - ) - - for doctype, module_and_ps in common_property_setters.items(): - if this_app not in module_and_ps.keys(): - continue - this_modules_ps = module_and_ps.pop(this_app) - for module, ps in module_and_ps.items(): - for p in ps: - if p in this_modules_ps: - exceptions.append( - f"Property Setter for {unscrub(doctype)} in {this_app} on '{p}' also appears in customizations for {module}" - ) - - return exceptions - - -def validate_customizations(set_module): - customized_doctypes = get_customized_doctypes() - exceptions = validate_no_custom_perms(customized_doctypes) - exceptions += validate_module(customized_doctypes, set_module) - exceptions += validate_duplicate_customizations(customized_doctypes) - - return exceptions - - -if __name__ == "__main__": - exceptions = [] - set_module = False - for arg in sys.argv: - if arg == "--set-module": - set_module = True - exceptions.append(validate_customizations(set_module)) - - if exceptions: - for exception in exceptions: - [print(e) for e in exception] # TODO: colorize - - sys.exit(1) if all(exceptions) else sys.exit(0) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d8a43730..3290d2f5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ fail_fast: false repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: trailing-whitespace files: 'check_run.*' diff --git a/check_run/public/js/check_run/check_run_quick_entry.js b/check_run/public/js/check_run/check_run_quick_entry.js index 1a4d1b48..ca170745 100644 --- a/check_run/public/js/check_run/check_run_quick_entry.js +++ b/check_run/public/js/check_run/check_run_quick_entry.js @@ -5,6 +5,7 @@ frappe.provide('check_run') frappe.provide('frappe.ui.form') frappe.ui.form.CheckRunQuickEntryForm = class CheckRunQuickEntryForm extends frappe.ui.form.QuickEntryForm { + /* jscpd:ignore-start */ constructor(doctype, after_insert, init_callback, doc, force) { super(doctype, after_insert, init_callback, doc, force) } @@ -75,6 +76,7 @@ frappe.ui.form.CheckRunQuickEntryForm = class CheckRunQuickEntryForm extends fra }) } } + /* jscpd:ignore-end */ register_primary_action() { const me = this this.dialog.set_primary_action(__('Start Check Run'), () => { diff --git a/check_run/public/js/check_run/check_run_settings_quick_entry.js b/check_run/public/js/check_run/check_run_settings_quick_entry.js index 8688b779..1bcc6061 100644 --- a/check_run/public/js/check_run/check_run_settings_quick_entry.js +++ b/check_run/public/js/check_run/check_run_settings_quick_entry.js @@ -4,7 +4,10 @@ frappe.provide('check_run') frappe.provide('frappe.ui.form') -frappe.ui.form.CheckRunSettingsQuickEntryForm = class CheckRunQuickEntryForm extends frappe.ui.form.QuickEntryForm { +frappe.ui.form.CheckRunSettingsQuickEntryForm = class CheckRunSettingsQuickEntryForm extends ( + frappe.ui.form.QuickEntryForm +) { + /* jscpd:ignore-start */ constructor(doctype, after_insert, init_callback, doc, force) { super(doctype, after_insert, init_callback, doc, force) } @@ -75,4 +78,5 @@ frappe.ui.form.CheckRunSettingsQuickEntryForm = class CheckRunQuickEntryForm ext }) } } + /* jscpd:ignore-end */ } From 304de6856a12a03584e7a480cea80779412c0f53 Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Mon, 23 Feb 2026 10:06:40 -0500 Subject: [PATCH 9/9] chore: switch to AT print format diff --- .github/workflows/print_format_diff.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/print_format_diff.yml b/.github/workflows/print_format_diff.yml index 28500ed5..2e9a308c 100644 --- a/.github/workflows/print_format_diff.yml +++ b/.github/workflows/print_format_diff.yml @@ -1,4 +1,4 @@ -name: Print Format Diff +name: Diff Print Formats on: pull_request: @@ -9,14 +9,9 @@ on: jobs: diff_print_format: runs-on: ubuntu-latest - name: Print Format Diff + name: Diff Print Formats steps: - - name: Checkout the code - uses: actions/checkout@v3 + - name: Diff Print Formats + uses: agritheory/test_utils/actions/diff_print_format@main with: - fetch-depth: 0 - - - name: Print Format Diff - uses: diamorafaela/diff-print-format@main - with: - github-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + github-token: ${{ secrets.GITHUB_TOKEN }}