Compare commits

...

181 Commits

Author SHA1 Message Date
coderabbitai[bot]
f6c8d5e038 📝 Add docstrings to fix/email-campaign-timeout
Docstrings generation was requested by @pratikb64.

* https://github.com/frappe/erpnext/pull/51994#issuecomment-3783742931

The following files were modified:

* `erpnext/crm/doctype/email_campaign/email_campaign.py`
2026-01-22 10:55:07 +00:00
Khushi Rawat
a030ea6fde Merge pull request #51756 from aerele/asset-repair
fix: disable asset repair when status is fully depreciated
2026-01-22 13:59:39 +05:30
Mihir Kandoi
e5d25a7f04 Merge pull request #51908 from ljain112/fix-inward-subcontracting 2026-01-22 10:34:44 +05:30
Mihir Kandoi
40e86b6670 Merge pull request #51929 from ljain112/fix-subcontracting-inward-rm-rate 2026-01-22 10:31:53 +05:30
Mihir Kandoi
d0c9924c37 Merge pull request #51966 from aerele/customer-group-filters 2026-01-22 10:26:22 +05:30
Mihir Kandoi
ede4faa152 Merge pull request #51967 from aerele/project-update-naming-series 2026-01-22 10:22:31 +05:30
Mihir Kandoi
05cf1dcab8 Merge pull request #51968 from mihir-kandoi/gh51965 2026-01-21 22:50:22 +05:30
Mihir Kandoi
43a6dd5657 Merge pull request #51964 from mihir-kandoi/dont-show-dn-btn-if-not-reqd 2026-01-21 22:39:08 +05:30
Mihir Kandoi
343ee9695b fix: rejected qty in PR doesn't consider conversion factor 2026-01-21 22:33:24 +05:30
ravibharathi656
49e64f4e1c fix(project): add missing counter to project update naming series 2026-01-21 19:55:33 +05:30
SowmyaArunachalam
1e3db9f916 fix(customer): add customer group filters 2026-01-21 17:37:37 +05:30
Mihir Kandoi
70ec977cb2 fix: create DN btn should not be shown if it cannot be created 2026-01-21 17:13:35 +05:30
Mihir Kandoi
d6bbe43fa0 Merge pull request #51958 from mihir-kandoi/force-serial-batch-stock-reco 2026-01-21 16:23:18 +05:30
Mihir Kandoi
035b3cb61e fix: tests 2026-01-21 15:58:46 +05:30
Mihir Kandoi
97c36d1edc Merge pull request #51947 from mihir-kandoi/st57849 2026-01-21 15:46:38 +05:30
Mihir Kandoi
7170a1bd78 fix: force user to enter batch or serial for serial/batch items 2026-01-21 15:30:55 +05:30
Diptanil Saha
936f13eb20 ci: generate pot files for version-16-hotfix (#51954) 2026-01-21 14:37:21 +05:30
Mihir Kandoi
ed51db3217 Merge pull request #51948 from mihir-kandoi/st57735 2026-01-21 13:05:43 +05:30
Mihir Kandoi
5bacb67d36 fix: warehouse permissions in MR incorrectly ignored 2026-01-21 12:50:50 +05:30
Mihir Kandoi
c919b1de38 fix: job cards should not be deleted on close of WO 2026-01-21 11:46:00 +05:30
Mihir Kandoi
46ab5e8e46 Merge pull request #51934 from mihir-kandoi/st57619 2026-01-20 20:46:38 +05:30
Mihir Kandoi
3960c01798 fix: validation message in stock reco row idx 2026-01-20 20:30:10 +05:30
rohitwaghchaure
3c5071cefc Merge pull request #51930 from frappe/revert-51920-fixed-do-reposting-for-lcv
Revert "perf: prevent duplicate reposting for the same item"
2026-01-20 19:48:35 +05:30
rohitwaghchaure
6e4b90055f Revert "perf: prevent duplicate reposting for the same item" 2026-01-20 19:30:42 +05:30
ljain112
37ee560eae fix: calculate weighted average rate for customer provided items in subcontracting inward order 2026-01-20 18:48:59 +05:30
Mihir Kandoi
4b3000b071 Merge pull request #51909 from mihir-kandoi/gh51906 2026-01-20 17:44:23 +05:30
rohitwaghchaure
ad6cb177e3 Merge pull request #51920 from rohitwaghchaure/fixed-do-reposting-for-lcv
perf: prevent duplicate reposting for the same item
2026-01-20 17:38:15 +05:30
ljain112
d256365f4a fix: throw if item order field is not set in subcontracting controller 2026-01-20 17:33:01 +05:30
Diptanil Saha
05fea7f66f Merge pull request #51887 from diptanilsaha/bank_ac 2026-01-20 17:21:51 +05:30
Rohit Waghchaure
7535931571 perf: prevent duplicate reposting for the same item 2026-01-20 17:13:16 +05:30
Mihir Kandoi
27915c9ce2 Merge pull request #51914 from mihir-kandoi/st57262 2026-01-20 16:44:43 +05:30
ruthra kumar
93b131f48a Merge pull request #51671 from nikkothari22/advance-taxes-dimensions
fix(accounts): add missing accounting dimensions in advance taxes and charges
2026-01-20 16:36:16 +05:30
Nikhil Kothari
10d5463a40 Merge branch 'develop' into advance-taxes-dimensions 2026-01-20 16:19:08 +05:30
Mihir Kandoi
017cc9d9f9 fix: continuous raw material consumption with bom validation 2026-01-20 16:18:06 +05:30
Mihir Kandoi
b691de0147 fix: allow creation of DN in SI for items not having DN reference 2026-01-20 15:08:37 +05:30
rohitwaghchaure
beabbb1fa2 Merge pull request #51900 from rohitwaghchaure/fixed-github-49961
fix: validation to check at-least one raw material for manufacture entry
2026-01-20 13:54:48 +05:30
rohitwaghchaure
65c3020d1b Merge pull request #51899 from rohitwaghchaure/fixed-github-51401
feat: option to import serial / batches using csv for outward entry
2026-01-20 13:37:35 +05:30
Rohit Waghchaure
f003b3c378 fix: validation to check at-least one raw material for manufacture entry 2026-01-20 13:36:46 +05:30
Rohit Waghchaure
a268316322 feat: option to import serial / batches using csv for outward entry 2026-01-20 13:10:40 +05:30
Mihir Kandoi
090dabeea5 Merge pull request #51895 from mihir-kandoi/st57390 2026-01-20 13:03:08 +05:30
Mihir Kandoi
edba9efb5e fix: overproduction % not considered when making WO from SO 2026-01-20 12:48:03 +05:30
Diptanil Saha
ad205546c3 fix: collapsible filters on accounts receivable and accounts payables reports (#51798)
Co-authored-by: sokumon <sohamkulkarns9@gmail.com>
2026-01-20 12:44:49 +05:30
ruthra kumar
47ee9ce0e2 Merge pull request #51886 from barredterra/translatable-return-msg
fix(accounts_controller): make return message translatable
2026-01-20 07:55:47 +05:30
Lakshit Jain
aea70c5ec1 Merge pull request #51561 from ljain112/fic-adv-ple-po
fix: delete advance ledger entries  while reconciling payment entry
2026-01-20 07:50:27 +05:30
diptanilsaha
7532ab01d6 fix(bank_account): validation for is_company_account 2026-01-20 00:46:46 +05:30
barredterra
0209f0fe29 fix(accounts_controller): make return message translatable 2026-01-19 17:55:50 +01:00
rohitwaghchaure
51fd15e2af Merge pull request #51830 from aerele/fix/work-order-produced-qty
fix(manufacturing): consider process loss qty while validating the work order
2026-01-19 21:46:06 +05:30
Mihir Kandoi
7b5f69bae8 Merge pull request #51880 from mihir-kandoi/gh51873 2026-01-19 20:04:26 +05:30
Mihir Kandoi
11d198fcd6 Merge pull request #51879 from mihir-kandoi/gh51875 2026-01-19 19:59:42 +05:30
Mihir Kandoi
ad11914fca fix: no attribute error on LCV 2026-01-19 19:49:01 +05:30
Mihir Kandoi
fbac8b032e fix: no attribute error on subcontracting receipt 2026-01-19 19:43:31 +05:30
Diptanil Saha
04a2a52639 Merge pull request #51595 from FHenry/dev_fr_chertofaccount_2025 2026-01-19 17:52:47 +05:30
Diptanil Saha
7dc8b74aa1 Merge pull request #51860 from frappe/pot_develop_2026-01-19 2026-01-19 15:42:08 +05:30
rohitwaghchaure
15047235cb Merge pull request #51769 from aerele/pos-set-warehouse-reset
fix(pos): reapply set warehouse during cart update
2026-01-19 15:35:53 +05:30
rohitwaghchaure
020bdfb5bc Merge pull request #51690 from nishkagosalia/gh-49830
feat: Adding Item name in update item dialog box
2026-01-19 15:29:08 +05:30
rohitwaghchaure
3a85c38417 Merge pull request #51856 from rohitwaghchaure/fixed-serial-no-count
fix: qty with serial no count
2026-01-19 15:24:43 +05:30
frappe-pr-bot
60ed4ada10 chore: update POT file 2026-01-19 09:52:35 +00:00
Khushi Rawat
4b27bcd432 Merge pull request #51822 from aerele/check-dimensions
fix(budget variance report): check budget dimensions
2026-01-19 15:22:23 +05:30
Diptanil Saha
a2ae2c1a1a Merge pull request #51819 from earona/patch-1 2026-01-19 15:21:08 +05:30
Rohit Waghchaure
56e58ef301 fix: qty with serial no count 2026-01-19 15:13:08 +05:30
rohitwaghchaure
7102036500 Refactor batch bundle get snos sle (#51644)
* refactor: Batch & Bundle get Stock ledger for snos

* refactor: Batch & Bundle get Stock ledger for snos v2

* refactor: Batch & Bundle get Stock ledger for snos - added posting date in select

* refactor: Batch & Bundle get sle for snos - Added docstring

* chore: fix semantic commit message

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2026-01-19 14:52:20 +05:30
Rohit Waghchaure
dfcbee9cc0 chore: fix semantic commit message 2026-01-19 14:22:32 +05:30
krupalvora
22dee50348 refactor: Batch & Bundle get sle for snos - Added docstring 2026-01-19 14:21:19 +05:30
krupalvora
1ccc7365a7 refactor: Batch & Bundle get Stock ledger for snos - added posting date in select 2026-01-19 14:21:18 +05:30
krupalvora
a074d81754 refactor: Batch & Bundle get Stock ledger for snos v2 2026-01-19 14:21:18 +05:30
krupalvora
c0149925ad refactor: Batch & Bundle get Stock ledger for snos 2026-01-19 14:21:17 +05:30
Mihir Kandoi
d8d74236dd Merge pull request #51845 from aerele/bom-company-filter 2026-01-19 14:03:15 +05:30
22-poojashree
73bcfc4710 fix(bom): pass company warehouse filter 2026-01-19 13:30:07 +05:30
mahsem
0c0f43f7f7 fix: common_party_path (#51826)
* fix: common_pary_path

* chore: remove non-existent anchor

---------

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2026-01-19 07:49:30 +00:00
MochaMind
998f206da1 fix: sync translations from crowdin (#51704)
* fix: Persian translations

* fix: Hungarian translations

* fix: Hungarian translations

* fix: Hungarian translations
2026-01-19 13:01:37 +05:30
ruthra kumar
e7f6125df8 Merge pull request #51513 from aerele/net-profit-calculation
fix: calculate net profit amount from root node accounts
2026-01-19 12:44:14 +05:30
Lakshit Jain
f00aeec9b4 Merge pull request #51787 from ljain112/fix-taxes-disc
fix: recalculate taxes when item tax template changes after discount
2026-01-19 12:30:29 +05:30
Smit Vora
83919119f8 fix: allow disassemble stock entry without work order (#51761)
* fix: allow disassemble stock entry without work order

* fix: use existing functionality to load fg item

* chore: better dict update
2026-01-19 11:36:12 +05:30
ruthra kumar
9a79beda04 Merge pull request #51742 from aerele/item-wise-sales-register
fix: add other charges in total
2026-01-19 11:13:51 +05:30
Sudharsanan11
e6366e830c fix(manufacturing): consider process loss qty while validating the work order 2026-01-19 11:09:21 +05:30
ruthra kumar
218c255543 Merge pull request #51803 from ljain112/unused-imports
chore: remove unused imports
2026-01-19 10:24:44 +05:30
Mihir Kandoi
167e9c5341 Merge pull request #51827 from trustedcomputer/fix-email-digest 2026-01-19 09:58:41 +05:30
Mihir Kandoi
7cbd644782 Merge pull request #51824 from mihir-kandoi/fg-qty-process-loss-fix 2026-01-18 22:50:21 +05:30
trustedcomputer
d2e01e97f0 fix: remove incorrect validation throwing spurious error 2026-01-18 08:32:46 -08:00
Mihir Kandoi
56f5df6847 fix: setting process loss qty causes fg item qty to be incorrect 2026-01-18 20:11:51 +05:30
ervishnucs
cb696a8880 fix(budget variance report): check budget dimensions 2026-01-18 19:32:51 +05:30
Florian HENRY
b3efb3084f chore: re add older template 2026-01-18 10:46:13 +01:00
Florian HENRY
4fe1b214c1 chore: fix bank account type 2026-01-18 10:43:09 +01:00
Mihir Kandoi
96c3fccb05 Merge pull request #51817 from aerele/fix/barcode-uom-fx-in-item 2026-01-18 15:04:59 +05:30
Florian HENRY
6a876de838 chore: fix CASH acount type 2026-01-17 22:05:53 +01:00
Florian HENRY
765487a087 chore: fix bank acount type 2026-01-17 21:17:43 +01:00
Exequiel Arona
d472888bf0 ci: fix generate POT workflow 2026-01-17 17:06:16 -03:00
Florian HENRY
b83640fae7 Merge branch 'develop' of https://github.com/frappe/erpnext into dev_fr_chertofaccount_2025 2026-01-17 20:57:19 +01:00
Florian HENRY
c519cd0268 chore: add Expenses Included In Valuation account 2026-01-17 20:57:08 +01:00
Pandiyan5273
30263b26a5 fix: prevent UOM from updating incorrectly while scanning barcode 2026-01-17 20:28:04 +05:30
Sowmya
3fe5b5c80d fix: change docfield type to render html format (#51795) 2026-01-17 14:55:25 +05:30
ljain112
e8510287e3 chore: remove unused imports 2026-01-17 14:45:57 +05:30
ruthra kumar
310cca6939 Merge pull request #51555 from ili-ad/fix/postgres-company-month-sales
fix(postgres): compute current month sales without DATE_FORMAT
2026-01-16 16:58:22 +05:30
Mihir Kandoi
e51b7155aa Merge pull request #51790 from aerele/fix/support-57170 2026-01-16 16:17:56 +05:30
Mihir Kandoi
96ade0b821 Merge pull request #51791 from mihir-kandoi/item-fields-visibility 2026-01-16 16:00:25 +05:30
Mihir Kandoi
b3db2981de fix: dont show certain fields based on permissions 2026-01-16 15:58:02 +05:30
Mihir Kandoi
0d7b2d812c Merge pull request #51784 from aerele/warehouse-filter 2026-01-16 15:13:56 +05:30
Pandiyan5273
f959b2c59a fix(stock): resolve quantity issue when adding items via barcode scan 2026-01-16 15:12:28 +05:30
Mihir Kandoi
7549f1ba95 Merge pull request #51788 from mihir-kandoi/js-errors 2026-01-16 15:11:53 +05:30
Mihir Kandoi
047343ca11 fix: js error on customer doctype 2026-01-16 15:10:31 +05:30
Mihir Kandoi
876c815bd8 Merge pull request #51693 from mihir-kandoi/sample-retention-refactor 2026-01-16 13:53:50 +05:30
Mihir Kandoi
8fd1d6aec8 chore: typo 2026-01-16 13:38:38 +05:30
rohitwaghchaure
589a393b5c fix: opening stock not working for serial / batch (#51781) 2026-01-16 13:15:24 +05:30
Mihir Kandoi
19ae405742 fix: bugs 2026-01-16 13:15:22 +05:30
SowmyaArunachalam
f952b92d71 fix: add company filters for warehouse 2026-01-16 13:15:00 +05:30
Mihir Kandoi
b567184dd7 test: add test case 2026-01-16 12:31:54 +05:30
Jatin3128
c5b0787de6 Merge pull request #51673 from Jatin3128/ar/ap-future-range-fix
fix: add below-0 column in ar/ap report
2026-01-16 12:06:22 +05:30
Mihir Kandoi
3d0f649411 feat: support for serial item 2026-01-16 10:23:11 +05:30
Mihir Kandoi
b54067e04d fix: remove already transferred batch 2026-01-16 10:23:11 +05:30
Mihir Kandoi
8d188cd32b refactor: sample retention stock entry 2026-01-16 10:23:11 +05:30
Diptanil Saha
5ebaee03da Merge pull request #51764 from diptanilsaha/hook_dv 2026-01-15 18:02:06 +05:30
rohitwaghchaure
7ff31a1d91 Merge pull request #51768 from rohitwaghchaure/fixed-stock-and-account-value-comparision-report
fix: Show non-SLE vouchers with GL entries in Stock vs Account Value …
2026-01-15 17:49:24 +05:30
Rohit Waghchaure
1db9ce205f fix: Show non-SLE vouchers with GL entries in Stock vs Account Value Comparison report 2026-01-15 17:04:49 +05:30
ravibharathi656
5a53c45321 fix(pos): reapply set warehouse during cart update 2026-01-15 17:03:16 +05:30
diptanilsaha
050ea96cc6 chore(hooks): develop_version bump 2026-01-15 15:14:27 +05:30
Mihir Kandoi
fb6e0be5fe Merge pull request #51753 from mahsem/docs_path 2026-01-14 21:29:33 +05:30
SowmyaArunachalam
66fe1aa85d fix: disable asset repair when status is fully depreciated 2026-01-14 21:22:10 +05:30
mahsem
7ef8c81caf fix: docs_path 2026-01-14 16:36:22 +01:00
rohitwaghchaure
2f3d4ddc58 Merge pull request #51729 from rohitwaghchaure/fixed-valuation-for-non-batchwise-valuation
fix: valuation rate for non batchwise valuation
2026-01-14 19:35:20 +05:30
Diptanil Saha
257f0c338c Merge pull request #51730 from diptanilsaha/st_56828 2026-01-14 15:51:09 +05:30
SowmyaArunachalam
9406c07c42 fix: add other charges in total 2026-01-14 12:49:30 +05:30
Ankush Menat
1d35e2b261 build: bump required frappe version (#51738) 2026-01-14 11:07:06 +05:30
Mihir Kandoi
0643beb079 Merge pull request #51684 from aerele/test/manufacture-entry-without-wo 2026-01-14 11:03:19 +05:30
Mihir Kandoi
22e0ca2d7e Merge pull request #51295 from aerele/partial-billing-timesheet 2026-01-14 11:02:18 +05:30
Mihir Kandoi
ce7be9fad5 Merge pull request #51733 from mihir-kandoi/gh51731 2026-01-14 10:24:36 +05:30
Mihir Kandoi
6d3f6d73d0 fix: add uom js error 2026-01-14 10:22:59 +05:30
diptanilsaha
8b445e04e5 fix(transaction.js): use flt instead of cint for plc_conversion_rate 2026-01-14 01:36:15 +05:30
Rohit Waghchaure
b6312bca9c fix: valuation rate for non batchwise valuation 2026-01-14 00:02:28 +05:30
Mihir Kandoi
201a04c49a Merge pull request #51725 from mihir-kandoi/ci-patch-test-develop-2 2026-01-13 20:12:13 +05:30
Mihir Kandoi
5e2c7a08d3 revert: make CI not run on .github change 2026-01-13 19:57:11 +05:30
Mihir Kandoi
0da98e6769 ci: patch test for v16 branch 2026-01-13 19:29:39 +05:30
rohitwaghchaure
da87f358c4 Merge pull request #51719 from rohitwaghchaure/fixed-github-51715
fix: stock module not opened when no warehouses
2026-01-13 17:19:33 +05:30
Rohit Waghchaure
9de3b07223 fix: stock module not opened when no warehouses 2026-01-13 17:02:48 +05:30
Khushi Rawat
d3cd887f5e Merge pull request #51666 from aerele/fix-asset-value-adjustment-cancel
fix(asset value adjustment): skip cancelling revaluation journal entry if already cancelled
2026-01-13 12:38:44 +05:30
Navin-S-R
d65cd605a1 fix: move validation to before_cancel 2026-01-13 12:16:52 +05:30
Ankush Menat
6ec41fa47e build: Bump dev version 2026-01-13 12:15:21 +05:30
Khushi Rawat
d879a91165 Merge pull request #51509 from khushi8112/fix-test-cases
fix: use system configured float precision for depreciation rate
2026-01-13 11:58:58 +05:30
Khushi Rawat
d21cfae095 Merge pull request #51363 from aerele/asset-partial-sales
fix(asset): handle partial asset sales by splitting remaining quantity
2026-01-13 11:54:20 +05:30
Mihir Kandoi
be5f2b6cf0 Merge pull request #51650 from mihir-kandoi/v16-prep 2026-01-13 11:06:02 +05:30
ruthra kumar
37b3a22825 Merge pull request #51412 from ljain112/fix-tds-customer
fix(tds): correct tax logic for customer
2026-01-13 11:05:31 +05:30
Mihir Kandoi
bb307dec0a chore: add v14
remove when EOL reached
2026-01-13 11:04:17 +05:30
Nabin Hait
3bc58fb46f fix: Redirect to Desktop after signup (#51696) 2026-01-12 19:20:27 +05:30
Navin-S-R
73b038084b fix: prevent manual cancellation of the linked Revaluation Journal Entry 2026-01-12 18:18:22 +05:30
Nishka Gosalia
e6133ad6d4 feat: Adding Item name in update item dialog box 2026-01-12 17:06:49 +05:30
Navin-S-R
eeb6d0e9bf fix: remove the redundant purchase receipt submit 2026-01-12 16:45:04 +05:30
Navin-S-R
ca97f34092 fix: use new_asset instead of asset_doc when checking values after splitting 2026-01-12 16:36:34 +05:30
Pandiyan5273
784e338be4 test(stock-entry): manufacture entry without work order 2026-01-12 15:52:38 +05:30
Nikhil Kothari
22e9cb4cf4 fix(accounts): add missing accounting dimensions in advance taxes and charges 2026-01-12 00:42:52 +05:30
Navin-S-R
500c44e3f5 fix: ignore permissions when cancelling revaluation journal entry 2026-01-11 21:30:09 +05:30
Navin-S-R
5f00239bba refactor(journal entry): replace raw SQL with query builder to unlink asset value adjustment 2026-01-11 19:25:22 +05:30
Navin-S-R
b1704ccef1 fix(asset value adjustment): skip cancelling revaluation journal entry if already cancelled 2026-01-11 19:20:01 +05:30
l0gesh29
f7004aa8c3 chore: modify error msg 2026-01-11 14:32:15 +05:30
l0gesh29
8379b39aaf fix: add validation for direct return 2026-01-11 13:52:46 +05:30
Mihir Kandoi
4987b2fe26 ci: ignore ci folder for tests 2026-01-10 17:01:04 +05:30
Mihir Kandoi
7e7e83440f ci: version 16 related changes 2026-01-10 16:43:39 +05:30
l0gesh29
ff9b936634 fix: add validation for return against 2026-01-09 19:08:23 +05:30
Logesh Periyasamy
43d1d685c6 fix: add validation for amount and hours
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-01-09 18:11:42 +05:30
l0gesh29
cda8a97f4a fix: add validation for duplication 2026-01-09 17:43:55 +05:30
Florian HENRY
bf430fce09 feat: remove old French chart of accounts with code as nex 2025 is provided 2026-01-08 13:49:16 +01:00
Florian HENRY
6bdaeb983d chore: Review PR #51595 2026-01-08 13:47:40 +01:00
Florian HENRY
c81dee137f feat: add new 2025 Charts of Accounts for France 2026-01-08 10:59:18 +01:00
Matt Howard
64f391adf7 fix(postgres): compute current month sales without DATE_FORMAT 2026-01-06 15:00:25 -05:00
khushi8112
c0a85faa68 test: set up float precision 2026-01-06 23:49:21 +05:30
khushi8112
825e3717ca fix: do not update float precision on setup 2026-01-06 14:41:36 +05:30
khushi8112
007258d657 refactor: modify test cases to handle float precision rounded to 2 decimals 2026-01-06 14:39:31 +05:30
Navin-S-R
c84986d00e fix: calculate net profit amount from root node accounts 2026-01-05 19:09:05 +05:30
khushi8112
8d186d6b3f fix: use correct test class 2026-01-05 16:47:32 +05:30
khushi8112
1296829b9c fix(test): Use the system-configured float precision 2026-01-05 16:44:06 +05:30
ljain112
86b0f67dbc fix(tds): correct tax logic for customer 2025-12-31 14:26:22 +05:30
Navin-S-R
4adeaedfde test: validate asset split for auto created asset from purchase voucher 2025-12-30 16:29:46 +05:30
Navin-S-R
23b094f151 fix(asset): handle same asset being sold in multiple line items in sales invoice 2025-12-30 14:47:28 +05:30
Navin-S-R
e7e6567792 fix(asset): skip purchase document validation while splitting existing asset 2025-12-30 12:09:37 +05:30
Navin-S-R
9eeccb765d test: validate asset partial sales 2025-12-29 22:14:26 +05:30
Navin-S-R
a88fe2ecab fix: refactor older testcases 2025-12-29 15:53:31 +05:30
Navin-S-R
9a2710b9d7 fix(asset): handle partial asset sales by splitting remaining quantity 2025-12-29 15:40:46 +05:30
l0gesh29
50f73a5072 fix: handle return cancellation 2025-12-24 22:09:03 +05:30
l0gesh29
ae594e81f9 test: add test for partial billing and return 2025-12-24 22:08:28 +05:30
l0gesh29
57d34ab146 fix: include total hours validation in depends on 2025-12-24 18:35:48 +05:30
l0gesh29
ff0b37055b feat: add list_view status for partial billing 2025-12-23 20:14:45 +05:30
l0gesh29
c87b5d3132 feat(timesheet): handle partial billing in sales invoice 2025-12-23 20:13:54 +05:30
l0gesh29
38a4642479 feat: modify field properties 2025-12-23 20:10:38 +05:30
357 changed files with 10387 additions and 3669 deletions

View File

@@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
branch: ["develop"]
branch: ["develop", "version-16-hotfix"]
permissions:
contents: write
@@ -30,6 +30,11 @@ jobs:
with:
python-version: "3.14"
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
- name: Run script to update POT file
run: |
bash ${GITHUB_WORKSPACE}/.github/helper/update_pot_file.sh

View File

@@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
matrix:
version: ["14", "15"]
version: ["14", "15", "16"]
steps:
- uses: octokit/request-action@v2.x

View File

@@ -113,8 +113,8 @@ jobs:
jq 'del(.install_apps)' ~/frappe-bench/sites/test_site/site_config.json > tmp.json
mv tmp.json ~/frappe-bench/sites/test_site/site_config.json
wget https://erpnext.com/files/v13-erpnext.sql.gz
bench --site test_site --force restore ~/frappe-bench/v13-erpnext.sql.gz
wget https://frappe.io/files/erpnext-v14.sql.gz
bench --site test_site --force restore ~/frappe-bench/erpnext-v14.sql.gz
git -C "apps/frappe" remote set-url upstream https://github.com/frappe/frappe.git
git -C "apps/erpnext" remote set-url upstream https://github.com/frappe/erpnext.git
@@ -142,8 +142,8 @@ jobs:
bench --site test_site migrate
}
update_to_version 14 3.11
update_to_version 15 3.13
update_to_version 16 3.14
echo "Updating to latest version"
git -C "apps/frappe" fetch --depth 1 upstream "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"

View File

@@ -50,13 +50,13 @@ pull_request_rules:
- version-15-hotfix
assignees:
- "{{ author }}"
- name: backport to version-16-beta
- name: backport to version-16-hotfix
conditions:
- label="backport version-16-beta"
- label="backport version-16-hotfix"
actions:
backport:
branches:
- version-16-beta
- version-16-hotfix
assignees:
- "{{ author }}"
- name: Automatic merge on CI success and review

View File

@@ -6,7 +6,7 @@ import frappe
from frappe.model.document import Document
from frappe.utils.user import is_website_user
__version__ = "16.0.0-dev"
__version__ = "17.0.0-dev"
def get_default_company(user=None):

View File

@@ -7,7 +7,6 @@ from frappe.utils import (
cint,
date_diff,
flt,
formatdate,
get_first_day,
get_last_day,
get_link_to_form,

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -3,7 +3,7 @@
import frappe
from frappe import _, scrub
from frappe import _
from frappe.model.document import Document

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -281,7 +281,7 @@
},
{
"default": "0",
"description": "Learn about <a href=\"https://docs.erpnext.com/docs/v13/user/manual/en/accounts/articles/common_party_accounting#:~:text=Common%20Party%20Accounting%20in%20ERPNext,Invoice%20against%20a%20primary%20Supplier.\">Common Party</a>",
"description": "Learn about <a href=\"https://docs.frappe.io/erpnext/user/manual/en/common_party_accounting\">Common Party</a>",
"fieldname": "enable_common_party_accounting",
"fieldtype": "Check",
"label": "Enable Common Party Accounting"

View File

@@ -1,5 +1,3 @@
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -42,8 +42,4 @@ frappe.ui.form.on("Bank Account", {
});
}
},
is_company_account: function (frm) {
frm.set_df_property("account", "reqd", frm.doc.is_company_account);
},
});

View File

@@ -52,6 +52,7 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company Account",
"mandatory_depends_on": "is_company_account",
"options": "Account"
},
{
@@ -98,6 +99,7 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Company",
"mandatory_depends_on": "is_company_account",
"options": "Company"
},
{
@@ -252,7 +254,7 @@
"link_fieldname": "default_bank_account"
}
],
"modified": "2025-08-29 12:32:01.081687",
"modified": "2026-01-20 00:46:16.633364",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Account",

View File

@@ -51,25 +51,29 @@ class BankAccount(Document):
delete_contact_and_address("Bank Account", self.name)
def validate(self):
self.validate_company()
self.validate_account()
self.validate_is_company_account()
self.update_default_bank_account()
def validate_account(self):
if self.account:
if accounts := frappe.db.get_all(
"Bank Account", filters={"account": self.account, "name": ["!=", self.name]}, as_list=1
):
frappe.throw(
_("'{0}' account is already used by {1}. Use another account.").format(
frappe.bold(self.account),
frappe.bold(comma_and([get_link_to_form(self.doctype, x[0]) for x in accounts])),
)
)
def validate_is_company_account(self):
if self.is_company_account:
if not self.company:
frappe.throw(_("Company is mandatory for company account"))
def validate_company(self):
if self.is_company_account and not self.company:
frappe.throw(_("Company is mandatory for company account"))
if not self.account:
frappe.throw(_("Company Account is mandatory"))
self.validate_account()
def validate_account(self):
if accounts := frappe.db.get_all(
"Bank Account", filters={"account": self.account, "name": ["!=", self.name]}, as_list=1
):
frappe.throw(
_("'{0}' account is already used by {1}. Use another account.").format(
frappe.bold(self.account),
frappe.bold(comma_and([get_link_to_form(self.doctype, x[0]) for x in accounts])),
)
)
def update_default_bank_account(self):
if self.is_default and not self.disabled:

View File

@@ -1,9 +1,6 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe import ValidationError
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -6,7 +6,7 @@ import frappe
from frappe import _, msgprint
from frappe.model.document import Document
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import cint, flt, fmt_money, get_link_to_form, getdate
from frappe.utils import cint, flt, fmt_money, getdate
from pypika import Order
import erpnext

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -14,7 +14,6 @@ import openpyxl
from frappe import _
from frappe.core.doctype.data_import.data_import import DataImport
from frappe.core.doctype.data_import.importer import Importer, ImportFile
from frappe.query_builder.functions import Count
from frappe.utils.background_jobs import enqueue
from frappe.utils.file_manager import get_file, save_file
from frappe.utils.xlsxutils import ILLEGAL_CHARACTERS_RE, handle_html

View File

@@ -2,14 +2,12 @@
# For license information, please see license.txt
from datetime import date
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.query_builder.functions import Sum
from frappe.utils import add_months, flt, fmt_money, get_last_day, getdate, month_diff
from frappe.utils.data import get_first_day, nowdate
from frappe.utils import add_months, flt, fmt_money, get_last_day, getdate
from frappe.utils.data import get_first_day
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,

View File

@@ -1,10 +1,8 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.client import submit
from frappe.utils import add_days, flt, get_first_day, get_last_day, getdate, now_datetime, nowdate
from frappe.utils import flt, now_datetime, nowdate
from erpnext.accounts.doctype.budget.budget import (
BudgetError,

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.query_builder.functions import Sum

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -5,7 +5,6 @@ import os
import shutil
import frappe
from frappe import _
from frappe.model.document import Document
from erpnext.accounts.doctype.account_category.account_category import import_account_categories

View File

@@ -1,18 +1,15 @@
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import ast
import json
import re
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from enum import Enum
from typing import Any, ClassVar
from typing import Any
import frappe
from frappe import _
from frappe.database.operator_map import OPERATOR_MAP
from frappe.database.query import SQLFunctionParser
@dataclass

View File

@@ -5,13 +5,9 @@ import frappe
from frappe.utils import flt
from erpnext.accounts.doctype.financial_report_template.financial_report_engine import (
AccountData,
DataCollector,
DependencyResolver,
FilterExpressionParser,
FinancialQueryBuilder,
FormulaCalculator,
PeriodValue,
)
from erpnext.accounts.doctype.financial_report_template.test_financial_report_template import (
FinancialReportTemplateTestCase,

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import unittest
import frappe
from frappe.model.naming import parse_naming_series

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -184,6 +184,9 @@ class JournalEntry(AccountsController):
else:
return self._submit()
def before_cancel(self):
self.has_asset_adjustment_entry()
def cancel(self):
if len(self.accounts) > 100:
queue_submission(self, "_cancel")
@@ -554,12 +557,27 @@ class JournalEntry(AccountsController):
)
frappe.db.set_value("Journal Entry", self.name, "inter_company_journal_entry_reference", "")
def unlink_asset_adjustment_entry(self):
frappe.db.sql(
""" update `tabAsset Value Adjustment`
set journal_entry = null where journal_entry = %s""",
self.name,
def has_asset_adjustment_entry(self):
if self.flags.get("via_asset_value_adjustment"):
return
asset_value_adjustment = frappe.db.get_value(
"Asset Value Adjustment", {"docstatus": 1, "journal_entry": self.name}, "name"
)
if asset_value_adjustment:
frappe.throw(
_(
"Cannot cancel this document as it is linked with the submitted Asset Value Adjustment <b>{0}</b>. Please cancel the Asset Value Adjustment to continue."
).format(frappe.utils.get_link_to_form("Asset Value Adjustment", asset_value_adjustment))
)
def unlink_asset_adjustment_entry(self):
AssetValueAdjustment = frappe.qb.DocType("Asset Value Adjustment")
(
frappe.qb.update(AssetValueAdjustment)
.set(AssetValueAdjustment.journal_entry, None)
.where(AssetValueAdjustment.journal_entry == self.name)
).run()
def validate_party(self):
for d in self.get("accounts"):

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,8 +1,6 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -12,7 +12,6 @@ from frappe.query_builder import Tuple
from frappe.query_builder.functions import Count
from frappe.utils import cint, comma_or, flt, getdate, nowdate
from frappe.utils.data import comma_and, fmt_money, get_link_to_form
from pypika import Case
from pypika.functions import Coalesce, Sum
import erpnext

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -2,7 +2,6 @@
# See license.txt
import re
import unittest
from unittest.mock import patch
import frappe

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -6,7 +6,6 @@ import copy
import frappe
from frappe import _
from frappe.query_builder.functions import Sum
from frappe.utils import add_days, flt, formatdate, getdate
from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import copy
import unittest
import frappe
from frappe import _

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import json
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.core.doctype.user_permission.test_user_permission import create_user

View File

@@ -3,7 +3,7 @@
import frappe
from frappe import _, msgprint, scrub, unscrub
from frappe import _, msgprint
from frappe.core.doctype.user_permission.user_permission import get_permitted_documents
from frappe.model.document import Document
from frappe.utils import get_link_to_form, now

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -2,8 +2,6 @@
# License: GNU General Public License v3. See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -6,7 +6,6 @@
import copy
import json
import math
import frappe
from frappe import _, bold

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -8,7 +8,7 @@ import frappe
from frappe import qb
from frappe.model.document import Document
from frappe.query_builder.functions import Count, Max, Min, Sum
from frappe.utils import add_days, flt, get_datetime
from frappe.utils import flt, get_datetime
from frappe.utils.scheduler import is_scheduler_inactive
from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (

View File

@@ -8,7 +8,7 @@ import frappe
from frappe import _
from frappe.desk.reportview import get_match_cond
from frappe.model.document import Document
from frappe.utils import add_days, add_months, add_to_date, format_date, getdate, today
from frappe.utils import add_days, add_months, format_date, getdate, today
from frappe.utils.jinja import validate_template
from frappe.utils.pdf import get_pdf
from frappe.www.printview import get_print_style

View File

@@ -5,7 +5,7 @@ import frappe
from frappe.model.document import Document
from frappe.utils import create_batch, getdate
from erpnext.accounts.doctype.subscription.subscription import DateTimeLikeObject, process_all
from erpnext.accounts.doctype.subscription.subscription import DateTimeLikeObject
class ProcessSubscription(Document):

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -9,8 +9,6 @@ from frappe.desk.form.linked_with import get_child_tables_of_doctypes
from frappe.model.document import Document
from frappe.utils.data import comma_and
from erpnext.stock import get_warehouse_account_map
class RepostAccountingLedger(Document):
# begin: auto-generated types

View File

@@ -115,18 +115,21 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
}
if (cint(doc.update_stock) != 1) {
// show Make Delivery Note button only if Sales Invoice is not created from Delivery Note
var from_delivery_note = false;
from_delivery_note = this.frm.doc.items.some(function (item) {
return item.delivery_note ? true : false;
});
if (!from_delivery_note && !is_delivered_by_supplier) {
this.frm.add_custom_button(
__("Delivery"),
this.frm.cscript["Make Delivery Note"],
__("Create")
if (!is_delivered_by_supplier) {
const should_create_delivery_note = doc.items.some(
(item) =>
item.qty - item.delivered_qty > 0 &&
!item.scio_detail &&
!item.dn_detail &&
!item.delivered_by_supplier
);
if (should_create_delivery_note) {
this.frm.add_custom_button(
__("Delivery Note"),
this.frm.cscript["Make Delivery Note"],
__("Create")
);
}
}
}

View File

@@ -778,8 +778,7 @@
},
{
"collapsible": 1,
"collapsible_depends_on": "eval:doc.total_billing_amount > 0",
"depends_on": "eval:!doc.is_return",
"collapsible_depends_on": "eval:doc.total_billing_amount > 0 || doc.total_billing_hours > 0",
"fieldname": "time_sheet_list",
"fieldtype": "Section Break",
"hide_border": 1,
@@ -793,7 +792,6 @@
"hide_days": 1,
"hide_seconds": 1,
"label": "Time Sheets",
"no_copy": 1,
"options": "Sales Invoice Timesheet",
"print_hide": 1
},
@@ -2092,7 +2090,7 @@
"fieldtype": "Column Break"
},
{
"depends_on": "eval:(!doc.is_return && doc.total_billing_amount > 0)",
"depends_on": "eval:doc.total_billing_amount > 0 || doc.total_billing_hours > 0",
"fieldname": "section_break_104",
"fieldtype": "Section Break"
},
@@ -2306,7 +2304,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2025-10-09 14:48:59.472826",
"modified": "2025-12-24 18:29:50.242618",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -33,6 +33,7 @@ from erpnext.accounts.utils import (
get_account_currency,
update_voucher_outstanding,
)
from erpnext.assets.doctype.asset.asset import split_asset
from erpnext.assets.doctype.asset.depreciation import (
depreciate_asset,
get_gl_entries_on_asset_disposal,
@@ -352,10 +353,22 @@ class SalesInvoice(SellingController):
self.is_opening = "No"
self.set_against_income_account()
self.validate_time_sheets_are_submitted()
if self.is_return and not self.return_against and self.timesheets:
frappe.throw(_("Direct return is not allowed for Timesheet."))
if not self.is_return:
self.validate_time_sheets_are_submitted()
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount")
if self.is_return:
self.timesheets = []
if self.is_return and self.return_against:
for row in self.timesheets:
if row.billing_hours:
row.billing_hours = -abs(row.billing_hours)
if row.billing_amount:
row.billing_amount = -abs(row.billing_amount)
self.update_packing_list()
self.set_billing_hours_and_amount()
self.update_timesheet_billing_for_project()
@@ -468,6 +481,8 @@ class SalesInvoice(SellingController):
self.update_stock_reservation_entries()
self.update_stock_ledger()
self.split_asset_based_on_sale_qty()
self.process_asset_depreciation()
# this sequence because outstanding may get -ve
@@ -484,7 +499,7 @@ class SalesInvoice(SellingController):
if cint(self.is_pos) != 1 and not self.is_return:
self.update_against_document_in_jv()
self.update_time_sheet(self.name)
self.update_time_sheet(None if (self.is_return and self.return_against) else self.name)
if frappe.get_single_value("Selling Settings", "sales_update_frequency") == "Each Transaction":
update_company_current_month_sales(self.company)
@@ -564,7 +579,7 @@ class SalesInvoice(SellingController):
self.check_if_consolidated_invoice()
super().before_cancel()
self.update_time_sheet(None)
self.update_time_sheet(self.return_against if (self.is_return and self.return_against) else None)
def on_cancel(self):
check_if_return_invoice_linked_with_payment_entry(self)
@@ -804,8 +819,20 @@ class SalesInvoice(SellingController):
for data in timesheet.time_logs:
if (
(self.project and args.timesheet_detail == data.name)
or (not self.project and not data.sales_invoice)
or (not sales_invoice and data.sales_invoice == self.name)
or (not self.project and not data.sales_invoice and args.timesheet_detail == data.name)
or (
not sales_invoice
and data.sales_invoice == self.name
and args.timesheet_detail == data.name
)
or (
self.is_return
and self.return_against
and data.sales_invoice
and data.sales_invoice == self.return_against
and not sales_invoice
and args.timesheet_detail == data.name
)
):
data.sales_invoice = sales_invoice
@@ -845,11 +872,26 @@ class SalesInvoice(SellingController):
payment.account = get_bank_cash_account(payment.mode_of_payment, self.company).get("account")
def validate_time_sheets_are_submitted(self):
# Note: This validation is skipped for return invoices
# to allow returns to reference already-billed timesheet details
for data in self.timesheets:
# Handle invoice duplication
if data.time_sheet and data.timesheet_detail:
if sales_invoice := frappe.db.get_value(
"Timesheet Detail", data.timesheet_detail, "sales_invoice"
):
frappe.throw(
_("Row {0}: Sales Invoice {1} is already created for {2}").format(
data.idx, frappe.bold(sales_invoice), frappe.bold(data.time_sheet)
)
)
if data.time_sheet:
status = frappe.db.get_value("Timesheet", data.time_sheet, "status")
if status not in ["Submitted", "Payslip"]:
frappe.throw(_("Timesheet {0} is already completed or cancelled").format(data.time_sheet))
if status not in ["Submitted", "Payslip", "Partially Billed"]:
frappe.throw(
_("Timesheet {0} cannot be invoiced in its current state").format(data.time_sheet)
)
def set_pos_fields(self, for_validate=False):
"""Set retail related fields from POS Profiles"""
@@ -1283,7 +1325,12 @@ class SalesInvoice(SellingController):
timesheet.billing_amount = ts_doc.total_billable_amount
def update_timesheet_billing_for_project(self):
if not self.timesheets and self.project and self.is_auto_fetch_timesheet_enabled():
if (
not self.is_return
and not self.timesheets
and self.project
and self.is_auto_fetch_timesheet_enabled()
):
self.add_timesheet_data()
else:
self.calculate_billing_amount_for_timesheet()
@@ -1358,6 +1405,51 @@ class SalesInvoice(SellingController):
):
throw(_("Delivery Note {0} is not submitted").format(d.delivery_note))
def split_asset_based_on_sale_qty(self):
asset_qty_map = self.get_asset_qty()
for asset, qty in asset_qty_map.items():
if qty["actual_qty"] < qty["sale_qty"]:
frappe.throw(
_(
"Sell quantity cannot exceed the asset quantity. Asset {0} has only {1} item(s)."
).format(asset, qty["actual_qty"])
)
remaining_qty = qty["actual_qty"] - qty["sale_qty"]
if remaining_qty > 0:
split_asset(asset, remaining_qty)
def get_asset_qty(self):
asset_qty_map = {}
assets = {row.asset for row in self.items if row.is_fixed_asset and row.asset}
if not assets or self.is_return:
return asset_qty_map
asset_actual_qty = dict(
frappe.db.get_all(
"Asset",
{"name": ["in", list(assets)]},
["name", "asset_quantity"],
as_list=True,
)
)
for row in self.items:
if row.is_fixed_asset and row.asset:
actual_qty = asset_actual_qty.get(row.asset)
if row.asset in asset_qty_map.keys():
asset_qty_map[row.asset]["sale_qty"] += flt(row.qty)
else:
asset_qty_map.setdefault(
row.asset,
{
"sale_qty": flt(row.qty),
"actual_qty": flt(actual_qty),
},
)
return asset_qty_map
def process_asset_depreciation(self):
if (self.is_return and self.docstatus == 2) or (not self.is_return and self.docstatus == 1):
self.depreciate_asset_on_sale()
@@ -2378,7 +2470,10 @@ def make_delivery_note(source_name, target_doc=None):
"cost_center": "cost_center",
},
"postprocess": update_item,
"condition": lambda doc: doc.delivered_by_supplier != 1 and not doc.scio_detail,
"condition": lambda doc: doc.delivered_by_supplier != 1
and not doc.scio_detail
and not doc.dn_detail
and doc.qty - doc.delivered_qty > 0,
},
"Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "reset_value": True},
"Sales Team": {

View File

@@ -2951,6 +2951,60 @@ class TestSalesInvoice(ERPNextTestSuite):
self.assertEqual(sales_invoice.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC")
self.assertEqual(sales_invoice.items[0].item_tax_rate, item_tax_map)
def test_item_tax_template_change_with_grand_total_discount(self):
"""
Test that when item tax template changes due to discount on Grand Total,
the tax calculations are consistent.
"""
item = create_item("Test Item With Multiple Tax Templates")
item.set("taxes", [])
item.append(
"taxes",
{
"item_tax_template": "_Test Account Excise Duty @ 10 - _TC",
"minimum_net_rate": 0,
"maximum_net_rate": 500,
},
)
item.append(
"taxes",
{
"item_tax_template": "_Test Account Excise Duty @ 12 - _TC",
"minimum_net_rate": 501,
"maximum_net_rate": 1000,
},
)
item.save()
si = create_sales_invoice(item=item.name, rate=700, do_not_save=True)
si.append(
"taxes",
{
"charge_type": "On Net Total",
"account_head": "_Test Account Excise Duty - _TC",
"cost_center": "_Test Cost Center - _TC",
"description": "Excise Duty",
"rate": 0,
},
)
si.insert()
self.assertEqual(si.items[0].item_tax_template, "_Test Account Excise Duty @ 12 - _TC")
si.apply_discount_on = "Grand Total"
si.discount_amount = 300
si.save()
# Verify template changed to 10%
self.assertEqual(si.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC")
self.assertEqual(si.taxes[0].tax_amount, 70) # 10% of 700
self.assertEqual(si.grand_total, 470) # 700 + 70 - 300
si.submit()
@IntegrationTestCase.change_settings("Selling Settings", {"enable_discount_accounting": 1})
def test_sales_invoice_with_discount_accounting_enabled(self):
discount_account = create_account(
@@ -4467,8 +4521,6 @@ class TestSalesInvoice(ERPNextTestSuite):
self.assertRaises(frappe.ValidationError, pos.insert)
def test_stand_alone_credit_note_valuation(self):
from erpnext.stock.doctype.item.test_item import make_item
item_code = "_Test Item for Credit Note Valuation"
make_item_for_si(
item_code,
@@ -4506,8 +4558,6 @@ class TestSalesInvoice(ERPNextTestSuite):
self.assertEqual(stock_ledger_entry.stock_value_difference, 2400.0)
def test_stand_alone_credit_note_zero_valuation(self):
from erpnext.stock.doctype.item.test_item import make_item
item_code = "_Test Item for Credit Note Zero Valuation"
make_item_for_si(
item_code,
@@ -4599,8 +4649,6 @@ class TestSalesInvoice(ERPNextTestSuite):
self.assertEqual(q[0][0], 1)
def test_non_batchwise_valuation_for_moving_average(self):
from erpnext.stock.doctype.item.test_item import make_item
item_code = "_Test Item for Non Batchwise Valuation"
make_item_for_si(
item_code,

View File

@@ -5,10 +5,8 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils.data import cint
from erpnext.assets.doctype.asset.depreciation import get_disposal_account_and_cost_center
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
class SalesInvoiceItem(Document):

View File

@@ -52,7 +52,6 @@
"fieldtype": "Data",
"hidden": 1,
"label": "Timesheet Detail",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
},
@@ -117,15 +116,16 @@
],
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:36.562795",
"modified": "2025-12-23 13:54:17.677187",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Timesheet",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -1,8 +1,6 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -8,7 +8,6 @@ from frappe.utils.data import (
add_days,
add_months,
add_to_date,
add_years,
cint,
date_diff,
flt,

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
from frappe.tests import IntegrationTestCase

View File

@@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests import IntegrationTestCase

View File

@@ -415,7 +415,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 500,
"description": "Test",
"add_deduct_tax": "Add",
},
)
pi.save()
@@ -506,7 +505,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 200,
"description": "Test Gross Tax",
"add_deduct_tax": "Add",
},
)
si.save()
@@ -541,10 +539,10 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 400,
"description": "Test Gross Tax",
"add_deduct_tax": "Add",
},
)
si.save()
si.reload()
si.submit()
invoices.append(si)
# For amount before threshold (first 8000 + VAT): TCS entry with amount zero
@@ -594,7 +592,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 500,
"description": "VAT added to test TDS calculation on gross amount",
"add_deduct_tax": "Add",
},
)
si.save()
@@ -1024,7 +1021,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 1000,
"description": "VAT added to test TDS calculation on gross amount",
"add_deduct_tax": "Add",
},
)
pi.save()
@@ -1162,7 +1158,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 8000,
"description": "Test",
"add_deduct_tax": "Add",
},
)

