From 58125778545e8e1166e110a563eb896d9b2bde52 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 3 Jul 2024 05:06:09 +0000 Subject: [PATCH 01/83] chore(release): Bumped to Version 15.29.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # [15.29.0](https://github.com/frappe/erpnext/compare/v15.28.2...v15.29.0) (2024-07-03) ### Bug Fixes * add auto-update for overdue status ([#42105](https://github.com/frappe/erpnext/issues/42105)) ([317cc03](https://github.com/frappe/erpnext/commit/317cc0358c0e3cb07da0d72657dddeb9ef7ee546)) * add string for translation (backport [#41903](https://github.com/frappe/erpnext/issues/41903)) ([#41963](https://github.com/frappe/erpnext/issues/41963)) ([48dc24b](https://github.com/frappe/erpnext/commit/48dc24b9bf65e788bffc700f4002f66cef9bcfed)) * always post to tax account heads if LCV is booked ([706a6c1](https://github.com/frappe/erpnext/commit/706a6c1ad7c7850974d7dc7b6a0ff162ef4c1a28)) * batch picking in pick list based on Stock Settings (backport [#42021](https://github.com/frappe/erpnext/issues/42021)) ([#42134](https://github.com/frappe/erpnext/issues/42134)) ([a45f8ca](https://github.com/frappe/erpnext/commit/a45f8ca5fd7403e61f4c836dc28ea7742c24441e)) * batch reset while making SABB (backport [#42076](https://github.com/frappe/erpnext/issues/42076)) ([#42123](https://github.com/frappe/erpnext/issues/42123)) ([c3f5a49](https://github.com/frappe/erpnext/commit/c3f5a494f32a4fff787dbd04c5d36f006bac0865)) * decimal issue in pick list (backport [#41972](https://github.com/frappe/erpnext/issues/41972)) ([#41982](https://github.com/frappe/erpnext/issues/41982)) ([9945a90](https://github.com/frappe/erpnext/commit/9945a90b3fdfdbe95c7205c7228372d3b47e0ce6)) * **Delivery Note:** only show permitted actions ([cef6d0d](https://github.com/frappe/erpnext/commit/cef6d0d74d11067e29e58d080fa09a328a5f016a)) * do not show zero balance stock items in stock balance report (backport [#41958](https://github.com/frappe/erpnext/issues/41958)) ([#41961](https://github.com/frappe/erpnext/issues/41961)) ([c10b123](https://github.com/frappe/erpnext/commit/c10b123a817ba0e1285a607c8514b57747d0ebf5)) * expense account from item group not fetched (backport [#41957](https://github.com/frappe/erpnext/issues/41957)) ([#41962](https://github.com/frappe/erpnext/issues/41962)) ([760b2e2](https://github.com/frappe/erpnext/commit/760b2e24f27c1dfdc70eb685562e83afc9f35ae3)) * fixed asset value in Fixed Asset Register (backport [#41930](https://github.com/frappe/erpnext/issues/41930)) ([#42027](https://github.com/frappe/erpnext/issues/42027)) ([f2feeaf](https://github.com/frappe/erpnext/commit/f2feeaf264febdbb3b9489b9d363c1e2798dd5f9)) * handle none type object error ([b0aef9e](https://github.com/frappe/erpnext/commit/b0aef9e42b34dfe6b8b0002647b8ba966a735a9a)) * incorrect against_account upon reposting ([a41577a](https://github.com/frappe/erpnext/commit/a41577a1cd901f7c66256f9bb877af1ddc610913)) * incorrect Difference Amount (backport [#42008](https://github.com/frappe/erpnext/issues/42008)) ([#42013](https://github.com/frappe/erpnext/issues/42013)) ([838cc5b](https://github.com/frappe/erpnext/commit/838cc5b72aff39d53093c71a52fe2645c69fe1a8)) * incorrect discount on other item ([77f4199](https://github.com/frappe/erpnext/commit/77f4199e2ad4b1b7b2b4122a67affcc2d845a80b)) * incorrect dr/cr on Adv Payment against Journals ([4e74257](https://github.com/frappe/erpnext/commit/4e74257ba9bf520d0a92622adf979e77cd4d8222)) * incorrect time period in asset depreciation schedule (backport [#41805](https://github.com/frappe/erpnext/issues/41805)) ([#42043](https://github.com/frappe/erpnext/issues/42043)) ([cf4d4ba](https://github.com/frappe/erpnext/commit/cf4d4ba3e97094bbe5d61b2f119ab157d4ffac08)) * lead status filter (backport [#41816](https://github.com/frappe/erpnext/issues/41816)) ([#42046](https://github.com/frappe/erpnext/issues/42046)) ([3536a75](https://github.com/frappe/erpnext/commit/3536a754ff8dd778e72679dd906e7703f1ef7c0f)) * manufacturing date issue in the batch (backport [#42034](https://github.com/frappe/erpnext/issues/42034)) ([#42037](https://github.com/frappe/erpnext/issues/42037)) ([a981633](https://github.com/frappe/erpnext/commit/a981633d949fb43054bb22b78c77c5bde3296742)) * move condition for shipment ([2180239](https://github.com/frappe/erpnext/commit/21802396ce0659de9097074916b3144ce576171e)) * not able to make purchase return (backport [#42053](https://github.com/frappe/erpnext/issues/42053)) ([#42055](https://github.com/frappe/erpnext/issues/42055)) ([8a91bf3](https://github.com/frappe/erpnext/commit/8a91bf315491e6b3b54c1b0f681397bb5acd4a66)) * pricing rule with and without 'apply multiple' and priority ([f3aa885](https://github.com/frappe/erpnext/commit/f3aa8854880173dd89a911ca4198c9fc605e35f1)) * provisional entry for non stock items ([d61dab8](https://github.com/frappe/erpnext/commit/d61dab856942ff94092c90963dedef71fdf6dfed)) * Re-open allows SO's to be over credit limit ([7fcb0f5](https://github.com/frappe/erpnext/commit/7fcb0f578ae7456c71313f1240d3a6e855d8f86e)) * refactor Asset Repair and Stock Entry linkage to resolve amendme… (backport [#41919](https://github.com/frappe/erpnext/issues/41919)) ([#42058](https://github.com/frappe/erpnext/issues/42058)) ([97c49b9](https://github.com/frappe/erpnext/commit/97c49b93b673f5a9472d505cc981a12e5e4aa00b)) * reload asset when creating asset depreciation ([7b5d504](https://github.com/frappe/erpnext/commit/7b5d5043c5220189240c04f90abb7ffbe75d7cd3)) * reposting file attachment permission issue (backport [#42068](https://github.com/frappe/erpnext/issues/42068)) ([#42075](https://github.com/frappe/erpnext/issues/42075)) ([1f3374f](https://github.com/frappe/erpnext/commit/1f3374fcdf3e29a9fa6ad7d317db1b9c087bdbfb)) * resolve gl entries duplication in asset purchase workflow (backport [#41845](https://github.com/frappe/erpnext/issues/41845)) ([#42120](https://github.com/frappe/erpnext/issues/42120)) ([58e18e2](https://github.com/frappe/erpnext/commit/58e18e2b1fa7d8e9e6fb43282be777af711ac865)) * **Sales Order:** only show permitted actions ([a0011c5](https://github.com/frappe/erpnext/commit/a0011c5b529662d28a1e0fc623c96644fbb68c96)) * show zero stock items filter in the stock balance report (backport [#42147](https://github.com/frappe/erpnext/issues/42147)) ([#42152](https://github.com/frappe/erpnext/issues/42152)) ([11ebbf2](https://github.com/frappe/erpnext/commit/11ebbf2a9cfad99c1e2a6406f537f75a4526185b)) * stock qty validation in SCR (backport [#42124](https://github.com/frappe/erpnext/issues/42124)) ([#42133](https://github.com/frappe/erpnext/issues/42133)) ([d9e62fe](https://github.com/frappe/erpnext/commit/d9e62fef2121efb39f9a2ef220e92bae98bf848d)) * Stock Reservation Entry was not getting created (backport [#42033](https://github.com/frappe/erpnext/issues/42033)) ([#42035](https://github.com/frappe/erpnext/issues/42035)) ([e278fc6](https://github.com/frappe/erpnext/commit/e278fc683f9cad5d709c1719d2bae502193387a5)) * **test:** incorrect field for customer default billing currency ([3b15708](https://github.com/frappe/erpnext/commit/3b15708f18e695a93f740f03ddb8b1153abc6208)) * this.frm.events.update_cost is not a function (backport [#41960](https://github.com/frappe/erpnext/issues/41960)) ([#41965](https://github.com/frappe/erpnext/issues/41965)) ([3b4d397](https://github.com/frappe/erpnext/commit/3b4d39766f78492bd2ba92dc6c6c5b91263d3e6d)) * timeout error while submitting JV (backport [#42040](https://github.com/frappe/erpnext/issues/42040)) ([#42099](https://github.com/frappe/erpnext/issues/42099)) ([a0e06a4](https://github.com/frappe/erpnext/commit/a0e06a4ba5c5efc2cd69a8b561c5832dcd210761)) * timeout while cancelling LCV (backport [#42030](https://github.com/frappe/erpnext/issues/42030)) (backport [#42031](https://github.com/frappe/erpnext/issues/42031)) ([#42032](https://github.com/frappe/erpnext/issues/42032)) ([068de08](https://github.com/frappe/erpnext/commit/068de08bbbcbe885523b484ed964e73ef38c4fdc)) * unhide serial no field (backport [#42045](https://github.com/frappe/erpnext/issues/42045)) ([#42047](https://github.com/frappe/erpnext/issues/42047)) ([482832f](https://github.com/frappe/erpnext/commit/482832f3c2be1b7cd63e5ffea595a88abdd3869b)) * valuation rate for the legacy batches (backport [#42011](https://github.com/frappe/erpnext/issues/42011)) ([#42020](https://github.com/frappe/erpnext/issues/42020)) ([f6be19c](https://github.com/frappe/erpnext/commit/f6be19cb7c46e67dde6c8dc43afe08d57d87acc5)) * Wrong Delete Batch on Purchase Receipt (backport [#42007](https://github.com/frappe/erpnext/issues/42007)) ([#42012](https://github.com/frappe/erpnext/issues/42012)) ([68b318a](https://github.com/frappe/erpnext/commit/68b318a94b679fef505090fa1ebb4adecb3862a8)) ### Features * accounting dimension filters in gp report ([fe9dffb](https://github.com/frappe/erpnext/commit/fe9dffb271021e554331f048931fe793b05bbaf1)) * default account head for operating cost (backport [#41985](https://github.com/frappe/erpnext/issues/41985)) ([#41987](https://github.com/frappe/erpnext/issues/41987)) ([44c1671](https://github.com/frappe/erpnext/commit/44c16713ba9fdda293d612b10720d63f6a83b0c8)) * **gp:** group by cost center ([068ae87](https://github.com/frappe/erpnext/commit/068ae87b8d56cb1161a9fd42136b72da33f6313f)) * Turkish Chart Of Accounts (backport [#41756](https://github.com/frappe/erpnext/issues/41756)) ([#42028](https://github.com/frappe/erpnext/issues/42028)) ([63b26e6](https://github.com/frappe/erpnext/commit/63b26e679b05d8f2c334257ba4f8921ad72a48db)) ### Performance Improvements * code optimization to handle large asset creation (backport [#42018](https://github.com/frappe/erpnext/issues/42018)) ([#42025](https://github.com/frappe/erpnext/issues/42025)) ([c27f272](https://github.com/frappe/erpnext/commit/c27f272f061732e9fc58d35a95f5c34c52c0a4ab)) * dont run queries unnecessarily, improved filters ([#41993](https://github.com/frappe/erpnext/issues/41993)) ([b59c91a](https://github.com/frappe/erpnext/commit/b59c91a341d3f4265ae966a12e3a002c0a4dbc0b)) * Performance optmization for Purchase Invoice submission (backport [#40263](https://github.com/frappe/erpnext/issues/40263)) ([#41946](https://github.com/frappe/erpnext/issues/41946)) ([d396c18](https://github.com/frappe/erpnext/commit/d396c18689e530d3f11a791ef1064c2d9775466e)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 4a9236066cc..4ebd5ee55d8 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.28.2" +__version__ = "15.29.0" def get_default_company(user=None): From 473aaf4e5baeccb1e2ed96a0ace637bb405c8692 Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Wed, 3 Jul 2024 13:12:00 +0530 Subject: [PATCH 02/83] fix: path of automatically updates the status of asset maintenance log (cherry picked from commit 909aa8f359c77cb92c3607cb46fea6a5292730dc) (cherry picked from commit 5317418a53815f421296d3861a7d10aa25d31136) --- erpnext/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index a080af9a827..028acc9cb11 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -442,7 +442,7 @@ scheduler_events = { "erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email", "erpnext.accounts.utils.auto_create_exchange_rate_revaluation_daily", "erpnext.accounts.utils.run_ledger_health_checks", - "erpnext.assets.doctype.asset.asset_maintenance_log.update_asset_maintenance_log_status", + "erpnext.assets.doctype.asset_maintenance_log.asset_maintenance_log.update_asset_maintenance_log_status", ], "weekly": [ "erpnext.accounts.utils.auto_create_exchange_rate_revaluation_weekly", From 7568af67e90b2a7ee56e298c29ec2f53a31b590e Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 3 Jul 2024 14:56:03 +0000 Subject: [PATCH 03/83] chore(release): Bumped to Version 15.29.1 ## [15.29.1](https://github.com/frappe/erpnext/compare/v15.29.0...v15.29.1) (2024-07-03) ### Bug Fixes * path of automatically updates the status of asset maintenance log ([473aaf4](https://github.com/frappe/erpnext/commit/473aaf4e5baeccb1e2ed96a0ace637bb405c8692)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 4ebd5ee55d8..e82ecf1039a 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.29.0" +__version__ = "15.29.1" def get_default_company(user=None): From 20d481de5e5b220db88191482e008ae9ad2a0778 Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Fri, 21 Jun 2024 15:49:40 +0530 Subject: [PATCH 04/83] fix: group by in item-wise purchase register (cherry picked from commit 3fab00135b1391c5f505fee599dac7234b0e1992) --- .../item_wise_purchase_register/item_wise_purchase_register.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 1cd9b872a9b..8bc05273092 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -309,7 +309,7 @@ def apply_conditions(query, pi, pii, filters): query = query.orderby(pi.posting_date, order=Order.desc) query = query.orderby(pii.item_group, order=Order.desc) else: - query = apply_group_by_conditions(filters, "Purchase Invoice") + query = apply_group_by_conditions(query, pi, pii, filters) return query From 8baef2454196cb57bd428f8b46f344b88a651b36 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 5 Jul 2024 07:43:13 +0530 Subject: [PATCH 05/83] fix: blank item-wise sales/purchase register reports on first load --- .../item_wise_purchase_register/item_wise_purchase_register.js | 2 +- .../report/item_wise_sales_register/item_wise_sales_register.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js index e05591e49df..836ec7b456c 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js @@ -52,7 +52,7 @@ frappe.query_reports["Item-wise Purchase Register"] = { label: __("Group By"), fieldname: "group_by", fieldtype: "Select", - options: ["Supplier", "Item Group", "Item", "Invoice"], + options: ["", "Supplier", "Item Group", "Item", "Invoice"], }, ], formatter: function (value, row, column, data, default_formatter) { diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js index 16a97733393..6fb015f7b74 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -70,7 +70,7 @@ frappe.query_reports["Item-wise Sales Register"] = { label: __("Group By"), fieldname: "group_by", fieldtype: "Select", - options: ["Customer Group", "Customer", "Item Group", "Item", "Territory", "Invoice"], + options: ["", "Customer Group", "Customer", "Item Group", "Item", "Territory", "Invoice"], }, ], formatter: function (value, row, column, data, default_formatter) { From c9e3dee5b2650ebe98774bf330194ca83f63db5d Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Fri, 5 Jul 2024 02:47:13 +0000 Subject: [PATCH 06/83] chore(release): Bumped to Version 15.29.2 ## [15.29.2](https://github.com/frappe/erpnext/compare/v15.29.1...v15.29.2) (2024-07-05) ### Bug Fixes * blank item-wise sales/purchase register reports on first load ([8baef24](https://github.com/frappe/erpnext/commit/8baef2454196cb57bd428f8b46f344b88a651b36)) * group by in item-wise purchase register ([20d481d](https://github.com/frappe/erpnext/commit/20d481de5e5b220db88191482e008ae9ad2a0778)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index e82ecf1039a..9170c683912 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.29.1" +__version__ = "15.29.2" def get_default_company(user=None): From f97533397030e81972dce301c7ed63e3e23f1559 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 10 Jul 2024 10:44:06 +0000 Subject: [PATCH 07/83] chore(release): Bumped to Version 15.29.3 ## [15.29.3](https://github.com/frappe/erpnext/compare/v15.29.2...v15.29.3) (2024-07-10) ### Bug Fixes * actual qty in sales order (backport [#42248](https://github.com/frappe/erpnext/issues/42248)) ([#42256](https://github.com/frappe/erpnext/issues/42256)) ([4866958](https://github.com/frappe/erpnext/commit/4866958a96bf99f69e842b6986ee339b885873ec)) * add missing german translations ([2f89461](https://github.com/frappe/erpnext/commit/2f89461ace6af52e17134cd2cb5ab535e3851985)) * added filter to show only submitted assets ([19ed6d1](https://github.com/frappe/erpnext/commit/19ed6d10815144c74e5221a3584c099022da5f11)) * auto serial and batch bundle not creating for Asset Capitalization (backport [#42231](https://github.com/frappe/erpnext/issues/42231)) ([#42242](https://github.com/frappe/erpnext/issues/42242)) ([7916d64](https://github.com/frappe/erpnext/commit/7916d6436f2152e90ec5d2f8de3416937c6de800)) * Billed Qty and Qty to Bill Calculation in Purchase Order Analysis (backport [#42100](https://github.com/frappe/erpnext/issues/42100)) ([#42249](https://github.com/frappe/erpnext/issues/42249)) ([43c7513](https://github.com/frappe/erpnext/commit/43c7513cfe20713e23627a77e0b6b23471073c0a)) * BOM Creator Recursion Error on duplicate save (backport [#41622](https://github.com/frappe/erpnext/issues/41622)) ([#42179](https://github.com/frappe/erpnext/issues/42179)) ([68a39df](https://github.com/frappe/erpnext/commit/68a39dfa331d7f2922f7961a243d303015e90008)) * changes as per review ([57896a8](https://github.com/frappe/erpnext/commit/57896a8f9936f4716d9282df04e890ab5201e44e)) * completed DC will not appear in a delivery trip ([0bab609](https://github.com/frappe/erpnext/commit/0bab609a6fd502740bb3e7f9f8dfa5bc50ea9e6a)) * completed DC will not appear in a delivery trip ([#41655](https://github.com/frappe/erpnext/issues/41655)) ([a3444a0](https://github.com/frappe/erpnext/commit/a3444a07b7f597f57b89ed2119be2a9da5273e2a)) * corrected mismatch in the Purchase Receipt Status [#15620](https://github.com/frappe/erpnext/issues/15620) (backport [#42138](https://github.com/frappe/erpnext/issues/42138)) ([#42252](https://github.com/frappe/erpnext/issues/42252)) ([e1b50ef](https://github.com/frappe/erpnext/commit/e1b50efeea222fd78eb68332638bbd17544a260e)) * correcting balance sheet calculation for zero liabilities and equity ([d48a2c9](https://github.com/frappe/erpnext/commit/d48a2c9f8e3c7bd47e253cb2c88ffc2c75290ed8)) * correcting balance sheet calculation for zero liabilities and equity ([#41497](https://github.com/frappe/erpnext/issues/41497)) ([2104d90](https://github.com/frappe/erpnext/commit/2104d903aa65a5a09b5ecfbb6b937fa181fc33af)) * custom delimiters ([43ad2fe](https://github.com/frappe/erpnext/commit/43ad2fed631a689cce9b88369f959f6e7049e8d7)) * download_import_log if rows are greater than 5000 ([4eb251b](https://github.com/frappe/erpnext/commit/4eb251b59ac5e26b06b0640a77bd6fe52f3e491b)) * empty item-wise sales/purchase register reports on initial load ([5ac3b34](https://github.com/frappe/erpnext/commit/5ac3b34a6fa85da41ec168037f520a503056df66)) * field position ([a04938d](https://github.com/frappe/erpnext/commit/a04938d5ae9f9312757568ee4e01e18c9f4df901)) * group by in item-wise purchase register ([a967d59](https://github.com/frappe/erpnext/commit/a967d5984434029ed47fd1807a23cf82592c43e0)) * **Holiday List:** sort holidays on save to avoid disorienting the user (backport [#42236](https://github.com/frappe/erpnext/issues/42236)) ([#42250](https://github.com/frappe/erpnext/issues/42250)) ([b555615](https://github.com/frappe/erpnext/commit/b5556156c18f218338deafb49e8581be73b6361e)) * import log preview ([62aac8b](https://github.com/frappe/erpnext/commit/62aac8bb85b3fc28d5db9074ccfc2a03a3d76fb9)) * import status ([71311ff](https://github.com/frappe/erpnext/commit/71311ffd624560994f7f558c3af73a66d4db38c6)) * **Inventory Dimension:** reduce perms for Stock User (backport [#42226](https://github.com/frappe/erpnext/issues/42226)) ([#42243](https://github.com/frappe/erpnext/issues/42243)) ([3cc59e4](https://github.com/frappe/erpnext/commit/3cc59e4a7a379b0dd22b95882ca26a07acdbbee2)) * manual pick allow to pick more than available stock (backport [#42155](https://github.com/frappe/erpnext/issues/42155)) ([#42159](https://github.com/frappe/erpnext/issues/42159)) ([a7b6530](https://github.com/frappe/erpnext/commit/a7b6530fde4ad7ae298f685d9917d9a701fcfd72)) * Multiple fixes for General Ledger Report ([ca57fd4](https://github.com/frappe/erpnext/commit/ca57fd42551dd3a4c6e8a2ffcd58ed75d89c532c)) * multiple free items on same Item Group ([9352863](https://github.com/frappe/erpnext/commit/93528631c3652edecfee3e712d94c4ace9d4b26a)) * path of automatically updates the status of asset maintenance log ([5317418](https://github.com/frappe/erpnext/commit/5317418a53815f421296d3861a7d10aa25d31136)) * Project Status should be Open again if `percent_complete` is not 100 ([90f5c78](https://github.com/frappe/erpnext/commit/90f5c78607656ed8b3a644f30de4efce2c127110)) * provision to enable do not use batch-wise valuation (backport [#42186](https://github.com/frappe/erpnext/issues/42186)) ([#42198](https://github.com/frappe/erpnext/issues/42198)) ([ec881ac](https://github.com/frappe/erpnext/commit/ec881ace76bd6c8b63dc6793cff29bde60b74795)) * **Putaway Rule:** reduce perms for Stock User (backport [#42227](https://github.com/frappe/erpnext/issues/42227)) ([#42244](https://github.com/frappe/erpnext/issues/42244)) ([b78a97d](https://github.com/frappe/erpnext/commit/b78a97df85c66ba0d3a8f4598d239be7df39c41d)) * remove deprecated field "statement_import_log" ([2f0b97d](https://github.com/frappe/erpnext/commit/2f0b97d91b6027126978642090f0e30686181ee6)) * removed max discount validation for sales return ([ab987e9](https://github.com/frappe/erpnext/commit/ab987e9a86ba143a6920609fb3818dd162a05bba)) * **Stock Entry Type:** reduce perms for Stock User (backport [#42225](https://github.com/frappe/erpnext/issues/42225)) ([#42245](https://github.com/frappe/erpnext/issues/42245)) ([954d9ab](https://github.com/frappe/erpnext/commit/954d9ab154ef824f3cdf847fbc7e8c02c55c6fb0)) * tax on stock_rbnb on repost of Purchase Receipt ([427439c](https://github.com/frappe/erpnext/commit/427439c3f19bfd1401628cf39a30ddd291dbfec7)) * **tds:** use doctype reference when mapping keys across multiple doctypes ([#42258](https://github.com/frappe/erpnext/issues/42258)) ([8264e3b](https://github.com/frappe/erpnext/commit/8264e3bc77dacc2ac62f46fac1bec83cf0ec93cb)) * updated logic for calculating tax_withholding_net_total in payment entry ([3fb5c7a](https://github.com/frappe/erpnext/commit/3fb5c7a3a629e60925709c136e735df73042e52d)) * use standard method to get `_doc_before_save` ([cfda5f6](https://github.com/frappe/erpnext/commit/cfda5f6d0b1b6f9757b6010c98c675c768e0cbb5)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 9170c683912..2fbbc6ac1d2 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.29.2" +__version__ = "15.29.3" def get_default_company(user=None): From ce8b423ad6aefd2a0355a8efd3505c2d9e161cee Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 12 Jul 2024 20:47:27 +0530 Subject: [PATCH 08/83] chore: release v15 (#42308) * fix(Warehouse): add buttons only if the user can use them (cherry picked from commit 10ae5aaf520dbe5a2c3d38d227dd9a3103f356c3) * fix: missing discount on POS Credit Notes (cherry picked from commit 1049550951011c09fd705c4b01b925e02b6a84ee) * chore: rename test suite for payable report (cherry picked from commit 9474f727760da7592fec05331643b145e9f132f9) * refactor: test suite for item-wise sales register (cherry picked from commit 3aaa22e672ae5363ca6347d0ce280aa7fba062f0) * refactor(test): use each instance UOM for assertion (cherry picked from commit cf4fbfb60150e5af44641a2dd0811fb64d003774) * fix: slowness in reposting dependent vouchers. (backport #42282) (#42292) fix: slowness in reposting dependent vouchers. (#42282) (cherry picked from commit b17696a8ae7f0ea1128887d29336de4ef67a220f) Co-authored-by: rohitwaghchaure * refactor(test): clear old records * fix: keep status as In Progress for RIV for Timeout Error (backport #42274) (#42296) fix: keep status as In Progress for RIV for Timeout Error (#42274) (cherry picked from commit 10280d6140837ffe2fcebb70a57311780c160e25) Co-authored-by: rohitwaghchaure * fix: cost center filter by company (backport #42297) (#42299) fix: cost center filter by company (#42297) (cherry picked from commit 9838f7e6bad8c9e205ca8e8c67f77a8f156ba355) Co-authored-by: rohitwaghchaure * feat: configurable depreciation calculation via accounts settings (#42276) * feat: configurable depreciation calculation via accounts settings * refactor: code optimization * style: changes in description and label (cherry picked from commit b04da63aad0bcf13c15c49d578d291f4d6f8f25b) * fix: not able to submit LCV entry (backport #42303) (#42304) fix: not able to submit LCV entry (#42303) (cherry picked from commit 9cf92eaeab359cb0f5ca46b84d36ebed60a68f1b) Co-authored-by: rohitwaghchaure * fix: While submitting PCV ensure previous FY is closed (backport #42284) (#42300) fix: While submitting PCV ensure previous FY is closed (#42284) (cherry picked from commit d0bbc8ca705f42a0a3c8be2508919f49b67fbdad) Co-authored-by: Nabin Hait --------- Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com> Co-authored-by: ruthra kumar Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: rohitwaghchaure Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> --- .../accounts_settings/accounts_settings.json | 17 ++++- .../accounts_settings/accounts_settings.py | 1 + .../journal_entry/test_journal_entry.py | 37 +++++++++++ .../period_closing_voucher.py | 20 ++++-- .../doctype/sales_invoice/sales_invoice.js | 3 + erpnext/accounts/general_ledger.py | 12 ++++ .../accounts_payable/test_accounts_payable.py | 2 +- .../test_item_wise_sales_register.py | 65 +++++++++++++++++++ .../asset_depreciation_schedule.py | 51 +++++++++++++-- .../test_asset_depreciation_schedule.py | 62 ++++++++++++++++++ .../repost_item_valuation.py | 7 +- erpnext/stock/doctype/warehouse/warehouse.js | 48 ++++++++------ erpnext/stock/stock_ledger.py | 34 +++++++++- .../subcontracting_order.js | 16 +++++ .../subcontracting_receipt.js | 16 +++++ 15 files changed, 354 insertions(+), 37 deletions(-) create mode 100644 erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 7bf3826e781..31991648158 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -55,6 +55,8 @@ "post_change_gl_entries", "assets_tab", "asset_settings_section", + "calculate_depr_using_total_days", + "column_break_gjcc", "book_asset_depreciation_entry_automatically", "closing_settings_tab", "period_closing_settings_section", @@ -462,6 +464,17 @@ "fieldname": "enable_immutable_ledger", "fieldtype": "Check", "label": "Enable Immutable Ledger" + }, + { + "fieldname": "column_break_gjcc", + "fieldtype": "Column Break" + }, + { + "default": "0", + "description": "Enable this option to calculate daily depreciation by considering the total number of days in the entire depreciation period, (including leap years) while using daily pro-rata based depreciation", + "fieldname": "calculate_depr_using_total_days", + "fieldtype": "Check", + "label": "Calculate daily depreciation using total days in depreciation period" } ], "icon": "icon-cog", @@ -469,7 +482,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-05-11 23:19:44.673975", + "modified": "2024-07-12 00:24:20.957726", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", @@ -498,4 +511,4 @@ "sort_order": "ASC", "states": [], "track_changes": 1 -} +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py index 34f0f24047b..93ff1e207c9 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py @@ -33,6 +33,7 @@ class AccountsSettings(Document): book_deferred_entries_based_on: DF.Literal["Days", "Months"] book_deferred_entries_via_journal_entry: DF.Check book_tax_discount_loss: DF.Check + calculate_depr_using_total_days: DF.Check check_supplier_invoice_uniqueness: DF.Check credit_controller: DF.Link | None delete_linked_ledger_entries: DF.Check diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index 5bfb65a3138..cf0aae96260 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -481,6 +481,43 @@ class TestJournalEntry(unittest.TestCase): for field in self.fields: self.assertEqual(self.expected_gle[i][field], gl_entries[i][field]) + def test_negative_debit_and_credit_with_same_account_head(self): + from erpnext.accounts.general_ledger import process_gl_map + + # Create JV with defaut cost center - _Test Cost Center + frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0) + + jv = make_journal_entry("_Test Bank - _TC", "_Test Bank - _TC", 100 * -1, save=True) + jv.append( + "accounts", + { + "account": "_Test Cash - _TC", + "debit": 100 * -1, + "credit": 100 * -1, + "debit_in_account_currency": 100 * -1, + "credit_in_account_currency": 100 * -1, + "exchange_rate": 1, + }, + ) + jv.flags.ignore_validate = True + jv.save() + + self.assertEqual(len(jv.accounts), 3) + + gl_map = jv.build_gl_map() + + for row in gl_map: + if row.account == "_Test Cash - _TC": + self.assertEqual(row.debit_in_account_currency, 100 * -1) + self.assertEqual(row.credit_in_account_currency, 100 * -1) + + gl_map = process_gl_map(gl_map, False) + + for row in gl_map: + if row.account == "_Test Cash - _TC": + self.assertEqual(row.debit_in_account_currency, 100) + self.assertEqual(row.credit_in_account_currency, 100) + def make_journal_entry( account1, diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py index e75057c7a7f..9bc110d243e 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -136,18 +136,28 @@ class PeriodClosingVoucher(AccountsController): def check_if_previous_year_closed(self): last_year_closing = add_days(self.year_start_date, -1) - previous_fiscal_year = get_fiscal_year(last_year_closing, company=self.company, boolean=True) + if not previous_fiscal_year: + return - if previous_fiscal_year and not frappe.db.exists( + previous_fiscal_year_start_date = previous_fiscal_year[0][1] + if not frappe.db.exists( "GL Entry", - {"posting_date": ("<=", last_year_closing), "company": self.company, "is_cancelled": 0}, + { + "posting_date": ("between", [previous_fiscal_year_start_date, last_year_closing]), + "company": self.company, + "is_cancelled": 0, + }, ): return - if previous_fiscal_year and not frappe.db.exists( + if not frappe.db.exists( "Period Closing Voucher", - {"posting_date": ("<=", last_year_closing), "docstatus": 1, "company": self.company}, + { + "posting_date": ("between", [previous_fiscal_year_start_date, last_year_closing]), + "docstatus": 1, + "company": self.company, + }, ): frappe.throw(_("Previous Year is not closed, please close it first")) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index c7505ce007d..1df21b7ebc4 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -505,6 +505,9 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends ( return this.frm.call({ doc: me.frm.doc, method: "set_missing_values", + args: { + for_validate: true, + }, callback: function (r) { if (!r.exc) { if (r.message && r.message.print_format) { diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 2fd7b5d3c81..a4d128a5845 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -310,6 +310,18 @@ def check_if_in_list(gle, gl_map): def toggle_debit_credit_if_negative(gl_map): for entry in gl_map: # toggle debit, credit if negative entry + if flt(entry.debit) < 0 and flt(entry.credit) < 0 and flt(entry.debit) == flt(entry.credit): + entry.credit *= -1 + entry.debit *= -1 + + if ( + flt(entry.debit_in_account_currency) < 0 + and flt(entry.credit_in_account_currency) < 0 + and flt(entry.debit_in_account_currency) == flt(entry.credit_in_account_currency) + ): + entry.credit_in_account_currency *= -1 + entry.debit_in_account_currency *= -1 + if flt(entry.debit) < 0: entry.credit = flt(entry.credit) - flt(entry.debit) entry.debit = 0.0 diff --git a/erpnext/accounts/report/accounts_payable/test_accounts_payable.py b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py index f5c9d16073e..43856bf569f 100644 --- a/erpnext/accounts/report/accounts_payable/test_accounts_payable.py +++ b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py @@ -7,7 +7,7 @@ from erpnext.accounts.report.accounts_payable.accounts_payable import execute from erpnext.accounts.test.accounts_mixin import AccountsTestMixin -class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): +class TestAccountsPayable(AccountsTestMixin, FrappeTestCase): def setUp(self): self.create_company() self.create_customer() diff --git a/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py new file mode 100644 index 00000000000..4dfdf3058e4 --- /dev/null +++ b/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py @@ -0,0 +1,65 @@ +import frappe +from frappe.tests.utils import FrappeTestCase +from frappe.utils import getdate, today + +from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice +from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import execute +from erpnext.accounts.test.accounts_mixin import AccountsTestMixin + + +class TestItemWiseSalesRegister(AccountsTestMixin, FrappeTestCase): + def setUp(self): + self.create_company() + self.create_customer() + self.create_item() + self.clear_old_entries() + + def tearDown(self): + frappe.db.rollback() + + def create_sales_invoice(self, do_not_submit=False): + si = create_sales_invoice( + item=self.item, + company=self.company, + customer=self.customer, + debit_to=self.debit_to, + posting_date=today(), + parent_cost_center=self.cost_center, + cost_center=self.cost_center, + rate=100, + price_list_rate=100, + do_not_save=1, + ) + si = si.save() + if not do_not_submit: + si = si.submit() + return si + + def test_basic_report_output(self): + si = self.create_sales_invoice() + + filters = frappe._dict({"from_date": today(), "to_date": today(), "company": self.company}) + report = execute(filters) + + self.assertEqual(len(report[1]), 1) + + expected_result = { + "item_code": si.items[0].item_code, + "invoice": si.name, + "posting_date": getdate(), + "customer": si.customer, + "debit_to": si.debit_to, + "company": self.company, + "income_account": si.items[0].income_account, + "stock_qty": 1.0, + "stock_uom": si.items[0].stock_uom, + "rate": 100.0, + "amount": 100.0, + "total_tax": 0, + "total_other_charges": 0, + "total": 100.0, + "currency": "INR", + } + + report_output = {k: v for k, v in report[1][0].items() if k in expected_result} + self.assertDictEqual(report_output, expected_result) diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py index bd67a173343..c533a634a5b 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py @@ -701,20 +701,57 @@ def get_straight_line_or_manual_depr_amount( def get_daily_prorata_based_straight_line_depr( asset, row, schedule_idx, number_of_pending_depreciations, amount ): - total_years = flt(number_of_pending_depreciations * row.frequency_of_depreciation) / 12 - every_year_depr = amount / total_years + daily_depr_amount = get_daily_depr_amount(asset, row, schedule_idx, amount) - year_start_date = add_years( - row.depreciation_start_date, (row.frequency_of_depreciation * schedule_idx) // 12 - ) - year_end_date = add_days(add_years(year_start_date, 1), -1) - daily_depr_amount = every_year_depr / (date_diff(year_end_date, year_start_date) + 1) from_date, total_depreciable_days = _get_total_days( row.depreciation_start_date, schedule_idx, row.frequency_of_depreciation ) return daily_depr_amount * total_depreciable_days +def get_daily_depr_amount(asset, row, schedule_idx, amount): + if cint(frappe.db.get_single_value("Accounts Settings", "calculate_depr_using_total_days")): + total_days = ( + date_diff( + get_last_day( + add_months( + row.depreciation_start_date, + flt( + row.total_number_of_depreciations + - asset.opening_number_of_booked_depreciations + - 1 + ) + * row.frequency_of_depreciation, + ) + ), + add_days( + get_last_day(add_months(row.depreciation_start_date, -1 * row.frequency_of_depreciation)), + 1, + ), + ) + + 1 + ) + + return amount / total_days + else: + total_years = ( + flt( + (row.total_number_of_depreciations - row.total_number_of_booked_depreciations) + * row.frequency_of_depreciation + ) + / 12 + ) + + every_year_depr = amount / total_years + + year_start_date = add_years( + row.depreciation_start_date, (row.frequency_of_depreciation * schedule_idx) // 12 + ) + year_end_date = add_days(add_years(year_start_date, 1), -1) + + return every_year_depr / (date_diff(year_end_date, year_start_date) + 1) + + def get_shift_depr_amount(asset_depr_schedule, asset, row, schedule_idx): if asset_depr_schedule.get("__islocal") and not asset.flags.shift_allocation: return ( diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py index c359715571e..107d38057a2 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py @@ -75,6 +75,68 @@ class TestAssetDepreciationSchedule(FrappeTestCase): ] self.assertEqual(schedules, expected_schedules) + # Enable Checkbox to Calculate depreciation using total days in depreciation period + def test_daily_prorata_based_depr_after_enabling_configuration(self): + frappe.db.set_single_value("Accounts Settings", "calculate_depr_using_total_days", 1) + + asset = create_asset( + calculate_depreciation=1, + depreciation_method="Straight Line", + daily_prorata_based=1, + gross_purchase_amount=1096, + available_for_use_date="2020-01-15", + depreciation_start_date="2020-01-31", + frequency_of_depreciation=1, + total_number_of_depreciations=36, + ) + + expected_schedule = [ + ["2020-01-31", 17.0, 17.0], + ["2020-02-29", 29.0, 46.0], + ["2020-03-31", 31.0, 77.0], + ["2020-04-30", 30.0, 107.0], + ["2020-05-31", 31.0, 138.0], + ["2020-06-30", 30.0, 168.0], + ["2020-07-31", 31.0, 199.0], + ["2020-08-31", 31.0, 230.0], + ["2020-09-30", 30.0, 260.0], + ["2020-10-31", 31.0, 291.0], + ["2020-11-30", 30.0, 321.0], + ["2020-12-31", 31.0, 352.0], + ["2021-01-31", 31.0, 383.0], + ["2021-02-28", 28.0, 411.0], + ["2021-03-31", 31.0, 442.0], + ["2021-04-30", 30.0, 472.0], + ["2021-05-31", 31.0, 503.0], + ["2021-06-30", 30.0, 533.0], + ["2021-07-31", 31.0, 564.0], + ["2021-08-31", 31.0, 595.0], + ["2021-09-30", 30.0, 625.0], + ["2021-10-31", 31.0, 656.0], + ["2021-11-30", 30.0, 686.0], + ["2021-12-31", 31.0, 717.0], + ["2022-01-31", 31.0, 748.0], + ["2022-02-28", 28.0, 776.0], + ["2022-03-31", 31.0, 807.0], + ["2022-04-30", 30.0, 837.0], + ["2022-05-31", 31.0, 868.0], + ["2022-06-30", 30.0, 898.0], + ["2022-07-31", 31.0, 929.0], + ["2022-08-31", 31.0, 960.0], + ["2022-09-30", 30.0, 990.0], + ["2022-10-31", 31.0, 1021.0], + ["2022-11-30", 30.0, 1051.0], + ["2022-12-31", 31.0, 1082.0], + ["2023-01-15", 14.0, 1096.0], + ] + + schedules = [ + [cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount] + for d in get_depr_schedule(asset.name, "Draft") + ] + self.assertEqual(schedules, expected_schedule) + frappe.db.set_single_value("Accounts Settings", "calculate_depr_using_total_days", 0) + # Test for Written Down Value Method # Frequency of deprciation = 3 def test_for_daily_prorata_based_depreciation_wdv_method_frequency_3_months(self): diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index 717b1c31026..c20eadeb78d 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -289,6 +289,11 @@ def repost(doc): if isinstance(message, dict): message = message.get("message") + status = "Failed" + # If failed because of timeout, set status to In Progress + if traceback and "timeout" in traceback.lower(): + status = "In Progress" + if traceback: message += "