View File

@@ -708,6 +708,10 @@ class TaxWithholdingController:
existing_taxes = {row.account_head: row for row in self.doc.taxes if row.is_tax_withholding_account}
precision = self.doc.precision("tax_amount", "taxes")
conversion_rate = self.get_conversion_rate()
add_deduct_tax = "Deduct"
if self.party_type == "Customer":
add_deduct_tax = "Add"
for account_head, base_amount in account_amount_map.items():
tax_amount = flt(base_amount / conversion_rate, precision)
@@ -724,6 +728,7 @@ class TaxWithholdingController:
tax_row = self._create_tax_row(account_head, tax_amount)
for_update = False
tax_row.add_deduct_tax = add_deduct_tax
# Set item-wise tax breakup for this tax row
self._set_item_wise_tax_for_tds(
tax_row, account_head, category_withholding_map, for_update=for_update
@@ -743,7 +748,6 @@ class TaxWithholdingController:
"account_head": account_head,
"description": account_head,
"cost_center": cost_center,
"add_deduct_tax": "Deduct",
"tax_amount": tax_amount,
"dont_recompute_tax": 1,
},
@@ -807,12 +811,14 @@ class TaxWithholdingController:
else:
item_tax_amount = 0
multiplier = -1 if tax_row.add_deduct_tax == "Deduct" else 1
self.doc._item_wise_tax_details.append(
frappe._dict(
item=item,
tax=tax_row,
rate=category.tax_rate,
amount=item_tax_amount * -1, # Negative because it's a deduction
amount=item_tax_amount * multiplier,
taxable_amount=item_base_taxable,
)
)

View File

@@ -9,7 +9,6 @@ from frappe import _
from frappe.model.meta import get_field_precision
from frappe.utils import cint, flt, formatdate, get_link_to_form, getdate, now
from frappe.utils.caching import request_cache
from frappe.utils.dashboard import cache_source
import erpnext
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (

View File

@@ -7,18 +7,16 @@ from frappe import _, msgprint, qb, scrub
from frappe.contacts.doctype.address.address import get_company_address, get_default_address
from frappe.core.doctype.user_permission.user_permission import get_permitted_documents
from frappe.model.utils import get_fetch_values
from frappe.query_builder.functions import Abs, Count, Date, Sum
from frappe.query_builder.functions import Abs, Date, Sum
from frappe.utils import (
add_days,
add_months,
add_years,
cint,
cstr,
date_diff,
flt,
formatdate,
get_last_day,
get_timestamp,
getdate,
nowdate,
)

View File

@@ -1,5 +1,3 @@
import unittest
import frappe
from frappe.tests import IntegrationTestCase
from frappe.utils import getdate

View File

@@ -151,6 +151,8 @@ frappe.query_reports["Accounts Payable"] = {
fieldtype: "Check",
},
],
collapsible_filters: true,
separate_check_filters: true,
formatter: function (value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);

View File