" + "Traceback:
" + traceback @@ -297,7 +302,7 @@ def repost(doc): doc.name, { "error_log": message, - "status": "Failed", + "status": status, }, ) diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js index 96cac9c06b2..6606a4f11a0 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.js +++ b/erpnext/stock/doctype/warehouse/warehouse.js @@ -40,32 +40,40 @@ frappe.ui.form.on("Warehouse", { if (!frm.is_new()) { frappe.contacts.render_address_and_contact(frm); - let enable_toggle = frm.doc.disabled ? "Enable" : "Disable"; - frm.add_custom_button(__(enable_toggle), () => { - frm.set_value("disabled", 1 - frm.doc.disabled); - frm.save(); - }); - - frm.add_custom_button(__("Stock Balance"), function () { - frappe.set_route("query-report", "Stock Balance", { - warehouse: frm.doc.name, - company: frm.doc.company, + if (frm.has_perm("write")) { + let enable_toggle = frm.doc.disabled ? "Enable" : "Disable"; + frm.add_custom_button(__(enable_toggle), () => { + frm.set_value("disabled", 1 - frm.doc.disabled); + frm.save(); }); - }); - frm.add_custom_button( - frm.doc.is_group - ? __("Convert to Ledger", null, "Warehouse") - : __("Convert to Group", null, "Warehouse"), - function () { - convert_to_group_or_ledger(frm); - } - ); + frm.add_custom_button( + frm.doc.is_group + ? __("Convert to Ledger", null, "Warehouse") + : __("Convert to Group", null, "Warehouse"), + function () { + convert_to_group_or_ledger(frm); + } + ); + } + + if ("Stock Balance" in frappe.boot.user.all_reports) { + frm.add_custom_button(__("Stock Balance"), function () { + frappe.set_route("query-report", "Stock Balance", { + warehouse: frm.doc.name, + company: frm.doc.company, + }); + }); + } } else { frappe.contacts.clear_address_and_contact(frm); } - if (!frm.doc.is_group && frm.doc.__onload && frm.doc.__onload.account) { + if ( + !frm.doc.is_group && + frm.doc.__onload?.account && + "General Ledger" in frappe.boot.user.all_reports + ) { frm.add_custom_button(__("General Ledger", null, "Warehouse"), function () { frappe.route_options = { account: frm.doc.__onload.account, diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index ff4798515c3..e14b0f87501 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -267,6 +267,8 @@ def repost_future_sle( "posting_time": args[i].get("posting_time"), "creation": args[i].get("creation"), "distinct_item_warehouses": distinct_item_warehouses, + "items_to_be_repost": args, + "current_index": i, }, allow_negative_stock=allow_negative_stock, via_landed_cost_voucher=via_landed_cost_voucher, @@ -685,11 +687,20 @@ class update_entries_after: self.distinct_item_warehouses[key] = val self.new_items_found = True else: + # Check if the dependent voucher is reposted + # If not, then do not add it to the list + if not self.is_dependent_voucher_reposted(dependant_sle): + return + existing_sle_posting_date = self.distinct_item_warehouses[key].get("sle", {}).get("posting_date") dependent_voucher_detail_nos = self.get_dependent_voucher_detail_nos(key) - if getdate(dependant_sle.posting_date) < getdate(existing_sle_posting_date): + if dependent_voucher_detail_nos and dependant_sle.voucher_detail_no in set( + dependent_voucher_detail_nos + ): + return + val.sle_changed = True dependent_voucher_detail_nos.append(dependant_sle.voucher_detail_no) val.dependent_voucher_detail_nos = dependent_voucher_detail_nos @@ -703,6 +714,27 @@ class update_entries_after: val.dependent_voucher_detail_nos = dependent_voucher_detail_nos self.distinct_item_warehouses[key] = val + def is_dependent_voucher_reposted(self, dependant_sle) -> bool: + # Return False if the dependent voucher is not reposted + + if self.args.items_to_be_repost and self.args.current_index: + index = self.args.current_index + while index < len(self.args.items_to_be_repost): + if ( + self.args.items_to_be_repost[index].get("item_code") == dependant_sle.item_code + and self.args.items_to_be_repost[index].get("warehouse") == dependant_sle.warehouse + ): + if getdate(self.args.items_to_be_repost[index].get("posting_date")) > getdate( + dependant_sle.posting_date + ): + self.args.items_to_be_repost[index]["posting_date"] = dependant_sle.posting_date + + return False + + index += 1 + + return True + def get_dependent_voucher_detail_nos(self, key): if "dependent_voucher_detail_nos" not in self.distinct_item_warehouses[key]: self.distinct_item_warehouses[key].dependent_voucher_detail_nos = [] diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js index 4ed73805314..c4eea3fda45 100644 --- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js +++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js @@ -31,6 +31,22 @@ frappe.ui.form.on("Subcontracting Order", { }; }); + frm.set_query("cost_center", (doc) => { + return { + filters: { + company: doc.company, + }, + }; + }); + + frm.set_query("cost_center", "items", (doc) => { + return { + filters: { + company: doc.company, + }, + }; + }); + frm.set_query("set_warehouse", () => { return { filters: { diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js index 8dfd9bd486d..b4a127702e0 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js @@ -174,6 +174,22 @@ frappe.ui.form.on("Subcontracting Receipt", { }; }); + frm.set_query("cost_center", (doc) => { + return { + filters: { + company: doc.company, + }, + }; + }); + + frm.set_query("cost_center", "items", (doc) => { + return { + filters: { + company: doc.company, + }, + }; + }); + frm.set_query("supplier_warehouse", () => { return { filters: { From 4b8b3ee46a88c5e478995cd4c88d4fd55e227f73 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 17 Jul 2024 05:19:44 +0000 Subject: [PATCH 09/83] chore(release): Bumped to Version 15.30.0 # [15.30.0](https://github.com/frappe/erpnext/compare/v15.29.4...v15.30.0) (2024-07-17) ### Bug Fixes * address and contact filters for SCO and SCR (backport [#42310](https://github.com/frappe/erpnext/issues/42310)) ([#42312](https://github.com/frappe/erpnext/issues/42312)) ([cb64c73](https://github.com/frappe/erpnext/commit/cb64c73c9e54dc6001a80fafb1f26faaa6352da9)) * bin deadlock issue (backport [#42342](https://github.com/frappe/erpnext/issues/42342)) ([#42357](https://github.com/frappe/erpnext/issues/42357)) ([29ee2d4](https://github.com/frappe/erpnext/commit/29ee2d46f0e493a3f22775a0cb7646555496c668)) * cost center filter by company (backport [#42297](https://github.com/frappe/erpnext/issues/42297)) ([#42299](https://github.com/frappe/erpnext/issues/42299)) ([4c9ce1b](https://github.com/frappe/erpnext/commit/4c9ce1b188672fe43f62735023b43694d71fa9f6)) * extra qty pick in pick list (backport [#42345](https://github.com/frappe/erpnext/issues/42345)) ([#42349](https://github.com/frappe/erpnext/issues/42349)) ([1754adf](https://github.com/frappe/erpnext/commit/1754adfcd64985866f0cf8d3aa5b2a6414ebc374)) * **gross profit:** incorrect valuation rate on different warehouses ([f161e59](https://github.com/frappe/erpnext/commit/f161e59cd7de888e6dc1975c736f480b0e4964ae)) * incoming rate zero for supplied items in returned SCR (backport [#42314](https://github.com/frappe/erpnext/issues/42314)) ([#42315](https://github.com/frappe/erpnext/issues/42315)) ([076bf17](https://github.com/frappe/erpnext/commit/076bf174396e045f8e87af165e40dbea718111cc)) * items not fetching in End Transit entry (backport [#42358](https://github.com/frappe/erpnext/issues/42358)) ([#42361](https://github.com/frappe/erpnext/issues/42361)) ([b5a2e5a](https://github.com/frappe/erpnext/commit/b5a2e5a375b39edf5f22a4d2276faeb3a4f85ced)) * keep status as In Progress for RIV for Timeout Error (backport [#42274](https://github.com/frappe/erpnext/issues/42274)) ([#42296](https://github.com/frappe/erpnext/issues/42296)) ([1de66e5](https://github.com/frappe/erpnext/commit/1de66e56eeb97d2f1c589298400e79ee9aaf1b02)) * missing discount on POS Credit Notes ([4055ef9](https://github.com/frappe/erpnext/commit/4055ef92b53e1528b2c286ff4028f3c501d1ea30)) * not able to cancel the inter transfer DN (backport [#42333](https://github.com/frappe/erpnext/issues/42333)) ([#42340](https://github.com/frappe/erpnext/issues/42340)) ([cf2651d](https://github.com/frappe/erpnext/commit/cf2651dd8597a4aacae9b6f89fea7d2ea138851d)) * not able to submit LCV entry (backport [#42303](https://github.com/frappe/erpnext/issues/42303)) ([#42304](https://github.com/frappe/erpnext/issues/42304)) ([6d098b7](https://github.com/frappe/erpnext/commit/6d098b7302f3409a7fa20e89611a6346f57d1463)) * remove doctype link from serial no ledger report (backport [#42327](https://github.com/frappe/erpnext/issues/42327)) ([#42348](https://github.com/frappe/erpnext/issues/42348)) ([b741b2a](https://github.com/frappe/erpnext/commit/b741b2a2858e0d106635c6be40ee2a6781af4d57)) * removed patch from patches.txt ([c45d11c](https://github.com/frappe/erpnext/commit/c45d11cd60d21064564d8266d70db6c08a25a91d)) * same posting date and time causing incorrect valuation rate (backport [#42351](https://github.com/frappe/erpnext/issues/42351)) ([#42356](https://github.com/frappe/erpnext/issues/42356)) ([62fc428](https://github.com/frappe/erpnext/commit/62fc42803f69a6e8a99b88f993276d0207a30792)) * service item capitalization ([#42188](https://github.com/frappe/erpnext/issues/42188)) ([2ffe7d5](https://github.com/frappe/erpnext/commit/2ffe7d5838464a222047cd26a045bc522da86edd)) * show total rows credit row in balance sheet ([0d2ef0d](https://github.com/frappe/erpnext/commit/0d2ef0df7dbc48d759fccd7516b5382eb4f45324)) * slowness in reposting dependent vouchers. (backport [#42282](https://github.com/frappe/erpnext/issues/42282)) ([#42292](https://github.com/frappe/erpnext/issues/42292)) ([ef16313](https://github.com/frappe/erpnext/commit/ef16313e0a4e09105dd1f0a3c004076675927b14)) * **Warehouse:** add buttons only if the user can use them ([a2b21c7](https://github.com/frappe/erpnext/commit/a2b21c757043cddd48fb67394d6c09a41bbfc65c)) * While submitting PCV ensure previous FY is closed (backport [#42284](https://github.com/frappe/erpnext/issues/42284)) ([#42300](https://github.com/frappe/erpnext/issues/42300)) ([e250dcc](https://github.com/frappe/erpnext/commit/e250dcc7c87e706055bfb92b72c7fa459d3208bc)) ### Features * configurable depreciation calculation via accounts settings ([#42276](https://github.com/frappe/erpnext/issues/42276)) ([ddd1ca7](https://github.com/frappe/erpnext/commit/ddd1ca7f7c2e2bdf5af2e535889d5ba714240079)) * create variant with/without image (backport [#41317](https://github.com/frappe/erpnext/issues/41317)) ([#42343](https://github.com/frappe/erpnext/issues/42343)) ([5f1d6ed](https://github.com/frappe/erpnext/commit/5f1d6ede31fd37454fd9de5f6500481ad3b4267a)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 2fbbc6ac1d2..63bf7fc9dc2 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.29.3" +__version__ = "15.30.0" def get_default_company(user=None): From e28c1e9c4bc987ba38ffef4414738d6a14642ded Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 24 Jul 2024 07:28:24 +0000 Subject: [PATCH 10/83] chore(release): Bumped to Version 15.31.0 # [15.31.0](https://github.com/frappe/erpnext/compare/v15.30.0...v15.31.0) (2024-07-24) ### Bug Fixes * Consider adding warranty period to serial nos (backport [#42051](https://github.com/frappe/erpnext/issues/42051)) ([#42182](https://github.com/frappe/erpnext/issues/42182)) ([8da28dc](https://github.com/frappe/erpnext/commit/8da28dcfb29ad5f922bd9d24215fe95c2909feb9)) * correct validation for depreciation posting date ([ffacf42](https://github.com/frappe/erpnext/commit/ffacf4222b0401f19a3986ff9d29d513084a6e32)) * Don't allow negative amount on Payment Request [#41905](https://github.com/frappe/erpnext/issues/41905) ([aee2cc2](https://github.com/frappe/erpnext/commit/aee2cc2e033b429a98bda6a54562a652a4d17f9f)) * missing cr/dr notes on payment reconciliation ([0a41ccd](https://github.com/frappe/erpnext/commit/0a41ccda9935d5096c235d43111a9283d7287760)) * not able to save QC (backport [#42371](https://github.com/frappe/erpnext/issues/42371)) ([#42373](https://github.com/frappe/erpnext/issues/42373)) ([18500b8](https://github.com/frappe/erpnext/commit/18500b8e3a887649413294be9d7960b8981e01e9)) * provide initial value for `.reduce()` call ([72bc539](https://github.com/frappe/erpnext/commit/72bc539ffdca0594d2175ba967c1285b691c74ac)) * Purchase Order Analysis Report Data (backport [#42387](https://github.com/frappe/erpnext/issues/42387)) ([#42394](https://github.com/frappe/erpnext/issues/42394)) ([709be13](https://github.com/frappe/erpnext/commit/709be13e8288d12204fc30109273293fb4d44582)) * qty in the 'Serial No Ledger' report (backport [#42429](https://github.com/frappe/erpnext/issues/42429)) ([#42433](https://github.com/frappe/erpnext/issues/42433)) ([926fd41](https://github.com/frappe/erpnext/commit/926fd41a2b4b5b08883383f9dbe5e3df701b0e04)) * remove proprietorship and update it with individual ([527781a](https://github.com/frappe/erpnext/commit/527781a588a986223716cf838f6a6a4c1a1882c3)) * rounding issue causing incorrect quantity in SE (backport [#42380](https://github.com/frappe/erpnext/issues/42380)) ([#42395](https://github.com/frappe/erpnext/issues/42395)) ([54791e9](https://github.com/frappe/erpnext/commit/54791e938bd56eb81f7d8d923381a006998919fe)) * serial and batch bundle for POS Invoice (backport [#41491](https://github.com/frappe/erpnext/issues/41491)) ([#42396](https://github.com/frappe/erpnext/issues/42396)) ([555be2b](https://github.com/frappe/erpnext/commit/555be2be11623d8fd8018ab3a2807e07a1050cf6)) * set filter to show only submitted asset ([29fc975](https://github.com/frappe/erpnext/commit/29fc975fb8830f3ce0dbed5e5797bd100718de9b)) * Show the rows in AR/AP report where outstanding equals to 0.01 ([886256c](https://github.com/frappe/erpnext/commit/886256c86b94aaf2e91e4ca6c6652bd503bb2ca2)) ### Features * add make_regional_gl_entries override for Sales Invoice ([#42399](https://github.com/frappe/erpnext/issues/42399)) ([22b17de](https://github.com/frappe/erpnext/commit/22b17de2b4adfc2383e2ed3ba1377c2febd2b54c)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 63bf7fc9dc2..4de860c504e 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.30.0" +__version__ = "15.31.0" def get_default_company(user=None): From 4bae4194abbf962d2f4b7fdfeaea0232fdaa6aa5 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 19:29:40 +0530 Subject: [PATCH 11/83] fix: incorrect current qty for the batch in stock reco (backport #42434) (backport #42459) (#42463) fix: incorrect current qty for the batch in stock reco (backport #42434) (#42459) fix: incorrect current qty for the batch in stock reco (#42434) (cherry picked from commit 9cd33741014e2f84614df73090617a9f53294d01) Co-authored-by: rohitwaghchaure (cherry picked from commit 298a5699f138d795d69889b63ece45400328499b) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../serial_and_batch_bundle.py | 15 +++ .../stock_reconciliation.py | 25 +++-- .../test_stock_reconciliation.py | 93 +++++++++++++++++++ 3 files changed, 124 insertions(+), 9 deletions(-) diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index 9b65e11f430..615d98a448d 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -2188,6 +2188,8 @@ def get_stock_ledgers_for_serial_nos(kwargs): def get_stock_ledgers_batches(kwargs): + from erpnext.stock.utils import get_combine_datetime + stock_ledger_entry = frappe.qb.DocType("Stock Ledger Entry") batch_table = frappe.qb.DocType("Batch") @@ -2214,6 +2216,19 @@ def get_stock_ledgers_batches(kwargs): else: query = query.where(stock_ledger_entry[field] == kwargs.get(field)) + if kwargs.get("posting_date"): + if kwargs.get("posting_time") is None: + kwargs.posting_time = nowtime() + + timestamp_condition = stock_ledger_entry.posting_datetime <= get_combine_datetime( + kwargs.posting_date, kwargs.posting_time + ) + + query = query.where(timestamp_condition) + + if kwargs.get("ignore_voucher_nos"): + query = query.where(stock_ledger_entry.voucher_no.notin(kwargs.get("ignore_voucher_nos"))) + if kwargs.based_on == "LIFO": query = query.orderby(batch_table.creation, order=frappe.qb.desc) elif kwargs.based_on == "Expiry": diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 674624e184b..93e3e69729b 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -16,7 +16,7 @@ from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle impor get_available_serial_nos, ) from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos -from erpnext.stock.utils import get_stock_balance +from erpnext.stock.utils import get_incoming_rate, get_stock_balance class OpeningEntryAccountError(frappe.ValidationError): @@ -952,14 +952,21 @@ class StockReconciliation(StockController): precesion = row.precision("current_qty") if flt(current_qty, precesion) != flt(row.current_qty, precesion): if not row.serial_no: - val_rate = get_valuation_rate( - row.item_code, - row.warehouse, - self.doctype, - self.name, - company=self.company, - batch_no=row.batch_no, - serial_and_batch_bundle=row.current_serial_and_batch_bundle, + val_rate = get_incoming_rate( + frappe._dict( + { + "item_code": row.item_code, + "warehouse": row.warehouse, + "qty": current_qty * -1, + "serial_and_batch_bundle": row.current_serial_and_batch_bundle, + "batch_no": row.batch_no, + "voucher_type": self.doctype, + "voucher_no": self.name, + "company": self.company, + "posting_date": self.posting_date, + "posting_time": self.posting_time, + } + ) ) row.current_valuation_rate = val_rate diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index 48d67c2cf46..9bb6ba9ec90 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -4,6 +4,7 @@ # ERPNext - web based ERP (http://erpnext.com) # For license information, please see license.txt +import json import frappe from frappe.tests.utils import FrappeTestCase, change_settings @@ -1182,6 +1183,98 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin): self.assertAlmostEqual(row.incoming_rate, 1000.00) self.assertEqual(row.serial_no, serial_nos[row.idx - 1]) + def test_stock_reco_with_legacy_batch(self): + from erpnext.stock.doctype.batch.batch import get_batch_qty + + batch_item_code = self.make_item( + "Test Batch Item Legacy Batch 1", + { + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "BH1-NRALL-S-.###", + }, + ).name + + warehouse = "_Test Warehouse - _TC" + + frappe.flags.ignore_serial_batch_bundle_validation = True + frappe.flags.use_serial_and_batch_fields = True + + batch_id = "BH1-NRALL-S-0001" + if not frappe.db.exists("Batch", batch_id): + batch_doc = frappe.get_doc( + { + "doctype": "Batch", + "batch_id": batch_id, + "item": batch_item_code, + "use_batchwise_valuation": 0, + } + ).insert(ignore_permissions=True) + + self.assertTrue(batch_doc.use_batchwise_valuation) + + stock_queue = [] + qty_after_transaction = 0 + balance_value = 0 + i = 0 + for qty, valuation in {10: 100, 20: 200}.items(): + i += 1 + stock_queue.append([qty, valuation]) + qty_after_transaction += qty + balance_value += qty_after_transaction * valuation + + doc = frappe.get_doc( + { + "doctype": "Stock Ledger Entry", + "posting_date": add_days(nowdate(), -2 * i), + "posting_time": nowtime(), + "batch_no": batch_id, + "incoming_rate": valuation, + "qty_after_transaction": qty_after_transaction, + "stock_value_difference": valuation * qty, + "balance_value": balance_value, + "valuation_rate": balance_value / qty_after_transaction, + "actual_qty": qty, + "item_code": batch_item_code, + "warehouse": "_Test Warehouse - _TC", + "stock_queue": json.dumps(stock_queue), + } + ) + + doc.flags.ignore_permissions = True + doc.flags.ignore_mandatory = True + doc.flags.ignore_links = True + doc.flags.ignore_validate = True + doc.submit() + doc.reload() + + frappe.flags.ignore_serial_batch_bundle_validation = False + frappe.flags.use_serial_and_batch_fields = False + + batch_doc = frappe.get_doc("Batch", batch_id) + + qty = get_batch_qty(batch_id, warehouse, batch_item_code) + self.assertEqual(qty, 30) + + sr = create_stock_reconciliation( + item_code=batch_item_code, + posting_date=add_days(nowdate(), -3), + posting_time=nowtime(), + warehouse=warehouse, + qty=100, + rate=1000, + reconcile_all_serial_batch=0, + batch_no=batch_id, + use_serial_batch_fields=1, + ) + + self.assertEqual(sr.items[0].current_qty, 20) + self.assertEqual(sr.items[0].qty, 100) + + qty = get_batch_qty(batch_id, warehouse, batch_item_code) + self.assertEqual(qty, 110) + def create_batch_item_with_batch(item_name, batch_id): batch_item_doc = create_item(item_name, is_stock_item=1) From 2de69e2b1267c62fd8568801e948a47a81bf8bdf Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 24 Jul 2024 14:00:57 +0000 Subject: [PATCH 12/83] chore(release): Bumped to Version 15.31.1 ## [15.31.1](https://github.com/frappe/erpnext/compare/v15.31.0...v15.31.1) (2024-07-24) ### Bug Fixes * incorrect current qty for the batch in stock reco (backport [#42434](https://github.com/frappe/erpnext/issues/42434)) (backport [#42459](https://github.com/frappe/erpnext/issues/42459)) ([#42463](https://github.com/frappe/erpnext/issues/42463)) ([4bae419](https://github.com/frappe/erpnext/commit/4bae4194abbf962d2f4b7fdfeaea0232fdaa6aa5)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 4de860c504e..62a018c0e6b 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.31.0" +__version__ = "15.31.1" def get_default_company(user=None): From 334c4d06766b67a4e35b4ec4fe99a9d8dc07691a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 27 Jul 2024 11:07:20 +0530 Subject: [PATCH 13/83] fix: dynamic condition in the pricing rule not working (backport #42467) (backport #42495) (#42496) fix: dynamic condition in the pricing rule not working (backport #42467) (#42495) fix: dynamic condition in the pricing rule not working (#42467) (cherry picked from commit 0e817f42ef96632df164fac6e5b2949a0d18e9f5) Co-authored-by: rohitwaghchaure (cherry picked from commit ac2ef218968e3855e015cc20cb2225f6d1f32c0c) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- erpnext/public/js/controllers/transaction.js | 2 +- erpnext/stock/get_item_details.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index dfb0ded8139..3e9a286b4cf 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1796,7 +1796,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe me.in_apply_price_list = true; return this.frm.call({ method: "erpnext.stock.get_item_details.apply_price_list", - args: { args: args }, + args: { args: args, doc: me.frm.doc }, callback: function(r) { if (!r.exc) { frappe.run_serially([ diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index a7aa7dce452..fe4d3b8602c 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -1189,7 +1189,7 @@ def get_batch_qty(batch_no, warehouse, item_code): @frappe.whitelist() -def apply_price_list(args, as_doc=False): +def apply_price_list(args, as_doc=False, doc=None): """Apply pricelist on a document-like dict object and return as {'parent': dict, 'children': list} @@ -1228,7 +1228,7 @@ def apply_price_list(args, as_doc=False): for item in item_list: args_copy = frappe._dict(args.copy()) args_copy.update(item) - item_details = apply_price_list_on_item(args_copy) + item_details = apply_price_list_on_item(args_copy, doc=doc) children.append(item_details) if as_doc: @@ -1246,10 +1246,10 @@ def apply_price_list(args, as_doc=False): return {"parent": parent, "children": children} -def apply_price_list_on_item(args): +def apply_price_list_on_item(args, doc=None): item_doc = frappe.db.get_value("Item", args.item_code, ["name", "variant_of"], as_dict=1) item_details = get_price_list_rate(args, item_doc) - item_details.update(get_pricing_rule_for_item(args)) + item_details.update(get_pricing_rule_for_item(args, doc=doc)) return item_details From 4b66fcad64aa3f64aa3d4727d2d89e23d4f5b617 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Sat, 27 Jul 2024 05:38:30 +0000 Subject: [PATCH 14/83] chore(release): Bumped to Version 15.31.2 ## [15.31.2](https://github.com/frappe/erpnext/compare/v15.31.1...v15.31.2) (2024-07-27) ### Bug Fixes * dynamic condition in the pricing rule not working (backport [#42467](https://github.com/frappe/erpnext/issues/42467)) (backport [#42495](https://github.com/frappe/erpnext/issues/42495)) ([#42496](https://github.com/frappe/erpnext/issues/42496)) ([334c4d0](https://github.com/frappe/erpnext/commit/334c4d06766b67a4e35b4ec4fe99a9d8dc07691a)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 62a018c0e6b..496ee5fe286 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.31.1" +__version__ = "15.31.2" def get_default_company(user=None): From da3eddeb26fa0bf2510c73b34ddeaba91bfa7938 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 31 Jul 2024 06:03:49 +0000 Subject: [PATCH 15/83] chore(release): Bumped to Version 15.31.3 ## [15.31.3](https://github.com/frappe/erpnext/compare/v15.31.2...v15.31.3) (2024-07-31) ### Bug Fixes * Adjust initial month's depreciation to end of depreciation period ([9d2ef4d](https://github.com/frappe/erpnext/commit/9d2ef4d3e8430f358e80a8d171816ef807d4d84d)) * builtins.KeyError: ('ABC', 'Store - CP') (backport [#42505](https://github.com/frappe/erpnext/issues/42505)) ([#42509](https://github.com/frappe/erpnext/issues/42509)) ([f25b38c](https://github.com/frappe/erpnext/commit/f25b38caf58ff5cb469c3c71a080a339c5eaef06)) * consider payment entries for checking if tds is deducted ([183ac41](https://github.com/frappe/erpnext/commit/183ac4155046dc5d18f9a28c560b7586c5f12b4b)) * dynamic condition in the pricing rule not working (backport [#42467](https://github.com/frappe/erpnext/issues/42467)) ([#42495](https://github.com/frappe/erpnext/issues/42495)) ([ac2ef21](https://github.com/frappe/erpnext/commit/ac2ef218968e3855e015cc20cb2225f6d1f32c0c)) * field_type is small text for v15 ([9e99eda](https://github.com/frappe/erpnext/commit/9e99eda3c3d2fa1ca409639fe559a5763b03b6d1)) * fields alteration related to subcontracting ([80d4dc2](https://github.com/frappe/erpnext/commit/80d4dc2016cd692b5e515b08e559324600b0ce43)) * Fields Modification for Subcontracting DocTypes ([#42383](https://github.com/frappe/erpnext/issues/42383)) ([422824b](https://github.com/frappe/erpnext/commit/422824b9e78963bb20fde2f3967950e20b78525e)) * ignore duplicates while creating default templates ([aea8271](https://github.com/frappe/erpnext/commit/aea8271f7e14ff6179e6f211d00175e086d90758)) * incorrect cost_center on AR/AP report ([0c2e948](https://github.com/frappe/erpnext/commit/0c2e9480cb8e4f42a2d90fd6b51e0479be20bb14)) * incorrect current qty for the batch in stock reco (backport [#42434](https://github.com/frappe/erpnext/issues/42434)) ([#42459](https://github.com/frappe/erpnext/issues/42459)) ([298a569](https://github.com/frappe/erpnext/commit/298a5699f138d795d69889b63ece45400328499b)) * keyerror posting_time (backport [#42452](https://github.com/frappe/erpnext/issues/42452)) ([#42460](https://github.com/frappe/erpnext/issues/42460)) ([2d2140a](https://github.com/frappe/erpnext/commit/2d2140aad0fb306d9f6a65402aea1fc2d8e13deb)) * not able to save BOM Creator ([#42540](https://github.com/frappe/erpnext/issues/42540)) ([61280e6](https://github.com/frappe/erpnext/commit/61280e607269bc4991ec863fe166895e55468afd)) * parenttype in item wise purchase and sales register ([322fbe9](https://github.com/frappe/erpnext/commit/322fbe92eed9d0fa6bd5d597d382443bcf819c7a)) * performance issue for the report Purchase Order Analysis report (backport [#42503](https://github.com/frappe/erpnext/issues/42503)) ([#42507](https://github.com/frappe/erpnext/issues/42507)) ([edf1fcb](https://github.com/frappe/erpnext/commit/edf1fcb7429eab23ca54c8c0c5c1d600e1d0dcd5)) * price_list_currency not found error (backport [#42534](https://github.com/frappe/erpnext/issues/42534)) ([#42539](https://github.com/frappe/erpnext/issues/42539)) ([5fa185d](https://github.com/frappe/erpnext/commit/5fa185d480000ead606e8c0dcfe93c303b6b2f82)) * purchase return from rejected warehouse (backport [#42531](https://github.com/frappe/erpnext/issues/42531)) ([#42535](https://github.com/frappe/erpnext/issues/42535)) ([b7d70ac](https://github.com/frappe/erpnext/commit/b7d70ac9286aad917bc73a903dc2557c59c8c64f)) * set pos data if not return doc ([25fe08e](https://github.com/frappe/erpnext/commit/25fe08eb740ebeb8e5a6c39189c1d92651f08a6b)) * **tests:** added tests for usecase ([1390c86](https://github.com/frappe/erpnext/commit/1390c86fc488e17d64fe6dc5b8bd22c03c08f9e7)) * warehouse filter in Product Bundle Balance (backport [#42532](https://github.com/frappe/erpnext/issues/42532)) ([#42537](https://github.com/frappe/erpnext/issues/42537)) ([826577c](https://github.com/frappe/erpnext/commit/826577c88f12dcb4b25a5a051c97b9158f4a6632)) * Warranty Expiry Date not set in the serial number (backport [#42513](https://github.com/frappe/erpnext/issues/42513)) ([#42515](https://github.com/frappe/erpnext/issues/42515)) ([fc0db19](https://github.com/frappe/erpnext/commit/fc0db1941a5915f7d2d3c9b79e27d7fce8e30b35)) ### Performance Improvements * huge number of serial no creation (backport [#42522](https://github.com/frappe/erpnext/issues/42522)) ([#42544](https://github.com/frappe/erpnext/issues/42544)) ([6840f6c](https://github.com/frappe/erpnext/commit/6840f6cb26054c89b8277bbbd4a06a96b39dcd68)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 496ee5fe286..29a6e351461 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.31.2" +__version__ = "15.31.3" def get_default_company(user=None): From bf0e2b3b52d2bb0f5f0d4a07923c4ac23a7842df Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:22:33 +0530 Subject: [PATCH 16/83] fix: inter transfer delivery note issue with batch (backport #42552) (#42556) fix: inter transfer delivery note issue with batch (#42552) (cherry picked from commit f620ef20aee3e74528d1c3916a77ff4adfeb0f08) Co-authored-by: rohitwaghchaure (cherry picked from commit 97cc3082e190e730c467c3db85dddb1f62a963cb) --- erpnext/controllers/selling_controller.py | 4 +- .../purchase_receipt/test_purchase_receipt.py | 116 ++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 7a85d2230f1..fd856194559 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -539,7 +539,9 @@ class SellingController(StockController): def get_sle_for_source_warehouse(self, item_row): serial_and_batch_bundle = ( - item_row.serial_and_batch_bundle if not self.is_internal_transfer() else None + item_row.serial_and_batch_bundle + if not self.is_internal_transfer() or self.docstatus == 1 + else None ) if serial_and_batch_bundle and self.is_internal_transfer() and self.is_return: if self.docstatus == 1: diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 416a2db43c4..c239360d945 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -3476,6 +3476,122 @@ class TestPurchaseReceipt(FrappeTestCase): frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1) + def test_internal_transfer_for_batch_items_with_cancel_use_serial_batch_fields(self): + from erpnext.controllers.sales_and_purchase_return import make_return_doc + from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_purchase_receipt + from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note + + frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1) + frappe.db.set_single_value("Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 0) + + prepare_data_for_internal_transfer() + + customer = "_Test Internal Customer 2" + company = "_Test Company with perpetual inventory" + + batch_item_doc = make_item( + "_Test Batch Item For Stock Transfer Cancel Case 11", + {"has_batch_no": 1, "create_new_batch": 1, "batch_number_series": "USBF11-BT-CANBIFST-.####"}, + ) + + serial_item_doc = make_item( + "_Test Serial No Item For Stock Transfer Cancel Case 11", + {"has_serial_no": 1, "serial_no_series": "USBF11-BT-CANBIFST-.####"}, + ) + + inward_entry = make_purchase_receipt( + item_code=batch_item_doc.name, + qty=10, + rate=150, + warehouse="Stores - TCP1", + company="_Test Company with perpetual inventory", + use_serial_batch_fields=1, + do_not_submit=1, + ) + + inward_entry.append( + "items", + { + "item_code": serial_item_doc.name, + "qty": 15, + "rate": 250, + "item_name": serial_item_doc.item_name, + "conversion_factor": 1.0, + "uom": serial_item_doc.stock_uom, + "stock_uom": serial_item_doc.stock_uom, + "warehouse": "Stores - TCP1", + "use_serial_batch_fields": 1, + }, + ) + + inward_entry.submit() + inward_entry.reload() + + for row in inward_entry.items: + self.assertTrue(row.serial_and_batch_bundle) + + inter_transfer_dn = create_delivery_note( + item_code=inward_entry.items[0].item_code, + company=company, + customer=customer, + cost_center="Main - TCP1", + expense_account="Cost of Goods Sold - TCP1", + qty=10, + rate=500, + warehouse="Stores - TCP1", + target_warehouse="Work In Progress - TCP1", + batch_no=get_batch_from_bundle(inward_entry.items[0].serial_and_batch_bundle), + use_serial_batch_fields=1, + do_not_submit=1, + ) + + inter_transfer_dn.append( + "items", + { + "item_code": serial_item_doc.name, + "qty": 15, + "rate": 350, + "item_name": serial_item_doc.item_name, + "conversion_factor": 1.0, + "uom": serial_item_doc.stock_uom, + "stock_uom": serial_item_doc.stock_uom, + "warehouse": "Stores - TCP1", + "target_warehouse": "Work In Progress - TCP1", + "serial_no": "\n".join( + get_serial_nos_from_bundle(inward_entry.items[1].serial_and_batch_bundle) + ), + "use_serial_batch_fields": 1, + }, + ) + + inter_transfer_dn.submit() + inter_transfer_dn.reload() + for row in inter_transfer_dn.items: + if row.item_code == batch_item_doc.name: + self.assertEqual(row.rate, 150.0) + else: + self.assertEqual(row.rate, 250.0) + + self.assertTrue(row.serial_and_batch_bundle) + + inter_transfer_pr = make_inter_company_purchase_receipt(inter_transfer_dn.name) + for row in inter_transfer_pr.items: + row.from_warehouse = "Work In Progress - TCP1" + row.warehouse = "Stores - TCP1" + inter_transfer_pr.submit() + + for row in inter_transfer_pr.items: + if row.item_code == batch_item_doc.name: + self.assertEqual(row.rate, 150.0) + else: + self.assertEqual(row.rate, 250.0) + + self.assertTrue(row.serial_and_batch_bundle) + + inter_transfer_pr.cancel() + inter_transfer_dn.cancel() + frappe.db.set_single_value("Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 1) + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier From 703b9accb8b6ffa3666f6d9c7d34a9d248fd4b0a Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 1 Aug 2024 09:12:25 +0000 Subject: [PATCH 17/83] chore(release): Bumped to Version 15.31.4 ## [15.31.4](https://github.com/frappe/erpnext/compare/v15.31.3...v15.31.4) (2024-08-01) ### Bug Fixes * inter transfer delivery note issue with batch (backport [#42552](https://github.com/frappe/erpnext/issues/42552)) ([#42556](https://github.com/frappe/erpnext/issues/42556)) ([bf0e2b3](https://github.com/frappe/erpnext/commit/bf0e2b3b52d2bb0f5f0d4a07923c4ac23a7842df)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 29a6e351461..c6ee5697976 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.31.3" +__version__ = "15.31.4" def get_default_company(user=None): From 02a31caa050556408fdae1e8ed5121e2783f4218 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 3 Aug 2024 09:27:16 +0530 Subject: [PATCH 18/83] fix: use get_last_day to get the correct date (backport #42564) (#42602) fix: use get_last_day to get the correct date (#42564) (cherry picked from commit 5d58eb67a6e025811ef0b2f1b96e3a5ccbded336) Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> --- .../asset_depreciation_schedule.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py index 02fcb8efb3d..e7b5a25cc73 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py @@ -729,10 +729,15 @@ def get_daily_depr_amount(asset, row, schedule_idx, amount): ) ), add_days( - add_months( - row.depreciation_start_date, - (row.frequency_of_depreciation * (asset.opening_number_of_booked_depreciations + 1)) - * -1, + get_last_day( + add_months( + row.depreciation_start_date, + ( + row.frequency_of_depreciation + * (asset.opening_number_of_booked_depreciations + 1) + ) + * -1, + ), ), 1, ), From d8080910c6a243b33e55409e42cb07ea56ca85c5 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Sat, 3 Aug 2024 03:58:31 +0000 Subject: [PATCH 19/83] chore(release): Bumped to Version 15.31.5 ## [15.31.5](https://github.com/frappe/erpnext/compare/v15.31.4...v15.31.5) (2024-08-03) ### Bug Fixes * use get_last_day to get the correct date (backport [#42564](https://github.com/frappe/erpnext/issues/42564)) ([#42602](https://github.com/frappe/erpnext/issues/42602)) ([02a31ca](https://github.com/frappe/erpnext/commit/02a31caa050556408fdae1e8ed5121e2783f4218)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index c6ee5697976..efe34d54580 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.31.4" +__version__ = "15.31.5" def get_default_company(user=None): From 2e3b2db03b902fbed0b3fec165f78d9b4a2110de Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 7 Aug 2024 09:30:48 +0000 Subject: [PATCH 20/83] chore(release): Bumped to Version 15.32.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # [15.32.0](https://github.com/frappe/erpnext/compare/v15.31.5...v15.32.0) (2024-08-07) ### Bug Fixes * 'undefined' in PL and BS report summary on Consolidated report ([3da7071](https://github.com/frappe/erpnext/commit/3da7071327810a0a6c10c1decc841cd2a2df5e4c)) * all warehouse filter for the stock report (backport [#42584](https://github.com/frappe/erpnext/issues/42584)) ([#42604](https://github.com/frappe/erpnext/issues/42604)) ([830b95b](https://github.com/frappe/erpnext/commit/830b95bdcbfb4e7cb513ef8f3dd21072538b3a07)) * company filter for filtring tax withheld vouchers ([3ad1f2d](https://github.com/frappe/erpnext/commit/3ad1f2d0d0ae299dddcb53010f276c54dc43fdad)) * disable primary action button only when there are no active capitalization ([2d644ac](https://github.com/frappe/erpnext/commit/2d644ac066746f4ce2e6335dcf49f2765aafc5d2)) * Discount and taxes in return document should follow the reference document (backport [#41911](https://github.com/frappe/erpnext/issues/41911)) ([#42574](https://github.com/frappe/erpnext/issues/42574)) ([9321408](https://github.com/frappe/erpnext/commit/93214081549295af170e838e6ebdf5bc8274c9c2)) * do not update item price and last purchase rate for inter transf… (backport [#42616](https://github.com/frappe/erpnext/issues/42616)) ([#42633](https://github.com/frappe/erpnext/issues/42633)) ([59b9b7d](https://github.com/frappe/erpnext/commit/59b9b7dc9185fee1814d5ef7d89d0875fead4bf7)) * german translations ([f27e9f3](https://github.com/frappe/erpnext/commit/f27e9f30890badb5b793e5523acc5fc2836ec2c8)) * inter transfer delivery note issue with batch (backport [#42552](https://github.com/frappe/erpnext/issues/42552)) ([#42556](https://github.com/frappe/erpnext/issues/42556)) ([97cc308](https://github.com/frappe/erpnext/commit/97cc3082e190e730c467c3db85dddb1f62a963cb)) * min height for rows in sales funnel ([2f81c99](https://github.com/frappe/erpnext/commit/2f81c991438a678ab163c0dc796124f447dc02cc)) * resolved conflict ([#42557](https://github.com/frappe/erpnext/issues/42557)) ([c3293d1](https://github.com/frappe/erpnext/commit/c3293d110c538c9f0888dd6c7dffe8ab36bf3632)) * reverse debit credit for party gl entry in payment entry based on negative amount ([#42367](https://github.com/frappe/erpnext/issues/42367)) ([14f9aef](https://github.com/frappe/erpnext/commit/14f9aef55cd2b48478f48b5f8b3a65534724c352)) * set currency on change of company considering customer default currency (backport [#42405](https://github.com/frappe/erpnext/issues/42405)) ([#42547](https://github.com/frappe/erpnext/issues/42547)) ([7c8d13c](https://github.com/frappe/erpnext/commit/7c8d13c51adc9be25264cfbba96321ef655970ee)) * set query filters for sales / purchase tax template on PE ([dc9cf74](https://github.com/frappe/erpnext/commit/dc9cf74be87c26ad8b0bf22c6bc145523953b28a)) * use get_last_day to get the correct date (backport [#42564](https://github.com/frappe/erpnext/issues/42564)) ([#42598](https://github.com/frappe/erpnext/issues/42598)) ([2de86eb](https://github.com/frappe/erpnext/commit/2de86eb0f45cbc287f238d7091ee2af99b8df5a7)) ### Features * expiry date column in Available Batch Report (backport [#42628](https://github.com/frappe/erpnext/issues/42628)) ([#42642](https://github.com/frappe/erpnext/issues/42642)) ([d8768c5](https://github.com/frappe/erpnext/commit/d8768c537733cf105761e9f95b523f44ec4cf5f7)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index efe34d54580..08765895684 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.31.5" +__version__ = "15.32.0" def get_default_company(user=None): From 2aa90fdc14bbd59d5f7471865038430f049c9ed2 Mon Sep 17 00:00:00 2001 From: Lakshit Jain <108322669+ljain112@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:19:54 +0530 Subject: [PATCH 21/83] fix: promotional scheme doctype fields in consitency with pricing rule (#42432) * fix: add "round_free_qty" check box in promotional scheme * fix: add `add_for_price_list` field * fix: set_query in setup for promotional scheme --------- (cherry picked from commit 8624aeca54eacf4b32e86b8d1d82245fcef65355) # Conflicts: # erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json # erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json (cherry picked from commit 87d8603d1d70c4a1d169322d99de3218a16ad5da) --- .../promotional_scheme/promotional_scheme.js | 12 ++++++++++++ .../promotional_scheme/promotional_scheme.py | 2 ++ .../promotional_scheme_price_discount.json | 12 ++++++++++++ .../promotional_scheme_price_discount.py | 1 + .../promotional_scheme_product_discount.json | 13 ++++++++++++- .../promotional_scheme_product_discount.py | 1 + 6 files changed, 40 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.js b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.js index 7a26c07d01f..43261e4080a 100644 --- a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.js +++ b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.js @@ -2,6 +2,18 @@ // For license information, please see license.txt frappe.ui.form.on("Promotional Scheme", { + setup: function (frm) { + frm.set_query("for_price_list", "price_discount_slabs", (doc) => { + return { + filters: { + selling: doc.selling, + buying: doc.buying, + currency: doc.currency, + }, + }; + }); + }, + refresh: function (frm) { frm.trigger("set_options_for_applicable_for"); frm.trigger("toggle_reqd_apply_on"); diff --git a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py index 71fe156dd7a..86bd2135515 100644 --- a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py +++ b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py @@ -51,6 +51,7 @@ price_discount_fields = [ "discount_percentage", "validate_applied_rule", "apply_multiple_pricing_rules", + "for_price_list", ] product_discount_fields = [ @@ -63,6 +64,7 @@ product_discount_fields = [ "recurse_for", "apply_recursion_over", "apply_multiple_pricing_rules", + "round_free_qty", ] diff --git a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json index aa3696d216d..fc7cd6e0921 100644 --- a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json +++ b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json @@ -21,6 +21,7 @@ "rate", "discount_amount", "discount_percentage", + "for_price_list", "section_break_11", "warehouse", "threshold_percentage", @@ -120,6 +121,13 @@ "fieldtype": "Float", "label": "Discount Percentage" }, + { + "depends_on": "eval:doc.rate_or_discount!=\"Rate\"", + "fieldname": "for_price_list", + "fieldtype": "Link", + "label": "For Price List", + "options": "Price List" + }, { "fieldname": "section_break_11", "fieldtype": "Section Break" @@ -169,7 +177,11 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], +<<<<<<< HEAD "modified": "2021-11-16 00:25:33.843996", +======= + "modified": "2024-07-23 12:33:46.574950", +>>>>>>> 8624aeca54 (fix: promotional scheme doctype fields in consitency with pricing rule (#42432)) "modified_by": "Administrator", "module": "Accounts", "name": "Promotional Scheme Price Discount", diff --git a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.py b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.py index 545c17dda89..3e07309dca5 100644 --- a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.py +++ b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.py @@ -19,6 +19,7 @@ class PromotionalSchemePriceDiscount(Document): disable: DF.Check discount_amount: DF.Currency discount_percentage: DF.Float + for_price_list: DF.Link | None max_amount: DF.Currency max_qty: DF.Float min_amount: DF.Currency diff --git a/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json b/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json index 4e61d04ad21..75bcad8c2c4 100644 --- a/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json +++ b/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json @@ -22,6 +22,7 @@ "column_break_9", "free_item_uom", "free_item_rate", + "round_free_qty", "section_break_12", "warehouse", "threshold_percentage", @@ -181,12 +182,22 @@ "fieldtype": "Float", "label": "Apply Recursion Over (As Per Transaction UOM)", "mandatory_depends_on": "is_recursive" + }, + { + "default": "0", + "fieldname": "round_free_qty", + "fieldtype": "Check", + "label": "Round Free Qty" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], +<<<<<<< HEAD "modified": "2024-03-12 12:53:58.199108", +======= + "modified": "2024-07-22 17:25:07.880984", +>>>>>>> 8624aeca54 (fix: promotional scheme doctype fields in consitency with pricing rule (#42432)) "modified_by": "Administrator", "module": "Accounts", "name": "Promotional Scheme Product Discount", @@ -195,4 +206,4 @@ "sort_field": "modified", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.py b/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.py index 1463a7b93a4..b071d658cb4 100644 --- a/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.py +++ b/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.py @@ -53,6 +53,7 @@ class PromotionalSchemeProductDiscount(Document): "20", ] recurse_for: DF.Float + round_free_qty: DF.Check rule_description: DF.SmallText same_item: DF.Check threshold_percentage: DF.Percent From a983d65404f73ced665834dbfb06945217879d87 Mon Sep 17 00:00:00 2001 From: Lakshit Jain <108322669+ljain112@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:38:38 +0530 Subject: [PATCH 22/83] chore: resolve conflicts (#42553) (cherry picked from commit 78eb4436149c5eeff71ee78f0d56cfa433f4f937) --- .../promotional_scheme_price_discount.json | 6 +----- .../promotional_scheme_product_discount.json | 4 ---- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json index fc7cd6e0921..32de0cec6fe 100644 --- a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json +++ b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json @@ -177,11 +177,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], -<<<<<<< HEAD - "modified": "2021-11-16 00:25:33.843996", -======= "modified": "2024-07-23 12:33:46.574950", ->>>>>>> 8624aeca54 (fix: promotional scheme doctype fields in consitency with pricing rule (#42432)) "modified_by": "Administrator", "module": "Accounts", "name": "Promotional Scheme Price Discount", @@ -189,4 +185,4 @@ "permissions": [], "sort_field": "modified", "sort_order": "DESC" -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json b/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json index 75bcad8c2c4..50d3ccb0dec 100644 --- a/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json +++ b/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json @@ -193,11 +193,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], -<<<<<<< HEAD - "modified": "2024-03-12 12:53:58.199108", -======= "modified": "2024-07-22 17:25:07.880984", ->>>>>>> 8624aeca54 (fix: promotional scheme doctype fields in consitency with pricing rule (#42432)) "modified_by": "Administrator", "module": "Accounts", "name": "Promotional Scheme Product Discount", From 6a4f06cf4a547b569b0bea79ff76f01b3b93783c Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 8 Aug 2024 07:06:38 +0000 Subject: [PATCH 23/83] chore(release): Bumped to Version 15.32.1 ## [15.32.1](https://github.com/frappe/erpnext/compare/v15.32.0...v15.32.1) (2024-08-08) ### Bug Fixes * promotional scheme doctype fields in consitency with pricing rule ([#42432](https://github.com/frappe/erpnext/issues/42432)) ([2aa90fd](https://github.com/frappe/erpnext/commit/2aa90fdc14bbd59d5f7471865038430f049c9ed2)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 08765895684..987a8717ce7 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.32.0" +__version__ = "15.32.1" def get_default_company(user=None): From 73af5be1c3be9a1fab19de1b96d63f907dcde8a1 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 14 Aug 2024 08:02:34 +0000 Subject: [PATCH 24/83] chore(release): Bumped to Version 15.33.0 # [15.33.0](https://github.com/frappe/erpnext/compare/v15.32.1...v15.33.0) (2024-08-14) ### Bug Fixes * allow sale of asset for internal transfer ([97cadfe](https://github.com/frappe/erpnext/commit/97cadfe5d360128934aaaac9346537a47515cf75)) * cancel Journal Entry on cancellation of asset value adjustment ([a429f2f](https://github.com/frappe/erpnext/commit/a429f2f626fdae163b7661935dd28f42ed68ce24)) * currency changing while making PR from the PO (backport [#42718](https://github.com/frappe/erpnext/issues/42718)) ([#42721](https://github.com/frappe/erpnext/issues/42721)) ([50b1fa5](https://github.com/frappe/erpnext/commit/50b1fa5deb2a502782cac6884c4ed9f82b1cd335)) * delivery note creation issue (backport [#42696](https://github.com/frappe/erpnext/issues/42696)) ([#42697](https://github.com/frappe/erpnext/issues/42697)) ([6f16ae3](https://github.com/frappe/erpnext/commit/6f16ae3e00d276b95cf805318d70591aecadfb5e)) * dimensions in common party journal entry ([fd4143e](https://github.com/frappe/erpnext/commit/fd4143e6862b3caa38d3f579bb2402be83f313fc)) * duplicate labels in stock entry (backport [#42756](https://github.com/frappe/erpnext/issues/42756)) ([#42758](https://github.com/frappe/erpnext/issues/42758)) ([8624a0a](https://github.com/frappe/erpnext/commit/8624a0abce26576616783b7ce4d43f912bc80d68)) * error message in coa importer ([20c1bcd](https://github.com/frappe/erpnext/commit/20c1bcd654ea6e6e795546379355b17758bb86b5)) * **Exchange Rate Revaluation:** translatable strings ([da6eea7](https://github.com/frappe/erpnext/commit/da6eea77437cffce628a08ef2ce5e6da2afdf193)) * fetch months last date to avoid miscalculation ([765c110](https://github.com/frappe/erpnext/commit/765c1104c4c4a76a2e65914b6e9fbf58e32ecb09)) * force fetch updates for subcription ([582fffc](https://github.com/frappe/erpnext/commit/582fffca931eca7754e24eee61d52c1d68ef8a4c)) * german translation of exit ([a2df276](https://github.com/frappe/erpnext/commit/a2df2768802c54001286913ac17ebaf207e40351)) * german translations for incoterms ([9789648](https://github.com/frappe/erpnext/commit/9789648175e61ea64d9a326c2f4b274067eecbc0)) * ledger entries for pos return with update outstanding for self ([8cd1952](https://github.com/frappe/erpnext/commit/8cd1952da3d07dc741aff6f3608480f9101f1e15)) * Maintain same rate on qty change on Quotation to Sales Order ([7ed7c22](https://github.com/frappe/erpnext/commit/7ed7c22469ba8876476214240540237491097b45)) * patch to fix incorrect against_voucher references in ledger ([389227b](https://github.com/frappe/erpnext/commit/389227bce8e62d25e0dc97a51885df1674e56b54)) * pre-commit for better code formatting ([94f4c92](https://github.com/frappe/erpnext/commit/94f4c92a039ae4039df55eb32bec0739387c6a65)) * price list when invoice created from timesheet ([2926915](https://github.com/frappe/erpnext/commit/2926915a06b13e2a29b07cad589ad0f2677b54e2)) * price list when invoice created from timesheet ([536dc47](https://github.com/frappe/erpnext/commit/536dc47eb062f7d512b0909a920f09592e528e49)) * promotional scheme doctype fields in consitency with pricing rule ([#42432](https://github.com/frappe/erpnext/issues/42432)) ([87d8603](https://github.com/frappe/erpnext/commit/87d8603d1d70c4a1d169322d99de3218a16ad5da)) * resolved conflict ([defd554](https://github.com/frappe/erpnext/commit/defd5541b060dd901171fcb2ffc0029c75931b26)) * Sort lists before calling itertools.groupby ([d8939e0](https://github.com/frappe/erpnext/commit/d8939e0bb0136ed6947d0f542ae0c91873f57237)) * text color in sales funnel report based on theme ([a8de8ae](https://github.com/frappe/erpnext/commit/a8de8aecf5a2e85bab16ae9a52b7c2bfe7038a4a)) * typeerror on payment entry ([64e75a8](https://github.com/frappe/erpnext/commit/64e75a8e089c7b347f255c7c8083d4297c0ea069)) * update 'Paid Amount' on forex payment request ([c71f06b](https://github.com/frappe/erpnext/commit/c71f06be9e8ad793a3d57cef7598415220e67925)) * Update Rate as per Valuation Rate for Internal Transfers only if Setting is Enabled ([#42050](https://github.com/frappe/erpnext/issues/42050)) ([6e833cc](https://github.com/frappe/erpnext/commit/6e833cce6af9d9542c23e74bda7c0b0e029a683e)) * warning message for negative stock (backport [#42683](https://github.com/frappe/erpnext/issues/42683)) ([#42710](https://github.com/frappe/erpnext/issues/42710)) ([a990577](https://github.com/frappe/erpnext/commit/a99057754d436022555101230b6a53e417fe9e61)) ### Features * changes in opportunity.py to show contacts and addresses from referenced and opportunities ([3cac4a5](https://github.com/frappe/erpnext/commit/3cac4a598fdead4f35f4130a899950625f51f167)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 987a8717ce7..b7406969305 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.32.1" +__version__ = "15.33.0" def get_default_company(user=None): From a3e3585e5054d254ebc198e34498738160e8569d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 11:47:53 +0530 Subject: [PATCH 25/83] fix: not able to create the batch (backport #42784) (backport #42785) (#42786) fix: not able to create the batch (backport #42784) (#42785) fix: not able to create the batch (#42784) (cherry picked from commit 32c4fab14f83dc5e2cec0c21395713e54d2537c9) Co-authored-by: rohitwaghchaure (cherry picked from commit 0f9849e6727b4fef3e3bf75048de553714b08298) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- erpnext/stock/doctype/batch/batch.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/batch/batch.js b/erpnext/stock/doctype/batch/batch.js index 4ed428421ca..77e4e560acf 100644 --- a/erpnext/stock/doctype/batch/batch.js +++ b/erpnext/stock/doctype/batch/batch.js @@ -3,7 +3,7 @@ frappe.ui.form.on("Batch", { setup: (frm) => { - frm.fields_dict["item"].get_query = function (doc, cdt, cdn) { + frm.set_query("item", () => { return { query: "erpnext.controllers.queries.item_query", filters: { @@ -11,7 +11,7 @@ frappe.ui.form.on("Batch", { has_batch_no: 1, }, }; - }; + }); }, refresh: (frm) => { if (!frm.is_new()) { From fbf1160357d4dd3c7970f8663c8cfa8a5bbc1f35 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Fri, 16 Aug 2024 06:19:07 +0000 Subject: [PATCH 26/83] chore(release): Bumped to Version 15.33.1 ## [15.33.1](https://github.com/frappe/erpnext/compare/v15.33.0...v15.33.1) (2024-08-16) ### Bug Fixes * not able to create the batch (backport [#42784](https://github.com/frappe/erpnext/issues/42784)) (backport [#42785](https://github.com/frappe/erpnext/issues/42785)) ([#42786](https://github.com/frappe/erpnext/issues/42786)) ([a3e3585](https://github.com/frappe/erpnext/commit/a3e3585e5054d254ebc198e34498738160e8569d)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index b7406969305..e28c96e466e 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.33.0" +__version__ = "15.33.1" def get_default_company(user=None): From 4d9f522f22d1abaea2a61714151767002f322a45 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 16 Aug 2024 13:07:53 +0530 Subject: [PATCH 27/83] fix(patch): replace repost with direct sql to update 'against_voucher (cherry picked from commit 13bb48434fd6897dcef2a7d79333d5373bec0cdb) --- .../v14_0/update_pos_return_ledger_entries.py | 112 ++++++++++++++---- 1 file changed, 89 insertions(+), 23 deletions(-) diff --git a/erpnext/patches/v14_0/update_pos_return_ledger_entries.py b/erpnext/patches/v14_0/update_pos_return_ledger_entries.py index 60e867d1bcb..6a6d15e0b34 100644 --- a/erpnext/patches/v14_0/update_pos_return_ledger_entries.py +++ b/erpnext/patches/v14_0/update_pos_return_ledger_entries.py @@ -1,8 +1,64 @@ import frappe from frappe import qb +from erpnext.accounts.utils import update_voucher_outstanding -def execute(): + +def get_valid_against_voucher_ref(pos_returns): + sinv = qb.DocType("Sales Invoice") + res = ( + qb.from_(sinv) + .select(sinv.name, sinv.return_against) + .where(sinv.name.isin(pos_returns) & sinv.return_against.notnull()) + .orderby(sinv.name) + .run(as_dict=True) + ) + return res + + +def build_dict_of_valid_against_reference(pos_returns): + _against_ref_dict = frappe._dict() + res = get_valid_against_voucher_ref(pos_returns) + for x in res: + _against_ref_dict[x.name] = x.return_against + return _against_ref_dict + + +def fix_incorrect_against_voucher_ref(affected_pos_returns): + if affected_pos_returns: + valid_against_voucher_dict = build_dict_of_valid_against_reference(affected_pos_returns) + + gle = qb.DocType("GL Entry") + gles_with_invalid_against = ( + qb.from_(gle) + .select(gle.name, gle.voucher_no) + .where( + gle.voucher_no.isin(affected_pos_returns) + & gle.against_voucher.notnull() + & gle.against_voucher.eq(gle.voucher_no) + & gle.is_cancelled.eq(0) + ) + .run(as_dict=True) + ) + # Update GL + if gles_with_invalid_against: + for gl in gles_with_invalid_against: + frappe.db.set_value( + "GL Entry", + gl.name, + "against_voucher", + valid_against_voucher_dict[gl.voucher_no], + ) + + # Update Payment Ledger + ple = qb.DocType("Payment Ledger Entry") + for x in affected_pos_returns: + qb.update(ple).set(ple.against_voucher_no, valid_against_voucher_dict[x]).where( + ple.voucher_no.eq(x) & ple.delinked.eq(0) + ).run() + + +def get_pos_returns_with_invalid_against_ref(): sinv = qb.DocType("Sales Invoice") pos_returns_without_self = ( qb.from_(sinv) @@ -32,30 +88,40 @@ def execute(): .run() ) - _vouchers = list(set([x[0] for x in gl_against_references])) - invoice_return_against = ( + if gl_against_references: + _vouchers = list(set([x[0] for x in gl_against_references])) + invoice_return_against = ( + qb.from_(sinv) + .select(sinv.name, sinv.return_against) + .where(sinv.name.isin(_vouchers) & sinv.return_against.notnull()) + .orderby(sinv.name) + .run() + ) + + valid_references = set(invoice_return_against) + actual_references = set(gl_against_references) + + invalid_references = actual_references.difference(valid_references) + if invalid_references: + return [x[0] for x in invalid_references] + return None + + +def update_outstanding_for_affected(affected_pos_returns): + if affected_pos_returns: + sinv = qb.DocType("Sales Invoice") + pos_with_accounts = ( qb.from_(sinv) - .select(sinv.name, sinv.return_against) - .where(sinv.name.isin(_vouchers) & sinv.return_against.notnull()) - .orderby(sinv.name) - .run() + .select(sinv.return_against, sinv.debit_to, sinv.customer) + .where(sinv.name.isin(affected_pos_returns)) + .run(as_dict=True) ) - valid_references = set(invoice_return_against) - actual_references = set(gl_against_references) + for x in pos_with_accounts: + update_voucher_outstanding("Sales Invoice", x.return_against, x.debit_to, "Customer", x.customer) - invalid_references = actual_references.difference(valid_references) - if invalid_references: - # Repost Accounting Ledger - pos_for_reposting = ( - qb.from_(sinv) - .select(sinv.company, sinv.name) - .where(sinv.name.isin([x[0] for x in invalid_references])) - .run(as_dict=True) - ) - for x in pos_for_reposting: - ral = frappe.new_doc("Repost Accounting Ledger") - ral.company = x.company - ral.append("vouchers", {"voucher_type": "Sales Invoice", "voucher_no": x.name}) - ral.save().submit() +def execute(): + affected_pos_returns = get_pos_returns_with_invalid_against_ref() + fix_incorrect_against_voucher_ref(affected_pos_returns) + update_outstanding_for_affected(affected_pos_returns) From eb8213c4e7b47f0dd30b33fb16906486b34ddf7f Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 16 Aug 2024 14:32:53 +0530 Subject: [PATCH 28/83] chore: update patches.txt (cherry picked from commit 1721175a207fde5e06d3f8646a766e4eb3b325b5) --- erpnext/patches.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 797e8cebc80..208c9e58d4f 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -357,7 +357,7 @@ erpnext.patches.v14_0.create_accounting_dimensions_in_reconciliation_tool erpnext.patches.v15_0.allow_on_submit_dimensions_for_repostable_doctypes erpnext.patches.v14_0.update_flag_for_return_invoices #2024-03-22 erpnext.patches.v15_0.create_accounting_dimensions_in_payment_request -erpnext.patches.v14_0.update_pos_return_ledger_entries +erpnext.patches.v14_0.update_pos_return_ledger_entries #2024-08-16 # below migration patch should always run last erpnext.patches.v14_0.migrate_gl_to_payment_ledger erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2023-12-20 From 81b1cbd367298d4f7d6f7566e8d2620bcef2277b Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Fri, 16 Aug 2024 11:09:43 +0000 Subject: [PATCH 29/83] chore(release): Bumped to Version 15.33.2 ## [15.33.2](https://github.com/frappe/erpnext/compare/v15.33.1...v15.33.2) (2024-08-16) ### Bug Fixes * **patch:** replace repost with direct sql to update 'against_voucher ([4d9f522](https://github.com/frappe/erpnext/commit/4d9f522f22d1abaea2a61714151767002f322a45)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index e28c96e466e..c31f06dfa79 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.33.1" +__version__ = "15.33.2" def get_default_company(user=None): From 28c9f2adab218368001e22f9edf66af19d8a8c70 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 21 Aug 2024 05:22:44 +0000 Subject: [PATCH 30/83] chore(release): Bumped to Version 15.33.3 ## [15.33.3](https://github.com/frappe/erpnext/compare/v15.33.2...v15.33.3) (2024-08-21) ### Bug Fixes * Auto Create Serial and Batch Bundle For Outward (backport [#42778](https://github.com/frappe/erpnext/issues/42778)) ([#42792](https://github.com/frappe/erpnext/issues/42792)) ([7cc7179](https://github.com/frappe/erpnext/commit/7cc7179b050edd87cda6519fd76c0e83a31aa909)) * backport german translations from develop ([9e9de4c](https://github.com/frappe/erpnext/commit/9e9de4c99e9f628469f93442c68a2fe8e69002fd)) * bank reconcilation tool cost center company filter adding ([cd59940](https://github.com/frappe/erpnext/commit/cd5994017c6960d6d357784e111e3e825a8cad18)) * Create Sales Order from Quotation for Prospect ([f547bef](https://github.com/frappe/erpnext/commit/f547befeb9f366311f2d9c874498193745d825c3)) * create SO from Quot for Prospect --conflicts ([ec0201c](https://github.com/frappe/erpnext/commit/ec0201cb85f0c46a92993c6082b51507091dffd9)) * create SO from Quot for Prospect --conflicts ([5d7fb1d](https://github.com/frappe/erpnext/commit/5d7fb1d9457c276d6bd91c66546f001f56fdb728)) * disable rename from warehouse ([3a1ad6e](https://github.com/frappe/erpnext/commit/3a1ad6e844e00f6ef12e56404c2efe1575add24b)) * disable rename from warehouse ([40abd82](https://github.com/frappe/erpnext/commit/40abd82e2dd8308a686484b77deec714cea0d05a)) * dropping index to improve performance (backport [#42820](https://github.com/frappe/erpnext/issues/42820)) ([#42821](https://github.com/frappe/erpnext/issues/42821)) ([b24de3e](https://github.com/frappe/erpnext/commit/b24de3e35b5a9eb34390c866fde35dc9b4ea1fe7)) * german translations ([751c209](https://github.com/frappe/erpnext/commit/751c20984f3e05944acdaa2ba73a7506e89badac)) * german translations of "HR" ([6f7fdbe](https://github.com/frappe/erpnext/commit/6f7fdbefac26b8098141880d3f3ea7e74a1b782c)) * ignore pricing rule while making DN from Pick List (backport [#42763](https://github.com/frappe/erpnext/issues/42763)) ([#42768](https://github.com/frappe/erpnext/issues/42768)) ([aba54ba](https://github.com/frappe/erpnext/commit/aba54ba18feadade01f9ff9d2150259c15bfc13e)) * not able to create the batch (backport [#42784](https://github.com/frappe/erpnext/issues/42784)) ([#42785](https://github.com/frappe/erpnext/issues/42785)) ([0f9849e](https://github.com/frappe/erpnext/commit/0f9849e6727b4fef3e3bf75048de553714b08298)) * **patch:** replace repost with direct sql to update 'against_voucher ([e420fa9](https://github.com/frappe/erpnext/commit/e420fa97799ad27a7ddb97c604319774b39e0aca)) * removed extra filter condition ([b84ca04](https://github.com/frappe/erpnext/commit/b84ca04975f5daf691c04870409d3c24dc1cc9d2)) * set up filters for dimensions ([abb8866](https://github.com/frappe/erpnext/commit/abb88662c1ac89dccc42aa3ff3d9825c062a3fa3)) * translatability of boldened text ([4914481](https://github.com/frappe/erpnext/commit/4914481105bba3a665b63784e4b48c03342e3270)) * update the testcase format ([33542cb](https://github.com/frappe/erpnext/commit/33542cb9097751492204d6ec3b0fe3573dbddf36)) * update the testcase format ([549dc28](https://github.com/frappe/erpnext/commit/549dc286d03a7ae267b5e2742704dd9f023ee363)) ### Performance Improvements * asset creation from purchase receipt ([1040198](https://github.com/frappe/erpnext/commit/1040198ce1a4077ec88d9f36adb7db792779e2ab)) * data import for stock entries (backport [#42711](https://github.com/frappe/erpnext/issues/42711)) ([#42819](https://github.com/frappe/erpnext/issues/42819)) ([0344442](https://github.com/frappe/erpnext/commit/0344442d42cbdbe8db2401f1c35d18f13674f786)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index c31f06dfa79..4a3021bda07 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.33.2" +__version__ = "15.33.3" def get_default_company(user=None): From 9f4cb98de65bd050a3ed846c9c6c67b248202714 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:37:00 +0530 Subject: [PATCH 31/83] fix: last purchase rate not updated from purchase invoice (backport #42847) (backport #42853) (#42855) fix: last purchase rate not updated from purchase invoice (backport #42847) (#42853) fix: last purchase rate not updated from purchase invoice (#42847) (cherry picked from commit 5b9309cf3410a4be0e94682ca6151bcc0b4ccb53) Co-authored-by: rohitwaghchaure (cherry picked from commit 2203ea9301eea01714809811ec8f774ebbc59b1e) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- erpnext/controllers/buying_controller.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index a55eded2a4c..f797374d64e 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -689,9 +689,11 @@ class BuyingController(SubcontractingController): if self.doctype in ["Purchase Receipt", "Purchase Invoice"]: self.process_fixed_asset() - if self.doctype in ["Purchase Order", "Purchase Receipt"] and not frappe.db.get_single_value( - "Buying Settings", "disable_last_purchase_rate" - ): + if self.doctype in [ + "Purchase Order", + "Purchase Receipt", + "Purchase Invoice", + ] and not frappe.db.get_single_value("Buying Settings", "disable_last_purchase_rate"): update_last_purchase_rate(self, is_submit=1) def on_cancel(self): From 8d8d84bae46ace28d05b79bee58a472360211dc9 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:37:08 +0530 Subject: [PATCH 32/83] fix: incorrect Received Qty Amount in Purchase Order Analysis (backport #42852) (backport #42854) (#42856) fix: incorrect Received Qty Amount in Purchase Order Analysis (backport #42852) (#42854) fix: incorrect Received Qty Amount in Purchase Order Analysis (#42852) (cherry picked from commit fb846ffa125cbc67f775a35376d0b541b1f5d9d1) Co-authored-by: rohitwaghchaure (cherry picked from commit 72c16097d64384a4218e7646e2c4efcdc0790d82) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../purchase_order_analysis/purchase_order_analysis.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py index da1c70d3179..084c3b5fc2b 100644 --- a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py +++ b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py @@ -40,6 +40,7 @@ def get_data(filters): po = frappe.qb.DocType("Purchase Order") po_item = frappe.qb.DocType("Purchase Order Item") pi_item = frappe.qb.DocType("Purchase Invoice Item") + pr_item = frappe.qb.DocType("Purchase Receipt Item") query = ( frappe.qb.from_(po) @@ -47,6 +48,8 @@ def get_data(filters): .on(po_item.parent == po.name) .left_join(pi_item) .on((pi_item.po_detail == po_item.name) & (pi_item.docstatus == 1)) + .left_join(pr_item) + .on((pr_item.purchase_order_item == po_item.name) & (pr_item.docstatus == 1)) .select( po.transaction_date.as_("date"), po_item.schedule_date.as_("required_date"), @@ -60,7 +63,7 @@ def get_data(filters): (po_item.qty - po_item.received_qty).as_("pending_qty"), Sum(IfNull(pi_item.qty, 0)).as_("billed_qty"), po_item.base_amount.as_("amount"), - (po_item.received_qty * po_item.base_rate).as_("received_qty_amount"), + (pr_item.base_amount).as_("received_qty_amount"), (po_item.billed_amt * IfNull(po.conversion_rate, 1)).as_("billed_amount"), (po_item.base_amount - (po_item.billed_amt * IfNull(po.conversion_rate, 1))).as_( "pending_amount" From 9ac665b4bdd4cde13b8b2a87198019b530adefab Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 21 Aug 2024 11:08:23 +0000 Subject: [PATCH 33/83] chore(release): Bumped to Version 15.33.4 ## [15.33.4](https://github.com/frappe/erpnext/compare/v15.33.3...v15.33.4) (2024-08-21) ### Bug Fixes * incorrect Received Qty Amount in Purchase Order Analysis (backport [#42852](https://github.com/frappe/erpnext/issues/42852)) (backport [#42854](https://github.com/frappe/erpnext/issues/42854)) ([#42856](https://github.com/frappe/erpnext/issues/42856)) ([8d8d84b](https://github.com/frappe/erpnext/commit/8d8d84bae46ace28d05b79bee58a472360211dc9)) * last purchase rate not updated from purchase invoice (backport [#42847](https://github.com/frappe/erpnext/issues/42847)) (backport [#42853](https://github.com/frappe/erpnext/issues/42853)) ([#42855](https://github.com/frappe/erpnext/issues/42855)) ([9f4cb98](https://github.com/frappe/erpnext/commit/9f4cb98de65bd050a3ed846c9c6c67b248202714)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 4a3021bda07..ecf8221f778 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.33.3" +__version__ = "15.33.4" def get_default_company(user=None): From be736cf6415a18d0811095d389a378bb22854d58 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 12 Aug 2024 17:45:11 +0530 Subject: [PATCH 34/83] fix: include erpnext in apps page (cherry picked from commit 1d52ef7afe34b229f33160d95b9acd463afb832f) --- erpnext/hooks.py | 10 ++++++++++ erpnext/public/images/erpnext-logo-blue.png | Bin 0 -> 4235 bytes 2 files changed, 10 insertions(+) create mode 100644 erpnext/public/images/erpnext-logo-blue.png diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 527be6ab337..ee0b33e27db 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -10,6 +10,16 @@ source_link = "https://github.com/frappe/erpnext" app_logo_url = "/assets/erpnext/images/erpnext-logo.svg" +include_as_app = [ + { + "name": "erpnext", + "logo": "/assets/erpnext/images/erpnext-logo-blue.png", + "title": "ERPNext", + "route": "/app/home", + # "has_permission": "erpnext.api.permission.has_app_permission" + } +] + develop_version = "14.x.x-develop" app_include_js = "erpnext.bundle.js" diff --git a/erpnext/public/images/erpnext-logo-blue.png b/erpnext/public/images/erpnext-logo-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..0134b3f0627c5bc95aee1682f7979f9590751b4e GIT binary patch literal 4235 zcmds5X;f3!7Cs50f>0}zp$e$27MUc15RF0{7=$nd1B5|>BA^i&gvcO}I8Z<)6&lb8 zC}T*%Ok^f;K-4f<3?LW~kXV8cQw&I$Ug%q^|K5+jAMIQ3$60sXefC}F+xy#hf9ISe zCkJaq`K|H*07aV<7R~@bxNBqMda0$P;q<)pAs2GOJq!SS)Y^a)nUPDSMo5^m^)XQ1 zr75B{wM%d>6?~L%L4H24jYT3m`KPpuk(_ZUo>0vu~xS9s%57AWw}c()pk4k zYSb6xVQ!>Y*?~x~S$Wl162aQozeB zGStK zj_lvbn=%L38wLE(0sZfZ%G=!%s-E{5(j2F925xSq>`uILdaEqfbXjLE`D-EKrb&$! z+5puQ4Bt{V9;>XwezoUnY_$XG8C{dRg7Ij--dhs}!CJaBpBs~$<&HPrLmRZ)PDKXl z%3_WE&ez*j=tX}bF!Obb0p+yic;i;I0jIfc47E>o0JghaJCx``j?X$oYf;>)1s7_q z1C$GvX$^aWF?rnWCf$n;N1*SSuD$W;bnU7_vLUToP<`rs7^($$6?om8eQf0YvC#{? z%!t#-;Ro*oFgrc-bfgLD397bq^^yhie&U;(6$N#rW*~*eQ}B%-PhcP$YqL5=hl``e|@OIbut`3dqBNOr1G zZLHb`F%L^xuo6GmTX%M`k68jboX&UjCm-lSu&7$$s}tVqK*#Y0i?FWKIog7?ukn}RHHEUDXo;e z8+TOJC+gF4PtjrjbEX+IUnLubuw>4~ z-^oNytkcwtgAJ(EooOrKy4~I-Es2&GR%*4`cYu*LUVI~>Iw;aS7IP(nqN6Nu0BnKH z&<&!*m)0^=H@yxpigW5!a8}nQ^9K*@dl_T{7>^KhMh;&0VixK&tPScy!rH$FeU^0h z^(*y=6ghkI(ns%}D3VNi&y%lm8jdO7)0a}Ibr}l!I1bI4%7!xOtfir*7=8jE5llvn zK7Y-?3!|lgamssT($%;D;+D!!o7j?}BwQ+y!1;~Cx@-^i=?x#7J3u*>VqQ92{Za;O z^Y5_VX(grT{yKK?*73rk*FSMR_lfr^gUUOC*V_)nIGYqfD<`e)yCyi&iZQ^Hm)I-l z%%JJ0fM~01*Wg@?eJSWMeo`B~T!^=oB_;oCNALf`v;N$R+QG(A_>3$FDXta$Y<6{n zHCKxTU;~O*pg4GGoH}6d*nVpMF_%hK&eUIqvI&pIYoddDHnh=V& z?cEwGVoD7>51r6|-`5b)1OX}KVO2Q+Xy%tqV7%c?*K9k+o(5oP(LIHd=Hb>Q2!Or0 ze3*`#uTkS7H|YYq5ASSR%X&Yy0Px(ct!cS#*_S3<4`4|s4(pdPIf%~>V)x^oCAbhf z74TCHk9S1J7DM!0`*1v5rpPtWT_Q`;na(V6t>*L)Rdw<2{@w5&f%n%^6e!#AIC;ccW5tdAq?Rb3eGu)p_tob8$TuWH zz=GO8mgBz`#D7%?YcvilHt|LC5aX~f?Q1ORud%qBnoiV&85_nK()4pDaDRJw{q@k_ z%KPXWveLiuH$T2}e)YS`kbHSx32*z4-b>cN>-7IOi+^V85mcQsj+@tF zjD4N|`CjoSy#Lg%)~fKp3d&-!gcOfh$s^sRjXfxr0oe}PL7prB!}tp=n3{kcuH|wu zx49Mu#6( z@hj-EF&H3;axR=Rq-jc}0(QI4{W!fJ7hbIdQiNZ26^$*O!h6dCSR*RI(X&4m00lHo z<3xA9#Hv|}EW9jP<~(8aX@EGwo)94e)cN%Xb0zSPte(ctBAXaxzz*SZRfhYDaNDJd z=M_u%wnd$5&3)+k7{cBd*MLZTR339uyHy^%k9KKJTo%0gHrj;7tRX?(TZ!L?-J)F` zSz@d_T2Q1P{@VOA{G6Q+a1pC|z@OuHI9){FP$;hHz|f}@k*0`JSH{nT?%iAFr7U=2zLypY?LPIN`#V%;G@;SBWKYD=A~(kS#JRwu_wV)+iPxm+v=wgPT=W{ zY{9lDy(bhq^U}GN*QeG?Hw%p7;R$28;&lA#R~nBDu$B`}{O{V)-4t_L{5V}Ytt~R- za!%Y)=H_d>o35uQ0=;pYFbx7y$)1@1tKX_Cad_z@QXXKvaVAGw)L#Dn6StLEu4S?C z6w1DYxQQD(+Hqv1a4^D&buJgF0I*uSsS#&b_g=naE@a?GD4iov8h`UY?c9}nn(Ufp)bRgJ}2 z#Lh`Xaynkb7{0i2Jw}s!9indSKC{fK&xn`gB}dYI8TwsbJa z5apCSk&Wp-L=~ELcRzh2&)$JD&B?8cK~IMDoYa1C7g~!Y zr>xID^W~U_DLzsK39mp!r=I^=oF<5BS&pA?R1SPruA}N>)m8l3t#fJ=;ZWHB_CD3S zFFjB$P(_HyQ1>}AJ(FZbSlWxQw_E-7a9`xsmX~}h!Y!r24F78v3EFR~DZPg}-Rhcz z^cni3>VUqVfI+bimgx7Vtqe2==d~gQ!`mtS76hf1np8+%7S`dzDul`$3P%<1^_1Qn O02@mOi}GVW*Zu`KlJAZH literal 0 HcmV?d00001 From 995773088a5c261b37c7900e827a28d78a22f4fb Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 12 Aug 2024 19:13:55 +0530 Subject: [PATCH 35/83] chore: renamed include_as_app to include_in_apps_screen (cherry picked from commit 528013242369d1dd6a32063e5011a91aff0550cd) --- erpnext/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index ee0b33e27db..448d0d2a57b 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -10,7 +10,7 @@ source_link = "https://github.com/frappe/erpnext" app_logo_url = "/assets/erpnext/images/erpnext-logo.svg" -include_as_app = [ +add_to_apps_screen = [ { "name": "erpnext", "logo": "/assets/erpnext/images/erpnext-logo-blue.png", From eb7e063d5cad01cddfe0a442e4b4e73727aab152 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Fri, 23 Aug 2024 00:37:45 +0000 Subject: [PATCH 36/83] chore(release): Bumped to Version 15.33.5 ## [15.33.5](https://github.com/frappe/erpnext/compare/v15.33.4...v15.33.5) (2024-08-23) ### Bug Fixes * include erpnext in apps page ([be736cf](https://github.com/frappe/erpnext/commit/be736cf6415a18d0811095d389a378bb22854d58)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index ecf8221f778..5ff4bdbe8ce 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.33.4" +__version__ = "15.33.5" def get_default_company(user=None): From cb2cb4447a1ede7052c5f929a1e91aea7ab6582d Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 28 Aug 2024 05:04:27 +0000 Subject: [PATCH 37/83] chore(release): Bumped to Version 15.34.0 # [15.34.0](https://github.com/frappe/erpnext/compare/v15.33.5...v15.34.0) (2024-08-28) ### Bug Fixes * calculation correction for annual depreciation ([fa85482](https://github.com/frappe/erpnext/commit/fa8548266290e543e77b8255b3b98645c7f0ed05)) * call 'process' directly instead of creating 'process_subscripti ([7582827](https://github.com/frappe/erpnext/commit/758282739ed6d7ab4f60c4e1fa4aaf752400a681)) * Cannot read properties of null (reading 'doctype') (backport [#42941](https://github.com/frappe/erpnext/issues/42941)) ([#42943](https://github.com/frappe/erpnext/issues/42943)) ([2c99075](https://github.com/frappe/erpnext/commit/2c990758992bc3f04be6f2606efb5450b8b89c52)) * Column 'valuation_rate' cannot be null (backport [#42909](https://github.com/frappe/erpnext/issues/42909)) ([#42913](https://github.com/frappe/erpnext/issues/42913)) ([8c350d4](https://github.com/frappe/erpnext/commit/8c350d43b26fe195824eedd73092bc9345668e3f)) * custom stock entry type issue (backport [#42835](https://github.com/frappe/erpnext/issues/42835)) ([#42846](https://github.com/frappe/erpnext/issues/42846)) ([831e2aa](https://github.com/frappe/erpnext/commit/831e2aaf1840a2350249eefecb10ea29e7567908)) * do not copy date fields in opportunity doctype ([7401dc4](https://github.com/frappe/erpnext/commit/7401dc4015fe15862faf59d0492e63a57cf13d73)) * get amount with taxes and charges from payment entry ([c54e97b](https://github.com/frappe/erpnext/commit/c54e97b89a09f6cecd7380cccca71ece07fed5f6)) * include erpnext in apps page ([7428df8](https://github.com/frappe/erpnext/commit/7428df8778ac770085bda24bdca21bc1959e298a)) * incorrect in and out qty in the Batch-Wise Balance History (backport [#42866](https://github.com/frappe/erpnext/issues/42866)) ([#42876](https://github.com/frappe/erpnext/issues/42876)) ([d9ca680](https://github.com/frappe/erpnext/commit/d9ca680a29eea5a4c8b90fd66309df346c248359)) * incorrect Received Qty Amount in Purchase Order Analysis (backport [#42852](https://github.com/frappe/erpnext/issues/42852)) ([#42854](https://github.com/frappe/erpnext/issues/42854)) ([72c1609](https://github.com/frappe/erpnext/commit/72c16097d64384a4218e7646e2c4efcdc0790d82)) * last purchase rate not updated from purchase invoice (backport [#42847](https://github.com/frappe/erpnext/issues/42847)) ([#42853](https://github.com/frappe/erpnext/issues/42853)) ([2203ea9](https://github.com/frappe/erpnext/commit/2203ea9301eea01714809811ec8f774ebbc59b1e)) * LCV based on purchase invoice amount with multi-currency (backport [#42890](https://github.com/frappe/erpnext/issues/42890)) ([#42894](https://github.com/frappe/erpnext/issues/42894)) ([ff868a9](https://github.com/frappe/erpnext/commit/ff868a9290f272b3dc6a47c5b9f890d392cc8c82)) * make party naming sequential when naming_by set as auto name ([0650c22](https://github.com/frappe/erpnext/commit/0650c22b53cfd801970f88aa3b0230869ace8a00)) * not able to make stock entry against MR (backport [#42874](https://github.com/frappe/erpnext/issues/42874)) ([#42875](https://github.com/frappe/erpnext/issues/42875)) ([08bed61](https://github.com/frappe/erpnext/commit/08bed618f611560635b17fc5d77b6934b31b7551)) * same posting date and time, creation causing incorrect balance qty (backport [#42904](https://github.com/frappe/erpnext/issues/42904)) ([#42920](https://github.com/frappe/erpnext/issues/42920)) ([2624892](https://github.com/frappe/erpnext/commit/26248924b651d466fc9cf7ffe071787d65159af0)) * spec mobile and email fields for notifications ([f56ee58](https://github.com/frappe/erpnext/commit/f56ee58e8161edd867fa19e9d0beeb8d87354985)) * timeout while submitting stock entry (backport [#42929](https://github.com/frappe/erpnext/issues/42929)) ([#42931](https://github.com/frappe/erpnext/issues/42931)) ([ec26c92](https://github.com/frappe/erpnext/commit/ec26c92263ba2c7acdd3941b2569f59af6a6bed9)) * unsupported operand type(s) for *: 'float' and 'NoneType' (backport [#42916](https://github.com/frappe/erpnext/issues/42916)) ([#42918](https://github.com/frappe/erpnext/issues/42918)) ([8d29dc6](https://github.com/frappe/erpnext/commit/8d29dc6a81e95703b1215b2278a7186f565eabe9)) * update dimesions in exchange_gain_loss jv based on base document ([caa6ca1](https://github.com/frappe/erpnext/commit/caa6ca1d0b300e30f08bd431186e31161f8ef0a2)) * Update get_amount to return currency precision grand total ([976abf7](https://github.com/frappe/erpnext/commit/976abf7b3c92cd6387275442f87c784d4adf16e1)) * use of incorrect attribute ([80244ba](https://github.com/frappe/erpnext/commit/80244bafa44bdd2198788453bd9bae0973dc16ec)) ### Features * added finance book filter in depreciation and balances report ([5bdd298](https://github.com/frappe/erpnext/commit/5bdd2989c67293ed0e5d786637f4373ef7bb7c97)) * Disassembly Order (backport [#42655](https://github.com/frappe/erpnext/issues/42655)) ([#42957](https://github.com/frappe/erpnext/issues/42957)) ([8d8dd0c](https://github.com/frappe/erpnext/commit/8d8dd0cd2bbb34e23832aa83055e78fa08be2245)) * report to identify incorrectly cleared cheques ([25193c5](https://github.com/frappe/erpnext/commit/25193c5e92f7423668c696bd5996150299f58288)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 5ff4bdbe8ce..c798ed0a02f 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.33.5" +__version__ = "15.34.0" def get_default_company(user=None): From 7f261f34483aa3f8ebb38e55f480cc7d80d655c9 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 5 Sep 2024 11:44:28 +0000 Subject: [PATCH 38/83] chore(release): Bumped to Version 15.34.1 ## [15.34.1](https://github.com/frappe/erpnext/compare/v15.34.0...v15.34.1) (2024-09-05) ### Bug Fixes * add the company in payment request bcz delete company transactions (backport [#42664](https://github.com/frappe/erpnext/issues/42664)) ([#42982](https://github.com/frappe/erpnext/issues/42982)) ([42e7725](https://github.com/frappe/erpnext/commit/42e7725442c0c6d4ace34c84a9ca4ec8ae6d6e8f)) * added app permission check for apps page ([a35ce12](https://github.com/frappe/erpnext/commit/a35ce12d6000152feef4e87a15046d63a7b85d7e)) * adjust price insertion logic for internal suppliers/customers ([#42988](https://github.com/frappe/erpnext/issues/42988)) ([daa75ee](https://github.com/frappe/erpnext/commit/daa75eea00d46c565380c4303eba1e939fe3579a)) * auto reorder material request mail issue (backport [#43066](https://github.com/frappe/erpnext/issues/43066)) ([#43068](https://github.com/frappe/erpnext/issues/43068)) ([d2b2002](https://github.com/frappe/erpnext/commit/d2b200266461b9eaafab2f8e349189f7e017022d)) * **capitalization:** debit cwip account instead of fixed asset account ([#42857](https://github.com/frappe/erpnext/issues/42857)) ([f3c60ea](https://github.com/frappe/erpnext/commit/f3c60ea0a781d0aea185013bda4baa4ec3064525)) * company accounts setup_queries ([b99cdb5](https://github.com/frappe/erpnext/commit/b99cdb5be7be2d31acadc252404b792ba1d31561)) * disabled batches showing in the list (backport [#43024](https://github.com/frappe/erpnext/issues/43024)) ([#43069](https://github.com/frappe/erpnext/issues/43069)) ([56dad7d](https://github.com/frappe/erpnext/commit/56dad7d365a7debf98b8739352002adb3294bc79)) * don't allow capitalizing only service item for new composite asset ([a833010](https://github.com/frappe/erpnext/commit/a833010d2bb09c7c5798d7aefad9c5dc61394641)) * improve asset item matching logic ([3bb1867](https://github.com/frappe/erpnext/commit/3bb186736d8adbf83cdb1d75bb4f5f9db8af8532)) * indentation ([4d7c0c0](https://github.com/frappe/erpnext/commit/4d7c0c004a2677be6fad1154ff1ff80eadfe7482)) * link Purchase Invoice and Receipt Items to Asset ([1121c66](https://github.com/frappe/erpnext/commit/1121c6663f325502e867eea76a144dfe55c522b3)) * retain date filter when redirecting in Profit and Loss report ([f0e3fb4](https://github.com/frappe/erpnext/commit/f0e3fb466a7deeb438b0ff7d9e932dea2298951d)) * typeerror on Payment Entry ([6d51d14](https://github.com/frappe/erpnext/commit/6d51d14dfd3924e369073fc18e643fcdaaa26e6f)) * typerror on default_currency ([7d6984c](https://github.com/frappe/erpnext/commit/7d6984c87331d27705f9a92be13d84ed46afa946)) * update develop_version in hooks ([6c8e0fd](https://github.com/frappe/erpnext/commit/6c8e0fd1fbefca5e69be899ce317ecb10a6c10e7)) * validate component quantity according to BOM (backport [#43011](https://github.com/frappe/erpnext/issues/43011)) ([#43014](https://github.com/frappe/erpnext/issues/43014)) ([fee2255](https://github.com/frappe/erpnext/commit/fee2255661e6a930a627acca9faa271f7b30c112)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index eab2a96b941..e782ce5e145 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.34.0" +__version__ = "15.34.1" def get_default_company(user=None): From 0bc947f30db9ae0f5d99d3f44bb85c6568fef472 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 7 Sep 2024 17:32:42 +0530 Subject: [PATCH 39/83] fix: incorrect qty after transaction in SLE (backport #43103) (#43105) fix: incorrect qty after transaction in SLE (#43103) (cherry picked from commit 5ff87edc85b6bf1a355a44650440055abbb75ef5) Co-authored-by: rohitwaghchaure (cherry picked from commit 8447bf34f07c230f3084a2fe66e0295db10a566f) --- erpnext/stock/stock_ledger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 556aac09abd..49a3a3335d1 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -1527,7 +1527,7 @@ def get_previous_sle_of_current_voucher(args, operator="<", exclude_current_vouc voucher_no = args.get("voucher_no") voucher_condition = f"and voucher_no != '{voucher_no}'" - elif args.get("creation"): + elif args.get("creation") and args.get("sle_id"): creation = args.get("creation") operator = "<=" voucher_condition = f"and creation < '{creation}'" From 829660e7f39cb5895a0df54e4ed3c2f335a400cd Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Sat, 7 Sep 2024 12:40:39 +0000 Subject: [PATCH 40/83] chore(release): Bumped to Version 15.34.2 ## [15.34.2](https://github.com/frappe/erpnext/compare/v15.34.1...v15.34.2) (2024-09-07) ### Bug Fixes * incorrect qty after transaction in SLE (backport [#43103](https://github.com/frappe/erpnext/issues/43103)) ([#43105](https://github.com/frappe/erpnext/issues/43105)) ([0bc947f](https://github.com/frappe/erpnext/commit/0bc947f30db9ae0f5d99d3f44bb85c6568fef472)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index e782ce5e145..10c7018c9c1 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.34.1" +__version__ = "15.34.2" def get_default_company(user=None): From d9d86dae35f3b07a54c5fc2916fcd4d32daac990 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 11 Sep 2024 05:11:52 +0000 Subject: [PATCH 41/83] chore(release): Bumped to Version 15.35.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # [15.35.0](https://github.com/frappe/erpnext/compare/v15.34.2...v15.35.0) (2024-09-11) ### Bug Fixes * `default_advance_account` field in Process Payment Reconciliation ([75cb298](https://github.com/frappe/erpnext/commit/75cb29890d5f275dc172c4528fb1ecf41e02d8ea)) * bom cost update is not working (backport [#43155](https://github.com/frappe/erpnext/issues/43155)) ([#43157](https://github.com/frappe/erpnext/issues/43157)) ([8c8dc24](https://github.com/frappe/erpnext/commit/8c8dc241e50ba72775c7651b0c19636d3f5a2182)) * cancel common party advance jv while canceling the invoice ([9bd3d7a](https://github.com/frappe/erpnext/commit/9bd3d7a020ad8ce4e90da1ffdfddfc71510aab74)) * Cannot read properties of null (reading 'doc') (backport [#43071](https://github.com/frappe/erpnext/issues/43071)) ([#43118](https://github.com/frappe/erpnext/issues/43118)) ([80b5c16](https://github.com/frappe/erpnext/commit/80b5c16a2e3183553c5ad95c0a70ecf94310aa12)) * check multi-currency on jv for common party accounting with foreign currency ([d17badd](https://github.com/frappe/erpnext/commit/d17baddb0d3c13212f8695967ffb971b55306224)) * concurrency issue while picking materials (backport [#43087](https://github.com/frappe/erpnext/issues/43087)) ([#43152](https://github.com/frappe/erpnext/issues/43152)) ([cd57e00](https://github.com/frappe/erpnext/commit/cd57e009dd3023e419e7d9114ac32e5408b48881)) * **Delivery Note:** translatability of validation errors ([ea4f736](https://github.com/frappe/erpnext/commit/ea4f7365ea8e6dc48af50369c2239b2ba665ab5e)) * ensure `SellingController.onload` gets called for SO & DN ([2c1f72e](https://github.com/frappe/erpnext/commit/2c1f72e44cac422f5f2ab94b7b2934a5b0979c83)) * incorrect actual cost in Procurement Tracker report (backport [#43109](https://github.com/frappe/erpnext/issues/43109)) ([#43138](https://github.com/frappe/erpnext/issues/43138)) ([5110975](https://github.com/frappe/erpnext/commit/5110975c6dc13aa894a60caace1fc4ba33d178cf)) * incorrect qty after transaction in SLE (backport [#43103](https://github.com/frappe/erpnext/issues/43103)) ([#43105](https://github.com/frappe/erpnext/issues/43105)) ([8447bf3](https://github.com/frappe/erpnext/commit/8447bf34f07c230f3084a2fe66e0295db10a566f)) * **minor:** reorder expected value validation ([6fde07d](https://github.com/frappe/erpnext/commit/6fde07da0e5a477f375429ace53067f1ab8eb0c8)) * multiple fixes related to remarks for GL Report ([#42753](https://github.com/frappe/erpnext/issues/42753)) ([f45b1db](https://github.com/frappe/erpnext/commit/f45b1db1a402d57b7a6312d39f6ca975098a6ae5)) * **Opening Invoice Creation Tool:** translatability of messages ([3fd9df0](https://github.com/frappe/erpnext/commit/3fd9df0d2e6efeef83384e480a0e81dc8e4966c7)) * pass company from asset to asset capitalization ([9e72a84](https://github.com/frappe/erpnext/commit/9e72a844f702d0e3e032765777ec1780d8a6b6ed)) * permission on guest PR creation ([a23e8b1](https://github.com/frappe/erpnext/commit/a23e8b13bebf83e05363c9074c84e36f835e6d04)) * return type of `get_party_details` (backport [#43131](https://github.com/frappe/erpnext/issues/43131)) ([#43134](https://github.com/frappe/erpnext/issues/43134)) ([d2923ba](https://github.com/frappe/erpnext/commit/d2923bae8582f2c2bc7b126ff6a41746f2f61262)) * set today in 'On This Date' in Available Batch Report ([03e3374](https://github.com/frappe/erpnext/commit/03e3374a8b0e90a3d84c8a61070510edf1c25b2b)) * uncomment internal parties ([33174b1](https://github.com/frappe/erpnext/commit/33174b1ba26e7002d3e3286816182dba2223954e)) * unhide action button after form redirect ([208bd2b](https://github.com/frappe/erpnext/commit/208bd2b8ff4d55dc9061f90f9b48027bf247a68e)) * unreconcile allocation child table redirect url voucher no issue ([2dddd79](https://github.com/frappe/erpnext/commit/2dddd7906bc0468bd8f8eb7b139e19af334b5f2e)) * validate the item code when updating the other item's price rule ([8f4dc80](https://github.com/frappe/erpnext/commit/8f4dc8048d86c2f103b3ded40074be80df0e5870)) ### Features * added revaluation surplus and impairment acc in standard charts… ([#43022](https://github.com/frappe/erpnext/issues/43022)) ([ea86bc2](https://github.com/frappe/erpnext/commit/ea86bc2235acb0712ae7205cff97c3e14614c3c4)) * utility report to identify invalid ledger entries ([5929d50](https://github.com/frappe/erpnext/commit/5929d50c72085a4a875b802b26f9364548342e49)) ### Performance Improvements * timeout error (backport [#43154](https://github.com/frappe/erpnext/issues/43154)) ([#43158](https://github.com/frappe/erpnext/issues/43158)) ([c9f49ca](https://github.com/frappe/erpnext/commit/c9f49caeccb7b04cc20f43768b72a8238122c893)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 10c7018c9c1..32c572e92c3 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.34.2" +__version__ = "15.35.0" def get_default_company(user=None): From 31e0bb477ecda7145771e53d642b4fa34a8d7f42 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 12 Sep 2024 10:36:32 +0530 Subject: [PATCH 42/83] fix: typo with po_date when creating remarks (cherry picked from commit a55502e0f14133d8e6dfca9e0741c07d20056b08) --- .../accounts/doctype/sales_invoice/sales_invoice.py | 2 +- .../doctype/sales_invoice/test_sales_invoice.py | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 12e26623ad0..1214ddee8cd 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -951,7 +951,7 @@ class SalesInvoice(SellingController): if self.po_no: self.remarks = _("Against Customer Order {0}").format(self.po_no) if self.po_date: - self.remarks += " " + _("dated {0}").format(formatdate(self.po_data)) + self.remarks += " " + _("dated {0}").format(formatdate(self.po_date)) else: self.remarks = _("No Remarks") diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index beb347e07db..7ac0d34e671 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -8,7 +8,7 @@ import frappe from frappe import qb from frappe.model.dynamic_links import get_dynamic_link_map from frappe.tests.utils import FrappeTestCase, change_settings -from frappe.utils import add_days, flt, getdate, nowdate, today +from frappe.utils import add_days, flt, format_date, getdate, nowdate, today import erpnext from erpnext.accounts.doctype.account.test_account import create_account, get_inventory_account @@ -3997,6 +3997,14 @@ class TestSalesInvoice(FrappeTestCase): self.assertTrue(jv) self.assertEqual(jv[0], si.grand_total) + def test_invoice_remarks(self): + si = frappe.copy_doc(test_records[0]) + si.po_no = "Test PO" + si.po_date = nowdate() + si.save() + si.submit() + self.assertEqual(si.remarks, f"Against Customer Order Test PO dated {format_date(nowdate())}") + def set_advance_flag(company, flag, default_account): frappe.db.set_value( From 7f95e42becfff89b31c8b6964fa237ba49445580 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 12 Sep 2024 06:11:04 +0000 Subject: [PATCH 43/83] chore(release): Bumped to Version 15.35.1 ## [15.35.1](https://github.com/frappe/erpnext/compare/v15.35.0...v15.35.1) (2024-09-12) ### Bug Fixes * typo with po_date when creating remarks ([31e0bb4](https://github.com/frappe/erpnext/commit/31e0bb477ecda7145771e53d642b4fa34a8d7f42)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 32c572e92c3..50acf5dd033 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.35.0" +__version__ = "15.35.1" def get_default_company(user=None): From 2f56ba7f428488c8a94160941df9c4d309dee5eb Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:30:36 +0530 Subject: [PATCH 44/83] fix: currency changing while making PO from Supplier Quotation (backport #43187) (#43205) fix: currency changing while making PO from Supplier Quotation (#43187) (cherry picked from commit 2b96e37c3486c5f4e1928cfcb5c3b9f0cad60f6b) Co-authored-by: rohitwaghchaure (cherry picked from commit ef6b172616ee473c1b05324d2e6217510cec8cda) --- erpnext/public/js/controllers/transaction.js | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 3dcd36b2cff..4b997b6d8fb 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1258,6 +1258,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe "Purchase Receipt": ["purchase_order_item", "purchase_invoice_item", "purchase_receipt_item"], "Purchase Invoice": ["purchase_order_item", "pr_detail", "po_detail"], "Sales Order": ["prevdoc_docname", "quotation_item"], + "Purchase Order": ["supplier_quotation_item"], }; const mappped_fields = mapped_item_field_map[this.frm.doc.doctype] || []; From 28f1f9355da9ad92733de78a141571c404755be1 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Tue, 17 Sep 2024 05:00:07 +0000 Subject: [PATCH 45/83] chore(release): Bumped to Version 15.35.2 ## [15.35.2](https://github.com/frappe/erpnext/compare/v15.35.1...v15.35.2) (2024-09-17) ### Bug Fixes * currency changing while making PO from Supplier Quotation (backport [#43187](https://github.com/frappe/erpnext/issues/43187)) ([#43205](https://github.com/frappe/erpnext/issues/43205)) ([2f56ba7](https://github.com/frappe/erpnext/commit/2f56ba7f428488c8a94160941df9c4d309dee5eb)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 50acf5dd033..8d6e2cc0d18 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.35.1" +__version__ = "15.35.2" def get_default_company(user=None): From 479e8573c2f12b1022a3b6b1e318bcd6ea787d58 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 18 Sep 2024 07:32:30 +0000 Subject: [PATCH 46/83] chore(release): Bumped to Version 15.36.0 # [15.36.0](https://github.com/frappe/erpnext/compare/v15.35.2...v15.36.0) (2024-09-18) ### Bug Fixes * A project without tasks should be able to complete ([dea735d](https://github.com/frappe/erpnext/commit/dea735de4df2ca427fce8803d3d4f8acdc89c789)) * add currency in options for rate field in pricing rule ([782c9dd](https://github.com/frappe/erpnext/commit/782c9dda1a7af57d330294d3b5ef51fd3e3904ef)) * batch based item price not working (backport [#43172](https://github.com/frappe/erpnext/issues/43172)) ([#43206](https://github.com/frappe/erpnext/issues/43206)) ([61a42ea](https://github.com/frappe/erpnext/commit/61a42ea5d71b9f28c73d9954168bc3e9ba37a3cc)) * cancel cost center allocation and journal entry after test ([3d29007](https://github.com/frappe/erpnext/commit/3d29007aeb053fad0b8040fa1753305def7a4948)) * consistent behaviour on refresh ([01f3068](https://github.com/frappe/erpnext/commit/01f30682ee9e15a51161a4f2a91681484e6ac8bf)) * create and link address while creating prospect & customer ([d6a3d0d](https://github.com/frappe/erpnext/commit/d6a3d0d46835559dffb50c502bfec10d15492031)) * create fiscal year without overlapping existing Fiscal Years ([78768f8](https://github.com/frappe/erpnext/commit/78768f883c09ec91de2dfee101923808ccd6fa55)) * currency changing while making PO from Supplier Quotation (backport [#43187](https://github.com/frappe/erpnext/issues/43187)) ([#43205](https://github.com/frappe/erpnext/issues/43205)) ([ef6b172](https://github.com/frappe/erpnext/commit/ef6b172616ee473c1b05324d2e6217510cec8cda)) * delete exchange gain loss journal entry while deleting payment entry ([5789de2](https://github.com/frappe/erpnext/commit/5789de25b94258c8e521885cde47c5706632cc98)) * do not auto apply tds in purchase order ([741c18b](https://github.com/frappe/erpnext/commit/741c18b14468f29586cc9c19c293b6f6518249e1)) * do not check appy_tds in Purchase Order Automatically ([5edebb2](https://github.com/frappe/erpnext/commit/5edebb28a5bcbeacc1084c9da3cb99e156d95b8d)) * do not validate purchase document for composite asset ([c505156](https://github.com/frappe/erpnext/commit/c5051561e4eb14374e85245c1068e807ef8b15a0)) * fetch cost center allocation percentage only from the applicable allocation ([0fe901a](https://github.com/frappe/erpnext/commit/0fe901a137c1b4d3ab5caee046ad4cc8911d7444)) * hide and reset discount control on new POS order ([42494db](https://github.com/frappe/erpnext/commit/42494db3c77db1ec590bf7e73bb89828cd06b029)) * **holiday-list:** use same date format for same holiday error message (backport [#42606](https://github.com/frappe/erpnext/issues/42606)) ([#43222](https://github.com/frappe/erpnext/issues/43222)) ([f101a1c](https://github.com/frappe/erpnext/commit/f101a1ce3b9e2e579ff200c80204a0231916eeec)) * ignore repost logic on Payment Reconciliation ([d91013a](https://github.com/frappe/erpnext/commit/d91013a46707095f62a009a2fbdcf84bd1303c62)) * invalid gp calculation ([291f0a5](https://github.com/frappe/erpnext/commit/291f0a580be176a4c87c03e54372dd7a7cca9cb1)) * item list view in website (backport [#43165](https://github.com/frappe/erpnext/issues/43165)) ([#43207](https://github.com/frappe/erpnext/issues/43207)) ([c1a6c56](https://github.com/frappe/erpnext/commit/c1a6c56217b326f4c948145c507c87bbc987bafc)) * map rows on journal entry by validating account, party, debit and credit value ([86e1818](https://github.com/frappe/erpnext/commit/86e1818420a3152cf47ef65943216c6a9bd0d29e)) * prevent KeyError by checking `report_filter` existence ([984acb6](https://github.com/frappe/erpnext/commit/984acb661d4314960bf2f1eb3542830b182441cc)) * revert 091c5496b20864577d133b0804e957ff8995606f ([2ad6d63](https://github.com/frappe/erpnext/commit/2ad6d637ee9193253fbade6ab35769636906c8d1)) * set party_type null when payment_type is changed to Internal Transfer ([45ff8fa](https://github.com/frappe/erpnext/commit/45ff8fa296b47c809ecb643a4b67fc775d9e9848)) * set tax_withholding_category from Purchase Order while creating pi form po ([7027be8](https://github.com/frappe/erpnext/commit/7027be8fbcf51282ea470299e4edb3d9ce89dd6f)) * tds workflow in purchase order ([11359bd](https://github.com/frappe/erpnext/commit/11359bd2353e7804e226ae000464093d8d5aa71c)) * typo with po_date when creating remarks ([1657a83](https://github.com/frappe/erpnext/commit/1657a83151fb002e0606c36923e722aa638cc6f2)) * updated filtering in depreciation and balances report ([78c6839](https://github.com/frappe/erpnext/commit/78c68397d9a5147970f4b19435c5352ced2a6a44)) * **ux:** set amount based on account currency while adding new row ([f7cedac](https://github.com/frappe/erpnext/commit/f7cedac5260d832aa6b95b9f0341c94d7ccd6203)) * **ux:** set amount on foreign currency when foreign currency account is selected on last row of journal ([d8d4cd2](https://github.com/frappe/erpnext/commit/d8d4cd23a518ec94b30f69dfc67dd042582fcbec)) ### Features * API for crm integration ([f060534](https://github.com/frappe/erpnext/commit/f060534625b6a7dcb7b60fd783f041ba3e980650)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 8d6e2cc0d18..46129bf0b24 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.35.2" +__version__ = "15.36.0" def get_default_company(user=None): From 17ad40269555d6a9c559dc925a414e2b6cee273c Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 18 Sep 2024 21:53:27 +0530 Subject: [PATCH 47/83] fix: create_address is failing (cherry picked from commit acc1d52ac8e51a4fd87cdfcfc7f5c0639157fad9) --- erpnext/crm/frappe_crm_api.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/crm/frappe_crm_api.py b/erpnext/crm/frappe_crm_api.py index 53f58ed57eb..a00f0ba798d 100644 --- a/erpnext/crm/frappe_crm_api.py +++ b/erpnext/crm/frappe_crm_api.py @@ -95,6 +95,8 @@ def create_contacts(contacts, organization=None, link_doctype=None, link_docname def create_address(doctype, docname, address): if not address: return + if isinstance(address, str): + address = json.loads(address) try: _address = frappe.db.exists("Address", address.get("name")) if not _address: @@ -105,6 +107,7 @@ def create_address(doctype, docname, address): "address_line1", "address_line2", "city", + "county", "state", "pincode", "country", From 34ca0c3bb6a61949c66f4d2aee5c7f06e2766244 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 19 Sep 2024 01:43:11 +0000 Subject: [PATCH 48/83] chore(release): Bumped to Version 15.36.1 ## [15.36.1](https://github.com/frappe/erpnext/compare/v15.36.0...v15.36.1) (2024-09-19) ### Bug Fixes * create_address is failing ([17ad402](https://github.com/frappe/erpnext/commit/17ad40269555d6a9c559dc925a414e2b6cee273c)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 46129bf0b24..d5db7ca59a6 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.36.0" +__version__ = "15.36.1" def get_default_company(user=None): From 8d188dccd74f2fc442fc386541f4730d14849339 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 25 Sep 2024 04:40:17 +0000 Subject: [PATCH 49/83] chore(release): Bumped to Version 15.36.2 ## [15.36.2](https://github.com/frappe/erpnext/compare/v15.36.1...v15.36.2) (2024-09-25) ### Bug Fixes * add currency in financial statement ([927f800](https://github.com/frappe/erpnext/commit/927f80035d4796bb1f75cede6c7aba16035bb5b7)) * added date condition ([0e18845](https://github.com/frappe/erpnext/commit/0e1884539ebfddd67c10f83f515bae23074fccf6)) * AR / AP report to ignore 0.0 outstanding ([979d801](https://github.com/frappe/erpnext/commit/979d801de5e2213474690a860be04db28c102d7b)) * **Bank Account:** dashboard connections (backport [#43365](https://github.com/frappe/erpnext/issues/43365)) ([#43367](https://github.com/frappe/erpnext/issues/43367)) ([cfea2de](https://github.com/frappe/erpnext/commit/cfea2de131fb5a32d3716d55a46cb1285266da2c)) * change dynamic link doctype fieldtype to data ([05c92cc](https://github.com/frappe/erpnext/commit/05c92cce71152f944086c272199540a2d323703b)) * closing amount reset to expected amount on save (backport [#43358](https://github.com/frappe/erpnext/issues/43358)) ([#43368](https://github.com/frappe/erpnext/issues/43368)) ([0722aa5](https://github.com/frappe/erpnext/commit/0722aa5a3f5c318110933fadd38303d690d0db32)) * create_address is failing ([557ef5d](https://github.com/frappe/erpnext/commit/557ef5d214abee8b7e7a7838a940a40e6f8d1477)) * handle missing liability account scenario in `set_liability_account` ([4045928](https://github.com/frappe/erpnext/commit/40459288f6c4bdcb88dc284c6874b1294a6b88a5)) * incorrect outstanding on non-pos invoice with write_off_account ([f89a3db](https://github.com/frappe/erpnext/commit/f89a3dbb6562bed6fa22088a63cd363f612ffbfd)) * incorrect stock balance for inventory dimension (backport [#43284](https://github.com/frappe/erpnext/issues/43284)) ([#43290](https://github.com/frappe/erpnext/issues/43290)) ([f6725e2](https://github.com/frappe/erpnext/commit/f6725e2eed39c326bd031ebc969bd40adf6235e1)) * item_query in pos_invoice ([99e004b](https://github.com/frappe/erpnext/commit/99e004b61962c4463ba8b18985835295d5711b03)) * make to tax category on tax rule to filter with percent ([63d4fdd](https://github.com/frappe/erpnext/commit/63d4fddb493e4ba1ec1b178464f5fd671da1fd8c)) * **minor:** include condition to check docstatus ([1f42302](https://github.com/frappe/erpnext/commit/1f423029970cb911c5a97d8b3ce92a02b151ea7e)) * not able to cancel Quality Inspection (backport [#43374](https://github.com/frappe/erpnext/issues/43374)) ([#43375](https://github.com/frappe/erpnext/issues/43375)) ([40fbb1d](https://github.com/frappe/erpnext/commit/40fbb1d6ffaa75a612b64159506ed2409e2afe25)) * partial return on POS invoice ([998fef7](https://github.com/frappe/erpnext/commit/998fef779bc2aba5ebd7e3b7d98189c1a8f388f3)) * partial return on POS invoice ([b99ca7d](https://github.com/frappe/erpnext/commit/b99ca7d9e988a09e32a9f85848184c829b805648)) * Payment Ledger Report currency fieldtype fix ([ad2d6a1](https://github.com/frappe/erpnext/commit/ad2d6a16258235a20d041174458e32bb6ebad8f7)) * **Payment Reconciliation:** German translations ([e06a01f](https://github.com/frappe/erpnext/commit/e06a01fae5dd5b42f54fcccf9c8c38106087b37e)) * set group_by condition if empty and voucher_no is set ([ec27077](https://github.com/frappe/erpnext/commit/ec27077d9cd5f3d5e832e35a32451cee7f5e3e6d)) * shipping rule must match the company ([085a4c6](https://github.com/frappe/erpnext/commit/085a4c61ac3ebef34b16f7e713d03809594fd455)) * show chart tool tip in report currency ([e5ae828](https://github.com/frappe/erpnext/commit/e5ae828580693d0f4b370868f39d70b649de4a7c)) * stock dashboard (backport [#43347](https://github.com/frappe/erpnext/issues/43347)) ([#43349](https://github.com/frappe/erpnext/issues/43349)) ([176feb2](https://github.com/frappe/erpnext/commit/176feb20ad62e4a137e5babcd363968af59b160a)) * transaction exchange rate on GL's for Multi currency Journals ([a7ccc94](https://github.com/frappe/erpnext/commit/a7ccc9420ba8fa30b7809b299a91ae3501d0b4fb)) * translate in js ([84e26e2](https://github.com/frappe/erpnext/commit/84e26e21abbbe0c8a8ab508d4d408e89e2e79467)) * Translation for button SO to PO ([73d98ad](https://github.com/frappe/erpnext/commit/73d98addbcbdb236cda9da130ff9a59a1f942a37)) * ui clean-up (backport [#43305](https://github.com/frappe/erpnext/issues/43305)) ([#43312](https://github.com/frappe/erpnext/issues/43312)) ([7e6d6f0](https://github.com/frappe/erpnext/commit/7e6d6f08a20a03ff5603d9b991d4ea69960780c5)) * update clearance date in invoice payment table ([10ecdb9](https://github.com/frappe/erpnext/commit/10ecdb99fe565d5f4ebedb034f5cbad1c246a865)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index d5db7ca59a6..89f9ab1605e 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.36.1" +__version__ = "15.36.2" def get_default_company(user=None): From c1f14f2991371006c9b8c942b3797fbf728ca54c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 27 Sep 2024 23:29:39 +0530 Subject: [PATCH 50/83] fix: Ignore transaction deletion check on ledger entry insertion (cherry picked from commit 998f6a92a48b57dbde1d76e848378bd743d0fa03) (cherry picked from commit 1d6f97ad945f8d0225533fb03e6866561316481b) --- .../transaction_deletion_record.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py index c9c3c837ceb..ce3f918f7eb 100644 --- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py +++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py @@ -485,8 +485,14 @@ def is_deletion_doc_running(company: str | None = None, err_msg: str | None = No def check_for_running_deletion_job(doc, method=None): # Check if DocType has 'company' field - df = qb.DocType("DocField") - if qb.from_(df).select(df.parent).where((df.fieldname == "company") & (df.parent == doc.doctype)).run(): - is_deletion_doc_running( - doc.company, _("Cannot make any transactions until the deletion job is completed") - ) + if doc.doctype not in ("GL Entry", "Payment Ledger Entry", "Stock Ledger Entry"): + df = qb.DocType("DocField") + if ( + qb.from_(df) + .select(df.parent) + .where((df.fieldname == "company") & (df.parent == doc.doctype)) + .run() + ): + is_deletion_doc_running( + doc.company, _("Cannot make any transactions until the deletion job is completed") + ) From e706aa692a988a51b6f8791cd2d55951dd2f4c46 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Fri, 27 Sep 2024 18:30:37 +0000 Subject: [PATCH 51/83] chore(release): Bumped to Version 15.36.3 ## [15.36.3](https://github.com/frappe/erpnext/compare/v15.36.2...v15.36.3) (2024-09-27) ### Bug Fixes * Ignore transaction deletion check on ledger entry insertion ([c1f14f2](https://github.com/frappe/erpnext/commit/c1f14f2991371006c9b8c942b3797fbf728ca54c)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 89f9ab1605e..34d07c1e23b 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.36.2" +__version__ = "15.36.3" def get_default_company(user=None): From 2c4610c021dcbc53af5f7f40a0682ab3d2590711 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 29 Sep 2024 21:18:25 +0530 Subject: [PATCH 52/83] fix: Data missing in table: None, MandatoryError (backport #43422) (#43429) fix: Data missing in table: None, MandatoryError (#43422) (cherry picked from commit 8e33e0e1d2df18d8401919e518cdf75e469d87a7) Co-authored-by: rohitwaghchaure (cherry picked from commit 4b3f143f8366881d8cc427d56a14d6c38403d688) --- erpnext/stock/doctype/stock_entry/stock_entry.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 4ee4c6b2930..627ad78be58 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -3148,11 +3148,13 @@ def get_available_materials(work_order) -> dict: if row.serial_no: for serial_no in get_serial_nos(row.serial_no): - item_data.serial_nos.remove(serial_no) + if serial_no in item_data.serial_nos: + item_data.serial_nos.remove(serial_no) elif row.serial_nos: for serial_no in get_serial_nos(row.serial_nos): - item_data.serial_nos.remove(serial_no) + if serial_no in item_data.serial_nos: + item_data.serial_nos.remove(serial_no) return available_materials @@ -3270,6 +3272,9 @@ def create_serial_and_batch_bundle(parent_doc, row, child, type_of_transaction=N for batch_no, qty in row.batches_to_be_consume.items(): doc.append("entries", {"batch_no": batch_no, "warehouse": row.warehouse, "qty": qty * -1}) + if not doc.entries: + return None + return doc.insert(ignore_permissions=True).name From 2d09ef250936bac9b46dc7b5050da9534a73b103 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Sun, 29 Sep 2024 16:38:13 +0000 Subject: [PATCH 53/83] chore(release): Bumped to Version 15.36.4 ## [15.36.4](https://github.com/frappe/erpnext/compare/v15.36.3...v15.36.4) (2024-09-29) ### Bug Fixes * Data missing in table: None, MandatoryError (backport [#43422](https://github.com/frappe/erpnext/issues/43422)) ([#43429](https://github.com/frappe/erpnext/issues/43429)) ([2c4610c](https://github.com/frappe/erpnext/commit/2c4610c021dcbc53af5f7f40a0682ab3d2590711)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 34d07c1e23b..aab2aa1480a 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.36.3" +__version__ = "15.36.4" def get_default_company(user=None): From 96d8b5242dd0bfa8ac48450501c32348ab4154c7 Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Thu, 26 Sep 2024 16:49:01 +0530 Subject: [PATCH 54/83] feat: added 'cost of new capitalized asset' column (cherry picked from commit 1eb9cc33fc298c90ef5a04e5de2ee4dec67f941a) (cherry picked from commit 27cd51e267b3a11ab474ca085b5a0dc6cef87fad) --- .../asset_depreciations_and_balances.py | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py index 64e6a340464..cdd5baf3240 100644 --- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py +++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py @@ -36,8 +36,9 @@ def get_group_by_asset_category_data(filters): + flt(row.cost_of_new_purchase) - flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset) + - flt(row.cost_of_capitalized_asset) ) - # Update row with corresponding asset data + row.update( next( asset @@ -111,13 +112,24 @@ def get_asset_categories_for_grouped_by_category(filters): end else 0 - end), 0) as cost_of_scrapped_asset + end), 0) as cost_of_scrapped_asset, + ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 + and a.disposal_date >= %(from_date)s + and a.disposal_date <= %(to_date)s then + case when a.status = "Capitalized" then + a.gross_purchase_amount + else + 0 + end + else + 0 + end), 0) as cost_of_capitalized_asset from `tabAsset` a where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition} and not exists( select 1 from `tabAsset Capitalization Asset Item` acai join `tabAsset Capitalization` ac on acai.parent=ac.name where acai.asset = a.name - and ac.posting_date <= %(to_date)s + and ac.posting_date < %(from_date)s and ac.docstatus=1 ) group by a.asset_category @@ -179,13 +191,24 @@ def get_asset_details_for_grouped_by_category(filters): end else 0 - end), 0) as cost_of_scrapped_asset + end), 0) as cost_of_scrapped_asset, + ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 + and a.disposal_date >= %(from_date)s + and a.disposal_date <= %(to_date)s then + case when a.status = "Capitalized" then + a.gross_purchase_amount + else + 0 + end + else + 0 + end), 0) as cost_of_capitalized_asset from `tabAsset` a where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition} and not exists( select 1 from `tabAsset Capitalization Asset Item` acai join `tabAsset Capitalization` ac on acai.parent=ac.name where acai.asset = a.name - and ac.posting_date <= %(to_date)s + and ac.posting_date < %(from_date)s and ac.docstatus=1 ) group by a.name @@ -217,6 +240,7 @@ def get_group_by_asset_data(filters): + flt(row.cost_of_new_purchase) - flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset) + - flt(row.cost_of_capitalized_asset) ) row.update(next(asset for asset in assets if asset["asset"] == asset_detail.get("name", ""))) @@ -445,6 +469,12 @@ def get_columns(filters): "fieldtype": "Currency", "width": 140, }, + { + "label": _("Cost of New Capitalized Asset"), + "fieldname": "cost_of_capitalized_asset", + "fieldtype": "Currency", + "width": 140, + }, { "label": _("Cost as on") + " " + formatdate(filters.to_date), "fieldname": "cost_as_on_to_date", From 01f9139ebdfd8c1a88dbfb292ec225ef9524e3b2 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Mon, 30 Sep 2024 17:21:09 +0000 Subject: [PATCH 55/83] chore(release): Bumped to Version 15.37.0 # [15.37.0](https://github.com/frappe/erpnext/compare/v15.36.4...v15.37.0) (2024-09-30) ### Features * added 'cost of new capitalized asset' column ([96d8b52](https://github.com/frappe/erpnext/commit/96d8b5242dd0bfa8ac48450501c32348ab4154c7)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index aab2aa1480a..c240944687b 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.36.4" +__version__ = "15.37.0" def get_default_company(user=None): From edfa6e41e1fe296332997c92c610f536ca76cda3 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Fri, 4 Oct 2024 03:07:05 +0000 Subject: [PATCH 56/83] chore(release): Bumped to Version 15.38.0 # [15.38.0](https://github.com/frappe/erpnext/compare/v15.37.0...v15.38.0) (2024-10-04) ### Bug Fixes * 'NoneType' object has no attribute 'has_serial_no' ([21a0157](https://github.com/frappe/erpnext/commit/21a01575b66aa5f620974f171fbbdd7c1d335fe0)) * add company filter in Warehouse wise Item Balance Age and Value ([4fc6d3e](https://github.com/frappe/erpnext/commit/4fc6d3ef64df33303078b624cba6ca09cea03845)) * adjustmen entry for stock reco ([c551c27](https://github.com/frappe/erpnext/commit/c551c2714c97da39541d3d47f8a9d0f9ecaa20e3)) * Cannot read properties of undefined (reading 'price_list_rate') (backport [#43376](https://github.com/frappe/erpnext/issues/43376)) ([#43377](https://github.com/frappe/erpnext/issues/43377)) ([47f06dc](https://github.com/frappe/erpnext/commit/47f06dc180ee434ce21eea9587fa43bb20079215)) * Data missing in table: None, MandatoryError (backport [#43422](https://github.com/frappe/erpnext/issues/43422)) ([#43429](https://github.com/frappe/erpnext/issues/43429)) ([4b3f143](https://github.com/frappe/erpnext/commit/4b3f143f8366881d8cc427d56a14d6c38403d688)) * **Dunning:** logic for fetching text (backport [#43160](https://github.com/frappe/erpnext/issues/43160)) ([#43490](https://github.com/frappe/erpnext/issues/43490)) ([1b28a4e](https://github.com/frappe/erpnext/commit/1b28a4e9285f5131504f20b36172b9716404dccb)) * Fix API endpoint for Frankfurter ([d96cee8](https://github.com/frappe/erpnext/commit/d96cee8779a8143b54231968888a1016dd00b42a)) * Ignore transaction deletion check on ledger entry insertion ([1d6f97a](https://github.com/frappe/erpnext/commit/1d6f97ad945f8d0225533fb03e6866561316481b)) * **Item:** error message on tax rate (backport [#42955](https://github.com/frappe/erpnext/issues/42955)) ([#42956](https://github.com/frappe/erpnext/issues/42956)) ([5fc5934](https://github.com/frappe/erpnext/commit/5fc59349421e739cea28aab29b437678808a4224)) * last purchase rate for purchase invoice (backport [#43448](https://github.com/frappe/erpnext/issues/43448)) ([#43452](https://github.com/frappe/erpnext/issues/43452)) ([ee2c8c8](https://github.com/frappe/erpnext/commit/ee2c8c869ad19a5d5e629b5598f508a9cc4927e9)) * negative stock error for batch (backport [#43450](https://github.com/frappe/erpnext/issues/43450)) ([#43454](https://github.com/frappe/erpnext/issues/43454)) ([7bf6251](https://github.com/frappe/erpnext/commit/7bf6251c21a5249c1c3ade63b29b25d1cb597433)) * patch to update Currency Exchange Settings for `frankfurter.app` (backport [#43481](https://github.com/frappe/erpnext/issues/43481)) ([#43483](https://github.com/frappe/erpnext/issues/43483)) ([35a08f8](https://github.com/frappe/erpnext/commit/35a08f88301b8c80e752a5bd236de97a3546245e)) * quality inspection creation (backport [#43416](https://github.com/frappe/erpnext/issues/43416)) ([#43417](https://github.com/frappe/erpnext/issues/43417)) ([a1b6628](https://github.com/frappe/erpnext/commit/a1b6628c41ef965d855cd6890f0919871b4ca58d)) * **Quotation:** calculate row values for alternative items (backport [#43054](https://github.com/frappe/erpnext/issues/43054)) ([#43495](https://github.com/frappe/erpnext/issues/43495)) ([4fa5131](https://github.com/frappe/erpnext/commit/4fa513159088aeb393d1365cac55af7628d02355)) * removed validation for materials return (backport [#43461](https://github.com/frappe/erpnext/issues/43461)) ([#43463](https://github.com/frappe/erpnext/issues/43463)) ([9c0a17e](https://github.com/frappe/erpnext/commit/9c0a17e4d5dceff6e4ef0a90e1d36de762f8d3af)) * serial and batch no selector (backport [#43387](https://github.com/frappe/erpnext/issues/43387)) ([#43390](https://github.com/frappe/erpnext/issues/43390)) ([74c880c](https://github.com/frappe/erpnext/commit/74c880c232d6fa1cf4f0d53c5faad16f7e809c16)) * set margin fields for purchase documents when updating items ([6516e68](https://github.com/frappe/erpnext/commit/6516e68fa0c296507e12ff6944d797e09da1d0cc)) * Stock Ledger Invariant Check report ([2984bad](https://github.com/frappe/erpnext/commit/2984bad2c09061c949a55d8d62f0fa39bbbbdfd2)) * Stock UOM not fetched when Stock Entry create from Item Dashboard (backport [#43457](https://github.com/frappe/erpnext/issues/43457)) ([#43465](https://github.com/frappe/erpnext/issues/43465)) ([f2a72e5](https://github.com/frappe/erpnext/commit/f2a72e5f82feec1683b858d72a2ca315892a97e2)) * tests for work order consumption (backport [#41814](https://github.com/frappe/erpnext/issues/41814)) ([#43430](https://github.com/frappe/erpnext/issues/43430)) ([86b10ce](https://github.com/frappe/erpnext/commit/86b10ce9bbfbf4279d52df9b17c660e6baeda934)) * use serial and batch fields (backport [#43421](https://github.com/frappe/erpnext/issues/43421)) ([#43423](https://github.com/frappe/erpnext/issues/43423)) ([d495d93](https://github.com/frappe/erpnext/commit/d495d93840c809bfdf7a7109e6fe883eae0e5193)) ### Features * added 'cost of new capitalized asset' column ([27cd51e](https://github.com/frappe/erpnext/commit/27cd51e267b3a11ab474ca085b5a0dc6cef87fad)) * provide hook point for bulk transaction tasks ([50e47e7](https://github.com/frappe/erpnext/commit/50e47e796dc4a91fb4b3e653fb5cc679c58916cf)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index c240944687b..bbb02e2ed0d 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.37.0" +__version__ = "15.38.0" def get_default_company(user=None): From 05db28c64f74bf95a1cd8a9d6a3e6ee782034d49 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:20:34 +0530 Subject: [PATCH 57/83] chore: Allow apps to extend voucher subtypes (backport #43528) (backport #43550) (#43551) chore: Allow apps to extend voucher subtypes (#43528) * chore: Allow apps to extend voucher subtypes (cherry picked from commit a1525d9b8e45c6b71f1a9e490af82e2e84b09c25) * chore: Allow apps to extend voucher subtypes (cherry picked from commit 8a1e38a43b8f47ef388a5d7f57b8e84212bbe2b3) * chore: Allow apps to extend voucher subtypes (cherry picked from commit ca8820b5660f371ec9bd05ac6afe104c55168b18) --------- Co-authored-by: Deepesh Garg (cherry picked from commit bcd0105915ddd7fc433f8de5f743a16023d99748) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- erpnext/controllers/accounts_controller.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 77f54818040..3c1fb8bae44 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1063,6 +1063,13 @@ class AccountsController(TransactionBase): "Stock Entry": "stock_entry_type", "Asset Capitalization": "entry_type", } + + for method_name in frappe.get_hooks("voucher_subtypes"): + voucher_subtype = frappe.get_attr(method_name)(self) + + if voucher_subtype: + return voucher_subtype + if self.doctype in voucher_subtypes: return self.get(voucher_subtypes[self.doctype]) elif self.doctype == "Purchase Receipt" and self.is_return: @@ -1073,6 +1080,7 @@ class AccountsController(TransactionBase): return "Credit Note" elif (self.doctype == "Purchase Invoice" and self.is_return) or self.doctype == "Sales Invoice": return "Debit Note" + return self.doctype def get_value_in_transaction_currency(self, account_currency, gl_dict, field): From d46cf46375e48d41cc10284305b9ca1b43a6c828 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 9 Oct 2024 12:02:42 +0000 Subject: [PATCH 58/83] chore(release): Bumped to Version 15.38.1 ## [15.38.1](https://github.com/frappe/erpnext/compare/v15.38.0...v15.38.1) (2024-10-09) ### Bug Fixes * 'NoneType' object has no attribute 'has_serial_no' (backport [#43514](https://github.com/frappe/erpnext/issues/43514)) ([#43574](https://github.com/frappe/erpnext/issues/43574)) ([60508a9](https://github.com/frappe/erpnext/commit/60508a97061ad910d7c9324ee1da7be64d326884)) * [#42014](https://github.com/frappe/erpnext/issues/42014) --resolve conflicts ([85d7405](https://github.com/frappe/erpnext/commit/85d74050e1b35126e4c9b2d4a7cb1bc3c27ae835)) * Accepted and Rejected warehouse cannot be same (backport [#43568](https://github.com/frappe/erpnext/issues/43568)) ([#43573](https://github.com/frappe/erpnext/issues/43573)) ([83ce3dd](https://github.com/frappe/erpnext/commit/83ce3dd91598b8c2aad65e7f934c16131a9dbdc7)) * add include closed orders option in so/po trends report v15 ([5660e8b](https://github.com/frappe/erpnext/commit/5660e8b26dc5cba40b18bbd532638ac52f84451a)) * add parenttype condition for item table in Purchase Register Report ([8ce81a0](https://github.com/frappe/erpnext/commit/8ce81a058a074ecf11c95137e3c14e30480f241e)) * Add removed test code `https://github.com/frappe/erpnext/commit/b41f10c1b98b01a181a6f9dbdf2531b108dc3bae` ([30fd11f](https://github.com/frappe/erpnext/commit/30fd11f138ce468f5c01f3c5a265eca071293b30)) * allow to change the batch in the subcontracting receipt (backport [#43584](https://github.com/frappe/erpnext/issues/43584)) ([#43588](https://github.com/frappe/erpnext/issues/43588)) ([9e109ac](https://github.com/frappe/erpnext/commit/9e109acec79823fa9bda46b4aeaf2909b941883c)) * create Account Closing Balance even though there are no transaction in period ([d6f70f5](https://github.com/frappe/erpnext/commit/d6f70f533acd24ddb1440cbced74336f59e109e5)) * creation of contact, customer, opportunity, quotation and prospect from lead ([ef10c4e](https://github.com/frappe/erpnext/commit/ef10c4ea4f969a0c6ef12f3733324ae43e689675)) * creation of contact, customer, opportunity, quotation and prospect from lead --prettier ([5a2a404](https://github.com/frappe/erpnext/commit/5a2a404a50ebb40507abbd34dc6a1975db4940ca)) * deduct advances adjusted for threshold check for tcs ([6decb7c](https://github.com/frappe/erpnext/commit/6decb7cc34a02c1bf8d33e019ead5cafc3f65363)) * do not include advances for tds vouchers ([ee8485a](https://github.com/frappe/erpnext/commit/ee8485a54ac0439e9cf3a6c8b9b7e0a02f3ae53f)) * frappe dependency update ([0a70b3f](https://github.com/frappe/erpnext/commit/0a70b3ffccf9367eb0a650b18e78fbc3cf793f90)) * include parent item group in query ([55464c7](https://github.com/frappe/erpnext/commit/55464c79c4a068146b7254f57c9575b44c3966ac)) * make LCV button not working for PI and PR (backport [#43592](https://github.com/frappe/erpnext/issues/43592)) ([#43593](https://github.com/frappe/erpnext/issues/43593)) ([120b481](https://github.com/frappe/erpnext/commit/120b481c4a9038c832d090f3a03a1fd7d5e2a1c3)) * multiple issues in Payment Request ([#42427](https://github.com/frappe/erpnext/issues/42427)) ([ea69ba7](https://github.com/frappe/erpnext/commit/ea69ba7cd8967af626d8efee1c4575d980533923)) * production plan bom error (backport [#43591](https://github.com/frappe/erpnext/issues/43591)) ([#43594](https://github.com/frappe/erpnext/issues/43594)) ([029021f](https://github.com/frappe/erpnext/commit/029021f035b31768acfb94386219e6602cbcbc46)) * read only filters in multidialog fields (backport [#43503](https://github.com/frappe/erpnext/issues/43503)) ([#43513](https://github.com/frappe/erpnext/issues/43513)) ([d69a974](https://github.com/frappe/erpnext/commit/d69a974a4de50e0208127ea3b078acbd0fa0364d)) * Remove `advance_payment_status` uses ([907e3af](https://github.com/frappe/erpnext/commit/907e3af1b0f5a08617f637573f3abc3e3eb56253)) * Remove unreference method ([770bc1c](https://github.com/frappe/erpnext/commit/770bc1c293b106c1bb3ec5077ce73c068973d179)) * Remove unused field ([e785928](https://github.com/frappe/erpnext/commit/e785928c0fcb5e2549302ea77217fe88f9797717)) * Remove unused function `get_paid_amount_against_order` ([7591662](https://github.com/frappe/erpnext/commit/75916629c857465a1a6efadd2fd0c77624c93cf5)) * Separate `on_submit` and `before_submit` of PR ([dbd7b83](https://github.com/frappe/erpnext/commit/dbd7b83204d1e36790d838a5c96c55d4d93464bd)) * the purchase receipt trends and delivery note trends report (backport [#43585](https://github.com/frappe/erpnext/issues/43585)) ([#43587](https://github.com/frappe/erpnext/issues/43587)) ([355ba2f](https://github.com/frappe/erpnext/commit/355ba2f6324c14de3adfdae398089d7c11903347)) * Unknown column 'serial_no' in 'field list' (backport [#43515](https://github.com/frappe/erpnext/issues/43515)) ([#43569](https://github.com/frappe/erpnext/issues/43569)) ([fc9a3c0](https://github.com/frappe/erpnext/commit/fc9a3c0c92cf2537e0b871c8a59a927517150d7f)) * Update Values before `after_mapping` hook is called ([#42682](https://github.com/frappe/erpnext/issues/42682)) ([6770610](https://github.com/frappe/erpnext/commit/6770610c6d62a2dcddf95221ed85ee37c5a56625)) * validation for corrective job card (backport [#43555](https://github.com/frappe/erpnext/issues/43555)) ([#43558](https://github.com/frappe/erpnext/issues/43558)) ([cf0fa0d](https://github.com/frappe/erpnext/commit/cf0fa0db7b7c2a9a5dbd3802ddec1db757afeb24)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index bbb02e2ed0d..784ac134a56 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.38.0" +__version__ = "15.38.1" def get_default_company(user=None): From 8bf8bcf7390296f79432d7a257fa85e095cc6277 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sat, 12 Oct 2024 14:52:35 +0530 Subject: [PATCH 59/83] fix: don't update reference to SI / PI on advances (cherry picked from commit b409f7462070f301469e958be1764b90352298b6) --- .../doctype/payment_entry/payment_entry.py | 16 ++++++++++++++-- erpnext/accounts/utils.py | 11 +++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 9424d722cf5..34179b0b104 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1211,11 +1211,23 @@ class PaymentEntry(AccountsController): { dr_or_cr: allocated_amount_in_company_currency, dr_or_cr + "_in_account_currency": d.allocated_amount, - "against_voucher_type": d.reference_doctype, - "against_voucher": d.reference_name, "cost_center": cost_center, } ) + + if self.book_advance_payments_in_separate_party_account and d.reference_doctype in [ + "Sales Order", + "Purchase Order", + ]: + gle.update( + { + "against_voucher_type": d.reference_doctype, + "against_voucher": d.reference_name, + } + ) + else: + gle.update({"against_voucher_type": self.doctype, "against_voucher": self.name}) + gl_entries.append(gle) if self.unallocated_amount: diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 8e47ddc3652..cf25b201129 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -476,8 +476,12 @@ def reconcile_against_document( # For payments with `Advance` in separate account feature enabled, only new ledger entries are posted for each reference. # No need to cancel/delete payment ledger entries + repost_whole_ledger = any([x.voucher_detail_no for x in entries]) if voucher_type == "Payment Entry" and doc.book_advance_payments_in_separate_party_account: - doc.make_advance_gl_entries(cancel=1) + if repost_whole_ledger: + doc.make_gl_entries(cancel=1) + else: + doc.make_advance_gl_entries(cancel=1) else: _delete_pl_entries(voucher_type, voucher_no) @@ -513,7 +517,10 @@ def reconcile_against_document( if voucher_type == "Payment Entry" and doc.book_advance_payments_in_separate_party_account: # both ledgers must be posted to for `Advance` in separate account feature # TODO: find a more efficient way post only for the new linked vouchers - doc.make_advance_gl_entries() + if repost_whole_ledger: + doc.make_gl_entries() + else: + doc.make_advance_gl_entries() else: gl_map = doc.build_gl_map() # Make sure there is no overallocation From 6267ab994c79b3ab8828069c760e81538ff73887 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sat, 12 Oct 2024 15:29:48 +0530 Subject: [PATCH 60/83] refactor: reference update logic in advance (cherry picked from commit a112581acd77b41f9140b0cee082db3b00cd1e22) --- .../doctype/payment_entry/payment_entry.py | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 34179b0b104..f031bda045e 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1215,18 +1215,26 @@ class PaymentEntry(AccountsController): } ) - if self.book_advance_payments_in_separate_party_account and d.reference_doctype in [ - "Sales Order", - "Purchase Order", - ]: + if self.book_advance_payments_in_separate_party_account: + if d.reference_doctype in [ + "Sales Order", + "Purchase Order", + ]: + gle.update( + { + "against_voucher_type": d.reference_doctype, + "against_voucher": d.reference_name, + } + ) + else: + gle.update({"against_voucher_type": self.doctype, "against_voucher": self.name}) + else: gle.update( { "against_voucher_type": d.reference_doctype, "against_voucher": d.reference_name, } ) - else: - gle.update({"against_voucher_type": self.doctype, "against_voucher": self.name}) gl_entries.append(gle) From 8c115e146b65cebbbf09b3c34090ef37a93ce530 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sat, 12 Oct 2024 15:54:21 +0530 Subject: [PATCH 61/83] refactor: use hooks to identify advance doctypes (cherry picked from commit e7bb960bb557a0cc05570b248962ba519a3278db) --- erpnext/accounts/doctype/payment_entry/payment_entry.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index f031bda045e..eddcdf56fb2 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1166,6 +1166,10 @@ class PaymentEntry(AccountsController): if not self.party_account: return + advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks( + "advance_payment_payable_doctypes" + ) + if self.payment_type == "Receive": against_account = self.paid_to else: @@ -1216,10 +1220,7 @@ class PaymentEntry(AccountsController): ) if self.book_advance_payments_in_separate_party_account: - if d.reference_doctype in [ - "Sales Order", - "Purchase Order", - ]: + if d.reference_doctype in advance_payment_doctypes: gle.update( { "against_voucher_type": d.reference_doctype, From e0477cf59f7612276e3d9549522c8fafa53557a1 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sat, 12 Oct 2024 15:55:51 +0530 Subject: [PATCH 62/83] refactor(test): utility methods for enabling advance in separate acc (cherry picked from commit a21a406d0409c28c0880b91577343f24db6e510a) # Conflicts: # erpnext/accounts/test/accounts_mixin.py --- erpnext/accounts/test/accounts_mixin.py | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/erpnext/accounts/test/accounts_mixin.py b/erpnext/accounts/test/accounts_mixin.py index d503f7bc4af..b67e190f431 100644 --- a/erpnext/accounts/test/accounts_mixin.py +++ b/erpnext/accounts/test/accounts_mixin.py @@ -87,6 +87,22 @@ class AccountsTestMixin: "parent_account": "Bank Accounts - " + abbr, } ), + frappe._dict( + { + "attribute_name": "advance_received", + "account_name": "Advance Received", + "parent_account": "Current Liabilities - " + abbr, + "account_type": "Receivable", + } + ), + frappe._dict( + { + "attribute_name": "advance_paid", + "account_name": "Advance Paid", + "parent_account": "Current Assets - " + abbr, + "account_type": "Payable", + } + ), ] for acc in other_accounts: acc_name = acc.account_name + " - " + abbr @@ -101,9 +117,34 @@ class AccountsTestMixin: "company": self.company, } ) + new_acc.account_type = acc.get("account_type", None) new_acc.save() setattr(self, acc.attribute_name, new_acc.name) +<<<<<<< HEAD +======= + self.identify_default_warehouses() + + def enable_advance_as_liability(self): + company = frappe.get_doc("Company", self.company) + company.book_advance_payments_in_separate_party_account = True + company.default_advance_received_account = self.advance_received + company.default_advance_paid_account = self.advance_paid + company.save() + + def disable_advance_as_liability(self): + company = frappe.get_doc("Company", self.company) + company.book_advance_payments_in_separate_party_account = False + company.default_advance_paid_account = company.default_advance_received_account = None + company.save() + + def identify_default_warehouses(self): + for w in frappe.db.get_all( + "Warehouse", filters={"company": self.company}, fields=["name", "warehouse_name"] + ): + setattr(self, "warehouse_" + w.warehouse_name.lower().strip().replace(" ", "_"), w.name) + +>>>>>>> a21a406d04 (refactor(test): utility methods for enabling advance in separate acc) def create_usd_receivable_account(self): account_name = "Debtors USD" if not frappe.db.get_value( From e56dd8268b6aa05fc9c6d52924baa0be1747adab Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sat, 12 Oct 2024 15:56:53 +0530 Subject: [PATCH 63/83] test: unreconciliation of individual SO from Advance Payment (cherry picked from commit 8a6978e55000efda874931dcf4a11403bf795e84) --- .../test_unreconcile_payment.py | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py b/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py index 43dfbfaef60..eb5530706b6 100644 --- a/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py +++ b/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py @@ -363,3 +363,54 @@ class TestUnreconcilePayment(AccountsTestMixin, FrappeTestCase): self.assertEqual(so.advance_paid, 0) self.assertEqual(len(pe.references), 0) self.assertEqual(pe.unallocated_amount, 100) + + def test_06_unreconcile_advance_from_payment_entry(self): + self.enable_advance_as_liability() + so1 = self.create_sales_order() + so2 = self.create_sales_order() + + pe = self.create_payment_entry() + # Allocation payment against Sales Order + pe.paid_amount = 260 + pe.append( + "references", + {"reference_doctype": so1.doctype, "reference_name": so1.name, "allocated_amount": 150}, + ) + pe.append( + "references", + {"reference_doctype": so2.doctype, "reference_name": so2.name, "allocated_amount": 110}, + ) + pe.save().submit() + + # Assert 'Advance Paid' + so1.reload() + self.assertEqual(so1.advance_paid, 150) + so2.reload() + self.assertEqual(so2.advance_paid, 110) + + unreconcile = frappe.get_doc( + { + "doctype": "Unreconcile Payment", + "company": self.company, + "voucher_type": pe.doctype, + "voucher_no": pe.name, + } + ) + unreconcile.add_references() + self.assertEqual(len(unreconcile.allocations), 2) + allocations = [(x.reference_name, x.allocated_amount) for x in unreconcile.allocations] + self.assertListEqual(allocations, [(so1.name, 150), (so2.name, 110)]) + # unreconcile so2 + unreconcile.remove(unreconcile.allocations[0]) + unreconcile.save().submit() + + # Assert 'Advance Paid' + so1.reload() + so2.reload() + pe.reload() + self.assertEqual(so1.advance_paid, 150) + self.assertEqual(so2.advance_paid, 0) + self.assertEqual(len(pe.references), 1) + self.assertEqual(pe.unallocated_amount, 110) + + self.disable_advance_as_liability() From 4752ed2483d7697129c2af245222977bdcb1b750 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sat, 12 Oct 2024 18:12:03 +0530 Subject: [PATCH 64/83] test: reconciled Invoice should not showup in tool Scenario should be tested on 'Advance in separate party account' (cherry picked from commit f1ec61c19ec8275804958e4eaf131906a2cffc90) --- .../test_unreconcile_payment.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py b/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py index eb5530706b6..13e5294aa78 100644 --- a/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py +++ b/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py @@ -7,7 +7,9 @@ from frappe.utils import today from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice +from erpnext.accounts.party import get_party_account from erpnext.accounts.test.accounts_mixin import AccountsTestMixin +from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order @@ -414,3 +416,49 @@ class TestUnreconcilePayment(AccountsTestMixin, FrappeTestCase): self.assertEqual(pe.unallocated_amount, 110) self.disable_advance_as_liability() + + def test_07_adv_from_so_to_invoice(self): + self.enable_advance_as_liability() + so = self.create_sales_order() + pe = self.create_payment_entry() + pe.paid_amount = 1000 + pe.append( + "references", + {"reference_doctype": so.doctype, "reference_name": so.name, "allocated_amount": 1000}, + ) + pe.save().submit() + + # Assert 'Advance Paid' + so.reload() + self.assertEqual(so.advance_paid, 1000) + + si = make_sales_invoice(so.name) + si.insert().submit() + + pr = frappe.get_doc( + { + "doctype": "Payment Reconciliation", + "company": self.company, + "party_type": "Customer", + "party": so.customer, + } + ) + accounts = get_party_account("Customer", so.customer, so.company, True) + pr.receivable_payable_account = accounts[0] + pr.default_advance_account = accounts[1] + pr.get_unreconciled_entries() + self.assertEqual(len(pr.get("invoices")), 1) + self.assertEqual(len(pr.get("payments")), 1) + invoices = [x.as_dict() for x in pr.get("invoices")] + payments = [x.as_dict() for x in pr.get("payments")] + pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) + pr.reconcile() + + self.assertEqual(len(pr.get("invoices")), 0) + self.assertEqual(len(pr.get("payments")), 0) + + # Assert 'Advance Paid' + so.reload() + self.assertEqual(so.advance_paid, 0) + + self.disable_advance_as_liability() From 4c78a682ad38121bd3b9135db9acca68f30028a9 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sun, 13 Oct 2024 08:08:54 +0530 Subject: [PATCH 65/83] chore: better comments for context (cherry picked from commit e7505e92c9b4200d52214d2dc97f7052b2333095) --- .../accounts/doctype/payment_entry/payment_entry.py | 2 ++ erpnext/accounts/utils.py | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index eddcdf56fb2..7e3aa25f358 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1221,6 +1221,7 @@ class PaymentEntry(AccountsController): if self.book_advance_payments_in_separate_party_account: if d.reference_doctype in advance_payment_doctypes: + # Upon reconciliation, whole ledger will be reposted. So, reference to SO/PO is fine gle.update( { "against_voucher_type": d.reference_doctype, @@ -1228,6 +1229,7 @@ class PaymentEntry(AccountsController): } ) else: + # Do not reference Invoices while Advance is in separate party account gle.update({"against_voucher_type": self.doctype, "against_voucher": self.name}) else: gle.update( diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index cf25b201129..1d75fafc1a9 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -474,8 +474,8 @@ def reconcile_against_document( doc = frappe.get_doc(voucher_type, voucher_no) frappe.flags.ignore_party_validation = True - # For payments with `Advance` in separate account feature enabled, only new ledger entries are posted for each reference. - # No need to cancel/delete payment ledger entries + # When Advance is allocated from an Order to an Invoice + # whole ledger must be reposted repost_whole_ledger = any([x.voucher_detail_no for x in entries]) if voucher_type == "Payment Entry" and doc.book_advance_payments_in_separate_party_account: if repost_whole_ledger: @@ -515,11 +515,13 @@ def reconcile_against_document( doc = frappe.get_doc(entry.voucher_type, entry.voucher_no) if voucher_type == "Payment Entry" and doc.book_advance_payments_in_separate_party_account: - # both ledgers must be posted to for `Advance` in separate account feature - # TODO: find a more efficient way post only for the new linked vouchers + # When Advance is allocated from an Order to an Invoice + # whole ledger must be reposted if repost_whole_ledger: doc.make_gl_entries() else: + # both ledgers must be posted to for `Advance` in separate account feature + # TODO: find a more efficient way post only for the new linked vouchers doc.make_advance_gl_entries() else: gl_map = doc.build_gl_map() From cf1eabe049c4ee3b7c8f6e978fd7788b4bc7e566 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sun, 13 Oct 2024 10:35:14 +0530 Subject: [PATCH 66/83] chore: resolve conflict --- erpnext/accounts/test/accounts_mixin.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/erpnext/accounts/test/accounts_mixin.py b/erpnext/accounts/test/accounts_mixin.py index b67e190f431..e526e07c734 100644 --- a/erpnext/accounts/test/accounts_mixin.py +++ b/erpnext/accounts/test/accounts_mixin.py @@ -121,8 +121,6 @@ class AccountsTestMixin: new_acc.save() setattr(self, acc.attribute_name, new_acc.name) -<<<<<<< HEAD -======= self.identify_default_warehouses() def enable_advance_as_liability(self): @@ -144,7 +142,6 @@ class AccountsTestMixin: ): setattr(self, "warehouse_" + w.warehouse_name.lower().strip().replace(" ", "_"), w.name) ->>>>>>> a21a406d04 (refactor(test): utility methods for enabling advance in separate acc) def create_usd_receivable_account(self): account_name = "Debtors USD" if not frappe.db.get_value( From a329003f7fc49ad1e534bcff6ce0bfa0fc76bbfe Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sun, 13 Oct 2024 10:35:48 +0530 Subject: [PATCH 67/83] chore: use correct hook for advance payment doctypes --- erpnext/accounts/doctype/payment_entry/payment_entry.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 7e3aa25f358..7885d825129 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1166,9 +1166,7 @@ class PaymentEntry(AccountsController): if not self.party_account: return - advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks( - "advance_payment_payable_doctypes" - ) + advance_payment_doctypes = frappe.get_hooks("advance_payment_doctypes") if self.payment_type == "Receive": against_account = self.paid_to From ef1e121bd409462da781360fca7eda5ae7495f9c Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Sun, 13 Oct 2024 05:23:41 +0000 Subject: [PATCH 68/83] chore(release): Bumped to Version 15.38.2 ## [15.38.2](https://github.com/frappe/erpnext/compare/v15.38.1...v15.38.2) (2024-10-13) ### Bug Fixes * don't update reference to SI / PI on advances ([8bf8bcf](https://github.com/frappe/erpnext/commit/8bf8bcf7390296f79432d7a257fa85e095cc6277)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 784ac134a56..076eaeada9b 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.38.1" +__version__ = "15.38.2" def get_default_company(user=None): From 99ead94ffeecd1976604c64da1c2cbbb26e63fb9 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 16 Oct 2024 05:01:44 +0000 Subject: [PATCH 69/83] chore(release): Bumped to Version 15.38.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [15.38.3](https://github.com/frappe/erpnext/compare/v15.38.2...v15.38.3) (2024-10-16) ### Bug Fixes * added parentheses for correct query formation for logical OR condition ([21a7dd4](https://github.com/frappe/erpnext/commit/21a7dd43a9f1fee1871e7962924330c03d7949fa)) * added string for translation in bank reconciliation statement ([e10a580](https://github.com/frappe/erpnext/commit/e10a58074f2f58c1fbcca7a85a41deca1f6db076)) * conversion factor issue (backport [#43645](https://github.com/frappe/erpnext/issues/43645)) ([#43674](https://github.com/frappe/erpnext/issues/43674)) ([b2deb89](https://github.com/frappe/erpnext/commit/b2deb8982646deccd4a4b0bef4c67796a64c09d8)) * delete invalid pricing rule on change of applicable_for ([5d6fc71](https://github.com/frappe/erpnext/commit/5d6fc71556ba70adec566c0711a401cfadbaf432)) * don't update reference to SI / PI on advances ([b72906a](https://github.com/frappe/erpnext/commit/b72906a7a1de57d9344384226cf8e9061ab47cfa)) * ignore free item when qty is zero ([e5aaa5b](https://github.com/frappe/erpnext/commit/e5aaa5b6e5ebdb340666123e86e3c3b78b57d6ce)) * incorrect warehouse in the serial no selector for rejection (backport [#43671](https://github.com/frappe/erpnext/issues/43671)) ([#43673](https://github.com/frappe/erpnext/issues/43673)) ([c490a66](https://github.com/frappe/erpnext/commit/c490a6654090b30de9e2aa9398859fbb6d2bd9da)) * Link opportunity from RFQ to supplier quotation ([eb1f125](https://github.com/frappe/erpnext/commit/eb1f1255ebb7f1424e982864bd2b08ceb54e86a2)) * missing child company accounts in consolidated balance sheet ([4db12fe](https://github.com/frappe/erpnext/commit/4db12fe2da4a3bdacf786c8a6c2ab47711ffecef)) * quotation to so frappe crm (backport [#43644](https://github.com/frappe/erpnext/issues/43644)) ([#43646](https://github.com/frappe/erpnext/issues/43646)) ([f3ceb4a](https://github.com/frappe/erpnext/commit/f3ceb4ac7d50969d2dcece661078e1ab0af575ac)) * refetch items from BOM if 'Use Multi-Level BOM' has changed usin… (backport [#43672](https://github.com/frappe/erpnext/issues/43672)) ([#43676](https://github.com/frappe/erpnext/issues/43676)) ([492ba53](https://github.com/frappe/erpnext/commit/492ba539e803b2b13abaf41443812d8ac172f858)) * removed unused query ([8668ae9](https://github.com/frappe/erpnext/commit/8668ae92d830a2eb1168739f9a8bd55281f5c451)) * run gl_entries and closing voucher processes in same function ([ea12897](https://github.com/frappe/erpnext/commit/ea12897ce96b8ba36f1a8db8ddbb192526f78141)) * show incorrect entries filter in Stock Ledger Invariant Check report (backport [#43619](https://github.com/frappe/erpnext/issues/43619)) ([#43622](https://github.com/frappe/erpnext/issues/43622)) ([d604b12](https://github.com/frappe/erpnext/commit/d604b12d5111e9dd5e0fcd3bc35f06c87284c349)) * **stock:** Grab posting date/time from SABB (backport [#43493](https://github.com/frappe/erpnext/issues/43493)) ([#43502](https://github.com/frappe/erpnext/issues/43502)) ([cd9f949](https://github.com/frappe/erpnext/commit/cd9f949b1288708876dd908403616ce0c2e7b6b8)) * update formatings ([c2c6d27](https://github.com/frappe/erpnext/commit/c2c6d27625a82fe836668773d0b8fe41426c5161)) * update formatings ([a70181e](https://github.com/frappe/erpnext/commit/a70181e0258ae209eb7012a507ce513def51f311)) * update item details with actual quantity. ([930e79c](https://github.com/frappe/erpnext/commit/930e79c3510ea7e92edf669f864024c02dbaf058)) * Use `ref_doc.get()` for `party_account_currency` ([928b6b1](https://github.com/frappe/erpnext/commit/928b6b1510b13fbf15e7d3a76fe204a3bcd12f30)) * zero incoming rate for delivery note return ([#43642](https://github.com/frappe/erpnext/issues/43642)) ([85088e4](https://github.com/frappe/erpnext/commit/85088e4aff41306bb132a1f4e22e7e4c85eb70b4)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 076eaeada9b..df1511b8847 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.38.2" +__version__ = "15.38.3" def get_default_company(user=None): From 752d175d22db3bb3c38b0ee68622640d1597bc29 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:57:57 +0530 Subject: [PATCH 70/83] fix: list view and form status not same for purchase order (backport #43690) (#43692) * fix: list view and form status not same for purchase order (#43690) (cherry picked from commit a671fe13d432de3a1b76f79284855172b36dcde8) # Conflicts: # erpnext/buying/doctype/purchase_order/purchase_order.js # erpnext/buying/doctype/purchase_order/purchase_order_list.js * chore: fix conflicts * chore: fix conflicts --------- Co-authored-by: rohitwaghchaure (cherry picked from commit a33d5535a7c88de749bfd47855717ac1410b65fb) --- .../doctype/purchase_order/purchase_order.js | 4 ++-- .../purchase_order/purchase_order_list.js | 17 +++++------------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index ac2aa43f23d..de335bd6292 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -382,7 +382,7 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends ( } if (doc.status != "Closed") { if (doc.status != "On Hold") { - if (flt(doc.per_received, 2) < 100 && allow_receipt) { + if (flt(doc.per_received) < 100 && allow_receipt) { cur_frm.add_custom_button( __("Purchase Receipt"), this.make_purchase_receipt, @@ -408,7 +408,7 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends ( } } } - if (flt(doc.per_billed, 2) < 100) + if (flt(doc.per_billed) < 100) cur_frm.add_custom_button( __("Purchase Invoice"), this.make_purchase_invoice, diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_list.js b/erpnext/buying/doctype/purchase_order/purchase_order_list.js index c1bf1f3b8d9..7b37987b926 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order_list.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order_list.js @@ -10,14 +10,15 @@ frappe.listview_settings["Purchase Order"] = { "status", ], get_indicator: function (doc) { + // Please do not add precision in the flt function if (doc.status === "Closed") { return [__("Closed"), "green", "status,=,Closed"]; } else if (doc.status === "On Hold") { return [__("On Hold"), "orange", "status,=,On Hold"]; } else if (doc.status === "Delivered") { return [__("Delivered"), "green", "status,=,Closed"]; - } else if (flt(doc.per_received, 2) < 100 && doc.status !== "Closed") { - if (flt(doc.per_billed, 2) < 100) { + } else if (flt(doc.per_received) < 100 && doc.status !== "Closed") { + if (flt(doc.per_billed) < 100) { return [ __("To Receive and Bill"), "orange", @@ -26,17 +27,9 @@ frappe.listview_settings["Purchase Order"] = { } else { return [__("To Receive"), "orange", "per_received,<,100|per_billed,=,100|status,!=,Closed"]; } - } else if ( - flt(doc.per_received, 2) >= 100 && - flt(doc.per_billed, 2) < 100 && - doc.status !== "Closed" - ) { + } else if (flt(doc.per_received) >= 100 && flt(doc.per_billed) < 100 && doc.status !== "Closed") { return [__("To Bill"), "orange", "per_received,=,100|per_billed,<,100|status,!=,Closed"]; - } else if ( - flt(doc.per_received, 2) >= 100 && - flt(doc.per_billed, 2) == 100 && - doc.status !== "Closed" - ) { + } else if (flt(doc.per_received) >= 100 && flt(doc.per_billed) == 100 && doc.status !== "Closed") { return [__("Completed"), "green", "per_received,=,100|per_billed,=,100|status,!=,Closed"]; } }, From 08cabd1717a0a08875edc94e9c48e104465336c9 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 17 Oct 2024 16:05:56 +0000 Subject: [PATCH 71/83] chore(release): Bumped to Version 15.38.4 ## [15.38.4](https://github.com/frappe/erpnext/compare/v15.38.3...v15.38.4) (2024-10-17) ### Bug Fixes * list view and form status not same for purchase order (backport [#43690](https://github.com/frappe/erpnext/issues/43690)) ([#43692](https://github.com/frappe/erpnext/issues/43692)) ([752d175](https://github.com/frappe/erpnext/commit/752d175d22db3bb3c38b0ee68622640d1597bc29)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index df1511b8847..e28b6e9bb91 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.38.3" +__version__ = "15.38.4" def get_default_company(user=None): From e0a45a5a5481f6c5328bed01a449994279a376e2 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 23 Oct 2024 04:48:23 +0000 Subject: [PATCH 72/83] chore(release): Bumped to Version 15.39.0 # [15.39.0](https://github.com/frappe/erpnext/compare/v15.38.4...v15.39.0) (2024-10-23) ### Bug Fixes * "show_remarks" checkbox in Process statement of accounts ([f7717c9](https://github.com/frappe/erpnext/commit/f7717c91bc48869a03ba5d76b0ac1e8879dfc074)) * added validation for UOM must be whole number (backport [#43710](https://github.com/frappe/erpnext/issues/43710)) ([#43712](https://github.com/frappe/erpnext/issues/43712)) ([60ffcd0](https://github.com/frappe/erpnext/commit/60ffcd0574bebbfa3e91fe82744c14792f9d8ad2)) * Call super onload_post_render inside pos_invoice.js ([1281d9d](https://github.com/frappe/erpnext/commit/1281d9d21dd2628fe755881b6d7189c0c5848ee7)) * coupon code validation logic ([aeaadb1](https://github.com/frappe/erpnext/commit/aeaadb1e300b622abf54d35364a471463b504a2e)) * **deferred_revenue:** Escape account in query ([fac27d9](https://github.com/frappe/erpnext/commit/fac27d9dff8fbd6babcbf92ede6a94d51484e36f)) * do not make new depreciation for fully depreciated asset ([ddb38db](https://github.com/frappe/erpnext/commit/ddb38db5c46fb20cecd1fd6dcca2ef2168d8a9f9)) * Freeze Screen on load invoices on POS Closing Entry ([f343d5a](https://github.com/frappe/erpnext/commit/f343d5a24dbcc38b63b9c94182d69cdea701b6db)) * get party advance amount based on account ([b673377](https://github.com/frappe/erpnext/commit/b673377b70210f2004df0cbc9eab29f86e17d778)) * get period estimate till service end date ([148d7e7](https://github.com/frappe/erpnext/commit/148d7e798bbe66cee8c8f3e5e0ed1db7dca8d734)) * get stock accounts from the doc instead of db in validate_stock_accounts ([39387e9](https://github.com/frappe/erpnext/commit/39387e9f54ddd27f77ddfb268a7d92e0c3e66f7b)) * incorrect amount in bank clearance ([52be45c](https://github.com/frappe/erpnext/commit/52be45c5dff5f0fcfb3573ba94f177816c3fa67b)) * lead create opp from connection not working ([9e56f21](https://github.com/frappe/erpnext/commit/9e56f213a3c7149a2067944f4adb274af69598f6)) * list view and form status not same for purchase order (backport [#43690](https://github.com/frappe/erpnext/issues/43690)) ([#43692](https://github.com/frappe/erpnext/issues/43692)) ([a33d553](https://github.com/frappe/erpnext/commit/a33d5535a7c88de749bfd47855717ac1410b65fb)) * only show pay button for specific doctype in portal ([d2e5b2a](https://github.com/frappe/erpnext/commit/d2e5b2aa1d22cdcaccc62b412732b8d12f9b1aa3)) * party_balance based on company in payment entry ([04fbcc6](https://github.com/frappe/erpnext/commit/04fbcc64ff661689e5b8e7a62569ef54674b64f1)) * remove extra space ([50dd8d9](https://github.com/frappe/erpnext/commit/50dd8d9df756fa1bf64fa0d86b719b6aeffd0228)) * removed unmerged patches ([2e0cf36](https://github.com/frappe/erpnext/commit/2e0cf36901b52369cd95c73a331269d123f94612)) * Required Changes to Support e-Waybill Generation for Material Transfer Return ([#43061](https://github.com/frappe/erpnext/issues/43061)) ([2205ae8](https://github.com/frappe/erpnext/commit/2205ae8e54126a868825bb6cb6fa54d01498b298)) * show total amount on report summary ([ab20344](https://github.com/frappe/erpnext/commit/ab20344141e60c43464263454a7c531cc0fd2b5e)) * use correct variable in error message (backport [#43790](https://github.com/frappe/erpnext/issues/43790)) ([#43792](https://github.com/frappe/erpnext/issues/43792)) ([879b2b7](https://github.com/frappe/erpnext/commit/879b2b778a6421c62b977cac82f9568da172ed04)) * Workspace link for Work Order Consumed Materials report (backport [#43753](https://github.com/frappe/erpnext/issues/43753)) ([#43754](https://github.com/frappe/erpnext/issues/43754)) ([1fa9030](https://github.com/frappe/erpnext/commit/1fa9030aee13c39c6aade9779145d86ff976ce90)) ### Features * added assignee email field in asset maintenance log ([a3b8f97](https://github.com/frappe/erpnext/commit/a3b8f9759d79d9ad45173248ab4bf3bb343aafc6)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index e28b6e9bb91..a5b8609d1d9 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.38.4" +__version__ = "15.39.0" def get_default_company(user=None): From d392660d455f0be92cc423eca611e40f96100c07 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 23 Oct 2024 14:27:10 +0530 Subject: [PATCH 73/83] chore: release version 15.39.1 (#43800) * fix: map doc from purchase order (cherry picked from commit 60ceb91ace8fbb8ddd127a00e7eadd431d4e250c) * test: auto create purchase receipt (cherry picked from commit 59887bbc13c223739750eb27599be5e251bca91e) * fix: better implementation, handle missing purchase order (cherry picked from commit 66211dafd69ecbdc56a52d8391b6fdcf02c3154a) * perf: performance optimizations for accounting reports by refactoring account closing balance and period closing voucher (#43798) * fix: Gl Entry form cleanup * fix: Added indexes in gl entry table * perf: Refactored period closing voucher to handle large volume of gle * fix: fixes as per new period start and end date fields in PCV * perf: performance optimization for accounting reports * perf: performance optimizations for account closing balance patch * fix: test cases * fix: lenter issues - direct use of sql query * fix: test cases * fix: test cases * fix: test cases * fix: wrong fieldname * fix: test cases --------- Co-authored-by: Ninad1306 Co-authored-by: Smit Vora --- .../account_closing_balance.py | 4 +- .../accounting_period/accounting_period.py | 2 + .../accounts/doctype/gl_entry/gl_entry.json | 106 ++- erpnext/accounts/doctype/gl_entry/gl_entry.py | 3 +- .../test_payment_reconciliation.py | 6 +- .../period_closing_voucher.js | 18 + .../period_closing_voucher.json | 38 +- .../period_closing_voucher.py | 721 ++++++++++-------- .../test_period_closing_voucher.py | 8 +- .../repost_accounting_ledger.py | 4 +- .../test_repost_accounting_ledger.py | 6 +- erpnext/accounts/general_ledger.py | 34 +- .../accounts_receivable.py | 29 +- .../accounts/report/financial_statements.py | 143 ++-- .../report/trial_balance/trial_balance.py | 20 +- erpnext/patches.txt | 1 + .../fix_additional_cost_in_mfg_stock_entry.py | 2 +- .../v14_0/set_period_start_end_date_in_pcv.py | 17 + .../patches/v14_0/single_to_multi_dunning.py | 2 +- .../patches/v14_0/update_closing_balances.py | 105 +-- .../doctype/delivery_note/delivery_note.py | 25 +- .../repost_item_valuation.py | 2 +- .../stock/doctype/stock_entry/stock_entry.py | 8 +- erpnext/stock/report/test_reports.py | 3 +- .../subcontracting_receipt.py | 167 ++-- .../test_subcontracting_receipt.py | 43 +- erpnext/tests/test_perf.py | 2 +- 27 files changed, 904 insertions(+), 615 deletions(-) create mode 100644 erpnext/patches/v14_0/set_period_start_end_date_in_pcv.py diff --git a/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py b/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py index 82821e140ea..6d5e023f039 100644 --- a/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py +++ b/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py @@ -113,9 +113,9 @@ def get_previous_closing_entries(company, closing_date, accounting_dimensions): entries = [] last_period_closing_voucher = frappe.db.get_all( "Period Closing Voucher", - filters={"docstatus": 1, "company": company, "posting_date": ("<", closing_date)}, + filters={"docstatus": 1, "company": company, "period_end_date": ("<", closing_date)}, fields=["name"], - order_by="posting_date desc", + order_by="period_end_date desc", limit=1, ) diff --git a/erpnext/accounts/doctype/accounting_period/accounting_period.py b/erpnext/accounts/doctype/accounting_period/accounting_period.py index 172ef93f14d..300d216618e 100644 --- a/erpnext/accounts/doctype/accounting_period/accounting_period.py +++ b/erpnext/accounts/doctype/accounting_period/accounting_period.py @@ -101,6 +101,8 @@ def validate_accounting_period_on_doc_save(doc, method=None): date = doc.available_for_use_date elif doc.doctype == "Asset Repair": date = doc.completion_date + elif doc.doctype == "Period Closing Voucher": + date = doc.period_end_date else: date = doc.posting_date diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json index 2d106ad8cee..c285a33f73e 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.json +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json @@ -6,38 +6,50 @@ "document_type": "Document", "engine": "InnoDB", "field_order": [ + "dates_section", "posting_date", "transaction_date", + "column_break_avko", + "fiscal_year", + "due_date", + "account_details_section", "account", + "account_currency", + "column_break_ifvf", + "against", "party_type", "party", - "cost_center", - "debit", - "credit", - "account_currency", - "debit_in_account_currency", - "credit_in_account_currency", - "against", + "transaction_details_section", + "voucher_type", + "voucher_no", + "voucher_subtype", + "transaction_currency", + "column_break_dpsx", "against_voucher_type", "against_voucher", - "voucher_type", - "voucher_subtype", - "voucher_no", "voucher_detail_no", + "transaction_exchange_rate", + "amounts_section", + "debit_in_account_currency", + "debit", + "debit_in_transaction_currency", + "column_break_bm1w", + "credit_in_account_currency", + "credit", + "credit_in_transaction_currency", + "dimensions_section", + "cost_center", + "column_break_lmnm", "project", - "remarks", + "more_info_section", + "finance_book", + "company", "is_opening", "is_advance", - "fiscal_year", - "company", - "finance_book", + "column_break_8abq", "to_rename", - "due_date", "is_cancelled", - "transaction_currency", - "debit_in_transaction_currency", - "credit_in_transaction_currency", - "transaction_exchange_rate" + "remarks" ], "fields": [ { @@ -285,13 +297,67 @@ "fieldname": "voucher_subtype", "fieldtype": "Small Text", "label": "Voucher Subtype" + }, + { + "fieldname": "dates_section", + "fieldtype": "Section Break", + "label": "Dates" + }, + { + "fieldname": "column_break_avko", + "fieldtype": "Column Break" + }, + { + "fieldname": "account_details_section", + "fieldtype": "Section Break", + "label": "Account Details" + }, + { + "fieldname": "column_break_ifvf", + "fieldtype": "Column Break" + }, + { + "fieldname": "transaction_details_section", + "fieldtype": "Section Break", + "label": "Transaction Details" + }, + { + "fieldname": "amounts_section", + "fieldtype": "Section Break", + "label": "Amounts" + }, + { + "fieldname": "column_break_dpsx", + "fieldtype": "Column Break" + }, + { + "fieldname": "more_info_section", + "fieldtype": "Section Break", + "label": "More Info" + }, + { + "fieldname": "column_break_bm1w", + "fieldtype": "Column Break" + }, + { + "fieldname": "dimensions_section", + "fieldtype": "Section Break", + "label": "Dimensions" + }, + { + "fieldname": "column_break_lmnm", + "fieldtype": "Column Break" + }, + { + "fieldname": "column_break_8abq", + "fieldtype": "Column Break" } ], "icon": "fa fa-list", "idx": 1, "in_create": 1, "links": [], - "modified": "2024-07-02 14:31:51.496466", + "modified": "2024-08-22 13:03:39.997475", "modified_by": "Administrator", "module": "Accounts", "name": "GL Entry", diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index d74224c4aa2..a7e7edb098d 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -430,8 +430,9 @@ def update_against_account(voucher_type, voucher_no): def on_doctype_update(): - frappe.db.add_index("GL Entry", ["against_voucher_type", "against_voucher"]) frappe.db.add_index("GL Entry", ["voucher_type", "voucher_no"]) + frappe.db.add_index("GL Entry", ["posting_date", "company"]) + frappe.db.add_index("GL Entry", ["party_type", "party"]) def rename_gle_sle_docs(): diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py index 883c638398c..1b19949bb7e 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py @@ -1986,13 +1986,15 @@ def make_period_closing_voucher(company, cost_center, posting_date=None, submit= parent_account=parent_account, doctype="Account", ) + fy = get_fiscal_year(posting_date, company=company) pcv = frappe.get_doc( { "doctype": "Period Closing Voucher", "transaction_date": posting_date or today(), - "posting_date": posting_date or today(), + "period_start_date": fy[1], + "period_end_date": fy[2], "company": company, - "fiscal_year": get_fiscal_year(posting_date or today(), company=company)[0], + "fiscal_year": fy[0], "cost_center": cost_center, "closing_account_head": surplus_account, "remarks": "test", diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.js b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.js index 82d8cb37fe7..095310c7e70 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.js +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.js @@ -19,6 +19,24 @@ frappe.ui.form.on("Period Closing Voucher", { }); }, + fiscal_year: function (frm) { + if (frm.doc.fiscal_year) { + frappe.call({ + method: "erpnext.accounts.doctype.period_closing_voucher.period_closing_voucher.get_period_start_end_date", + args: { + fiscal_year: frm.doc.fiscal_year, + company: frm.doc.company, + }, + callback: function (r) { + if (r.message) { + frm.set_value("period_start_date", r.message[0]); + frm.set_value("period_end_date", r.message[1]); + } + }, + }); + } + }, + refresh: function (frm) { if (frm.doc.docstatus > 0) { frm.add_custom_button( diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json index 624b5f82f64..f41cff0e0d8 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json @@ -6,39 +6,32 @@ "engine": "InnoDB", "field_order": [ "transaction_date", - "posting_date", - "fiscal_year", - "year_start_date", - "amended_from", "company", + "fiscal_year", + "period_start_date", + "period_end_date", + "amended_from", "column_break1", "closing_account_head", - "remarks", "gle_processing_status", + "remarks", "error_message" ], "fields": [ { + "default": "Today", "fieldname": "transaction_date", "fieldtype": "Date", "label": "Transaction Date", "oldfieldname": "transaction_date", "oldfieldtype": "Date" }, - { - "fieldname": "posting_date", - "fieldtype": "Date", - "label": "Posting Date", - "oldfieldname": "posting_date", - "oldfieldtype": "Date", - "reqd": 1 - }, { "fieldname": "fiscal_year", "fieldtype": "Link", "in_list_view": 1, "in_standard_filter": 1, - "label": "Closing Fiscal Year", + "label": "Fiscal Year", "oldfieldname": "fiscal_year", "oldfieldtype": "Select", "options": "Fiscal Year", @@ -103,16 +96,25 @@ "read_only": 1 }, { - "fieldname": "year_start_date", + "fieldname": "period_end_date", "fieldtype": "Date", - "label": "Year Start Date" + "label": "Period End Date", + "reqd": 1 + }, + { + "fieldname": "period_start_date", + "fieldtype": "Date", + "label": "Period Start Date", + "oldfieldname": "posting_date", + "oldfieldtype": "Date", + "reqd": 1 } ], "icon": "fa fa-file-text", "idx": 1, "is_submittable": 1, "links": [], - "modified": "2023-09-11 20:19:11.810533", + "modified": "2024-09-15 17:22:45.291628", "modified_by": "Administrator", "module": "Accounts", "name": "Period Closing Voucher", @@ -148,7 +150,7 @@ "write": 1 } ], - "search_fields": "posting_date, fiscal_year", + "search_fields": "fiscal_year, period_start_date, period_end_date", "sort_field": "modified", "sort_order": "DESC", "states": [], diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py index dd8a5ff16c3..d6bd217650b 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -2,15 +2,20 @@ # License: GNU General Public License v3. See license.txt +import copy + import frappe from frappe import _ from frappe.query_builder.functions import Sum -from frappe.utils import add_days, flt +from frappe.utils import add_days, flt, formatdate, getdate +from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import ( + make_closing_entries, +) from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( get_accounting_dimensions, ) -from erpnext.accounts.utils import get_account_currency, get_fiscal_year, validate_fiscal_year +from erpnext.accounts.utils import get_account_currency, get_fiscal_year from erpnext.controllers.accounts_controller import AccountsController @@ -29,36 +34,386 @@ class PeriodClosingVoucher(AccountsController): error_message: DF.Text | None fiscal_year: DF.Link gle_processing_status: DF.Literal["In Progress", "Completed", "Failed"] - posting_date: DF.Date + period_end_date: DF.Date + period_start_date: DF.Date remarks: DF.SmallText transaction_date: DF.Date | None - year_start_date: DF.Date | None # end: auto-generated types def validate(self): - self.validate_account_head() - self.validate_posting_date() + self.validate_start_and_end_date() + self.check_if_previous_year_closed() + self.block_if_future_closing_voucher_exists() + self.check_closing_account_type() + self.check_closing_account_currency() + + def validate_start_and_end_date(self): + self.fy_start_date, self.fy_end_date = frappe.db.get_value( + "Fiscal Year", self.fiscal_year, ["year_start_date", "year_end_date"] + ) + + prev_closed_period_end_date = get_previous_closed_period_in_current_year( + self.fiscal_year, self.company + ) + valid_start_date = ( + add_days(prev_closed_period_end_date, 1) if prev_closed_period_end_date else self.fy_start_date + ) + + if getdate(self.period_start_date) != getdate(valid_start_date): + frappe.throw(_("Period Start Date must be {0}").format(formatdate(valid_start_date))) + + if getdate(self.period_start_date) > getdate(self.period_end_date): + frappe.throw(_("Period Start Date cannot be greater than Period End Date")) + + if getdate(self.period_end_date) > getdate(self.fy_end_date): + frappe.throw(_("Period End Date cannot be greater than Fiscal Year End Date")) + + def check_if_previous_year_closed(self): + last_year_closing = add_days(self.fy_start_date, -1) + previous_fiscal_year = get_fiscal_year(last_year_closing, company=self.company, boolean=True) + if not previous_fiscal_year: + return + + previous_fiscal_year_start_date = previous_fiscal_year[0][1] + gle_exists_in_previous_year = frappe.db.exists( + "GL Entry", + { + "posting_date": ("between", [previous_fiscal_year_start_date, last_year_closing]), + "company": self.company, + "is_cancelled": 0, + }, + ) + if not gle_exists_in_previous_year: + return + + previous_fiscal_year_closed = frappe.db.exists( + "Period Closing Voucher", + { + "period_end_date": ("between", [previous_fiscal_year_start_date, last_year_closing]), + "docstatus": 1, + "company": self.company, + }, + ) + if not previous_fiscal_year_closed: + frappe.throw(_("Previous Year is not closed, please close it first")) + + def block_if_future_closing_voucher_exists(self): + future_closing_voucher = self.get_future_closing_voucher() + if future_closing_voucher and future_closing_voucher[0][0]: + action = "cancel" if self.docstatus == 2 else "create" + frappe.throw( + _( + "You cannot {0} this document because another Period Closing Entry {1} exists after {2}" + ).format(action, future_closing_voucher[0][0], self.period_end_date) + ) + + def get_future_closing_voucher(self): + return frappe.db.get_value( + "Period Closing Voucher", + {"period_end_date": (">", self.period_end_date), "docstatus": 1, "company": self.company}, + "name", + ) + + def check_closing_account_type(self): + closing_account_type = frappe.get_cached_value("Account", self.closing_account_head, "root_type") + + if closing_account_type not in ["Liability", "Equity"]: + frappe.throw( + _("Closing Account {0} must be of type Liability / Equity").format(self.closing_account_head) + ) + + def check_closing_account_currency(self): + account_currency = get_account_currency(self.closing_account_head) + company_currency = frappe.get_cached_value("Company", self.company, "default_currency") + if account_currency != company_currency: + frappe.throw(_("Currency of the Closing Account must be {0}").format(company_currency)) def on_submit(self): self.db_set("gle_processing_status", "In Progress") - get_opening_entries = False - - if not frappe.db.exists( - "Period Closing Voucher", {"company": self.company, "docstatus": 1, "name": ("!=", self.name)} - ): - get_opening_entries = True - - self.make_gl_entries(get_opening_entries=get_opening_entries) + self.make_gl_entries() def on_cancel(self): - self.validate_future_closing_vouchers() - self.db_set("gle_processing_status", "In Progress") self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry") - gle_count = frappe.db.count( + self.block_if_future_closing_voucher_exists() + self.db_set("gle_processing_status", "In Progress") + self.cancel_gl_entries() + + def make_gl_entries(self): + if self.get_gle_count_in_selected_period() > 5000: + frappe.enqueue( + process_gl_and_closing_entries, + doc=self, + timeout=1800, + ) + frappe.msgprint( + _( + "The GL Entries and closing balances will be processed in the background, it can take a few minutes." + ), + alert=True, + ) + else: + process_gl_and_closing_entries(self) + + def get_gle_count_in_selected_period(self): + return frappe.db.count( "GL Entry", - {"voucher_type": "Period Closing Voucher", "voucher_no": self.name, "is_cancelled": 0}, + { + "posting_date": ["between", [self.period_start_date, self.period_end_date]], + "company": self.company, + "is_cancelled": 0, + }, ) - if gle_count > 5000: + + def get_pcv_gl_entries(self): + self.pl_accounts_reverse_gle = [] + self.closing_account_gle = [] + + pl_account_balances = self.get_account_balances_based_on_dimensions(report_type="Profit and Loss") + for dimensions, account_balances in pl_account_balances.items(): + for acc, balances in account_balances.items(): + balance_in_company_currency = flt(balances.debit_in_account_currency) - flt( + balances.credit_in_account_currency + ) + if balance_in_company_currency and acc != "balances": + self.pl_accounts_reverse_gle.append( + self.get_gle_for_pl_account(acc, balances, dimensions) + ) + + # closing liability account + self.closing_account_gle.append( + self.get_gle_for_closing_account(account_balances["balances"], dimensions) + ) + + return self.pl_accounts_reverse_gle + self.closing_account_gle + + def get_gle_for_pl_account(self, acc, balances, dimensions): + balance_in_account_currency = flt(balances.debit_in_account_currency) - flt( + balances.credit_in_account_currency + ) + balance_in_company_currency = flt(balances.debit) - flt(balances.credit) + gl_entry = frappe._dict( + { + "company": self.company, + "posting_date": self.period_end_date, + "account": acc, + "account_currency": balances.account_currency, + "debit_in_account_currency": abs(balance_in_account_currency) + if balance_in_account_currency < 0 + else 0, + "debit": abs(balance_in_company_currency) if balance_in_company_currency < 0 else 0, + "credit_in_account_currency": abs(balance_in_account_currency) + if balance_in_account_currency > 0 + else 0, + "credit": abs(balance_in_company_currency) if balance_in_company_currency > 0 else 0, + "is_period_closing_voucher_entry": 1, + "voucher_type": "Period Closing Voucher", + "voucher_no": self.name, + "fiscal_year": self.fiscal_year, + "remarks": self.remarks, + "is_opening": "No", + } + ) + self.update_default_dimensions(gl_entry, dimensions) + return gl_entry + + def get_gle_for_closing_account(self, dimension_balance, dimensions): + balance_in_account_currency = flt(dimension_balance.balance_in_account_currency) + balance_in_company_currency = flt(dimension_balance.balance_in_company_currency) + gl_entry = frappe._dict( + { + "company": self.company, + "posting_date": self.period_end_date, + "account": self.closing_account_head, + "account_currency": frappe.db.get_value( + "Account", self.closing_account_head, "account_currency" + ), + "debit_in_account_currency": balance_in_account_currency + if balance_in_account_currency > 0 + else 0, + "debit": balance_in_company_currency if balance_in_company_currency > 0 else 0, + "credit_in_account_currency": abs(balance_in_account_currency) + if balance_in_account_currency < 0 + else 0, + "credit": abs(balance_in_company_currency) if balance_in_company_currency < 0 else 0, + "is_period_closing_voucher_entry": 1, + "voucher_type": "Period Closing Voucher", + "voucher_no": self.name, + "fiscal_year": self.fiscal_year, + "remarks": self.remarks, + "is_opening": "No", + } + ) + self.update_default_dimensions(gl_entry, dimensions) + return gl_entry + + def update_default_dimensions(self, gl_entry, dimensions): + for i, dimension in enumerate(self.accounting_dimension_fields): + gl_entry[dimension] = dimensions[i] + + def get_account_balances_based_on_dimensions(self, report_type): + """Get balance for dimension-wise pl accounts""" + self.get_accounting_dimension_fields() + acc_bal_dict = frappe._dict() + gl_entries = [] + + with frappe.db.unbuffered_cursor(): + gl_entries = self.get_gl_entries_for_current_period(report_type, as_iterator=True) + for gle in gl_entries: + acc_bal_dict = self.set_account_balance_dict(gle, acc_bal_dict) + + if report_type == "Balance Sheet" and self.is_first_period_closing_voucher(): + opening_entries = self.get_gl_entries_for_current_period(report_type, only_opening_entries=True) + for gle in opening_entries: + acc_bal_dict = self.set_account_balance_dict(gle, acc_bal_dict) + + return acc_bal_dict + + def get_accounting_dimension_fields(self): + default_dimensions = ["cost_center", "finance_book", "project"] + self.accounting_dimension_fields = default_dimensions + get_accounting_dimensions() + + def get_gl_entries_for_current_period(self, report_type, only_opening_entries=False, as_iterator=False): + date_condition = "" + if only_opening_entries: + date_condition = "is_opening = 'Yes'" + else: + date_condition = f"posting_date BETWEEN '{self.period_start_date}' AND '{self.period_end_date}' and is_opening = 'No'" + + # nosemgrep + return frappe.db.sql( + """ + SELECT + name, + posting_date, + account, + account_currency, + debit_in_account_currency, + credit_in_account_currency, + debit, + credit, + {} + FROM `tabGL Entry` + WHERE + {} + AND company = %s + AND voucher_type != 'Period Closing Voucher' + AND EXISTS(SELECT name FROM `tabAccount` WHERE name = account AND report_type = %s) + AND is_cancelled = 0 + """.format( + ", ".join(self.accounting_dimension_fields), + date_condition, + ), + (self.company, report_type), + as_dict=1, + as_iterator=as_iterator, + ) + + def set_account_balance_dict(self, gle, acc_bal_dict): + key = self.get_key(gle) + + acc_bal_dict.setdefault(key, frappe._dict()).setdefault( + gle.account, + frappe._dict( + { + "debit_in_account_currency": 0, + "credit_in_account_currency": 0, + "debit": 0, + "credit": 0, + "account_currency": gle.account_currency, + } + ), + ) + + acc_bal_dict[key][gle.account].debit_in_account_currency += flt(gle.debit_in_account_currency) + acc_bal_dict[key][gle.account].credit_in_account_currency += flt(gle.credit_in_account_currency) + acc_bal_dict[key][gle.account].debit += flt(gle.debit) + acc_bal_dict[key][gle.account].credit += flt(gle.credit) + + # dimension-wise total balances + acc_bal_dict[key].setdefault( + "balances", + frappe._dict( + { + "balance_in_account_currency": 0, + "balance_in_company_currency": 0, + } + ), + ) + + balance_in_account_currency = flt(gle.debit_in_account_currency) - flt(gle.credit_in_account_currency) + balance_in_company_currency = flt(gle.debit) - flt(gle.credit) + + acc_bal_dict[key]["balances"].balance_in_account_currency += balance_in_account_currency + acc_bal_dict[key]["balances"].balance_in_company_currency += balance_in_company_currency + + return acc_bal_dict + + def get_key(self, gle): + return tuple([gle.get(dimension) for dimension in self.accounting_dimension_fields]) + + def get_account_closing_balances(self): + pl_closing_entries = self.get_closing_entries_for_pl_accounts() + bs_closing_entries = self.get_closing_entries_for_balance_sheet_accounts() + closing_entries = pl_closing_entries + bs_closing_entries + return closing_entries + + def get_closing_entries_for_pl_accounts(self): + closing_entries = copy.deepcopy(self.pl_accounts_reverse_gle) + for d in self.pl_accounts_reverse_gle: + # reverse debit and credit + gle_copy = copy.deepcopy(d) + gle_copy.debit = d.credit + gle_copy.credit = d.debit + gle_copy.debit_in_account_currency = d.credit_in_account_currency + gle_copy.credit_in_account_currency = d.debit_in_account_currency + gle_copy.is_period_closing_voucher_entry = 0 + gle_copy.period_closing_voucher = self.name + closing_entries.append(gle_copy) + + return closing_entries + + def get_closing_entries_for_balance_sheet_accounts(self): + closing_entries = [] + balance_sheet_account_balances = self.get_account_balances_based_on_dimensions( + report_type="Balance Sheet" + ) + + for dimensions, account_balances in balance_sheet_account_balances.items(): + for acc, balances in account_balances.items(): + balance_in_company_currency = flt(balances.debit_in_account_currency) - flt( + balances.credit_in_account_currency + ) + if acc != "balances" and balance_in_company_currency: + closing_entries.append(self.get_closing_entry(acc, balances, dimensions)) + + return closing_entries + + def get_closing_entry(self, account, balances, dimensions): + closing_entry = frappe._dict( + { + "company": self.company, + "closing_date": self.period_end_date, + "period_closing_voucher": self.name, + "account": account, + "account_currency": balances.account_currency, + "debit_in_account_currency": flt(balances.debit_in_account_currency), + "debit": flt(balances.debit), + "credit_in_account_currency": flt(balances.credit_in_account_currency), + "credit": flt(balances.credit), + "is_period_closing_voucher_entry": 0, + } + ) + self.update_default_dimensions(closing_entry, dimensions) + return closing_entry + + def is_first_period_closing_voucher(self): + return not frappe.db.exists( + "Period Closing Voucher", + {"company": self.company, "docstatus": 1, "name": ("!=", self.name)}, + ) + + def cancel_gl_entries(self): + if self.get_gle_count_against_current_pcv() > 5000: frappe.enqueue( process_cancellation, voucher_type="Period Closing Voucher", @@ -73,308 +428,30 @@ class PeriodClosingVoucher(AccountsController): else: process_cancellation(voucher_type="Period Closing Voucher", voucher_no=self.name) - def validate_future_closing_vouchers(self): - if frappe.db.exists( - "Period Closing Voucher", - {"posting_date": (">", self.posting_date), "docstatus": 1, "company": self.company}, - ): - frappe.throw( - _( - "You can not cancel this Period Closing Voucher, please cancel the future Period Closing Vouchers first" - ) - ) - - def validate_account_head(self): - closing_account_type = frappe.get_cached_value("Account", self.closing_account_head, "root_type") - - if closing_account_type not in ["Liability", "Equity"]: - frappe.throw( - _("Closing Account {0} must be of type Liability / Equity").format(self.closing_account_head) - ) - - account_currency = get_account_currency(self.closing_account_head) - company_currency = frappe.get_cached_value("Company", self.company, "default_currency") - if account_currency != company_currency: - frappe.throw(_("Currency of the Closing Account must be {0}").format(company_currency)) - - def validate_posting_date(self): - validate_fiscal_year( - self.posting_date, self.fiscal_year, self.company, label=_("Posting Date"), doc=self - ) - - self.year_start_date = get_fiscal_year(self.posting_date, self.fiscal_year, company=self.company)[1] - - self.check_if_previous_year_closed() - - pcv = frappe.qb.DocType("Period Closing Voucher") - existing_entry = ( - frappe.qb.from_(pcv) - .select(pcv.name) - .where( - (pcv.posting_date >= self.posting_date) - & (pcv.fiscal_year == self.fiscal_year) - & (pcv.docstatus == 1) - & (pcv.company == self.company) - ) - .run() - ) - - if existing_entry and existing_entry[0][0]: - frappe.throw( - _("Another Period Closing Entry {0} has been made after {1}").format( - existing_entry[0][0], self.posting_date - ) - ) - - def check_if_previous_year_closed(self): - last_year_closing = add_days(self.year_start_date, -1) - previous_fiscal_year = get_fiscal_year(last_year_closing, company=self.company, boolean=True) - if not previous_fiscal_year: - return - - previous_fiscal_year_start_date = previous_fiscal_year[0][1] - if not frappe.db.exists( + def get_gle_count_against_current_pcv(self): + return frappe.db.count( "GL Entry", - { - "posting_date": ("between", [previous_fiscal_year_start_date, last_year_closing]), - "company": self.company, - "is_cancelled": 0, - }, - ): - return - - if not frappe.db.exists( - "Period Closing Voucher", - { - "posting_date": ("between", [previous_fiscal_year_start_date, last_year_closing]), - "docstatus": 1, - "company": self.company, - }, - ): - frappe.throw(_("Previous Year is not closed, please close it first")) - - def make_gl_entries(self, get_opening_entries=False): - gl_entries = self.get_gl_entries() - closing_entries = self.get_grouped_gl_entries(get_opening_entries=get_opening_entries) - if len(gl_entries + closing_entries) > 3000: - frappe.enqueue( - process_gl_and_closing_entries, - gl_entries=gl_entries, - closing_entries=closing_entries, - voucher_name=self.name, - company=self.company, - closing_date=self.posting_date, - timeout=3000, - ) - - frappe.msgprint( - _("The GL Entries will be processed in the background, it can take a few minutes."), - alert=True, - ) - else: - process_gl_and_closing_entries( - gl_entries, closing_entries, self.name, self.company, self.posting_date - ) - - def get_grouped_gl_entries(self, get_opening_entries=False): - closing_entries = [] - for acc in self.get_balances_based_on_dimensions( - group_by_account=True, for_aggregation=True, get_opening_entries=get_opening_entries - ): - closing_entries.append(self.get_closing_entries(acc)) - - return closing_entries - - def get_gl_entries(self): - gl_entries = [] - - # pl account - for acc in self.get_balances_based_on_dimensions( - group_by_account=True, report_type="Profit and Loss" - ): - if flt(acc.bal_in_company_currency): - gl_entries.append(self.get_gle_for_pl_account(acc)) - - # closing liability account - for acc in self.get_balances_based_on_dimensions( - group_by_account=False, report_type="Profit and Loss" - ): - if flt(acc.bal_in_company_currency): - gl_entries.append(self.get_gle_for_closing_account(acc)) - - return gl_entries - - def get_gle_for_pl_account(self, acc): - gl_entry = self.get_gl_dict( - { - "company": self.company, - "closing_date": self.posting_date, - "account": acc.account, - "cost_center": acc.cost_center, - "finance_book": acc.finance_book, - "account_currency": acc.account_currency, - "debit_in_account_currency": abs(flt(acc.bal_in_account_currency)) - if flt(acc.bal_in_account_currency) < 0 - else 0, - "debit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) < 0 else 0, - "credit_in_account_currency": abs(flt(acc.bal_in_account_currency)) - if flt(acc.bal_in_account_currency) > 0 - else 0, - "credit": abs(flt(acc.bal_in_company_currency)) - if flt(acc.bal_in_company_currency) > 0 - else 0, - "is_period_closing_voucher_entry": 1, - }, - item=acc, - ) - self.update_default_dimensions(gl_entry, acc) - return gl_entry - - def get_gle_for_closing_account(self, acc): - gl_entry = self.get_gl_dict( - { - "company": self.company, - "closing_date": self.posting_date, - "account": self.closing_account_head, - "cost_center": acc.cost_center, - "finance_book": acc.finance_book, - "account_currency": acc.account_currency, - "debit_in_account_currency": abs(flt(acc.bal_in_account_currency)) - if flt(acc.bal_in_account_currency) > 0 - else 0, - "debit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) > 0 else 0, - "credit_in_account_currency": abs(flt(acc.bal_in_account_currency)) - if flt(acc.bal_in_account_currency) < 0 - else 0, - "credit": abs(flt(acc.bal_in_company_currency)) - if flt(acc.bal_in_company_currency) < 0 - else 0, - "is_period_closing_voucher_entry": 1, - }, - item=acc, - ) - self.update_default_dimensions(gl_entry, acc) - return gl_entry - - def get_closing_entries(self, acc): - closing_entry = self.get_gl_dict( - { - "company": self.company, - "closing_date": self.posting_date, - "period_closing_voucher": self.name, - "account": acc.account, - "cost_center": acc.cost_center, - "finance_book": acc.finance_book, - "account_currency": acc.account_currency, - "debit_in_account_currency": flt(acc.debit_in_account_currency), - "debit": flt(acc.debit), - "credit_in_account_currency": flt(acc.credit_in_account_currency), - "credit": flt(acc.credit), - }, - item=acc, + {"voucher_type": "Period Closing Voucher", "voucher_no": self.name, "is_cancelled": 0}, ) - for dimension in self.accounting_dimensions: - closing_entry.update({dimension: acc.get(dimension)}) - return closing_entry - - def update_default_dimensions(self, gl_entry, acc): - if not self.accounting_dimensions: - self.accounting_dimensions = get_accounting_dimensions() - - for dimension in self.accounting_dimensions: - gl_entry.update({dimension: acc.get(dimension)}) - - def get_balances_based_on_dimensions( - self, group_by_account=False, report_type=None, for_aggregation=False, get_opening_entries=False - ): - """Get balance for dimension-wise pl accounts""" - - qb_dimension_fields = ["cost_center", "finance_book", "project"] - - self.accounting_dimensions = get_accounting_dimensions() - for dimension in self.accounting_dimensions: - qb_dimension_fields.append(dimension) - - if group_by_account: - qb_dimension_fields.append("account") - - account_filters = { - "company": self.company, - "is_group": 0, - } - - if report_type: - account_filters.update({"report_type": report_type}) - - accounts = frappe.get_all("Account", filters=account_filters, pluck="name") - - gl_entry = frappe.qb.DocType("GL Entry") - query = frappe.qb.from_(gl_entry).select(gl_entry.account, gl_entry.account_currency) - - if not for_aggregation: - query = query.select( - (Sum(gl_entry.debit_in_account_currency) - Sum(gl_entry.credit_in_account_currency)).as_( - "bal_in_account_currency" - ), - (Sum(gl_entry.debit) - Sum(gl_entry.credit)).as_("bal_in_company_currency"), - ) - else: - query = query.select( - (Sum(gl_entry.debit_in_account_currency)).as_("debit_in_account_currency"), - (Sum(gl_entry.credit_in_account_currency)).as_("credit_in_account_currency"), - (Sum(gl_entry.debit)).as_("debit"), - (Sum(gl_entry.credit)).as_("credit"), - ) - - for dimension in qb_dimension_fields: - query = query.select(gl_entry[dimension]) - - query = query.where( - (gl_entry.company == self.company) - & (gl_entry.is_cancelled == 0) - & (gl_entry.account.isin(accounts)) - ) - - if get_opening_entries: - query = query.where( - ( # noqa: UP034 - (gl_entry.posting_date.between(self.get("year_start_date"), self.posting_date)) - | (gl_entry.is_opening == "Yes") - ) - ) - else: - query = query.where( - gl_entry.posting_date.between(self.get("year_start_date"), self.posting_date) - & gl_entry.is_opening - == "No" - ) - - if for_aggregation: - query = query.where(gl_entry.voucher_type != "Period Closing Voucher") - - for dimension in qb_dimension_fields: - query = query.groupby(gl_entry[dimension]) - - return query.run(as_dict=1) - - -def process_gl_and_closing_entries(gl_entries, closing_entries, voucher_name, company, closing_date): - from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import ( - make_closing_entries, - ) +def process_gl_and_closing_entries(doc): from erpnext.accounts.general_ledger import make_gl_entries try: + gl_entries = doc.get_pcv_gl_entries() if gl_entries: make_gl_entries(gl_entries, merge_entries=False) - make_closing_entries(gl_entries + closing_entries, voucher_name, company, closing_date) - frappe.db.set_value("Period Closing Voucher", voucher_name, "gle_processing_status", "Completed") + + closing_entries = doc.get_account_closing_balances() + if closing_entries: + make_closing_entries(closing_entries, doc.name, doc.company, doc.period_end_date) + + frappe.db.set_value(doc.doctype, doc.name, "gle_processing_status", "Completed") except Exception as e: frappe.db.rollback() frappe.log_error(e) - frappe.db.set_value("Period Closing Voucher", voucher_name, "gle_processing_status", "Failed") + frappe.db.set_value(doc.doctype, doc.name, "gle_processing_status", "Failed") def process_cancellation(voucher_type, voucher_no): @@ -395,3 +472,29 @@ def delete_closing_entries(voucher_no): frappe.qb.from_(closing_balance).delete().where( closing_balance.period_closing_voucher == voucher_no ).run() + + +@frappe.whitelist() +def get_period_start_end_date(fiscal_year, company): + fy_start_date, fy_end_date = frappe.db.get_value( + "Fiscal Year", fiscal_year, ["year_start_date", "year_end_date"] + ) + prev_closed_period_end_date = get_previous_closed_period_in_current_year(fiscal_year, company) + period_start_date = ( + add_days(prev_closed_period_end_date, 1) if prev_closed_period_end_date else fy_start_date + ) + return period_start_date, fy_end_date + + +def get_previous_closed_period_in_current_year(fiscal_year, company): + prev_closed_period_end_date = frappe.db.get_value( + "Period Closing Voucher", + filters={ + "company": company, + "fiscal_year": fiscal_year, + "docstatus": 1, + }, + fieldname=["period_end_date"], + order_by="period_end_date desc", + ) + return prev_closed_period_end_date diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py index 1bd565e1b36..e9d65f7f856 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py @@ -317,16 +317,18 @@ class TestPeriodClosingVoucher(unittest.TestCase): repost_doc.posting_date = today() repost_doc.save() - def make_period_closing_voucher(self, posting_date=None, submit=True): + def make_period_closing_voucher(self, posting_date, submit=True): surplus_account = create_account() cost_center = create_cost_center("Test Cost Center 1") + fy = get_fiscal_year(posting_date, company="Test PCV Company") pcv = frappe.get_doc( { "doctype": "Period Closing Voucher", "transaction_date": posting_date or today(), - "posting_date": posting_date or today(), + "period_start_date": fy[1], + "period_end_date": fy[2], "company": "Test PCV Company", - "fiscal_year": get_fiscal_year(today(), company="Test PCV Company")[0], + "fiscal_year": fy[0], "cost_center": cost_center, "closing_account_head": surplus_account, "remarks": "test", diff --git a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py index 8c8ba633df0..f37e542dd89 100644 --- a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py +++ b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py @@ -46,8 +46,8 @@ class RepostAccountingLedger(Document): frappe.db.get_all( "Period Closing Voucher", filters={"company": self.company}, - order_by="posting_date desc", - pluck="posting_date", + order_by="period_end_date desc", + pluck="period_end_date", limit=1, ) or None diff --git a/erpnext/accounts/doctype/repost_accounting_ledger/test_repost_accounting_ledger.py b/erpnext/accounts/doctype/repost_accounting_ledger/test_repost_accounting_ledger.py index f631ef437d6..9f906bb7647 100644 --- a/erpnext/accounts/doctype/repost_accounting_ledger/test_repost_accounting_ledger.py +++ b/erpnext/accounts/doctype/repost_accounting_ledger/test_repost_accounting_ledger.py @@ -129,13 +129,15 @@ class TestRepostAccountingLedger(AccountsTestMixin, FrappeTestCase): cost_center=self.cost_center, rate=100, ) + fy = get_fiscal_year(today(), company=self.company) pcv = frappe.get_doc( { "doctype": "Period Closing Voucher", "transaction_date": today(), - "posting_date": today(), + "period_start_date": fy[1], + "period_end_date": today(), "company": self.company, - "fiscal_year": get_fiscal_year(today(), company=self.company)[0], + "fiscal_year": fy[0], "cost_center": self.cost_center, "closing_account_head": self.retained_earnings, "remarks": "test", diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index ad8cc97e101..856e2b96af0 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -37,13 +37,14 @@ def make_gl_entries( validate_disabled_accounts(gl_map) gl_map = process_gl_map(gl_map, merge_entries) if gl_map and len(gl_map) > 1: - create_payment_ledger_entry( - gl_map, - cancel=0, - adv_adj=adv_adj, - update_outstanding=update_outstanding, - from_repost=from_repost, - ) + if gl_map[0].voucher_type != "Period Closing Voucher": + create_payment_ledger_entry( + gl_map, + cancel=0, + adv_adj=adv_adj, + update_outstanding=update_outstanding, + from_repost=from_repost, + ) save_entries(gl_map, adv_adj, update_outstanding, from_repost) # Post GL Map proccess there may no be any GL Entries elif gl_map: @@ -116,17 +117,16 @@ def get_accounting_dimensions_for_offsetting_entry(gl_map, company): def validate_disabled_accounts(gl_map): accounts = [d.account for d in gl_map if d.account] - Account = frappe.qb.DocType("Account") + disabled_accounts = frappe.get_all( + "Account", + filters={"disabled": 1, "is_group": 0, "company": gl_map[0].company}, + fields=["name"], + ) - disabled_accounts = ( - frappe.qb.from_(Account) - .where(Account.name.isin(accounts) & Account.disabled == 1) - .select(Account.name, Account.disabled) - ).run(as_dict=True) - - if disabled_accounts: + used_disabled_accounts = set(accounts).intersection(set([d.name for d in disabled_accounts])) + if used_disabled_accounts: account_list = "
" - account_list += ", ".join([frappe.bold(d.name) for d in disabled_accounts]) + account_list += ", ".join([frappe.bold(d) for d in used_disabled_accounts]) frappe.throw( _("Cannot create accounting entries against disabled accounts: {0}").format(account_list), title=_("Disabled Account Selected"), @@ -708,7 +708,7 @@ def validate_against_pcv(is_opening, posting_date, company): ) last_pcv_date = frappe.db.get_value( - "Period Closing Voucher", {"docstatus": 1, "company": company}, "max(posting_date)" + "Period Closing Voucher", {"docstatus": 1, "company": company}, "max(period_end_date)" ) if last_pcv_date and getdate(posting_date) <= getdate(last_pcv_date): diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 43100c81285..8d4a8579ae3 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -385,6 +385,7 @@ class ReceivablePayableReport: self.delivery_notes = frappe._dict() # delivery note link inside sales invoice + # nosemgrep si_against_dn = frappe.db.sql( """ select parent, delivery_note @@ -400,6 +401,7 @@ class ReceivablePayableReport: if d.delivery_note: self.delivery_notes.setdefault(d.parent, set()).add(d.delivery_note) + # nosemgrep dn_against_si = frappe.db.sql( """ select distinct parent, against_sales_invoice @@ -417,13 +419,16 @@ class ReceivablePayableReport: def get_invoice_details(self): self.invoice_details = frappe._dict() if self.account_type == "Receivable": + # nosemgrep si_list = frappe.db.sql( """ select name, due_date, po_no from `tabSales Invoice` where posting_date <= %s + and company = %s + and docstatus = 1 """, - self.filters.report_date, + (self.filters.report_date, self.filters.company), as_dict=1, ) for d in si_list: @@ -431,6 +436,7 @@ class ReceivablePayableReport: # Get Sales Team if self.filters.show_sales_person: + # nosemgrep sales_team = frappe.db.sql( """ select parent, sales_person @@ -445,25 +451,33 @@ class ReceivablePayableReport: ) if self.account_type == "Payable": + # nosemgrep for pi in frappe.db.sql( """ select name, due_date, bill_no, bill_date from `tabPurchase Invoice` - where posting_date <= %s + where + posting_date <= %s + and company = %s + and docstatus = 1 """, - self.filters.report_date, + (self.filters.report_date, self.filters.company), as_dict=1, ): self.invoice_details.setdefault(pi.name, pi) # Invoices booked via Journal Entries + # nosemgrep journal_entries = frappe.db.sql( """ select name, due_date, bill_no, bill_date from `tabJournal Entry` - where posting_date <= %s + where + posting_date <= %s + and company = %s + and docstatus = 1 """, - self.filters.report_date, + (self.filters.report_date, self.filters.company), as_dict=1, ) @@ -472,6 +486,8 @@ class ReceivablePayableReport: self.invoice_details.setdefault(je.name, je) def set_party_details(self, row): + if not row.party: + return # customer / supplier name party_details = self.get_party_details(row.party) or {} row.update(party_details) @@ -496,6 +512,7 @@ class ReceivablePayableReport: def get_payment_terms(self, row): # build payment_terms for row + # nosemgrep payment_terms_details = frappe.db.sql( f""" select @@ -708,6 +725,7 @@ class ReceivablePayableReport: def get_return_entries(self): doctype = "Sales Invoice" if self.account_type == "Receivable" else "Purchase Invoice" filters = { + "posting_date": ("<=", self.filters.report_date), "is_return": 1, "docstatus": 1, "company": self.filters.company, @@ -815,6 +833,7 @@ class ReceivablePayableReport: if self.filters.get("sales_person"): lft, rgt = frappe.db.get_value("Sales Person", self.filters.get("sales_person"), ["lft", "rgt"]) + # nosemgrep records = frappe.db.sql( """ select distinct parent, parenttype diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 6d7635979bb..c233f3c7e2b 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -9,6 +9,7 @@ import re import frappe from frappe import _ from frappe.utils import add_days, add_months, cint, cstr, flt, formatdate, get_first_day, getdate +from pypika.terms import ExistsCriterion from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( get_accounting_dimensions, @@ -181,12 +182,12 @@ def get_data( company, period_list[0]["year_start_date"] if only_current_fiscal_year else None, period_list[-1]["to_date"], - root.lft, - root.rgt, filters, gl_entries_by_account, - ignore_closing_entries=ignore_closing_entries, + root.lft, + root.rgt, root_type=root_type, + ignore_closing_entries=ignore_closing_entries, ) calculate_values( @@ -419,93 +420,78 @@ def set_gl_entries_by_account( company, from_date, to_date, - root_lft, - root_rgt, filters, gl_entries_by_account, + root_lft=None, + root_rgt=None, + root_type=None, ignore_closing_entries=False, ignore_opening_entries=False, - root_type=None, ): """Returns a dict like { "account": [gl entries], ... }""" gl_entries = [] - account_filters = { - "company": company, - "is_group": 0, - "lft": (">=", root_lft), - "rgt": ("<=", root_rgt), - } - - if root_type: - account_filters.update( - { - "root_type": root_type, - } + # For balance sheet + ignore_closing_balances = frappe.db.get_single_value( + "Accounts Settings", "ignore_account_closing_balance" + ) + if not from_date and not ignore_closing_balances: + last_period_closing_voucher = frappe.db.get_all( + "Period Closing Voucher", + filters={ + "docstatus": 1, + "company": filters.company, + "period_end_date": ("<", filters["period_start_date"]), + }, + fields=["period_end_date", "name"], + order_by="period_end_date desc", + limit=1, ) + if last_period_closing_voucher: + gl_entries += get_accounting_entries( + "Account Closing Balance", + from_date, + to_date, + filters, + root_lft, + root_rgt, + root_type, + ignore_closing_entries, + last_period_closing_voucher[0].name, + ) + from_date = add_days(last_period_closing_voucher[0].period_end_date, 1) + ignore_opening_entries = True - accounts_list = frappe.db.get_all( - "Account", - filters=account_filters, - pluck="name", + gl_entries += get_accounting_entries( + "GL Entry", + from_date, + to_date, + filters, + root_lft, + root_rgt, + root_type, + ignore_closing_entries, + ignore_opening_entries=ignore_opening_entries, ) - if accounts_list: - # For balance sheet - ignore_closing_balances = frappe.db.get_single_value( - "Accounts Settings", "ignore_account_closing_balance" - ) - if not from_date and not ignore_closing_balances: - last_period_closing_voucher = frappe.db.get_all( - "Period Closing Voucher", - filters={ - "docstatus": 1, - "company": filters.company, - "posting_date": ("<", filters["period_start_date"]), - }, - fields=["posting_date", "name"], - order_by="posting_date desc", - limit=1, - ) - if last_period_closing_voucher: - gl_entries += get_accounting_entries( - "Account Closing Balance", - from_date, - to_date, - accounts_list, - filters, - ignore_closing_entries, - last_period_closing_voucher[0].name, - ) - from_date = add_days(last_period_closing_voucher[0].posting_date, 1) - ignore_opening_entries = True + if filters and filters.get("presentation_currency"): + convert_to_presentation_currency(gl_entries, get_currency(filters)) - gl_entries += get_accounting_entries( - "GL Entry", - from_date, - to_date, - accounts_list, - filters, - ignore_closing_entries, - ignore_opening_entries=ignore_opening_entries, - ) + for entry in gl_entries: + gl_entries_by_account.setdefault(entry.account, []).append(entry) - if filters and filters.get("presentation_currency"): - convert_to_presentation_currency(gl_entries, get_currency(filters)) - - for entry in gl_entries: - gl_entries_by_account.setdefault(entry.account, []).append(entry) - - return gl_entries_by_account + return gl_entries_by_account def get_accounting_entries( doctype, from_date, to_date, - accounts, filters, - ignore_closing_entries, + root_lft=None, + root_rgt=None, + root_type=None, + ignore_closing_entries=None, period_closing_voucher=None, ignore_opening_entries=False, ): @@ -535,13 +521,30 @@ def get_accounting_entries( query = query.where(gl_entry.period_closing_voucher == period_closing_voucher) query = apply_additional_conditions(doctype, query, from_date, ignore_closing_entries, filters) - query = query.where(gl_entry.account.isin(accounts)) + + if (root_lft and root_rgt) or root_type: + account_filter_query = get_account_filter_query(root_lft, root_rgt, root_type, gl_entry) + query = query.where(ExistsCriterion(account_filter_query)) entries = query.run(as_dict=True) return entries +def get_account_filter_query(root_lft, root_rgt, root_type, gl_entry): + acc = frappe.qb.DocType("Account") + exists_query = ( + frappe.qb.from_(acc).select(acc.name).where(acc.name == gl_entry.account).where(acc.is_group == 0) + ) + if root_lft and root_rgt: + exists_query = exists_query.where(acc.lft >= root_lft).where(acc.rgt <= root_rgt) + + if root_type: + exists_query = exists_query.where(acc.root_type == root_type) + + return exists_query + + def apply_additional_conditions(doctype, query, from_date, ignore_closing_entries, filters): gl_entry = frappe.qb.DocType(doctype) accounting_dimensions = get_accounting_dimensions(as_list=False) diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py index f216ecea15a..8ca850f301e 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.py +++ b/erpnext/accounts/report/trial_balance/trial_balance.py @@ -94,12 +94,6 @@ def get_data(filters): accounts, accounts_by_name, parent_children_map = filter_accounts(accounts) - min_lft, max_rgt = frappe.db.sql( - """select min(lft), max(rgt) from `tabAccount` - where company=%s""", - (filters.company,), - )[0] - gl_entries_by_account = {} opening_balances = get_opening_balances(filters) @@ -112,10 +106,10 @@ def get_data(filters): filters.company, filters.from_date, filters.to_date, - min_lft, - max_rgt, filters, gl_entries_by_account, + root_lft=None, + root_rgt=None, ignore_closing_entries=not flt(filters.with_period_closing_entry_for_current_period), ignore_opening_entries=True, ) @@ -150,9 +144,9 @@ def get_rootwise_opening_balances(filters, report_type): if not ignore_closing_balances: last_period_closing_voucher = frappe.db.get_all( "Period Closing Voucher", - filters={"docstatus": 1, "company": filters.company, "posting_date": ("<", filters.from_date)}, - fields=["posting_date", "name"], - order_by="posting_date desc", + filters={"docstatus": 1, "company": filters.company, "period_end_date": ("<", filters.from_date)}, + fields=["period_end_date", "name"], + order_by="period_end_date desc", limit=1, ) @@ -168,8 +162,8 @@ def get_rootwise_opening_balances(filters, report_type): ) # Report getting generate from the mid of a fiscal year - if getdate(last_period_closing_voucher[0].posting_date) < getdate(add_days(filters.from_date, -1)): - start_date = add_days(last_period_closing_voucher[0].posting_date, 1) + if getdate(last_period_closing_voucher[0].period_end_date) < getdate(add_days(filters.from_date, -1)): + start_date = add_days(last_period_closing_voucher[0].period_end_date, 1) gle += get_opening_balance( "GL Entry", filters, report_type, accounting_dimensions, start_date=start_date ) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index e59938909c7..515a299504a 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -314,6 +314,7 @@ erpnext.patches.v13_0.update_docs_link erpnext.patches.v15_0.update_asset_value_for_manual_depr_entries erpnext.patches.v15_0.update_gpa_and_ndb_for_assdeprsch erpnext.patches.v14_0.create_accounting_dimensions_for_closing_balance +erpnext.patches.v14_0.set_period_start_end_date_in_pcv erpnext.patches.v14_0.update_closing_balances #14-07-2023 execute:frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0) erpnext.patches.v14_0.update_reference_type_in_journal_entry_accounts diff --git a/erpnext/patches/v13_0/fix_additional_cost_in_mfg_stock_entry.py b/erpnext/patches/v13_0/fix_additional_cost_in_mfg_stock_entry.py index e305b375c7f..5609b6bb895 100644 --- a/erpnext/patches/v13_0/fix_additional_cost_in_mfg_stock_entry.py +++ b/erpnext/patches/v13_0/fix_additional_cost_in_mfg_stock_entry.py @@ -15,7 +15,7 @@ def execute(): def find_broken_stock_entries() -> list[StockEntryCode]: period_closing_date = frappe.db.get_value( - "Period Closing Voucher", {"docstatus": 1}, "posting_date", order_by="posting_date desc" + "Period Closing Voucher", {"docstatus": 1}, "period_end_date", order_by="period_end_date desc" ) stock_entries_to_patch = frappe.db.sql( diff --git a/erpnext/patches/v14_0/set_period_start_end_date_in_pcv.py b/erpnext/patches/v14_0/set_period_start_end_date_in_pcv.py new file mode 100644 index 00000000000..8020a286f69 --- /dev/null +++ b/erpnext/patches/v14_0/set_period_start_end_date_in_pcv.py @@ -0,0 +1,17 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors +# License: MIT. See LICENSE + + +import frappe + + +def execute(): + # nosemgrep + frappe.db.sql( + """ + UPDATE `tabPeriod Closing Voucher` + SET + period_start_date = (select year_start_date from `tabFiscal Year` where name = fiscal_year), + period_end_date = posting_date + """ + ) diff --git a/erpnext/patches/v14_0/single_to_multi_dunning.py b/erpnext/patches/v14_0/single_to_multi_dunning.py index 3b01871d437..98be0204518 100644 --- a/erpnext/patches/v14_0/single_to_multi_dunning.py +++ b/erpnext/patches/v14_0/single_to_multi_dunning.py @@ -66,7 +66,7 @@ def get_accounts_closing_date(): ) # always returns datetime.date period_closing_date = frappe.db.get_value( - "Period Closing Voucher", {"docstatus": 1}, "posting_date", order_by="posting_date desc" + "Period Closing Voucher", {"docstatus": 1}, "period_end_date", order_by="period_end_date desc" ) # Set most recent frozen/closing date as filter diff --git a/erpnext/patches/v14_0/update_closing_balances.py b/erpnext/patches/v14_0/update_closing_balances.py index cfc29c87fa1..a2670717ee9 100644 --- a/erpnext/patches/v14_0/update_closing_balances.py +++ b/erpnext/patches/v14_0/update_closing_balances.py @@ -7,67 +7,68 @@ import frappe from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import ( make_closing_entries, ) +from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( + get_accounting_dimensions, +) from erpnext.accounts.utils import get_fiscal_year def execute(): frappe.db.truncate("Account Closing Balance") + gle_fields = get_gle_fields() + for company in frappe.get_all("Company", pluck="name"): i = 0 company_wise_order = {} - for pcv in frappe.db.get_all( - "Period Closing Voucher", - fields=["company", "posting_date", "name"], - filters={"docstatus": 1, "company": company}, - order_by="posting_date", - ): + for pcv in get_period_closing_vouchers(company): company_wise_order.setdefault(pcv.company, []) - if pcv.posting_date not in company_wise_order[pcv.company]: - pcv_doc = frappe.get_doc("Period Closing Voucher", pcv.name) - pcv_doc.year_start_date = get_fiscal_year( - pcv.posting_date, pcv.fiscal_year, company=pcv.company - )[1] + if pcv.period_end_date not in company_wise_order[pcv.company]: + pcv.pl_accounts_reverse_gle = get_pcv_gl_entries(pcv, gle_fields) + closing_entries = pcv.get_account_closing_balances() + if closing_entries: + make_closing_entries(closing_entries, pcv.name, pcv.company, pcv.period_end_date) - # get gl entries against pcv - gl_entries = frappe.db.get_all( - "GL Entry", filters={"voucher_no": pcv.name, "is_cancelled": 0}, fields=["*"] - ) - for entry in gl_entries: - entry["is_period_closing_voucher_entry"] = 1 - entry["closing_date"] = pcv_doc.posting_date - entry["period_closing_voucher"] = pcv_doc.name - - closing_entries = [] - - if pcv.posting_date not in company_wise_order[pcv.company]: - # get all gl entries for the year - closing_entries = frappe.db.get_all( - "GL Entry", - filters={ - "is_cancelled": 0, - "voucher_no": ["!=", pcv.name], - "posting_date": ["between", [pcv_doc.year_start_date, pcv.posting_date]], - "is_opening": "No", - "company": company, - }, - fields=["*"], - ) - - if i == 0: - # add opening entries only for the first pcv - closing_entries += frappe.db.get_all( - "GL Entry", - filters={"is_cancelled": 0, "is_opening": "Yes", "company": company}, - fields=["*"], - ) - - for entry in closing_entries: - entry["closing_date"] = pcv_doc.posting_date - entry["period_closing_voucher"] = pcv_doc.name - - entries = gl_entries + closing_entries - - make_closing_entries(entries, pcv.name, pcv.company, pcv.posting_date) - company_wise_order[pcv.company].append(pcv.posting_date) + company_wise_order[pcv.company].append(pcv.period_end_date) i += 1 + + +def get_gle_fields(): + default_diemnsion_fields = ["cost_center", "finance_book", "project"] + accounting_dimension_fields = get_accounting_dimensions() + gle_fields = [ + "name", + "posting_date", + "account", + "account_currency", + "debit", + "credit", + "debit_in_account_currency", + "credit_in_account_currency", + *default_diemnsion_fields, + *accounting_dimension_fields, + ] + + return gle_fields + + +def get_period_closing_vouchers(company): + return frappe.db.get_all( + "Period Closing Voucher", + fields=["name", "closing_account_head", "period_start_date", "period_end_date", "company"], + filters={"docstatus": 1, "company": company}, + order_by="period_end_date", + ) + + +def get_pcv_gl_entries(pcv, gle_fields): + gl_entries = frappe.db.get_all( + "GL Entry", + filters={"voucher_no": pcv.name, "account": ["!=", pcv.closing_account_head], "is_cancelled": 0}, + fields=gle_fields, + ) + for entry in gl_entries: + entry["is_period_closing_voucher_entry"] = 1 + entry["closing_date"] = pcv.period_end_date + entry["period_closing_voucher"] = pcv.name + return gl_entries diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index d203b979c61..cb006bb3e99 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -1188,18 +1188,19 @@ def make_shipment(source_name, target_doc=None): # As we are using session user details in the pickup_contact then pickup_contact_person will be session user target.pickup_contact_person = frappe.session.user - contact = frappe.db.get_value( - "Contact", source.contact_person, ["email_id", "phone", "mobile_no"], as_dict=1 - ) - delivery_contact_display = f"{source.contact_display}" - if contact: - if contact.email_id: - delivery_contact_display += "
" + contact.email_id - if contact.phone: - delivery_contact_display += "
" + contact.phone - if contact.mobile_no and not contact.phone: - delivery_contact_display += "
" + contact.mobile_no - target.delivery_contact = delivery_contact_display + if source.contact_person: + contact = frappe.db.get_value( + "Contact", source.contact_person, ["email_id", "phone", "mobile_no"], as_dict=1 + ) + delivery_contact_display = f"{source.contact_display}" + if contact: + if contact.email_id: + delivery_contact_display += "
" + contact.email_id + if contact.phone: + delivery_contact_display += "
" + contact.phone + if contact.mobile_no and not contact.phone: + delivery_contact_display += "
" + contact.mobile_no + target.delivery_contact = delivery_contact_display if source.shipping_address_name: target.delivery_address_name = source.shipping_address_name diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index c20eadeb78d..0c81a296d5e 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -125,7 +125,7 @@ class RepostItemValuation(Document): query = ( frappe.qb.from_(table) - .select(Max(table.posting_date)) + .select(Max(table.period_end_date)) .where((table.company == company) & (table.docstatus == 1)) ).run() diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index ae6ca4e25d0..5993580032f 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -1309,10 +1309,10 @@ class StockEntry(StockController): 3. Check FG Item and Qty against WO if present (mfg) """ production_item, wo_qty, finished_items = None, 0, [] - - wo_details = frappe.db.get_value("Work Order", self.work_order, ["production_item", "qty"]) - if wo_details: - production_item, wo_qty = wo_details + if self.work_order: + wo_details = frappe.db.get_value("Work Order", self.work_order, ["production_item", "qty"]) + if wo_details: + production_item, wo_qty = wo_details for d in self.get("items"): if d.is_finished_item: diff --git a/erpnext/stock/report/test_reports.py b/erpnext/stock/report/test_reports.py index 85337a3bf54..ad2b46b393f 100644 --- a/erpnext/stock/report/test_reports.py +++ b/erpnext/stock/report/test_reports.py @@ -1,6 +1,7 @@ import unittest import frappe +from frappe.utils.make_random import get_random from erpnext.tests.utils import ReportFilters, ReportName, execute_script_report @@ -11,7 +12,7 @@ DEFAULT_FILTERS = { } -batch = frappe.db.get_value("Batch", fieldname=["name"], as_dict=True, order_by="creation desc") +batch = get_random("Batch") REPORT_FILTER_TEST_CASES: list[tuple[ReportName, ReportFilters]] = [ ("Stock Ledger", {"_optional": True}), diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index db912514988..50ce270c166 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -687,86 +687,103 @@ def make_purchase_receipt(source_name, target_doc=None, save=False, submit=False else: source_doc = source_name - if not source_doc.is_return: - if not target_doc: - target_doc = frappe.new_doc("Purchase Receipt") - target_doc.is_subcontracted = 1 - target_doc.is_old_subcontracting_flow = 0 + if source_doc.is_return: + return - target_doc = get_mapped_doc( - "Subcontracting Receipt", - source_doc.name, - { - "Subcontracting Receipt": { - "doctype": "Purchase Receipt", - "field_map": { - "posting_date": "posting_date", - "posting_time": "posting_time", - "name": "subcontracting_receipt", - "supplier_warehouse": "supplier_warehouse", - }, - "field_no_map": ["total_qty", "total"], - }, - }, - target_doc, - ignore_child_tables=True, + po_sr_item_dict = {} + po_name = None + for item in source_doc.items: + if not item.purchase_order: + continue + + if not po_name: + po_name = item.purchase_order + + po_sr_item_dict[item.purchase_order_item] = { + "qty": flt(item.qty), + "rejected_qty": flt(item.rejected_qty), + "warehouse": item.warehouse, + "rejected_warehouse": item.rejected_warehouse, + "subcontracting_receipt_item": item.name, + } + + if not po_name: + frappe.throw( + _("Purchase Order Item reference is missing in Subcontracting Receipt {0}").format( + source_doc.name + ) ) - target_doc.currency = frappe.get_cached_value("Company", target_doc.company, "default_currency") + def update_item(obj, target, source_parent): + sr_item_details = po_sr_item_dict.get(obj.name) + ratio = flt(obj.qty) / flt(obj.fg_item_qty) - po_items_details = {} - for item in source_doc.items: - if item.purchase_order and item.purchase_order_item: - if item.purchase_order not in po_items_details: - po_doc = frappe.get_doc("Purchase Order", item.purchase_order) - po_items_details[item.purchase_order] = { - po_item.name: po_item for po_item in po_doc.items - } + target.update( + { + "qty": ratio * sr_item_details["qty"], + "rejected_qty": ratio * sr_item_details["rejected_qty"], + "warehouse": sr_item_details["warehouse"], + "rejected_warehouse": sr_item_details["rejected_warehouse"], + "subcontracting_receipt_item": sr_item_details["subcontracting_receipt_item"], + } + ) - if po_item := po_items_details[item.purchase_order].get(item.purchase_order_item): - conversion_factor = flt(po_item.qty) / flt(po_item.fg_item_qty) - item_row = { - "item_code": po_item.item_code, - "item_name": po_item.item_name, - "conversion_factor": conversion_factor, - "qty": flt(item.qty) * conversion_factor, - "rejected_qty": flt(item.rejected_qty) * conversion_factor, - "uom": po_item.uom, - "rate": po_item.rate, - "warehouse": item.warehouse, - "rejected_warehouse": item.rejected_warehouse, - "purchase_order": item.purchase_order, - "purchase_order_item": item.purchase_order_item, - "subcontracting_receipt_item": item.name, - "project": po_item.project, - } - target_doc.append("items", item_row) + def post_process(source, target): + target.set_missing_values() + target.update( + { + "posting_date": source_doc.posting_date, + "posting_time": source_doc.posting_time, + "subcontracting_receipt": source_doc.name, + "supplier_warehouse": source_doc.supplier_warehouse, + "is_subcontracted": 1, + "is_old_subcontracting_flow": 0, + "currency": frappe.get_cached_value("Company", target.company, "default_currency"), + } + ) - if not target_doc.items: - frappe.throw( - _("Purchase Order Item reference is missing in Subcontracting Receipt {0}").format( - source_doc.name - ) + target_doc = get_mapped_doc( + "Purchase Order", + po_name, + { + "Purchase Order": { + "doctype": "Purchase Receipt", + "field_map": {"supplier_warehouse": "supplier_warehouse"}, + "validation": { + "docstatus": ["=", 1], + }, + }, + "Purchase Order Item": { + "doctype": "Purchase Receipt Item", + "field_map": { + "name": "purchase_order_item", + "parent": "purchase_order", + "bom": "bom", + }, + "postprocess": update_item, + "condition": lambda doc: doc.name in po_sr_item_dict, + }, + "Purchase Taxes and Charges": {"doctype": "Purchase Taxes and Charges", "reset_value": True}, + }, + postprocess=post_process, + ) + + if (save or submit) and frappe.has_permission(target_doc.doctype, "create"): + target_doc.save() + + if submit and frappe.has_permission(target_doc.doctype, "submit", target_doc): + try: + target_doc.submit() + except Exception as e: + target_doc.add_comment("Comment", _("Submit Action Failed") + "

" + str(e)) + + if notify: + frappe.msgprint( + _("Purchase Receipt {0} created.").format( + get_link_to_form(target_doc.doctype, target_doc.name) + ), + indicator="green", + alert=True, ) - target_doc.set_missing_values() - - if (save or submit) and frappe.has_permission(target_doc.doctype, "create"): - target_doc.save() - - if submit and frappe.has_permission(target_doc.doctype, "submit", target_doc): - try: - target_doc.submit() - except Exception as e: - target_doc.add_comment("Comment", _("Submit Action Failed") + "

" + str(e)) - - if notify: - frappe.msgprint( - _("Purchase Receipt {0} created.").format( - get_link_to_form(target_doc.doctype, target_doc.name) - ), - indicator="green", - alert=True, - ) - - return target_doc + return target_doc diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py index 27ad7dbebdf..e0fa7923ef9 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py @@ -1075,18 +1075,42 @@ class TestSubcontractingReceipt(FrappeTestCase): @change_settings("Buying Settings", {"auto_create_purchase_receipt": 1}) def test_auto_create_purchase_receipt(self): + from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order + fg_item = "Subcontracted Item SA1" service_items = [ { "warehouse": "_Test Warehouse - _TC", "item_code": "Subcontracted Service Item 1", - "qty": 5, + "qty": 10, "rate": 100, "fg_item": fg_item, "fg_item_qty": 5, }, ] - sco = get_subcontracting_order(service_items=service_items) + + po = create_purchase_order( + rm_items=service_items, + is_subcontracted=1, + supplier_warehouse="_Test Warehouse 1 - _TC", + do_not_submit=True, + ) + po.append( + "taxes", + { + "account_head": "_Test Account Excise Duty - _TC", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Excise Duty", + "doctype": "Purchase Taxes and Charges", + "rate": 10, + }, + ) + po.save() + po.submit() + + sco = get_subcontracting_order(po_name=po.name) + rm_items = get_rm_items(sco.supplied_items) itemwise_details = make_stock_in_entry(rm_items=rm_items) make_stock_transfer_entry( @@ -1094,11 +1118,24 @@ class TestSubcontractingReceipt(FrappeTestCase): rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details), ) + scr = make_subcontracting_receipt(sco.name) + scr.items[0].qty = 3 scr.save() scr.submit() - self.assertTrue(frappe.db.get_value("Purchase Receipt", {"subcontracting_receipt": scr.name})) + pr_details = frappe.get_all( + "Purchase Receipt", + filters={"subcontracting_receipt": scr.name}, + fields=["name", "total_taxes_and_charges"], + ) + + self.assertTrue(pr_details) + + pr_qty = frappe.db.get_value("Purchase Receipt Item", {"parent": pr_details[0]["name"]}, "qty") + self.assertEqual(pr_qty, 6) + + self.assertEqual(pr_details[0]["total_taxes_and_charges"], 60) def test_use_serial_batch_fields_for_subcontracting_receipt(self): fg_item = make_item( diff --git a/erpnext/tests/test_perf.py b/erpnext/tests/test_perf.py index fc17b1dcbda..db54ca97395 100644 --- a/erpnext/tests/test_perf.py +++ b/erpnext/tests/test_perf.py @@ -3,7 +3,7 @@ from frappe.tests.utils import FrappeTestCase INDEXED_FIELDS = { "Bin": ["item_code"], - "GL Entry": ["voucher_type", "against_voucher_type"], + "GL Entry": ["voucher_no", "posting_date", "company", "party"], "Purchase Order Item": ["item_code"], "Stock Ledger Entry": ["warehouse"], } From 1c4eef2ef6fc34c3e2cf95306e15f2073d228bb6 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 17:41:41 +0530 Subject: [PATCH 74/83] fix: consider gle based on balances in company currency (copy #43805) (#43809) fix: consider gle based on balances in company currency (#43805) (cherry picked from commit 2fb441763a74bd4c5233e77f39611ee0c95b7efa) Co-authored-by: Nabin Hait --- .../doctype/period_closing_voucher/period_closing_voucher.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py index d6bd217650b..99b42089501 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -380,9 +380,7 @@ class PeriodClosingVoucher(AccountsController): for dimensions, account_balances in balance_sheet_account_balances.items(): for acc, balances in account_balances.items(): - balance_in_company_currency = flt(balances.debit_in_account_currency) - flt( - balances.credit_in_account_currency - ) + balance_in_company_currency = flt(balances.debit) - flt(balances.credit) if acc != "balances" and balance_in_company_currency: closing_entries.append(self.get_closing_entry(acc, balances, dimensions)) From 188645bfd6cadfc05d506667e9a256245450e696 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 23 Oct 2024 12:12:56 +0000 Subject: [PATCH 75/83] chore(release): Bumped to Version 15.39.2 ## [15.39.2](https://github.com/frappe/erpnext/compare/v15.39.1...v15.39.2) (2024-10-23) ### Bug Fixes * consider gle based on balances in company currency (copy [#43805](https://github.com/frappe/erpnext/issues/43805)) ([#43809](https://github.com/frappe/erpnext/issues/43809)) ([1c4eef2](https://github.com/frappe/erpnext/commit/1c4eef2ef6fc34c3e2cf95306e15f2073d228bb6)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index a5b8609d1d9..fea98a77374 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.39.0" +__version__ = "15.39.2" def get_default_company(user=None): From a79bc4d35abbfb7597d7c01dbdb4f4cb798eeff6 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:37:57 +0530 Subject: [PATCH 76/83] fix: Unnecessary validation for non deferred sales invoices (#43816) fix: Unnecessary validation for non deferred sales invoices (#43816) (cherry picked from commit af472054f6a8f77aca8811e3f575893ba7ea1c00) Co-authored-by: Deepesh Garg (cherry picked from commit bf4fb53575be594e2e13e0c53cd4218fe4215ac5) --- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index c680bd46130..ebdbb01fdc2 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -297,8 +297,11 @@ class SalesInvoice(SellingController): self.update_current_stock() self.validate_delivery_note() + is_deferred_invoice = any(d.get("enable_deferred_revenue") for d in self.get("items")) + # validate service stop date to lie in between start and end date - validate_service_stop_date(self) + if is_deferred_invoice: + validate_service_stop_date(self) if not self.is_opening: self.is_opening = "No" From f48ce906582cee31272300414b4387da56d47307 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 24 Oct 2024 08:22:31 +0000 Subject: [PATCH 77/83] chore(release): Bumped to Version 15.39.3 ## [15.39.3](https://github.com/frappe/erpnext/compare/v15.39.2...v15.39.3) (2024-10-24) ### Bug Fixes * Unnecessary validation for non deferred sales invoices ([#43816](https://github.com/frappe/erpnext/issues/43816)) ([a79bc4d](https://github.com/frappe/erpnext/commit/a79bc4d35abbfb7597d7c01dbdb4f4cb798eeff6)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index fea98a77374..645337290fb 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.39.2" +__version__ = "15.39.3" def get_default_company(user=None): From 94a03c6e17f797dd4ffb533ce9ff0af2f3d5d6ff Mon Sep 17 00:00:00 2001 From: Venkatesh <47534423+venkat102@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:47:40 +0530 Subject: [PATCH 78/83] =?UTF-8?q?fix:=20use=20period=20closing=20voucher?= =?UTF-8?q?=20object=20to=20call=20get=5Faccount=5Fclosing=5Fba=E2=80=A6?= =?UTF-8?q?=20(#43880)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: use period closing voucher object to call get_account_closing_balances method (cherry picked from commit 99d1c5f34221d3f450aa74825339209c7595bcb9) --- erpnext/patches/v14_0/update_closing_balances.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v14_0/update_closing_balances.py b/erpnext/patches/v14_0/update_closing_balances.py index a2670717ee9..73204b0d6c4 100644 --- a/erpnext/patches/v14_0/update_closing_balances.py +++ b/erpnext/patches/v14_0/update_closing_balances.py @@ -24,8 +24,9 @@ def execute(): for pcv in get_period_closing_vouchers(company): company_wise_order.setdefault(pcv.company, []) if pcv.period_end_date not in company_wise_order[pcv.company]: - pcv.pl_accounts_reverse_gle = get_pcv_gl_entries(pcv, gle_fields) - closing_entries = pcv.get_account_closing_balances() + pcv_doc = frappe.get_doc("Period Closing Voucher", pcv.name) + pcv_doc.pl_accounts_reverse_gle = get_pcv_gl_entries(pcv, gle_fields) + closing_entries = pcv_doc.get_account_closing_balances() if closing_entries: make_closing_entries(closing_entries, pcv.name, pcv.company, pcv.period_end_date) From be6cd6adc3d00cf925f91db5c7cf31157af534fa Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Tue, 29 Oct 2024 15:34:46 +0000 Subject: [PATCH 79/83] chore(release): Bumped to Version 15.39.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [15.39.4](https://github.com/frappe/erpnext/compare/v15.39.3...v15.39.4) (2024-10-29) ### Bug Fixes * use period closing voucher object to call get_account_closing_ba… ([#43880](https://github.com/frappe/erpnext/issues/43880)) ([94a03c6](https://github.com/frappe/erpnext/commit/94a03c6e17f797dd4ffb533ce9ff0af2f3d5d6ff)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 645337290fb..d8473c0d258 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.39.3" +__version__ = "15.39.4" def get_default_company(user=None): From becfd980b2f4219aa15ec9dc7b94f7ae037196d7 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 29 Oct 2024 16:53:11 +0530 Subject: [PATCH 80/83] fix: post account closing balance against pcv closing account (#43887) (cherry picked from commit 34295d0344573a296d5fb76e6cc2c819a93354b2) --- .../period_closing_voucher.py | 13 ++++++++++--- erpnext/patches/v14_0/update_closing_balances.py | 3 +-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py index 99b42089501..6ffa6346702 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -354,7 +354,8 @@ class PeriodClosingVoucher(AccountsController): def get_account_closing_balances(self): pl_closing_entries = self.get_closing_entries_for_pl_accounts() bs_closing_entries = self.get_closing_entries_for_balance_sheet_accounts() - closing_entries = pl_closing_entries + bs_closing_entries + closing_entries_for_closing_account = self.get_closing_entries_for_closing_account() + closing_entries = pl_closing_entries + bs_closing_entries + closing_entries_for_closing_account return closing_entries def get_closing_entries_for_pl_accounts(self): @@ -404,6 +405,13 @@ class PeriodClosingVoucher(AccountsController): self.update_default_dimensions(closing_entry, dimensions) return closing_entry + def get_closing_entries_for_closing_account(self): + closing_entries = copy.deepcopy(self.closing_account_gle) + for d in closing_entries: + d.period_closing_voucher = self.name + + return closing_entries + def is_first_period_closing_voucher(self): return not frappe.db.exists( "Period Closing Voucher", @@ -442,8 +450,7 @@ def process_gl_and_closing_entries(doc): make_gl_entries(gl_entries, merge_entries=False) closing_entries = doc.get_account_closing_balances() - if closing_entries: - make_closing_entries(closing_entries, doc.name, doc.company, doc.period_end_date) + make_closing_entries(closing_entries, doc.name, doc.company, doc.period_end_date) frappe.db.set_value(doc.doctype, doc.name, "gle_processing_status", "Completed") except Exception as e: diff --git a/erpnext/patches/v14_0/update_closing_balances.py b/erpnext/patches/v14_0/update_closing_balances.py index 73204b0d6c4..f216f209d4f 100644 --- a/erpnext/patches/v14_0/update_closing_balances.py +++ b/erpnext/patches/v14_0/update_closing_balances.py @@ -27,8 +27,7 @@ def execute(): pcv_doc = frappe.get_doc("Period Closing Voucher", pcv.name) pcv_doc.pl_accounts_reverse_gle = get_pcv_gl_entries(pcv, gle_fields) closing_entries = pcv_doc.get_account_closing_balances() - if closing_entries: - make_closing_entries(closing_entries, pcv.name, pcv.company, pcv.period_end_date) + make_closing_entries(closing_entries, pcv.name, pcv.company, pcv.period_end_date) company_wise_order[pcv.company].append(pcv.period_end_date) i += 1 From 50db0aca61c31b1f32b5d96baaff63ddc9c20e1c Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Tue, 29 Oct 2024 15:39:40 +0000 Subject: [PATCH 81/83] chore(release): Bumped to Version 15.39.5 ## [15.39.5](https://github.com/frappe/erpnext/compare/v15.39.4...v15.39.5) (2024-10-29) ### Bug Fixes * post account closing balance against pcv closing account ([#43887](https://github.com/frappe/erpnext/issues/43887)) ([becfd98](https://github.com/frappe/erpnext/commit/becfd980b2f4219aa15ec9dc7b94f7ae037196d7)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index d8473c0d258..3b36669ae7c 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.39.4" +__version__ = "15.39.5" def get_default_company(user=None): From c2eb771c4d228458a95db99dbbb2f96c4a00db02 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 23:07:58 +0530 Subject: [PATCH 82/83] fix: Patch for reposting account closing balance (backport #43905) (#43909) fix: Patch for reposting account closing balance (#43905) (cherry picked from commit 3a0d27b393a6224e9213d23c022f9b45687d7508) Co-authored-by: Nabin Hait --- erpnext/patches.txt | 2 +- .../patches/v14_0/update_closing_balances.py | 21 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 515a299504a..f48dc00fc8e 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -315,7 +315,7 @@ erpnext.patches.v15_0.update_asset_value_for_manual_depr_entries erpnext.patches.v15_0.update_gpa_and_ndb_for_assdeprsch erpnext.patches.v14_0.create_accounting_dimensions_for_closing_balance erpnext.patches.v14_0.set_period_start_end_date_in_pcv -erpnext.patches.v14_0.update_closing_balances #14-07-2023 +erpnext.patches.v14_0.update_closing_balances #29-10-2024 execute:frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0) erpnext.patches.v14_0.update_reference_type_in_journal_entry_accounts erpnext.patches.v14_0.update_subscription_details diff --git a/erpnext/patches/v14_0/update_closing_balances.py b/erpnext/patches/v14_0/update_closing_balances.py index f216f209d4f..31c7e85d875 100644 --- a/erpnext/patches/v14_0/update_closing_balances.py +++ b/erpnext/patches/v14_0/update_closing_balances.py @@ -25,7 +25,8 @@ def execute(): company_wise_order.setdefault(pcv.company, []) if pcv.period_end_date not in company_wise_order[pcv.company]: pcv_doc = frappe.get_doc("Period Closing Voucher", pcv.name) - pcv_doc.pl_accounts_reverse_gle = get_pcv_gl_entries(pcv, gle_fields) + pcv_doc.pl_accounts_reverse_gle = get_pcv_gl_entries_for_pl_accounts(pcv, gle_fields) + pcv_doc.closing_account_gle = get_pcv_gl_entries_for_closing_accounts(pcv, gle_fields) closing_entries = pcv_doc.get_account_closing_balances() make_closing_entries(closing_entries, pcv.name, pcv.company, pcv.period_end_date) @@ -38,6 +39,7 @@ def get_gle_fields(): accounting_dimension_fields = get_accounting_dimensions() gle_fields = [ "name", + "company", "posting_date", "account", "account_currency", @@ -61,14 +63,27 @@ def get_period_closing_vouchers(company): ) -def get_pcv_gl_entries(pcv, gle_fields): +def get_pcv_gl_entries_for_pl_accounts(pcv, gle_fields): + return get_gl_entries(pcv, gle_fields, {"account": ["!=", pcv.closing_account_head]}) + + +def get_pcv_gl_entries_for_closing_accounts(pcv, gle_fields): + return get_gl_entries(pcv, gle_fields, {"account": pcv.closing_account_head}) + + +def get_gl_entries(pcv, gle_fields, accounts_filter=None): + filters = {"voucher_no": pcv.name, "is_cancelled": 0} + if accounts_filter: + filters.update(accounts_filter) + gl_entries = frappe.db.get_all( "GL Entry", - filters={"voucher_no": pcv.name, "account": ["!=", pcv.closing_account_head], "is_cancelled": 0}, + filters=filters, fields=gle_fields, ) for entry in gl_entries: entry["is_period_closing_voucher_entry"] = 1 entry["closing_date"] = pcv.period_end_date entry["period_closing_voucher"] = pcv.name + return gl_entries From d8e1a21bdc34d88c77c33b2f21d53561fe81b1b1 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Tue, 29 Oct 2024 17:39:33 +0000 Subject: [PATCH 83/83] chore(release): Bumped to Version 15.39.6 ## [15.39.6](https://github.com/frappe/erpnext/compare/v15.39.5...v15.39.6) (2024-10-29) ### Bug Fixes * Patch for reposting account closing balance (backport [#43905](https://github.com/frappe/erpnext/issues/43905)) ([#43909](https://github.com/frappe/erpnext/issues/43909)) ([c2eb771](https://github.com/frappe/erpnext/commit/c2eb771c4d228458a95db99dbbb2f96c4a00db02)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 3b36669ae7c..b05af8dad95 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from frappe.utils.user import is_website_user -__version__ = "15.39.5" +__version__ = "15.39.6" def get_default_company(user=None):