@@ -108,6 +108,8 @@ frappe.query_reports["Accounts Payable Summary"] = {
fieldtype: "Check",
},
],
collapsible_filters: true,
separate_check_filters: true,
onload: function (report) {
report.page.add_inner_button(__("Accounts Payable"), function () {

View File

@@ -178,6 +178,8 @@ frappe.query_reports["Accounts Receivable"] = {
fieldtype: "Check",
},
],
collapsible_filters: true,
separate_check_filters: true,
formatter: function (value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);

View File

@@ -877,11 +877,15 @@ class ReceivablePayableReport:
else:
entry_date = row.posting_date
row.range0 = 0.0
self.get_ageing_data(entry_date, row)
# ageing buckets should not have amounts if due date is not reached
if getdate(entry_date) > getdate(self.age_as_on):
row.range0 = row.outstanding
[setattr(row, f"range{i}", 0.0) for i in self.range_numbers]
row.total_due = 0
return
row.total_due = sum(row[f"range{i}"] for i in self.range_numbers)
@@ -1281,6 +1285,8 @@ class ReceivablePayableReport:
ranges = [*self.ranges, _("Above")]
prev_range_value = 0
self.add_column(label=_("<0"), fieldname="range0", fieldtype="Currency")
self.ageing_column_labels.append(_("<0"))
for idx, curr_range_value in enumerate(ranges):
label = f"{prev_range_value}-{curr_range_value}"
self.add_column(label=label, fieldname="range" + str(idx + 1))
@@ -1296,7 +1302,9 @@ class ReceivablePayableReport:
for row in self.data:
row = frappe._dict(row)
if not cint(row.bold):
values = [flt(row.get(f"range{i}", None), precision) for i in self.range_numbers]
values = [flt(row.get("range0", 0), precision)] + [
flt(row.get(f"range{i}", 0), precision) for i in self.range_numbers
]
rows.append({"values": values})
self.chart = {

Some files were not shown because too many files have changed in this diff Show More