Compare commits

..

592 Commits

Author SHA1 Message Date
Frappe PR Bot
3035dcab07 chore(release): Bumped to Version 15.16.2
## [15.16.2](https://github.com/frappe/erpnext/compare/v15.16.1...v15.16.2) (2024-03-07)

### Bug Fixes

* use serial/batch field for rejected items (backport [#40327](https://github.com/frappe/erpnext/issues/40327)) (backport [#40329](https://github.com/frappe/erpnext/issues/40329)) ([#40332](https://github.com/frappe/erpnext/issues/40332)) ([5af335d](5af335dc33))
2024-03-07 09:25:12 +00:00
mergify[bot]
5af335dc33 fix: use serial/batch field for rejected items (backport #40327) (backport #40329) (#40332)
fix: use serial/batch field for rejected items (backport #40327) (#40329)

fix: use serial/batch field for rejected items (#40327)

(cherry picked from commit 01856a6e9d)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 7ca72423b9)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-03-07 14:53:29 +05:30
Frappe PR Bot
643189a0ce chore(release): Bumped to Version 15.16.1
## [15.16.1](https://github.com/frappe/erpnext/compare/v15.16.0...v15.16.1) (2024-03-06)

### Bug Fixes

* batch no not copied while making Material Consumption entry (backport [#40290](https://github.com/frappe/erpnext/issues/40290)) (backport [#40300](https://github.com/frappe/erpnext/issues/40300)) ([#40303](https://github.com/frappe/erpnext/issues/40303)) ([f21918d](f21918d06c))
* not able to cancel purchase receipt for old subcontracting flow (backport [#40298](https://github.com/frappe/erpnext/issues/40298)) (backport [#40302](https://github.com/frappe/erpnext/issues/40302)) ([#40305](https://github.com/frappe/erpnext/issues/40305)) ([3814c5a](3814c5a54a))
* stock ledger balance qty for the batch (backport [#40274](https://github.com/frappe/erpnext/issues/40274)) (backport [#40301](https://github.com/frappe/erpnext/issues/40301)) ([#40304](https://github.com/frappe/erpnext/issues/40304)) ([539eb79](539eb794c0))
* use serial batch fields for subcontracting receipt (backport [#40311](https://github.com/frappe/erpnext/issues/40311)) (backport [#40315](https://github.com/frappe/erpnext/issues/40315)) ([#40316](https://github.com/frappe/erpnext/issues/40316)) ([e357497](e357497bcb))
2024-03-06 14:48:42 +00:00
mergify[bot]
e357497bcb fix: use serial batch fields for subcontracting receipt (backport #40311) (backport #40315) (#40316)
fix: use serial batch fields for subcontracting receipt (backport #40311) (#40315)

fix: use serial batch fields for subcontracting receipt (#40311)

(cherry picked from commit cef6291311)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 4b15c00b11)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-03-06 20:17:30 +05:30
mergify[bot]
f21918d06c fix: batch no not copied while making Material Consumption entry (backport #40290) (backport #40300) (#40303)
fix: batch no not copied while making Material Consumption entry (backport #40290) (#40300)

fix: batch no not copied while making Material Consumption entry (#40290)

(cherry picked from commit 1eaa386657)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 6d1c144a66)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-03-06 20:17:20 +05:30
mergify[bot]
539eb794c0 fix: stock ledger balance qty for the batch (backport #40274) (backport #40301) (#40304)
fix: stock ledger balance qty for the batch (backport #40274) (#40301)

fix: stock ledger balance qty for the batch (#40274)

(cherry picked from commit e178ffc3c1)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 62aefcef04)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-03-06 20:17:09 +05:30
mergify[bot]
3814c5a54a fix: not able to cancel purchase receipt for old subcontracting flow (backport #40298) (backport #40302) (#40305)
fix: not able to cancel purchase receipt for old subcontracting flow (backport #40298) (#40302)

fix: not able to cancel purchase receipt for old subcontracting flow (#40298)

(cherry picked from commit 48da952fd7)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit e0e80f7eed)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-03-06 20:17:01 +05:30
Frappe PR Bot
eb9b2e896e chore(release): Bumped to Version 15.16.0
# [15.16.0](https://github.com/frappe/erpnext/compare/v15.15.0...v15.16.0) (2024-03-06)

### Bug Fixes

* allow editable accounting dimensions for repostable doctypes ([cd24a2a](cd24a2a05d))
* allow gain/loss for Journals against Journals ([d8cf6ba](d8cf6ba38d))
* check child rows before update ([e20c1ac](e20c1acb6e))
* disable editable account heads ([c55c0f7](c55c0f7173))
* do not allow to cancel incomplete reposting (backport [#40224](https://github.com/frappe/erpnext/issues/40224)) ([#40230](https://github.com/frappe/erpnext/issues/40230)) ([63209f4](63209f4eac))
* don't override reference exchange rate ([4513d83](4513d83f22))
* handle partial invoice against provisional entry ([87596e6](87596e6e29))
* ignore self on GL account validation for Bank Account ([1947a67](1947a67f3d))
* include Debit To/Credit To account while fetching advance ([23d7a1f](23d7a1fc76))
* incorrect exchange rate if JE has multi parties ([b785901](b785901efa))
* incorrect TCS on customer and suppliers with same name ([d74647d](d74647d5a5))
* make use of 'flt' to prevent really low precision exc gain/loss ([9057bff](9057bff786))
* make warning for previously existing SO an alert ([4f9b194](4f9b194fe9))
* over billing qty along with rate ([00d410c](00d410cc1d))
* **Project:** filter department by company ([13e3343](13e334398e))
* provisional reverse entry amount ([0182b95](0182b95230))
* rate change on changing of the qty (backport [#40241](https://github.com/frappe/erpnext/issues/40241)) ([#40243](https://github.com/frappe/erpnext/issues/40243)) ([1d42171](1d421713be))
* remove free item row only if pricing rule matches ([6352bfe](6352bfe34e))
* report path from the Item and Putaway Rule list (backport [#40190](https://github.com/frappe/erpnext/issues/40190)) ([#40266](https://github.com/frappe/erpnext/issues/40266)) ([c7b96df](c7b96df69c))
* serial no valuation rate (backport [#40221](https://github.com/frappe/erpnext/issues/40221)) ([#40223](https://github.com/frappe/erpnext/issues/40223)) ([85ae9ee](85ae9eee25))
* **setup:** avoid duplicate entry for Analytics role (backport [#40183](https://github.com/frappe/erpnext/issues/40183)) ([#40185](https://github.com/frappe/erpnext/issues/40185)) ([9cb8d33](9cb8d33923))
* test for repost accounting in JVs ([1634955](16349553c7))
* test for reposting pi ([6230bbc](6230bbc77d))
* uom wise price in sales or purchase transaction (backport [#40216](https://github.com/frappe/erpnext/issues/40216)) ([#40225](https://github.com/frappe/erpnext/issues/40225)) ([b398cc6](b398cc6579))

### Features

* add company filter to child table field ([0ede99b](0ede99b3cb))
* add patch for making repostable dimension fields editable ([4b57126](4b5712688a))
* allow on submit for selected fields ([6c3b5bb](6c3b5bb402))
* repost ledger button in JV ([e5eeb21](e5eeb216e8))
* update after submit in JV ([cdab3fa](cdab3fa970))
* validate before allowing repost ([8585cfc](8585cfc533))

### Performance Improvements

* serial and batch bundle valuation (reposting) (backport [#40255](https://github.com/frappe/erpnext/issues/40255)) ([#40262](https://github.com/frappe/erpnext/issues/40262)) ([93f3af7](93f3af7dba))
2024-03-06 03:31:25 +00:00
Deepesh Garg
5e89676d05 Merge pull request #40280 from frappe/version-15-hotfix
chore: release v15
2024-03-06 09:00:14 +05:30
ruthra kumar
50e49bef85 Merge pull request #40284 from frappe/mergify/bp/version-15-hotfix/pr-40278
fix: incorrect TCS on customer and suppliers with same name (backport #40278)
2024-03-05 15:48:25 +05:30
ruthra kumar
d74647d5a5 fix: incorrect TCS on customer and suppliers with same name
(cherry picked from commit 9904a9868c)
2024-03-05 09:54:46 +00:00
mergify[bot]
ee119f30fb chore: fixed fetch from (backport #40270) (#40275)
chore: fixed fetch from (#40270)

(cherry picked from commit 34051bc04f)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-03-05 14:32:36 +05:30
mergify[bot]
c7b96df69c fix: report path from the Item and Putaway Rule list (backport #40190) (#40266)
fix: report path from the Item and Putaway Rule list (#40190)

(cherry picked from commit 8e2f9787c1)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-03-04 20:03:42 +05:30
mergify[bot]
63209f4eac fix: do not allow to cancel incomplete reposting (backport #40224) (#40230)
* fix: do not allow to cancel incomplete reposting (#40224)

(cherry picked from commit 72ac56b6c4)

# Conflicts:
#	erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-03-04 13:14:21 +05:30
mergify[bot]
93f3af7dba perf: serial and batch bundle valuation (reposting) (backport #40255) (#40262)
* perf: serial and batch bundle valuation (reposting) (#40255)

perf: serial and batch bundle valuation
(cherry picked from commit 6379238893)

* chore: fix styles

* chore: fix linters

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-03-04 13:13:49 +05:30
Gursheen Kaur Anand
0b1417e891 Merge pull request #40256 from GursheenK/editable-journals-v15
feat: editable journals v15
2024-03-04 11:15:41 +05:30
Gursheen Anand
16349553c7 fix: test for repost accounting in JVs 2024-03-04 00:25:57 +05:30
Gursheen Anand
4b5712688a feat: add patch for making repostable dimension fields editable 2024-03-04 00:25:54 +05:30
Gursheen Anand
cd24a2a05d fix: allow editable accounting dimensions for repostable doctypes 2024-03-04 00:24:32 +05:30
Gursheen Anand
c55c0f7173 fix: disable editable account heads 2024-03-04 00:24:26 +05:30
Gursheen Anand
6230bbc77d fix: test for reposting pi 2024-03-04 00:18:09 +05:30
Gursheen Anand
e20c1acb6e fix: check child rows before update 2024-03-04 00:18:09 +05:30
Gursheen Anand
6173654093 chore: correct typo 2024-03-04 00:18:09 +05:30
Gursheen Anand
b0be08f05d test: reposting entries for JV 2024-03-04 00:18:09 +05:30
Gursheen Anand
7aeb53a806 refactor: use qb for JV tests 2024-03-04 00:18:09 +05:30
Gursheen Anand
e5eeb216e8 feat: repost ledger button in JV 2024-03-04 00:18:09 +05:30
Gursheen Anand
8585cfc533 feat: validate before allowing repost 2024-03-04 00:18:04 +05:30
Gursheen Anand
a512ec7af5 refactor: better abstraction for controller code 2024-03-04 00:16:39 +05:30
Gursheen Anand
cdab3fa970 feat: update after submit in JV 2024-03-04 00:16:32 +05:30
Gursheen Anand
6c3b5bb402 feat: allow on submit for selected fields 2024-03-04 00:14:28 +05:30
Gursheen Anand
db7348a1de refactor: remove controller logic for setting balances 2024-03-04 00:13:32 +05:30
Gursheen Anand
84672e2275 refactor: exclude balances while setting currency 2024-03-04 00:13:32 +05:30
Gursheen Anand
c68939a0e0 refactor: exclude balance while setting acc details 2024-03-04 00:13:32 +05:30
Gursheen Anand
0c234e5c1a refactor: remove balance formatter 2024-03-04 00:13:32 +05:30
Gursheen Anand
689f277d13 refactor: remove balance fields from jv account 2024-03-04 00:11:23 +05:30
Gursheen Kaur Anand
328728e3a4 Merge pull request #40252 from frappe/mergify/bp/version-15-hotfix/pr-40250
fix(minor): company filter in cost center allocation (backport #40250)
2024-03-03 18:24:27 +05:30
Gursheen Anand
0ede99b3cb feat: add company filter to child table field
(cherry picked from commit 51909077bd)
2024-03-03 12:45:39 +00:00
Gursheen Kaur Anand
d130aadcf3 Merge pull request #40205 from frappe/mergify/bp/version-15-hotfix/pr-39584
fix: use receipt amount for reverse provisional entry (backport #39584)
2024-03-03 17:55:31 +05:30
mergify[bot]
1d421713be fix: rate change on changing of the qty (backport #40241) (#40243)
fix: rate change on changing of the qty (#40241)

(cherry picked from commit e7d707797a)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-03-02 16:50:01 +05:30
ruthra kumar
0b091aaf14 Merge pull request #40239 from frappe/mergify/bp/version-15-hotfix/pr-40220
refactor: Gain/Loss Journal creation for Journals against Journals (backport #40220)
2024-03-02 15:57:18 +05:30
ruthra kumar
e5fdca7b05 test: gain/loss on Journals against Journals
(cherry picked from commit 8a5078b826)
2024-03-02 10:08:19 +00:00
ruthra kumar
d8cf6ba38d fix: allow gain/loss for Journals against Journals
(cherry picked from commit 5b67631d40)
2024-03-02 10:08:19 +00:00
ruthra kumar
9057bff786 fix: make use of 'flt' to prevent really low precision exc gain/loss
(cherry picked from commit 0aa72f841d)
2024-03-02 10:08:18 +00:00
ruthra kumar
014d21a050 Merge pull request #40233 from frappe/mergify/bp/version-15-hotfix/pr-40149
fix: incorrect exchange rate if JE has multi parties (backport #40149)
2024-03-02 14:35:25 +05:30
ruthra kumar
05e4d1c240 test: exchange rate fetch on JE with multiple forex parties
(cherry picked from commit ed95d41a51)
2024-03-02 08:22:47 +00:00
ruthra kumar
4513d83f22 fix: don't override reference exchange rate
(cherry picked from commit eaac02655b)
2024-03-02 08:22:47 +00:00
ruthra kumar
b785901efa fix: incorrect exchange rate if JE has multi parties
(cherry picked from commit 694c17487d)
2024-03-02 08:22:45 +00:00
mergify[bot]
b398cc6579 fix: uom wise price in sales or purchase transaction (backport #40216) (#40225)
fix: uom wise price in sales or purchase transaction (#40216)

fix: uom wise price
(cherry picked from commit 13b05aa7fb)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-03-02 13:00:52 +05:30
mergify[bot]
85ae9eee25 fix: serial no valuation rate (backport #40221) (#40223)
fix: serial no valuation rate (#40221)

(cherry picked from commit a5232d9c10)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-03-01 22:48:15 +05:30
ruthra kumar
70ab25a611 Merge pull request #40201 from frappe/mergify/bp/version-15-hotfix/pr-40197
fix: ignore self on GL account validation for Bank Account (backport #40197)
2024-03-01 09:45:39 +05:30
Raffael Meyer
0d8358bdd1 Merge pull request #40210 from frappe/mergify/bp/version-15-hotfix/pr-40203
fix(Project): filter department by company (backport #40203)
2024-02-29 23:34:38 +01:00
barredterra
13e334398e fix(Project): filter department by company
(cherry picked from commit 5e736f0d06)
2024-02-29 17:30:05 +00:00
Gursheen Anand
823abfd6e0 test: partial billing for provisional accounting
(cherry picked from commit c5770f2ecc)
2024-02-29 15:48:36 +00:00
Gursheen Anand
e55dc2a7c0 test: overbilling for provisional accounting
(cherry picked from commit ff3ca50a4b)
2024-02-29 15:48:36 +00:00
Gursheen Anand
00d410cc1d fix: over billing qty along with rate
(cherry picked from commit cc96d2b50c)
2024-02-29 15:48:36 +00:00
Gursheen Anand
87596e6e29 fix: handle partial invoice against provisional entry
(cherry picked from commit 2a46799188)
2024-02-29 15:48:36 +00:00
Gursheen Anand
0182b95230 fix: provisional reverse entry amount
(cherry picked from commit 3e59c66806)
2024-02-29 15:48:36 +00:00
ruthra kumar
1947a67f3d fix: ignore self on GL account validation for Bank Account
(cherry picked from commit 3c19186654)
2024-02-29 14:25:48 +00:00
ruthra kumar
8720115f01 Merge pull request #40199 from frappe/mergify/bp/version-15-hotfix/pr-40196
fix: include debit_to or credit_to account while fetching advance on Sales/Purchase Invoice (backport #40196)
2024-02-29 19:54:45 +05:30
ruthra kumar
a5b3c1e7cb test: advance pulling logic on Sales/Purchase Invoice
(cherry picked from commit 646e9ca0dd)
2024-02-29 12:22:48 +00:00
ruthra kumar
23d7a1fc76 fix: include Debit To/Credit To account while fetching advance
(cherry picked from commit 3327599c9d)
2024-02-29 12:22:48 +00:00
Gursheen Kaur Anand
c7ca929ddb Merge pull request #40189 from frappe/mergify/bp/version-15-hotfix/pr-40176
fix(minor): make warning for previously existing SO an alert (backport #40176)
2024-02-29 11:59:36 +05:30
Gursheen Anand
4f9b194fe9 fix: make warning for previously existing SO an alert
(cherry picked from commit 24dcd64c16)
2024-02-29 06:04:16 +00:00
Gursheen Kaur Anand
cda1c5ca10 Merge pull request #40182 from frappe/mergify/bp/version-15-hotfix/pr-40174
fix: promotional scheme remove free item if pricing rule matches (backport #40174)
2024-02-29 11:34:00 +05:30
mergify[bot]
9cb8d33923 fix(setup): avoid duplicate entry for Analytics role (backport #40183) (#40185)
fix(setup): avoid duplicate entry for Analytics role (#40183)

(cherry picked from commit 29f91a7919)

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2024-02-29 11:09:24 +05:30
Gursheen Anand
6352bfe34e fix: remove free item row only if pricing rule matches
(cherry picked from commit fea20db262)
2024-02-29 04:49:35 +00:00
Frappe PR Bot
23011df86b chore(release): Bumped to Version 15.15.0
# [15.15.0](https://github.com/frappe/erpnext/compare/v15.14.7...v15.15.0) (2024-02-28)

### Bug Fixes

* add flags for repost to ensure correct accounting from India Compliance App ([7d14ecf](7d14ecfcb8))
* amount label according to party type ([d541ba3](d541ba3e61))
* Cannot read properties of undefined (backport [#40081](https://github.com/frappe/erpnext/issues/40081)) ([#40083](https://github.com/frappe/erpnext/issues/40083)) ([53d943e](53d943ec70))
* capacity planning issue in the job card (backport [#40092](https://github.com/frappe/erpnext/issues/40092)) ([#40101](https://github.com/frappe/erpnext/issues/40101)) ([27703b5](27703b54bd))
* change label name ([824df72](824df72eeb))
* check for pricing rules on item ([32d9642](32d9642379))
* check_credit_limit on_update_after_submit of Sales Order ([83d7111](83d7111649))
* communication_date in party dashboards (backport [#40005](https://github.com/frappe/erpnext/issues/40005)) ([#40021](https://github.com/frappe/erpnext/issues/40021)) ([4269ef8](4269ef8c98))
* Completed Work Orders report not working ([ca03e9c](ca03e9cfd3))
* Cr/Dr notes with POS Payments ([2e07b03](2e07b03307))
* currency symbol in landed cost voucher and material request (backport [#40138](https://github.com/frappe/erpnext/issues/40138)) ([#40141](https://github.com/frappe/erpnext/issues/40141)) ([57bb031](57bb031602))
* Data too long for column 'serial_no' at row 1 (backport [#40098](https://github.com/frappe/erpnext/issues/40098)) ([#40139](https://github.com/frappe/erpnext/issues/40139)) ([9d19ec4](9d19ec43c8))
* default taxable value for item not found in item list ([7e43f6b](7e43f6b7e0))
* delete PLE containing invoice in against ([190bd45](190bd45bd7))
* do not make MR against raw materials of available sub assemblies (backport [#40085](https://github.com/frappe/erpnext/issues/40085)) ([#40087](https://github.com/frappe/erpnext/issues/40087)) ([cf5fa21](cf5fa210bb))
* Fiscal Year exception on demo data setup ([56ee843](56ee843233))
* incorrect item name in MR (backport [#40018](https://github.com/frappe/erpnext/issues/40018)) ([#40024](https://github.com/frappe/erpnext/issues/40024)) ([9f8f3db](9f8f3db953))
* Issues regarding asset cancellation and deletion ([8eb2f67](8eb2f67910))
* negative stock error while making stock reconciliation (backport [#40016](https://github.com/frappe/erpnext/issues/40016)) ([#40026](https://github.com/frappe/erpnext/issues/40026)) ([c964c45](c964c45f4e))
* on unreconciliation, update advance paid ([4d1f56c](4d1f56c4bd))
* only check for delinked PLEs ([a75a69a](a75a69a01e))
* only consider contributed qty towards achieved targets ([194f46b](194f46be57))
* parent warehouse checks in the production plan for sub-assemblies (backport [#40150](https://github.com/frappe/erpnext/issues/40150)) ([#40157](https://github.com/frappe/erpnext/issues/40157)) ([4784117](4784117a8f))
* remove cancelled payment entry from Payment Period Based On Invoice Date ([72da308](72da3083e6))
* remove cancelled payment entry from PPBOID report ([0be5203](0be520331c))
* remove config for default bank account in test ([36b442a](36b442a951))
* remove microsecond from posting datetime (backport [#40017](https://github.com/frappe/erpnext/issues/40017)) ([#40022](https://github.com/frappe/erpnext/issues/40022)) ([eaa3849](eaa3849df4))
* removed unwanted patch ([ee2d108](ee2d108bef))
* resolved conflict ([6928674](692867427c))
* resolved conflict ([a0c0ab7](a0c0ab7709))
* skip max discount validation for rate adjustment ([3b96aae](3b96aaeead))
* skip SO & DN validation for debit note ([cd42089](cd42089e20))
* Supplier users not able to see RFQ on the Portal (backport [#40161](https://github.com/frappe/erpnext/issues/40161)) ([#40165](https://github.com/frappe/erpnext/issues/40165)) ([6a63a6c](6a63a6c98a))
* timesheet per billed state edge case (backport [#40010](https://github.com/frappe/erpnext/issues/40010)) ([#40029](https://github.com/frappe/erpnext/issues/40029)) ([a543bf4](a543bf47ef))
* translatable columns in Sales Pipeline Analytics report ([1c5a7e2](1c5a7e29f2))
* type error for missing frm obj ([6b5e1cf](6b5e1cfeb7))
* unique gl account for plaid bank accounts ([65853da](65853da505))
* use correct variable name on hotfix branches ([0694fd1](0694fd19fd))
* use frm instead of cur_frm ([341f903](341f9030f5))
* use serial batch fields for packed items (backport [#40140](https://github.com/frappe/erpnext/issues/40140)) ([#40142](https://github.com/frappe/erpnext/issues/40142)) ([1860399](1860399ccb))

### Features

* show contributed qty in transaction summary ([38abfdb](38abfdb8ae))
* update billed amount in PO and PR ([e7e8149](e7e8149fbe))

### Performance Improvements

* new column Posting Datetime in SLE to optimize stock ledger related queries (backport [#39800](https://github.com/frappe/erpnext/issues/39800)) ([#40004](https://github.com/frappe/erpnext/issues/40004)) ([b9181e8](b9181e85dc))
2024-02-28 05:13:40 +00:00
Deepesh Garg
4291b9fa8d Merge pull request #40148 from frappe/version-15-hotfix
chore: release v15
2024-02-28 10:42:31 +05:30
Deepesh Garg
930df21a5f Merge pull request #40170 from frappe/mergify/bp/version-15-hotfix/pr-40137
fix: default taxable value for item not found in item list (#40137)
2024-02-28 08:24:15 +05:30
mergify[bot]
6a63a6c98a fix: Supplier users not able to see RFQ on the Portal (backport #40161) (#40165)
* fix: Supplier users not able to see RFQ on the Portal (#40161)

(cherry picked from commit f8ba560394)

* chore: fix travis

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-27 22:30:26 +05:30
ljain112
7e43f6b7e0 fix: default taxable value for item not found in item list
(cherry picked from commit 5885978fc2)
2024-02-27 16:40:19 +00:00
Deepesh Garg
84a359c760 Merge pull request #40163 from vorasmit/ic-deps-v15
fix: add flags for repost to ensure correct accounting from India Compliance App (#40162)
2024-02-27 22:08:45 +05:30
Smit Vora
7d14ecfcb8 fix: add flags for repost to ensure correct accounting from India Compliance App 2024-02-27 20:30:28 +05:30
Gursheen Kaur Anand
07fd93a6f6 Merge pull request #40152 from frappe/mergify/bp/version-15-hotfix/pr-40095
fix: unique GL account for plaid bank accounts (backport #40095)
2024-02-27 17:08:37 +05:30
mergify[bot]
4784117a8f fix: parent warehouse checks in the production plan for sub-assemblies (backport #40150) (#40157)
fix: parent warehouse checks in the production plan for sub-assemblies (#40150)

(cherry picked from commit 6f5815e44f)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-27 17:03:21 +05:30
Gursheen Kaur Anand
7a9beb4d47 Merge pull request #40154 from frappe/mergify/bp/version-15-hotfix/pr-40102
feat: toggle updation of billed amount in previous purchase docs (backport #40102)
2024-02-27 16:40:14 +05:30
Gursheen Kaur Anand
87f36ce425 chore: fix typo 2024-02-27 16:24:14 +05:30
Gursheen Kaur Anand
48992cd205 chore: resolve conflicts 2024-02-27 16:18:27 +05:30
Gursheen Kaur Anand
99d1f1d67b chore: resolve conflicts 2024-02-27 16:15:49 +05:30
Gursheen Kaur Anand
eadea0207c chore: resolve conflicts 2024-02-27 16:13:49 +05:30
Gursheen Anand
e67d579ac4 test: pr billed amount against debit note
(cherry picked from commit 6d40844894)
2024-02-27 10:24:01 +00:00
Gursheen Anand
bac2f66344 test: po billed amount against debit note
(cherry picked from commit 81dbfe189e)

# Conflicts:
#	erpnext/buying/doctype/purchase_order/test_purchase_order.py
2024-02-27 10:24:01 +00:00
Gursheen Anand
e7e8149fbe feat: update billed amount in PO and PR
(cherry picked from commit 9f6535472d)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
2024-02-27 10:24:00 +00:00
Gursheen Anand
36b442a951 fix: remove config for default bank account in test
(cherry picked from commit c42444ab3b)
2024-02-27 10:10:20 +00:00
Gursheen Anand
65853da505 fix: unique gl account for plaid bank accounts
(cherry picked from commit bf6e32a960)
2024-02-27 10:10:20 +00:00
Gursheen Kaur Anand
df7afc3154 Merge pull request #40145 from frappe/mergify/bp/version-15-hotfix/pr-40143
fix(minor): type error for missing form object in hide_company util (backport #40143)
2024-02-27 13:33:13 +05:30
Gursheen Anand
341f9030f5 fix: use frm instead of cur_frm
(cherry picked from commit ceeb8fc9e5)
2024-02-27 07:45:36 +00:00
Gursheen Anand
6b5e1cfeb7 fix: type error for missing frm obj
(cherry picked from commit 20fa3da950)
2024-02-27 07:45:36 +00:00
ruthra kumar
9f8a27833a Merge pull request #40135 from frappe/mergify/bp/version-15-hotfix/pr-40133
fix: reset advance amount on unreconciliation of Sales/Purchase Orders (backport #40133)
2024-02-27 10:33:07 +05:30
mergify[bot]
1860399ccb fix: use serial batch fields for packed items (backport #40140) (#40142)
fix: use serial batch fields for packed items (#40140)

(cherry picked from commit bc9c480246)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-27 07:57:37 +05:30
mergify[bot]
57bb031602 fix: currency symbol in landed cost voucher and material request (backport #40138) (#40141)
fix: currency symbol in landed cost voucher and material request (#40138)

(cherry picked from commit 8aa2b7c183)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-26 23:16:49 +05:30
mergify[bot]
9d19ec43c8 fix: Data too long for column 'serial_no' at row 1 (backport #40098) (#40139)
* fix: Data too long for column 'serial_no' at row 1 (#40098)

(cherry picked from commit 08caa7cfa1)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-26 23:00:01 +05:30
ruthra kumar
0694fd19fd fix: use correct variable name on hotfix branches 2024-02-26 20:35:22 +05:30
ruthra kumar
94bb6241ef test: advance paid update on sales/purchase order unreconciliation
(cherry picked from commit 1f01ff3487)
2024-02-26 12:22:55 +00:00
ruthra kumar
4d1f56c4bd fix: on unreconciliation, update advance paid
(cherry picked from commit c9e2f03a3a)
2024-02-26 12:22:55 +00:00
ruthra kumar
ad53633c66 Merge pull request #40118 from frappe/mergify/bp/version-15-hotfix/pr-40113
refactor: patch to setup dimensions in Reconciliation tool (backport #40113)
2024-02-26 14:21:40 +05:30
ruthra kumar
2bf6125b71 refactor: patch to setup dimensions in Reconciliation tool
(cherry picked from commit 461fb183fc)
2024-02-26 13:08:47 +05:30
Frappe PR Bot
792de1be03 chore(release): Bumped to Version 15.14.7
## [15.14.7](https://github.com/frappe/erpnext/compare/v15.14.6...v15.14.7) (2024-02-26)

### Bug Fixes

* Issues regarding asset cancellation and deletion ([6fc4dac](6fc4dac4db))
* removed unwanted patch ([3c98368](3c98368e45))
* resolved conflict ([fc565ec](fc565ecd99))
* resolved conflict ([d196aa5](d196aa5a36))
2024-02-26 07:33:28 +00:00
Nabin Hait
66156fcfa7 Merge pull request #40031 from frappe/mergify/bp/version-15/pr-39983
fix: Issues regarding asset cancellation and deletion (backport #39983)
2024-02-26 13:02:20 +05:30
Nabin Hait
fc565ecd99 fix: resolved conflict 2024-02-26 12:21:57 +05:30
Nabin Hait
d196aa5a36 fix: resolved conflict 2024-02-26 12:21:25 +05:30
Gursheen Kaur Anand
e68d2d1c7a Merge pull request #40109 from frappe/mergify/bp/version-15-hotfix/pr-40105
fix(minor): tax amount label according to party type (backport #40105)
2024-02-26 11:10:08 +05:30
Gursheen Kaur Anand
93f64396ac Merge pull request #40111 from frappe/mergify/bp/version-15-hotfix/pr-40062
fix: sales person / partner achieved targets in report (backport #40062)
2024-02-26 11:08:15 +05:30
Gursheen Anand
91c21d13e5 test: sales person target variance
(cherry picked from commit 7566c1ee78)
2024-02-26 05:09:45 +00:00
Gursheen Anand
38abfdb8ae feat: show contributed qty in transaction summary
(cherry picked from commit a823f16dff)
2024-02-26 05:09:45 +00:00
Gursheen Anand
194f46be57 fix: only consider contributed qty towards achieved targets
(cherry picked from commit 339698d172)
2024-02-26 05:09:45 +00:00
Gursheen Anand
d541ba3e61 fix: amount label according to party type
(cherry picked from commit 9c8d103d8a)
2024-02-26 05:05:27 +00:00
mergify[bot]
27703b54bd fix: capacity planning issue in the job card (backport #40092) (#40101)
fix: capacity planning issue in the job card (#40092)

* fix: capacity planning issue in the job card

* test: test case to test capacity planning for workstation

(cherry picked from commit 75f8464724)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-25 19:22:51 +05:30
ruthra kumar
9ffbf5623a Merge pull request #40097 from frappe/mergify/bp/version-15-hotfix/pr-40096
fix: Fiscal Year exception on demo data setup (backport #40096)
2024-02-25 16:09:51 +05:30
ruthra kumar
56ee843233 fix: Fiscal Year exception on demo data setup
(cherry picked from commit 3c3c57c674)
2024-02-25 10:13:09 +00:00
ruthra kumar
383dfdd4ab Merge pull request #40091 from frappe/mergify/bp/version-15-hotfix/pr-40073
refactor: update payments section on item removal (backport #40073)
2024-02-25 09:34:42 +05:30
ruthra kumar
5c269a9947 refactor: update payments section on item removal
(cherry picked from commit 406793a6ff)
2024-02-25 03:58:19 +00:00
mergify[bot]
cf5fa210bb fix: do not make MR against raw materials of available sub assemblies (backport #40085) (#40087)
fix: do not make MR against raw materials of available sub assemblies (#40085)

(cherry picked from commit 4c9048fb39)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-24 21:02:17 +05:30
mergify[bot]
53d943ec70 fix: Cannot read properties of undefined (backport #40081) (#40083)
fix: Cannot read properties of undefined

(cherry picked from commit 44ed52c5cf)

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2024-02-24 17:04:36 +05:30
rohitwaghchaure
d755b9d38c Merge pull request #40080 from frappe/mergify/bp/version-15-hotfix/pr-40079
chore: change label name (backport #40079)
2024-02-24 13:29:04 +05:30
Rohit Waghchaure
824df72eeb fix: change label name
(cherry picked from commit 635174f1ce)
2024-02-24 07:40:56 +00:00
Gursheen Kaur Anand
e4baacd79e Merge pull request #40066 from frappe/mergify/bp/version-15-hotfix/pr-40040
fix: skip max discount validation for rate adjustment (backport #40040)
2024-02-23 15:10:38 +05:30
Gursheen Kaur Anand
38b384dfa2 Merge pull request #40064 from frappe/mergify/bp/version-15-hotfix/pr-40035
fix: delete PLE containing invoice in against (backport #40035)
2024-02-23 15:07:48 +05:30
ruthra kumar
10fe201bc8 Merge pull request #40068 from frappe/mergify/bp/version-15-hotfix/pr-39830
fix: check_credit_limit on_update_after_submit of Sales Order (backport #39830)
2024-02-23 14:48:08 +05:30
ruthra kumar
bcb280c5e8 test: credit limit on update after submit
(cherry picked from commit 467c0898e9)
2024-02-23 08:51:39 +00:00
Nihantra C. Patel
83d7111649 fix: check_credit_limit on_update_after_submit of Sales Order
(cherry picked from commit 17452b7693)
2024-02-23 08:51:38 +00:00
Gursheen Anand
cd42089e20 fix: skip SO & DN validation for debit note
(cherry picked from commit e2d16955dd)
2024-02-23 07:28:38 +00:00
Gursheen Anand
3b96aaeead fix: skip max discount validation for rate adjustment
(cherry picked from commit 5a3b133d65)
2024-02-23 07:28:37 +00:00
Ankush Menat
83b4cc5091 build: specify frappe dependency (#40061)
build: specify frappe dependency 

Added 15.10 as dependency because stock balance depends on https://github.com/frappe/frappe/pull/24346
2024-02-23 12:43:01 +05:30
Gursheen Anand
a75a69a01e fix: only check for delinked PLEs
(cherry picked from commit 146c5b3e16)
2024-02-23 07:10:08 +00:00
Gursheen Anand
190bd45bd7 fix: delete PLE containing invoice in against
(cherry picked from commit c1e1fd8829)
2024-02-23 07:10:08 +00:00
ruthra kumar
c752bec2d9 Merge pull request #40058 from frappe/mergify/bp/version-15-hotfix/pr-40011
fix: Ledger entries for Cr/Dr notes with POS Payments (backport #40011)
2024-02-23 06:20:30 +05:30
ruthra kumar
8fef484f0f Merge pull request #40056 from frappe/mergify/bp/version-15-hotfix/pr-39831
fix: remove cancelled payment entry from Payment Period Based On Invoice Date (backport #39831)
2024-02-23 06:20:14 +05:30
ruthra kumar
b40baf5e63 refactor: skip popup for POS invoices
(cherry picked from commit 3634c4c284)
2024-02-23 00:33:08 +00:00
ruthra kumar
2c8ba892ac test: ledger entries of Cr Note of POS Invoice
(cherry picked from commit 4288713abe)
2024-02-23 00:33:07 +00:00
ruthra kumar
2e07b03307 fix: Cr/Dr notes with POS Payments
(cherry picked from commit 68a23730f3)
2024-02-23 00:33:07 +00:00
Nihantra C. Patel
0be520331c fix: remove cancelled payment entry from PPBOID report
(cherry picked from commit 186cc3d748)
2024-02-23 00:30:50 +00:00
Nihantra C. Patel
72da3083e6 fix: remove cancelled payment entry from Payment Period Based On Invoice Date
(cherry picked from commit a2a8a8f2e0)
2024-02-23 00:30:50 +00:00
ruthra kumar
a3ddd326d6 Merge pull request #40049 from frappe/mergify/bp/version-15-hotfix/pr-39828
fix: translate Sales Pipeline Analytics report (backport #39828)
2024-02-22 20:46:55 +05:30
Nihantra C. Patel
1c5a7e29f2 fix: translatable columns in Sales Pipeline Analytics report
(cherry picked from commit c5050c935b)
2024-02-22 14:54:53 +00:00
Frappe PR Bot
f723d7b561 chore(release): Bumped to Version 15.14.6
## [15.14.6](https://github.com/frappe/erpnext/compare/v15.14.5...v15.14.6) (2024-02-22)

### Bug Fixes

* communication_date in party dashboards (backport [#40005](https://github.com/frappe/erpnext/issues/40005)) ([#40043](https://github.com/frappe/erpnext/issues/40043)) ([6662c32](6662c321a5))
2024-02-22 11:14:07 +00:00
mergify[bot]
6662c321a5 fix: communication_date in party dashboards (backport #40005) (#40043)
fix: accommodate for changed orderby statement

(cherry picked from commit 87df7ff717)

Co-authored-by: Gursheen Anand <gursheen@frappe.io>
2024-02-22 16:40:46 +05:30
mergify[bot]
4269ef8c98 fix: communication_date in party dashboards (backport #40005) (#40021)
fix: accommodate for changed orderby statement

(cherry picked from commit 87df7ff717)

Co-authored-by: Gursheen Anand <gursheen@frappe.io>
2024-02-22 16:20:02 +05:30
mergify[bot]
a543bf47ef fix: timesheet per billed state edge case (backport #40010) (#40029)
fix: timesheet per billed state edge case (#40010)

If value is 100.0000x then it won't set status correctly but will set it the next time it's loaded from db.

(cherry picked from commit 38e88db2c9)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-02-22 12:29:53 +05:30
mergify[bot]
c964c45f4e fix: negative stock error while making stock reconciliation (backport #40016) (#40026)
* fix: negative stock error while making stock reconciliation (#40016)

fix: negative stock error while making stock reco
(cherry picked from commit da184d709b)

# Conflicts:
#	erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-22 11:38:49 +05:30
Nabin Hait
3c98368e45 fix: removed unwanted patch
(cherry picked from commit 85471533e9)
2024-02-22 05:40:58 +00:00
Nabin Hait
6fc4dac4db fix: Issues regarding asset cancellation and deletion
(cherry picked from commit 17f85de6fb)

# Conflicts:
#	erpnext/assets/doctype/asset/depreciation.py
#	erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
2024-02-22 05:40:57 +00:00
Frappe PR Bot
afc87a4486 chore(release): Bumped to Version 15.14.5
## [15.14.5](https://github.com/frappe/erpnext/compare/v15.14.4...v15.14.5) (2024-02-22)

### Bug Fixes

* check for pricing rules on item ([5084b9b](5084b9bd4b))
2024-02-22 05:38:47 +00:00
Deepesh Garg
5137966fe5 Merge pull request #40030 from frappe/mergify/bp/version-15/pr-40019
fix: TypeError for item pricing rules (#39999)
2024-02-22 11:07:32 +05:30
Nabin Hait
6f364df48c Merge pull request #39990 from frappe/mergify/bp/version-15-hotfix/pr-39983
fix: Issues regarding asset cancellation and deletion (backport #39983)
2024-02-22 11:07:01 +05:30
Gursheen Anand
5084b9bd4b fix: check for pricing rules on item
(cherry picked from commit ecd83b12ab)
(cherry picked from commit 32d9642379)
2024-02-22 05:36:43 +00:00
mergify[bot]
eaa3849df4 fix: remove microsecond from posting datetime (backport #40017) (#40022)
fix: remove microsecond from posting datetime (#40017)

(cherry picked from commit 0b04d04da3)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-22 09:51:07 +05:30
mergify[bot]
9f8f3db953 fix: incorrect item name in MR (backport #40018) (#40024)
fix: incorrect item name in MR (#40018)

(cherry picked from commit 864d7ae04c)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-22 09:50:45 +05:30
Gursheen Kaur Anand
43c218c673 Merge pull request #40019 from frappe/mergify/bp/version-15-hotfix/pr-39999
fix: TypeError for item pricing rules (backport #39999)
2024-02-22 09:10:17 +05:30
Gursheen Anand
32d9642379 fix: check for pricing rules on item
(cherry picked from commit ecd83b12ab)
2024-02-22 03:37:17 +00:00
mergify[bot]
b9181e85dc perf: new column Posting Datetime in SLE to optimize stock ledger related queries (backport #39800) (#40004)
* perf: new column posting datetime in SLE to optimize stock ledger related queries

(cherry picked from commit d80ca523a4)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py

* test: test cases to test clash timestamp entries

(cherry picked from commit f04676aaed)

* chore: remove microsecond from posting_datetime

(cherry picked from commit a73ba2c0d2)

* chore: fix conflicts

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2024-02-21 21:14:28 +05:30
rohitwaghchaure
66a05087b8 Merge pull request #40001 from frappe/mergify/bp/version-15-hotfix/pr-39998
fix: Completed Work Orders report not working (backport #39998)
2024-02-21 17:44:44 +05:30
Rohit Waghchaure
ca03e9cfd3 fix: Completed Work Orders report not working
(cherry picked from commit 11f4cb914a)
2024-02-21 11:21:04 +00:00
Nabin Hait
692867427c fix: resolved conflict 2024-02-21 11:38:21 +05:30
Nabin Hait
a0c0ab7709 fix: resolved conflict 2024-02-21 11:37:47 +05:30
Nabin Hait
ee2d108bef fix: removed unwanted patch
(cherry picked from commit 85471533e9)
2024-02-21 05:45:27 +00:00
Nabin Hait
8eb2f67910 fix: Issues regarding asset cancellation and deletion
(cherry picked from commit 17f85de6fb)

# Conflicts:
#	erpnext/assets/doctype/asset/depreciation.py
#	erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
2024-02-21 05:45:27 +00:00
Frappe PR Bot
3d7e87185c chore(release): Bumped to Version 15.14.4
## [15.14.4](https://github.com/frappe/erpnext/compare/v15.14.3...v15.14.4) (2024-02-21)

### Bug Fixes

* 'NoneType' object is not iterable (backport [#39977](https://github.com/frappe/erpnext/issues/39977)) ([#39981](https://github.com/frappe/erpnext/issues/39981)) ([0f87ec1](0f87ec15ad))
* **Bank Transaction:** precision for `(un)allocated_amount` ([bf5d2f5](bf5d2f5fe4))
* batch filter not working in stock ledger report (backport [#39934](https://github.com/frappe/erpnext/issues/39934)) ([#39935](https://github.com/frappe/erpnext/issues/39935)) ([1513595](15135952fc))
* do not empty serial batch fields (backport [#39948](https://github.com/frappe/erpnext/issues/39948)) ([#39956](https://github.com/frappe/erpnext/issues/39956)) ([acd2e93](acd2e93f8c))
* fetch company terms ([14fe0af](14fe0af887))
* float division by zero ([b954bdf](b954bdfdf9))
* group node in warehouse filter in Item-wise Sales Register ([74819b8](74819b8e70))
* **Issue:** create communication ([f5d7fbd](f5d7fbdaf8))
* no need call for company method in sales invoice js ([bef38f7](bef38f74fe))
* not able to make purchase receipt ([3732946](37329469c3))
* party item code in Blanket Order ([518b22b](518b22bffc))
* reposting failed status not updated (backport [#39970](https://github.com/frappe/erpnext/issues/39970)) ([#39972](https://github.com/frappe/erpnext/issues/39972)) ([46f7569](46f7569a54))
* set batch created from bundle to batch field in stock transaction (backport [#39966](https://github.com/frappe/erpnext/issues/39966)) ([#39987](https://github.com/frappe/erpnext/issues/39987)) ([2ee51d3](2ee51d36ff))
* show active bom in the dropdown while making stock entry and MR (backport [#39974](https://github.com/frappe/erpnext/issues/39974)) ([#39976](https://github.com/frappe/erpnext/issues/39976)) ([7201448](720144898f))
* update_dimension is required and not need party account method ([a56d5b8](a56d5b805c))
* use serial batch fields not enabled for new stock entry ([40d4e32](40d4e3261e))
2024-02-21 05:29:45 +00:00
rohitwaghchaure
177110349d Merge pull request #39979 from frappe/version-15-hotfix
chore: release v15
2024-02-21 10:58:33 +05:30
rohitwaghchaure
ed553b89a4 Merge branch 'version-15' into version-15-hotfix 2024-02-21 09:34:20 +05:30
mergify[bot]
2ee51d36ff fix: set batch created from bundle to batch field in stock transaction (backport #39966) (#39987)
fix: set batch created from bundle to batch field in stock transaction (#39966)

* fix: set batch created from bundle to batch field in stock transaction

* fix: validation for serial and batch no

(cherry picked from commit 4b24fcd221)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-21 00:04:01 +05:30
mergify[bot]
0f87ec15ad fix: 'NoneType' object is not iterable (backport #39977) (#39981)
fix: 'NoneType' object is not iterable (#39977)

(cherry picked from commit 8e7d47b3a7)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-20 15:53:12 +05:30
mergify[bot]
720144898f fix: show active bom in the dropdown while making stock entry and MR (backport #39974) (#39976)
fix: show active bom in the dropdown while making stock entry and MR (#39974)

(cherry picked from commit 133f8bd92a)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-20 13:13:00 +05:30
mergify[bot]
46f7569a54 fix: reposting failed status not updated (backport #39970) (#39972)
fix: reposting failed status not updated (#39970)

(cherry picked from commit d4264f7ba1)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-20 12:35:46 +05:30
rohitwaghchaure
a102172982 Merge pull request #39968 from frappe/mergify/bp/version-15-hotfix/pr-39967
fix: float division by zero (backport #39967)
2024-02-20 12:07:38 +05:30
Rohit Waghchaure
b954bdfdf9 fix: float division by zero
(cherry picked from commit e8ae4ed61d)
2024-02-20 01:02:35 +00:00
Frappe PR Bot
9c01a5f7ed chore(release): Bumped to Version 15.14.3
## [15.14.3](https://github.com/frappe/erpnext/compare/v15.14.2...v15.14.3) (2024-02-19)

### Bug Fixes

* do not empty serial batch fields (backport [#39948](https://github.com/frappe/erpnext/issues/39948)) ([#39956](https://github.com/frappe/erpnext/issues/39956)) ([2db79cd](2db79cdf3b))
2024-02-19 05:33:59 +00:00
rohitwaghchaure
0c9d7434f9 Merge pull request #39957 from frappe/mergify/bp/version-15/pr-39956
fix: do not empty serial batch fields (backport #39948) (backport #39956)
2024-02-19 11:02:11 +05:30
mergify[bot]
2db79cdf3b fix: do not empty serial batch fields (backport #39948) (#39956)
fix: do not empty serial batch fields (#39948)

(cherry picked from commit a4cbfabe0e)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit acd2e93f8c)
2024-02-19 05:16:58 +00:00
mergify[bot]
acd2e93f8c fix: do not empty serial batch fields (backport #39948) (#39956)
fix: do not empty serial batch fields (#39948)

(cherry picked from commit a4cbfabe0e)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-19 10:45:28 +05:30
ruthra kumar
c81a15eac3 Merge pull request #39955 from frappe/mergify/bp/version-15-hotfix/pr-39914
refactor: add total row if only one party is being filtered (backport #39914)
2024-02-19 09:16:34 +05:30
ruthra kumar
18fcbb6f97 Merge pull request #39953 from frappe/mergify/bp/version-15-hotfix/pr-39942
fix: group node in warehouse filter in Item-wise Sales Register (backport #39942)
2024-02-19 09:15:09 +05:30
ruthra kumar
baa83ece21 refactor: add total row if only one party is being filtered
(cherry picked from commit b1dfa2537b)
2024-02-19 02:57:35 +00:00
ruthra kumar
74819b8e70 fix: group node in warehouse filter in Item-wise Sales Register
(cherry picked from commit 44538bd02a)
2024-02-19 02:56:17 +00:00
ruthra kumar
a2a5b34099 Merge pull request #39950 from frappe/mergify/bp/version-15-hotfix/pr-39943
refactor: use popup to inform on additional reconciliation step for Cr/Dr Notes (backport #39943)
2024-02-19 07:48:27 +05:30
ruthra kumar
ce11180793 refactor: use popup to inform on additional reconciliation step
(cherry picked from commit 0d260faa00)
2024-02-19 07:31:33 +05:30
Raffael Meyer
0b7a95351a Merge pull request #39907 from frappe/mergify/bp/version-15-hotfix/pr-39857
fix: fetch company terms (backport #39857)
2024-02-17 01:11:09 +01:00
Raffael Meyer
d225508ab1 Merge pull request #39928 from frappe/mergify/bp/version-15-hotfix/pr-39926
fix(Bank Transaction): precision for `(un)allocated_amount` (backport #39926)
2024-02-17 00:33:24 +01:00
Raffael Meyer
d213db90af Merge pull request #39940 from frappe/mergify/bp/version-15-hotfix/pr-39938
fix(Issue): create communication (backport #39938)
2024-02-16 20:47:30 +01:00
barredterra
f5d7fbdaf8 fix(Issue): create communication
Ignore permisions and mandatory. Required, for example, when Issue is created by Customer via portal.

(cherry picked from commit 3f1d008741)
2024-02-16 19:15:39 +00:00
Frappe PR Bot
fd76847cfa chore(release): Bumped to Version 15.14.2
## [15.14.2](https://github.com/frappe/erpnext/compare/v15.14.1...v15.14.2) (2024-02-16)

### Bug Fixes

* batch filter not working in stock ledger report (backport [#39934](https://github.com/frappe/erpnext/issues/39934)) ([#39935](https://github.com/frappe/erpnext/issues/39935)) ([3cd3159](3cd315973c))
2024-02-16 16:20:27 +00:00
rohitwaghchaure
709faaac69 Merge pull request #39937 from frappe/mergify/bp/version-15/pr-39935
fix: batch filter not working in stock ledger report (backport #39934) (backport #39935)
2024-02-16 21:48:52 +05:30
mergify[bot]
3cd315973c fix: batch filter not working in stock ledger report (backport #39934) (#39935)
fix: batch filter not working in stock ledger report

(cherry picked from commit a995e87567)

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
(cherry picked from commit 15135952fc)
2024-02-16 15:19:21 +00:00
mergify[bot]
15135952fc fix: batch filter not working in stock ledger report (backport #39934) (#39935)
fix: batch filter not working in stock ledger report

(cherry picked from commit a995e87567)

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2024-02-16 20:47:20 +05:30
Frappe PR Bot
6d6a3a10fb chore(release): Bumped to Version 15.14.1
## [15.14.1](https://github.com/frappe/erpnext/compare/v15.14.0...v15.14.1) (2024-02-16)

### Bug Fixes

* use serial batch fields not enabled for new stock entry ([72ff56b](72ff56be13))
2024-02-16 10:29:29 +00:00
rohitwaghchaure
7af62fb6c8 Merge pull request #39932 from frappe/mergify/bp/version-15/pr-39931
fix: use serial batch fields not enabled for new stock entry (backport #39930) (backport #39931)
2024-02-16 15:58:17 +05:30
Rohit Waghchaure
72ff56be13 fix: use serial batch fields not enabled for new stock entry
(cherry picked from commit dc9115a586)
(cherry picked from commit 40d4e3261e)
2024-02-16 10:25:03 +00:00
rohitwaghchaure
b91f65d4cf Merge pull request #39931 from frappe/mergify/bp/version-15-hotfix/pr-39930
fix: use serial batch fields not enabled for new stock entry (backport #39930)
2024-02-16 15:53:44 +05:30
Rohit Waghchaure
40d4e3261e fix: use serial batch fields not enabled for new stock entry
(cherry picked from commit dc9115a586)
2024-02-16 10:20:35 +00:00
barredterra
bf5d2f5fe4 fix(Bank Transaction): precision for (un)allocated_amount
(cherry picked from commit 8a702a6338)
2024-02-15 19:05:21 +00:00
rohitwaghchaure
bb77f85d89 Merge pull request #39922 from frappe/mergify/bp/version-15-hotfix/pr-39916
fix: not able to make purchase receipt (backport #39916)
2024-02-15 17:55:41 +05:30
Rohit Waghchaure
37329469c3 fix: not able to make purchase receipt
(cherry picked from commit 2fb0499923)
2024-02-15 12:04:49 +00:00
rohitwaghchaure
ab03ab388c Merge pull request #39918 from frappe/mergify/bp/version-15-hotfix/pr-39905
fix: party item code in Blanket Order (backport #39905)
2024-02-15 17:31:50 +05:30
rohitwaghchaure
c50639334f chore: fix linter issue
(cherry picked from commit 230a7d8d53)
2024-02-15 09:33:40 +00:00
Rohit Waghchaure
518b22bffc fix: party item code in Blanket Order
(cherry picked from commit 1a8f7f9403)
2024-02-15 09:33:39 +00:00
kunhi
a56d5b805c fix: update_dimension is required and not need party account method
(cherry picked from commit e6949d71f6)
2024-02-14 14:54:55 +00:00
kunhi
bef38f74fe fix: no need call for company method in sales invoice js
(cherry picked from commit e3bd8d10b0)
2024-02-14 14:54:54 +00:00
kunhi
14fe0af887 fix: fetch company terms
(cherry picked from commit d97b6d38ef)
2024-02-14 14:54:54 +00:00
Frappe PR Bot
c78d085e24 chore(release): Bumped to Version 15.14.0
# [15.14.0](https://github.com/frappe/erpnext/compare/v15.13.0...v15.14.0) (2024-02-14)

### Bug Fixes

*  production plan issue with sales order (backport [#39901](https://github.com/frappe/erpnext/issues/39901)) ([#39904](https://github.com/frappe/erpnext/issues/39904)) ([88a7248](88a7248888))
* add permissions to SRE (backport [#39780](https://github.com/frappe/erpnext/issues/39780)) ([#39786](https://github.com/frappe/erpnext/issues/39786)) ([ba05648](ba05648741))
* Brazilian COA for demo data creation ([#39839](https://github.com/frappe/erpnext/issues/39839)) ([4daee6d](4daee6d9c7))
* calculate `stock_value_diff` ([5a66c85](5a66c8585c))
* create SBB for `transfer_qty` in SE (backport [#39835](https://github.com/frappe/erpnext/issues/39835)) ([#39863](https://github.com/frappe/erpnext/issues/39863)) ([92e6017](92e6017a29))
* do not consider rejected warehouses in pick list (backport [#39539](https://github.com/frappe/erpnext/issues/39539)) (backport [#39804](https://github.com/frappe/erpnext/issues/39804)) ([#39811](https://github.com/frappe/erpnext/issues/39811)) ([30dacce](30daccecc7))
* incorrect planned qty in PP (backport [#39785](https://github.com/frappe/erpnext/issues/39785)) ([#39793](https://github.com/frappe/erpnext/issues/39793)) ([60e04ab](60e04ab661))
* landed cost voucher not submitting because of incorrect reference (backport [#39898](https://github.com/frappe/erpnext/issues/39898)) ([#39900](https://github.com/frappe/erpnext/issues/39900)) ([a548f12](a548f12941))
* remove duplicates from tax category map ([3c6114a](3c6114ab72))
* set rate for PO created against BO (backport [#39765](https://github.com/frappe/erpnext/issues/39765)) ([#39767](https://github.com/frappe/erpnext/issues/39767)) ([2213886](22138867f5))
* stock entry for use serial batch fields (backport [#39843](https://github.com/frappe/erpnext/issues/39843)) ([#39844](https://github.com/frappe/erpnext/issues/39844)) ([43fce29](43fce29a04))
* use correct field name in accounts controller (backport [#39884](https://github.com/frappe/erpnext/issues/39884)) ([#39897](https://github.com/frappe/erpnext/issues/39897)) ([f08b424](f08b424972))
* **ux:** set rate as price list rate on uom change in MR (backport [#39816](https://github.com/frappe/erpnext/issues/39816)) ([#39818](https://github.com/frappe/erpnext/issues/39818)) ([63b4d20](63b4d20bdf))
* validate duplicate SBB (backport [#39862](https://github.com/frappe/erpnext/issues/39862)) ([#39866](https://github.com/frappe/erpnext/issues/39866)) ([a2f1a96](a2f1a964f1))
* warehouse issue in pick list (backport [#39826](https://github.com/frappe/erpnext/issues/39826)) ([#39827](https://github.com/frappe/erpnext/issues/39827)) ([b625b05](b625b05ddc))

### Features

* get RM costs from consumption entry in manufacture SE (backport [#39822](https://github.com/frappe/erpnext/issues/39822)) ([#39847](https://github.com/frappe/erpnext/issues/39847)) ([2d5f186](2d5f186812))

### Performance Improvements

* cached get_last_purchase_details to fix performance issue (backport [#39854](https://github.com/frappe/erpnext/issues/39854)) ([#39856](https://github.com/frappe/erpnext/issues/39856)) ([c643e70](c643e70e2f))
* production plan submission (backport [#39846](https://github.com/frappe/erpnext/issues/39846)) ([#39860](https://github.com/frappe/erpnext/issues/39860)) ([10f17df](10f17dfcc8))
2024-02-14 12:06:08 +00:00
rohitwaghchaure
8c12b3dbe0 Merge pull request #39880 from frappe/version-15-hotfix
chore: release v15
2024-02-14 17:34:57 +05:30
mergify[bot]
88a7248888 fix: production plan issue with sales order (backport #39901) (#39904)
fix:  production plan issue with sales order (#39901)

(cherry picked from commit d0df5df4a6)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-14 16:58:28 +05:30
mergify[bot]
a548f12941 fix: landed cost voucher not submitting because of incorrect reference (backport #39898) (#39900)
fix: landed cost voucher not submitting because of incorrect reference (#39898)

(cherry picked from commit 6239fd704b)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-14 15:57:40 +05:30
mergify[bot]
f08b424972 fix: use correct field name in accounts controller (backport #39884) (#39897)
fix: use correct field name in accounts controller (#39884)

Changes to get advance payments in SI or PI from JV's

(cherry picked from commit b124081065)

Co-authored-by: Rohit Gunjegaonkar <135806454+rohitg-pbspl@users.noreply.github.com>
2024-02-14 13:21:55 +05:30
Raffael Meyer
375859a25f Merge pull request #39894 from frappe/mergify/bp/version-15-hotfix/pr-39868
fix(Purchase Receipt): calculate `stock_value_diff` (backport #39868)
2024-02-14 01:21:38 +01:00
barredterra
5a66c8585c fix: calculate stock_value_diff
`d.item_tax_amount` is already in base currency.

(cherry picked from commit 5df5851798)
2024-02-13 23:52:33 +00:00
mergify[bot]
a2f1a964f1 fix: validate duplicate SBB (backport #39862) (#39866)
* fix: validate duplicate SBB

(cherry picked from commit 094ecc1f62)

* test: duplicate SBB

(cherry picked from commit 55e66db315)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-13 09:09:03 +05:30
mergify[bot]
92e6017a29 fix: create SBB for transfer_qty in SE (backport #39835) (#39863)
fix: create SBB for `transfer_qty` in SE

(cherry picked from commit d59caf08e6)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-12 19:59:07 +05:30
mergify[bot]
10f17dfcc8 perf: production plan submission (backport #39846) (#39860)
perf: production plan submission

(cherry picked from commit aa1c69dd7a)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-12 18:17:36 +05:30
mergify[bot]
c643e70e2f perf: cached get_last_purchase_details to fix performance issue (backport #39854) (#39856)
perf: cached get_last_purchase_details to fix performance issue (#39854)

(cherry picked from commit b966c06a4f)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-12 15:53:50 +05:30
mergify[bot]
4daee6d9c7 fix: Brazilian COA for demo data creation (#39839)
fix: Brazilian COA for demo data creation (#39839)

fix: Brazilian COA
(cherry picked from commit 4b1c851da1)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-02-11 18:12:18 +05:30
Frappe PR Bot
a29468f6fe chore(release): Bumped to Version 15.13.0
# [15.13.0](https://github.com/frappe/erpnext/compare/v15.12.2...v15.13.0) (2024-02-11)

### Features

* get RM costs from consumption entry in manufacture SE (backport [#39822](https://github.com/frappe/erpnext/issues/39822)) (backport [#39847](https://github.com/frappe/erpnext/issues/39847)) ([#39849](https://github.com/frappe/erpnext/issues/39849)) ([beb4137](beb4137dac))
2024-02-11 12:20:07 +00:00
mergify[bot]
beb4137dac feat: get RM costs from consumption entry in manufacture SE (backport #39822) (backport #39847) (#39849)
feat: get RM costs from consumption entry in manufacture SE (backport #39822) (#39847)

feat: get RM costs from consumption entry in manufacture SE (#39822)

(cherry picked from commit 39067c7614)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
(cherry picked from commit 2d5f186812)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-02-11 17:48:47 +05:30
mergify[bot]
2d5f186812 feat: get RM costs from consumption entry in manufacture SE (backport #39822) (#39847)
feat: get RM costs from consumption entry in manufacture SE (#39822)

(cherry picked from commit 39067c7614)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-11 17:29:21 +05:30
mergify[bot]
43fce29a04 fix: stock entry for use serial batch fields (backport #39843) (#39844)
fix: stock entry for use serial batch fields (#39843)

(cherry picked from commit e5824fc3f1)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-11 11:28:48 +05:30
mergify[bot]
63b4d20bdf fix(ux): set rate as price list rate on uom change in MR (backport #39816) (#39818)
* fix: add price list rate field in MR Item

(cherry picked from commit 61a29eb5fb)

* fix: set rate as price list rate on uom change

(cherry picked from commit 5cf0759b0c)

* chore: linter

(cherry picked from commit 1745371cd6)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-10 15:58:33 +05:30
mergify[bot]
b625b05ddc fix: warehouse issue in pick list (backport #39826) (#39827)
fix: warehouse issue in pick list (#39826)

(cherry picked from commit 159a123dc7)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-09 11:32:51 +05:30
mergify[bot]
30daccecc7 fix: do not consider rejected warehouses in pick list (backport #39539) (backport #39804) (#39811)
* fix: do not consider rejected warehouses in pick list (backport #39539) (#39804)

* fix: do not consider rejected warehouses in pick list (#39539)

* fix: do not picked rejected materials

* test: test case for pick list without rejected materials

(cherry picked from commit f6725e4342)

# Conflicts:
#	erpnext/selling/doctype/sales_order/test_sales_order.py
#	erpnext/stock/doctype/pick_list/pick_list.json
#	erpnext/stock/doctype/pick_list/pick_list.py

* chore: fix conflicts

* chore: fix conflicts

* chore: fix conflicts

* chore: fixed test case

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 2c8e4c1ab3)

# Conflicts:
#	erpnext/selling/doctype/sales_order/test_sales_order.py

* chore: fix conflicts

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-08 14:41:58 +05:30
ruthra kumar
db4efd3332 Merge pull request #39803 from frappe/mergify/bp/version-15/pr-39783
fix: cancelling cr/dr notes should update the linked Invoice status (backport #39783)
2024-02-08 10:23:53 +05:30
ruthra kumar
7556457e3e refactor(test): Forex Credit Note cancellation against Invoice
(cherry picked from commit 2f676ced5c)
2024-02-08 04:36:15 +00:00
ruthra kumar
5590b04c89 refactor(test): assert Invoice status as well
(cherry picked from commit 33efe0d12d)
2024-02-08 04:36:14 +00:00
ruthra kumar
490cbc53d8 test: Invoice status on Cr/Dr note cancellation
(cherry picked from commit 31a8c3bdc4)
2024-02-08 04:36:14 +00:00
ruthra kumar
592b3ff7b7 refactor: cancel Cr/Dr JE's on Sales/Purchase return cancel
(cherry picked from commit 0549535603)
2024-02-08 04:36:14 +00:00
ruthra kumar
0bde22fe46 Merge pull request #39799 from frappe/mergify/bp/version-15-hotfix/pr-39783
fix: cancelling cr/dr notes should update the linked Invoice status (backport #39783)
2024-02-08 10:00:34 +05:30
mergify[bot]
60e04ab661 fix: incorrect planned qty in PP (backport #39785) (#39793)
fix: incorrect planned qty in PP

(cherry picked from commit a8ebc94a36)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-08 09:13:38 +05:30
ruthra kumar
83bf2c17e0 refactor(test): Forex Credit Note cancellation against Invoice
(cherry picked from commit 2f676ced5c)
2024-02-07 15:00:48 +00:00
ruthra kumar
a805796c0a refactor(test): assert Invoice status as well
(cherry picked from commit 33efe0d12d)
2024-02-07 15:00:47 +00:00
ruthra kumar
0bff065f0b test: Invoice status on Cr/Dr note cancellation
(cherry picked from commit 31a8c3bdc4)
2024-02-07 15:00:46 +00:00
ruthra kumar
5fd4ca56f5 refactor: cancel Cr/Dr JE's on Sales/Purchase return cancel
(cherry picked from commit 0549535603)
2024-02-07 15:00:45 +00:00
Frappe PR Bot
bc9a63497a chore(release): Bumped to Version 15.12.2
## [15.12.2](https://github.com/frappe/erpnext/compare/v15.12.1...v15.12.2) (2024-02-07)

### Bug Fixes

* remove duplicates from tax category map ([1f21607](1f21607e4f))
2024-02-07 14:22:43 +00:00
Gursheen Kaur Anand
b9dc0f3896 Merge pull request #39794 from frappe/mergify/bp/version-15/pr-39787
fix: remove duplicates from tax category map (backport #39787)
2024-02-07 19:51:02 +05:30
Gursheen Anand
1f21607e4f fix: remove duplicates from tax category map
(cherry picked from commit 3c6114ab72)
2024-02-07 13:54:03 +00:00
Gursheen Kaur Anand
a5ad318a37 Merge pull request #39787 from GursheenK/duplicates-in-tax-category-bpv15
fix: remove duplicates from tax category map
2024-02-07 19:22:27 +05:30
mergify[bot]
ba05648741 fix: add permissions to SRE (backport #39780) (#39786)
fix: add permissions to SRE

(cherry picked from commit 50f54d983d)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-07 19:03:25 +05:30
Gursheen Anand
3c6114ab72 fix: remove duplicates from tax category map 2024-02-07 18:27:08 +05:30
Frappe PR Bot
488e693ed8 chore(release): Bumped to Version 15.12.1
## [15.12.1](https://github.com/frappe/erpnext/compare/v15.12.0...v15.12.1) (2024-02-07)

### Bug Fixes

* set rate for PO created against BO (backport [#39765](https://github.com/frappe/erpnext/issues/39765)) (backport [#39767](https://github.com/frappe/erpnext/issues/39767)) ([#39775](https://github.com/frappe/erpnext/issues/39775)) ([ae2a8db](ae2a8db0d7))
2024-02-07 06:07:15 +00:00
mergify[bot]
ae2a8db0d7 fix: set rate for PO created against BO (backport #39765) (backport #39767) (#39775)
fix: set rate for PO created against BO (backport #39765) (#39767)

* fix: set rate for PO created against BO

(cherry picked from commit 0e5b4e5f07)

# Conflicts:
#	erpnext/manufacturing/doctype/blanket_order/blanket_order.py

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
(cherry picked from commit 22138867f5)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-02-07 11:35:55 +05:30
mergify[bot]
22138867f5 fix: set rate for PO created against BO (backport #39765) (#39767)
* fix: set rate for PO created against BO

(cherry picked from commit 0e5b4e5f07)

# Conflicts:
#	erpnext/manufacturing/doctype/blanket_order/blanket_order.py

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-07 10:48:58 +05:30
Frappe PR Bot
2ba283d138 chore(release): Bumped to Version 15.12.0
# [15.12.0](https://github.com/frappe/erpnext/compare/v15.11.1...v15.12.0) (2024-02-06)

### Bug Fixes

* Blanket Order Ordered Quantity (backport [#39725](https://github.com/frappe/erpnext/issues/39725)) ([#39739](https://github.com/frappe/erpnext/issues/39739)) ([b126720](b126720826))
* conditionally display show btn setting ([e931432](e9314325cc))
* correctly calculate diff amount for included taxes ([#39655](https://github.com/frappe/erpnext/issues/39655)) ([7f4cd3c](7f4cd3cd15))
* do not throw validation for cancelled sle ([02f56ee](02f56ee20e))
* don't overwrite existing terms in transaction ([dcdd3e8](dcdd3e8cc4))
* Exchange rate on MR to PO creation for muticurrency POs ([#39646](https://github.com/frappe/erpnext/issues/39646)) ([29eb090](29eb090528))
* fetch/change tax template on basis of base_net_rate instead of net_rate ([#39448](https://github.com/frappe/erpnext/issues/39448)) ([d7c7748](d7c7748c03))
* incorrect landed cost voucher amount ([a40864d](a40864dede))
* out of range for valuation_rate column in SE (backport [#39687](https://github.com/frappe/erpnext/issues/39687)) ([#39691](https://github.com/frappe/erpnext/issues/39691)) ([41e4632](41e46326c0))
* Percentage handling in queries ([#39692](https://github.com/frappe/erpnext/issues/39692)) ([e76f598](e76f59803c))
* **portal:** show PO pay button if payments installed ([cea4ed6](cea4ed6f88))
* Pricing rule application/removal on qty change ([#39084](https://github.com/frappe/erpnext/issues/39084)) ([f310707](f31070741a))
* production plan date filters for orders (backport [#39702](https://github.com/frappe/erpnext/issues/39702)) ([#39720](https://github.com/frappe/erpnext/issues/39720)) ([3eac436](3eac436e7b))
* remove applied pricing rule on qty change (backport [#39688](https://github.com/frappe/erpnext/issues/39688)) ([#39737](https://github.com/frappe/erpnext/issues/39737)) ([f246684](f246684694))
* remove file from the disk after the completion of reposting ([b582e9c](b582e9c42c))
* show warehouse title field in sales docs (backport [#39746](https://github.com/frappe/erpnext/issues/39746)) ([#39755](https://github.com/frappe/erpnext/issues/39755)) ([53992de](53992deb10))
* update company in serial no doc (backport [#39733](https://github.com/frappe/erpnext/issues/39733)) ([#39747](https://github.com/frappe/erpnext/issues/39747)) ([00e86bf](00e86bf318))
* use old serial / batch fields to make serial batch bundle ([282c19e](282c19e7e1))
* **work order:** resolve type error during job card creation (backport [#39713](https://github.com/frappe/erpnext/issues/39713)) ([#39714](https://github.com/frappe/erpnext/issues/39714)) ([5fe40ac](5fe40ac085))

### Features

* copy emails from lead to customer ([#38647](https://github.com/frappe/erpnext/issues/38647)) ([986273b](986273b6d3))
* make material request for job card from workstation dashboard ([3bef12c](3bef12cb55))
* Period-wise closing entries for TB ([#39712](https://github.com/frappe/erpnext/issues/39712)) ([1822325](1822325f34))
* reference for POS SI payments ([#39523](https://github.com/frappe/erpnext/issues/39523)) ([4ee8cf3](4ee8cf3907))
* visual plant floor ([75bd1e6](75bd1e6b65))

### Performance Improvements

* memory consumption for the stock balance report ([#39626](https://github.com/frappe/erpnext/issues/39626)) ([5e29aab](5e29aab83b))
* Move dimension validation out of GL Entry doctype ([#39730](https://github.com/frappe/erpnext/issues/39730)) ([451c288](451c288011))
* timeout for auto material request through reorder level ([1b2831b](1b2831bdfe))
* timeout while submitting the purchase receipt entry ([55a8326](55a8326d06))
2024-02-06 18:44:29 +00:00
rohitwaghchaure
af8af2b36e Merge pull request #39758 from frappe/version-15-hotfix
chore: release v15
2024-02-07 00:13:18 +05:30
rohitwaghchaure
789aee4544 Merge pull request #39770 from frappe/mergify/bp/version-15-hotfix/pr-39769
fix: do not throw validation for canceled SLE (backport #39769)
2024-02-06 23:46:00 +05:30
Rohit Waghchaure
02f56ee20e fix: do not throw validation for cancelled sle
(cherry picked from commit 32ccf3524a)
2024-02-06 17:43:17 +00:00
rohitwaghchaure
c78d4c15d3 Merge pull request #39768 from frappe/mergify/bp/version-15-hotfix/pr-39764
fix: remove file from the disk after the completion of reposting (backport #39764)
2024-02-06 22:22:46 +05:30
Rohit Waghchaure
7833138c57 test: test case to check removed attached file
(cherry picked from commit 76b57a4338)
2024-02-06 15:58:17 +00:00
Rohit Waghchaure
b582e9c42c fix: remove file from the disk after the completion of reposting
(cherry picked from commit fb330d1b5a)
2024-02-06 15:58:16 +00:00
rohitwaghchaure
faf79f4d2a Merge pull request #39761 from frappe/mergify/bp/version-15-hotfix/pr-39718
fix: use old serial / batch fields to make serial batch bundle (backport #39718)
2024-02-06 16:26:33 +05:30
ruthra kumar
47c2bd7335 Merge pull request #39751 from frappe/mergify/bp/version-15-hotfix/pr-39694
refactor: enforce unique GL Account for each 'Bank Account' (backport #39694)
2024-02-06 15:48:31 +05:30
Rohit Waghchaure
73618f0605 test: test case to check use serial / batch fields feature
(cherry picked from commit 01650120d4)
2024-02-06 10:18:06 +00:00
Rohit Waghchaure
a08b97e886 test: fixed test cases
(cherry picked from commit c1e869f040)
2024-02-06 10:18:05 +00:00
Rohit Waghchaure
282c19e7e1 fix: use old serial / batch fields to make serial batch bundle
(cherry picked from commit 9fafc83632)
2024-02-06 10:18:05 +00:00
mergify[bot]
53992deb10 fix: show warehouse title field in sales docs (backport #39746) (#39755)
fix: show warehouse title field in sales docs

(cherry picked from commit ee14faaa39)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-06 12:45:37 +05:30
ruthra kumar
4235e08668 refactor(test): make use of test fixtures in Payment Order
(cherry picked from commit 322cdbaccf)
2024-02-06 04:00:23 +00:00
ruthra kumar
949f4c3790 refactor(test): generate uniq GL acc and Bank acc for each test case
(cherry picked from commit a9a2ec81de)
2024-02-06 04:00:23 +00:00
ruthra kumar
11d4382e19 refactor: ensure unique accounts for each Bank Account's
(cherry picked from commit 2caa2d677c)
2024-02-06 04:00:23 +00:00
mergify[bot]
00e86bf318 fix: update company in serial no doc (backport #39733) (#39747)
fix: update company in serial no doc

(cherry picked from commit 7a04f0f7ba)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-05 21:55:56 +05:30
rohitwaghchaure
d3c4bd7f5f Merge pull request #39745 from frappe/mergify/bp/version-15-hotfix/pr-39742
perf: timeout while submitting the purchase receipt entry (backport #39742)
2024-02-05 21:17:59 +05:30
rohitwaghchaure
cb15ff1d74 Merge pull request #39743 from frappe/mergify/bp/version-15-hotfix/pr-39730
perf: Move dimension validation out of GL Entry doctype (backport #39730)
2024-02-05 21:17:43 +05:30
Rohit Waghchaure
55a8326d06 perf: timeout while submitting the purchase receipt entry
(cherry picked from commit 1fa6233377)
2024-02-05 15:33:04 +00:00
Deepesh Garg
451c288011 perf: Move dimension validation out of GL Entry doctype (#39730)
(cherry picked from commit b834ed10d6)
2024-02-05 15:31:36 +00:00
rohitwaghchaure
7923bd7964 Merge pull request #39741 from frappe/mergify/bp/version-15-hotfix/pr-38362
feat: visual plant floor (backport #38362)
2024-02-05 19:42:20 +05:30
Rohit Waghchaure
3bef12cb55 feat: make material request for job card from workstation dashboard
(cherry picked from commit 6fea9d6dfe)
2024-02-05 13:50:45 +00:00
Rohit Waghchaure
75bd1e6b65 feat: visual plant floor
(cherry picked from commit 68c997aa06)
2024-02-05 13:50:44 +00:00
mergify[bot]
b126720826 fix: Blanket Order Ordered Quantity (backport #39725) (#39739)
* fix: disable no-copy for blanket order in PO

(cherry picked from commit 5ce5c352e4)

* fix: update BO Ordered Quantity on PO Close/Open

(cherry picked from commit 61ded697a7)

* test: BO on PO Close/Open

(cherry picked from commit 27d6c8b6d5)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-05 16:31:20 +05:30
mergify[bot]
f246684694 fix: remove applied pricing rule on qty change (backport #39688) (#39737)
fix: remove pricing rule

(cherry picked from commit 7c6a5a0f23)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-05 16:09:00 +05:30
mergify[bot]
1822325f34 feat: Period-wise closing entries for TB (#39712)
feat: Period-wise closing entries for TB (#39712)

(cherry picked from commit 6e6c818084)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-02-05 14:34:33 +05:30
mergify[bot]
986273b6d3 feat: copy emails from lead to customer (#38647)
feat: copy emails from lead to customer

(cherry picked from commit 906ac093e3)

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
2024-02-05 14:05:44 +05:30
rohitwaghchaure
f4ac00595d Merge pull request #39729 from frappe/mergify/bp/version-15-hotfix/pr-39659
perf: timeout for auto material request through reorder level (backport #39659)
2024-02-05 13:20:22 +05:30
rohitwaghchaure
66661d0649 Merge pull request #39732 from frappe/mergify/bp/version-15-hotfix/pr-39626
perf: memory consumption for the stock balance report (backport #39626)
2024-02-05 13:17:41 +05:30
rohitwaghchaure
326751c8bd Merge pull request #39727 from frappe/mergify/bp/version-15-hotfix/pr-39684
fix: incorrect landed cost voucher amount (backport #39684)
2024-02-05 13:17:11 +05:30
rohitwaghchaure
5e29aab83b perf: memory consumption for the stock balance report (#39626)
(cherry picked from commit b70f3de16b)
2024-02-05 06:18:52 +00:00
Rohit Waghchaure
1b2831bdfe perf: timeout for auto material request through reorder level
(cherry picked from commit 951023f434)
2024-02-05 06:10:56 +00:00
Rohit Waghchaure
a40864dede fix: incorrect landed cost voucher amount
(cherry picked from commit d78a1e7814)
2024-02-05 06:09:51 +00:00
mergify[bot]
3eac436e7b fix: production plan date filters for orders (backport #39702) (#39720)
fix: production plan date filters for orders (#39702)

(cherry picked from commit 407045a1de)

Co-authored-by: Gursheen Kaur Anand <40693548+GursheenK@users.noreply.github.com>
2024-02-05 10:14:42 +05:30
mergify[bot]
5fe40ac085 fix(work order): resolve type error during job card creation (backport #39713) (#39714)
fix(work order): resolve type error during job card creation (#39713)

fix: type error
(cherry picked from commit c81d597ca5)

Co-authored-by: Vishnu  VS <Vishnuviswambaran2002@gmail.com>
2024-02-04 22:59:17 +05:30
mergify[bot]
4ee8cf3907 feat: reference for POS SI payments (#39523)
feat: reference for POS SI payments (#39523)

* feat: reference field in SI payment

* fix: document link for pos si

* refactor: pos invoice queries

(cherry picked from commit d9a72c1e61)

Co-authored-by: Gursheen Kaur Anand <40693548+GursheenK@users.noreply.github.com>
2024-02-04 17:54:56 +05:30
mergify[bot]
d7c7748c03 fix: fetch/change tax template on basis of base_net_rate instead of net_rate (#39448)
fix: fetch/change tax template on basis of base_net_rate instead of net_rate (#39448)

fix: change tax template on basis of base_net_rate instead of net_rate

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
(cherry picked from commit e9fe10c6f1)

Co-authored-by: Divyam Mistry <73271406+divyam-mistry@users.noreply.github.com>
2024-02-03 09:09:59 +05:30
mergify[bot]
f31070741a fix: Pricing rule application/removal on qty change (#39084)
fix: Pricing rule application/removal on qty change

(cherry picked from commit f52d7c7665)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-02-03 08:49:50 +05:30
Frappe PR Bot
317a74b58c chore(release): Bumped to Version 15.11.1
## [15.11.1](https://github.com/frappe/erpnext/compare/v15.11.0...v15.11.1) (2024-02-02)

### Bug Fixes

* Percentage handling in queries ([#39692](https://github.com/frappe/erpnext/issues/39692)) ([0405a2b](0405a2b817))
2024-02-02 15:24:10 +00:00
mergify[bot]
0405a2b817 fix: Percentage handling in queries (#39692)
fix: Percentage handling in queries (#39692)

fix: Percentage handling in queries (#39692)

* fix: Percentage handling in queries

* test: Account with percent sign

* chore: add test records

(cherry picked from commit 6d87cfeb8d)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
(cherry picked from commit e76f59803c)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-02-02 20:53:03 +05:30
mergify[bot]
e76f59803c fix: Percentage handling in queries (#39692)
fix: Percentage handling in queries (#39692)

* fix: Percentage handling in queries

* test: Account with percent sign

* chore: add test records

(cherry picked from commit 6d87cfeb8d)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-02-02 20:27:36 +05:30
mergify[bot]
41e46326c0 fix: out of range for valuation_rate column in SE (backport #39687) (#39691)
fix: out of range for valuation_rate column in SE

(cherry picked from commit 1e15a3cc15)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-02 15:24:45 +05:30
Gursheen Kaur Anand
8574941cb6 Merge pull request #39648 from frappe/mergify/bp/version-15-hotfix/pr-39519
fix: don't overwrite existing terms in transaction (backport #39519)
2024-02-01 23:48:18 +05:30
ruthra kumar
4f994cf26c Merge pull request #39666 from frappe/mergify/bp/version-15-hotfix/pr-39655
fix: correctly calculate diff amount for included taxes (backport #39655)
2024-02-01 19:44:57 +05:30
ruthra kumar
bb3591deec Merge pull request #39680 from frappe/mergify/bp/version-15-hotfix/pr-39674
refactor: use pop up to inform of possible data issue (backport #39674)
2024-02-01 17:31:18 +05:30
ruthra kumar
e2d041f51c refactor: use pop up to inform of possible data issue
and leave a comment in communcation trail as well

(cherry picked from commit 78483e2ee6)
2024-02-01 11:43:19 +00:00
ruthra kumar
63f306f1b4 Merge pull request #39676 from frappe/mergify/bp/version-15-hotfix/pr-39671
refactor: move ignore ERR filter from SOA to General Ledger (backport #39671)
2024-02-01 16:38:33 +05:30
ruthra kumar
72c95d31d1 refactor(test): use party with USD billing currency
(cherry picked from commit beff566c82)
2024-02-01 10:41:39 +00:00
ruthra kumar
1ee15f65a8 test: ignore_err filter out in General Ledger
(cherry picked from commit affca3a519)
2024-02-01 10:41:39 +00:00
ruthra kumar
0a235584ad refactor: move ignore ERR filters from SOA to General Ledger
(cherry picked from commit c077eda64e)
2024-02-01 10:41:39 +00:00
Gursheen Kaur Anand
7f4cd3cd15 fix: correctly calculate diff amount for included taxes (#39655)
(cherry picked from commit 772f540bef)
2024-02-01 04:44:40 +00:00
barredterra
ba55d0ede7 chore: resolve conflicts 2024-01-31 13:19:19 +01:00
rohitwaghchaure
c74482a27c Merge pull request #39658 from frappe/mergify/bp/version-15-hotfix/pr-39643
fix(portal): show PO pay button if payments installed (backport #39643)
2024-01-31 17:30:48 +05:30
rohitwaghchaure
510ab769f1 chore: fix conflicts 2024-01-31 15:23:14 +05:30
Gursheen Anand
e9314325cc fix: conditionally display show btn setting
(cherry picked from commit 0c9572bb48)

# Conflicts:
#	erpnext/buying/doctype/buying_settings/buying_settings.json
2024-01-31 09:16:12 +00:00
Gursheen Anand
cea4ed6f88 fix(portal): show PO pay button if payments installed
(cherry picked from commit ae7be84d87)
2024-01-31 09:16:11 +00:00
mergify[bot]
29eb090528 fix: Exchange rate on MR to PO creation for muticurrency POs (#39646)
fix: Exchange rate on MR to PO creation for muticurrency POs (#39646)

(cherry picked from commit cfd1666181)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-01-31 12:49:48 +05:30
mergify[bot]
aebb0c7979 chore: cleanup doctype descriptions (backport #39637) (#39652)
* chore: cleanup doctype descriptions (#39637)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit 6b8f046fb4)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
#	erpnext/accounts/doctype/fiscal_year/fiscal_year.json
#	erpnext/stock/doctype/item_price/item_price.json
#	erpnext/stock/doctype/stock_settings/stock_settings.json

* chore: fix conflicts

---------

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2024-01-31 12:38:37 +05:30
barredterra
dcdd3e8cc4 fix: don't overwrite existing terms in transaction
(cherry picked from commit 77b044f1a6)

# Conflicts:
#	erpnext/public/js/controllers/transaction.js
2024-01-31 00:14:44 +00:00
Frappe PR Bot
f84f82c7d7 chore(release): Bumped to Version 15.11.0
# [15.11.0](https://github.com/frappe/erpnext/compare/v15.10.8...v15.11.0) (2024-01-30)

### Bug Fixes

* AttributeError in company transaction deletion ([222005c](222005ca44))
* **Batch:** reload doc after splitting ([a97b8fd](a97b8fd876))
* check page obj before adding menu ([0aa73e3](0aa73e31ce))
* default enable closing stock balance (backport [#39551](https://github.com/frappe/erpnext/issues/39551)) ([#39554](https://github.com/frappe/erpnext/issues/39554)) ([4853ab1](4853ab1fec))
* do not auto-populate item delivery date ([5cdc22a](5cdc22adf3))
* email list for auto reorder material request ([98c5653](98c56535d8))
* enqueue JV submission when more than 100 accounts ([07bcc24](07bcc24e35))
* fetch correct quantity and amount for grouped asset ([3bdd1e9](3bdd1e9514))
* honour currency precision while fetching balance ([e0a3820](e0a38207f6))
* incorrect active serial nos (backport [#39389](https://github.com/frappe/erpnext/issues/39389)) ([#39589](https://github.com/frappe/erpnext/issues/39589)) ([7def475](7def475eb1))
* incorrect amount in the material request item (backport [#39567](https://github.com/frappe/erpnext/issues/39567)) ([#39569](https://github.com/frappe/erpnext/issues/39569)) ([e0c35d6](e0c35d60b4))
* Item Tax template is not working for e-commerce ([2905db1](2905db19e5))
* make SO item code reqd ([171586d](171586db9b))
* not able to edit address through portal ([1f5dbeb](1f5dbebe68))
* not able to save BOM (duplicate key error) (backport [#39620](https://github.com/frappe/erpnext/issues/39620)) ([#39623](https://github.com/frappe/erpnext/issues/39623)) ([53c7055](53c705506b))
* not able to save subcontracting purchase receipt (old flow) (backport [#39590](https://github.com/frappe/erpnext/issues/39590)) ([#39592](https://github.com/frappe/erpnext/issues/39592)) ([63eef68](63eef680d0))
* not able to submit subcontracting pr (old flow) (backport [#39622](https://github.com/frappe/erpnext/issues/39622)) ([#39625](https://github.com/frappe/erpnext/issues/39625)) ([960443d](960443d268))
* Payment Terms Status for Sales Order report should show all payment terms from order not only this comming from template ([b2e0d24](b2e0d24954))
* perf issue while submitting stock entry (backport [#39634](https://github.com/frappe/erpnext/issues/39634)) ([#39642](https://github.com/frappe/erpnext/issues/39642)) ([d785c6c](d785c6ce3e))
* prevent extra transfer against inter transfer transaction (backport [#39213](https://github.com/frappe/erpnext/issues/39213)) ([#39596](https://github.com/frappe/erpnext/issues/39596)) ([6d4ca6a](6d4ca6a1ee))
* qtn tests using delivery date ([6b20a7e](6b20a7eed1))
* return doc obj after submit ([da33079](da33079f12))
* Serial No Ledger permission issue ([f9d1995](f9d1995954))
* skip liability account for internal transfer ([e2d85c5](e2d85c513c))
* type error on company doc ([a7d1368](a7d13686c7))

### Features

* In words in payment entry ([5df2f5d](5df2f5d523))
* New financial views - Growth and margin views for P&L and balance sheet ([#39588](https://github.com/frappe/erpnext/issues/39588)) ([a83f310](a83f3106f3))
* Partly billed status in Purchase Receipt ([#39543](https://github.com/frappe/erpnext/issues/39543)) ([e4230cf](e4230cf6d9))
2024-01-30 14:14:58 +00:00
rohitwaghchaure
32f77eae5d Merge pull request #39639 from frappe/version-15-hotfix
chore: release v15
2024-01-30 19:42:27 +05:30
mergify[bot]
d785c6ce3e fix: perf issue while submitting stock entry (backport #39634) (#39642)
fix: perf issue while submitting stock entry (#39634)

(cherry picked from commit b14886b227)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-30 15:43:50 +05:30
ruthra kumar
bc8ab51f9d Merge pull request #39633 from frappe/mergify/bp/version-15-hotfix/pr-39559
fix: prevent Return Invoices(Credit/Debit Note) from using a different account  (backport #39559)
2024-01-30 11:20:25 +05:30
ruthra kumar
5c9c3bee70 test: debit note account mismatch
(cherry picked from commit bdca718103)
2024-01-30 05:31:53 +00:00
ruthra kumar
c9ea83591f test: account mismatch validation
(cherry picked from commit 8bdc760733)
2024-01-30 05:31:53 +00:00
ruthra kumar
10fcf5af5f refactor: prevent '{debit/credit}_to' account mismatch
(cherry picked from commit 6f2fae1b61)
2024-01-30 05:31:52 +00:00
mergify[bot]
e4230cf6d9 feat: Partly billed status in Purchase Receipt (#39543)
feat: Partly billed status in Purchase Receipt (#39543)

(cherry picked from commit a673220feb)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-01-29 22:41:09 +05:30
mergify[bot]
53c705506b fix: not able to save BOM (duplicate key error) (backport #39620) (#39623)
fix: not able to save BOM (duplicate key error) (#39620)

(cherry picked from commit 4e182b89ce)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-29 21:22:34 +05:30
mergify[bot]
960443d268 fix: not able to submit subcontracting pr (old flow) (backport #39622) (#39625)
fix: not able to submit subcontracting pr (old flow) (#39622)

(cherry picked from commit 5cf47ae5f9)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-29 21:22:21 +05:30
Gursheen Kaur Anand
f71af209c0 Merge pull request #39618 from frappe/mergify/bp/version-15-hotfix/pr-39616
fix(minor): do not auto-populate item delivery date from qtn (backport #39616)
2024-01-29 16:53:39 +05:30
Gursheen Anand
6b20a7eed1 fix: qtn tests using delivery date
(cherry picked from commit 079cd30b9c)
2024-01-29 10:22:01 +00:00
Gursheen Anand
5cdc22adf3 fix: do not auto-populate item delivery date
(cherry picked from commit 49cb11c1f3)
2024-01-29 10:22:00 +00:00
mergify[bot]
9e36ab7de7 fix amount not updated when change rate in material request (backport #39606) (#39615)
fix amount not updated when change rate in material request (#39606)

* fix amount not updated when change rate in material request

* make code consistent

(cherry picked from commit efade9b9ae)

Co-authored-by: Jeffry Suryadharma <41689493+jeffrysurya@users.noreply.github.com>
2024-01-29 13:36:27 +05:30
Gursheen Kaur Anand
daafe45dd4 Merge pull request #39612 from frappe/mergify/bp/version-15-hotfix/pr-39562
fix: enqueue JV submission when > 100 accounts (backport #39562)
2024-01-29 11:55:58 +05:30
Gursheen Kaur Anand
706d1111ad Merge pull request #39610 from frappe/mergify/bp/version-15-hotfix/pr-39598
fix(minor): type error in financial statements for dashboard (backport #39598)
2024-01-29 11:42:17 +05:30
Gursheen Anand
da33079f12 fix: return doc obj after submit
(cherry picked from commit fc677811b7)
2024-01-29 06:10:03 +00:00
Gursheen Anand
07bcc24e35 fix: enqueue JV submission when more than 100 accounts
(cherry picked from commit 53b44ccf29)
2024-01-29 06:10:02 +00:00
Nabin Hait
0f0a5b73f6 Merge pull request #39566 from frappe/mergify/bp/version-15-hotfix/pr-39489
fix: fetch correct quantity and amount for grouped asset (backport #39489)
2024-01-29 11:38:33 +05:30
Gursheen Anand
0aa73e31ce fix: check page obj before adding menu
(cherry picked from commit 2486b646a1)
2024-01-29 06:07:13 +00:00
Frappe PR Bot
a3d4f63ba1 chore(release): Bumped to Version 15.10.8
## [15.10.8](https://github.com/frappe/erpnext/compare/v15.10.7...v15.10.8) (2024-01-29)

### Bug Fixes

* not able to save subcontracting purchase receipt (old flow) (backport [#39590](https://github.com/frappe/erpnext/issues/39590)) (backport [#39592](https://github.com/frappe/erpnext/issues/39592)) ([#39608](https://github.com/frappe/erpnext/issues/39608)) ([ff166e8](ff166e8104))
2024-01-29 04:39:51 +00:00
mergify[bot]
ff166e8104 fix: not able to save subcontracting purchase receipt (old flow) (backport #39590) (backport #39592) (#39608)
fix: not able to save subcontracting purchase receipt (old flow) (backport #39590) (#39592)

fix: not able to save subcontracting purchase receipt (old flow) (#39590)

(cherry picked from commit 67d828dab3)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 63eef680d0)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-01-29 10:08:40 +05:30
mergify[bot]
a118417645 refactor: provision to filter on dimensions in reconciliation tool (#39054)
* refactor: dimensions section in allocation table in reconciliation

(cherry picked from commit 1cde804c77)

# Conflicts:
#	erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json

* refactor: update dimension doctypes in hooks

(cherry picked from commit cfb3d87267)

* refactor: dimensions filter section in payment reconciliation

(cherry picked from commit 20e0acc20a)

* refactor: column break in dimension section

(cherry picked from commit 20576e0f47)

# Conflicts:
#	erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json

* refactor: handle dimension filters

(cherry picked from commit c1fe4bcc64)

* refactor: pass dimension filters to query

(cherry picked from commit ff60ec85b8)

* refactor: set query filters for dimensions

(cherry picked from commit ad8475cb8b)

* refactor: pass dimension details to query

(cherry picked from commit 5dc22e1811)

* refactor: replace sql with query builder for Jourals query

(cherry picked from commit 9c5a79209e)

* refactor: partial change on outstanding invoice popup

(cherry picked from commit 2154502955)

* fix: typo's and parameter changes

(cherry picked from commit 0ec17590ae)

* refactor: Credit Note and its Exc gain/loss JE inherits dimensions

(cherry picked from commit ab939cc6e8)

* refactor: apply dimension filters on cr/dr notes

(cherry picked from commit 188ff8cde7)

* chore: test dimension filter output

(cherry picked from commit e3c44231ab)

* test: dimension inheritance for cr note reconciliation

(cherry picked from commit ba5a7c8cd8)

* refactor: pass dimension values to Gain/Loss journal

(cherry picked from commit c44eb432a5)

# Conflicts:
#	erpnext/accounts/utils.py

* test: dimension inheritance in PE reconciliation

(cherry picked from commit 6148fb024b)

* refactor: pass dimensions on advance allocation

(cherry picked from commit cbd443a78a)

* test: dimension inheritance on adv allocation

(cherry picked from commit fcf4687c52)

* refactor: dynamic dimension filters in pop up

(cherry picked from commit f8bbb0619c)

* refactor: update dimensions, only if provided

(cherry picked from commit ec0f17ca8b)

* refactor: handle dynamic dimension in order query

(cherry picked from commit 7c2cb70387)

* chore: resolve conflicts

---------

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2024-01-28 13:50:08 +05:30
mergify[bot]
a83f3106f3 feat: New financial views - Growth and margin views for P&L and balance sheet (#39588)
feat: New financial views - Growth and margin views for P&L and balance sheet (#39588)
2024-01-28 13:48:55 +05:30
mergify[bot]
6d4ca6a1ee fix: prevent extra transfer against inter transfer transaction (backport #39213) (#39596)
fix: prevent extra transfer against inter transfer transaction (#39213)

* fix: prevent extra transfer against inter transfer transaction

* fix: internal transfer dashboard

(cherry picked from commit 8fdc244e16)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-27 23:25:13 +05:30
ruthra kumar
ebec463166 Merge pull request #39594 from frappe/mergify/bp/version-15-hotfix/pr-39591
refactor: Do proper currency conversion on Future Payments column in AR/AP report (backport #39591)
2024-01-27 13:19:27 +05:30
ruthra kumar
10488520e7 test: future payment with foreign currency
(cherry picked from commit 7b37389115)
2024-01-27 07:23:17 +00:00
ruthra kumar
9e15a3c981 refactor: do currency conversion on future amount columns
(cherry picked from commit 0de4197c88)
2024-01-27 07:23:16 +00:00
mergify[bot]
63eef680d0 fix: not able to save subcontracting purchase receipt (old flow) (backport #39590) (#39592)
fix: not able to save subcontracting purchase receipt (old flow) (#39590)

(cherry picked from commit 67d828dab3)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-27 12:15:11 +05:30
mergify[bot]
7def475eb1 fix: incorrect active serial nos (backport #39389) (#39589)
fix: incorrect active serial nos

(cherry picked from commit 64cb1153de)

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2024-01-27 11:57:58 +05:30
Frappe PR Bot
0e2f57ba89 chore(release): Bumped to Version 15.10.7
## [15.10.7](https://github.com/frappe/erpnext/compare/v15.10.6...v15.10.7) (2024-01-27)

### Bug Fixes

* incorrect amount in the material request item (backport [#39567](https://github.com/frappe/erpnext/issues/39567)) (backport [#39569](https://github.com/frappe/erpnext/issues/39569)) ([#39587](https://github.com/frappe/erpnext/issues/39587)) ([30bdba4](30bdba4801))
2024-01-27 04:43:59 +00:00
mergify[bot]
30bdba4801 fix: incorrect amount in the material request item (backport #39567) (backport #39569) (#39587)
fix: incorrect amount in the material request item (backport #39567) (#39569)

fix: incorrect amount in the material request item (#39567)

fix: incoorect amount in the material request
(cherry picked from commit 2bdfdeeb9a)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit e0c35d60b4)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-01-27 10:12:45 +05:30
mergify[bot]
ed06f0cd1b refactor: BOM creator item selector with short description (backport #39433) (#39435)
refactor: BOM creator item selector with short description

(cherry picked from commit 0f881bc90a)

Co-authored-by: Florian HENRY <florian.henry@open-concept.pro>
2024-01-27 09:51:14 +05:30
Gursheen Kaur Anand
9abc07e34b Merge pull request #39585 from frappe/mergify/bp/version-15-hotfix/pr-39532
fix: type error in transaction.js (backport #39532)
2024-01-26 23:46:57 +05:30
Gursheen Anand
a7d13686c7 fix: type error on company doc
(cherry picked from commit 030d35628d)
2024-01-26 17:31:07 +00:00
Deepesh Garg
ab99414242 Merge pull request #39577 from frappe/mergify/bp/version-15-hotfix/pr-39511
refactor(Sales Invoice): set account and sum for payments (#39511)
2024-01-26 10:04:23 +05:30
Deepesh Garg
fa8fb7a49e Merge pull request #39575 from frappe/mergify/bp/version-15-hotfix/pr-39108
feat: In words in payment entry (#39108)
2024-01-26 09:46:01 +05:30
barredterra
4fc3a264f9 refactor(Sales Invoice): set account for mode of payment
(cherry picked from commit 3815f07c33)
2024-01-26 04:15:14 +00:00
Deepesh Garg
5df2f5d523 feat: In words in payment entry
(cherry picked from commit b21da472f6)
2024-01-26 04:01:45 +00:00
mergify[bot]
e0c35d60b4 fix: incorrect amount in the material request item (backport #39567) (#39569)
fix: incorrect amount in the material request item (#39567)

fix: incoorect amount in the material request
(cherry picked from commit 2bdfdeeb9a)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-25 17:22:31 +05:30
Gursheen Kaur Anand
14aa9d3d0f Merge pull request #39564 from frappe/mergify/bp/version-15-hotfix/pr-39557
fix: make SO item code mandatory (backport #39557)
2024-01-25 16:39:39 +05:30
Nabin Hait
3bdd1e9514 fix: fetch correct quantity and amount for grouped asset
(cherry picked from commit 06f48c678b)
2024-01-25 10:51:53 +00:00
Gursheen Anand
171586db9b fix: make SO item code reqd
(cherry picked from commit 7f8303a493)
2024-01-25 10:50:38 +00:00
ruthra kumar
c3557a87ef Merge pull request #39552 from frappe/mergify/bp/version-15-hotfix/pr-38218
fix: honour currency precision while fetching balance (backport #38218)
2024-01-25 13:25:15 +05:30
mergify[bot]
4853ab1fec fix: default enable closing stock balance (backport #39551) (#39554)
fix: default enable closing stock balance (#39551)

(cherry picked from commit d1fb90edff)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-25 12:51:55 +05:30
Dany Robert
ed032b3224 chore: avoid explicit escaping for precision
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
(cherry picked from commit a8949174c8)
2024-01-25 07:00:45 +00:00
Dany Robert
8b7900e6a7 chore: change f-string to sql params
(cherry picked from commit 383a4b132e)
2024-01-25 07:00:45 +00:00
Dany Robert
e0a38207f6 fix: honour currency precision while fetching balance
(cherry picked from commit bfaa93b0ca)
2024-01-25 07:00:45 +00:00
Frappe PR Bot
53b844f173 chore(release): Bumped to Version 15.10.6
## [15.10.6](https://github.com/frappe/erpnext/compare/v15.10.5...v15.10.6) (2024-01-25)

### Bug Fixes

* Item Tax template is not working for e-commerce ([83c1208](83c120849f))
2024-01-25 06:48:53 +00:00
rohitwaghchaure
34e581715a Merge pull request #39550 from frappe/mergify/bp/version-15/pr-39549
fix: Item Tax template is not working for e-commerce (backport #39547) (backport #39549)
2024-01-25 12:17:43 +05:30
Rohit Waghchaure
83c120849f fix: Item Tax template is not working for e-commerce
(cherry picked from commit 7d3240ae3a)
(cherry picked from commit 2905db19e5)
2024-01-25 06:24:19 +00:00
rohitwaghchaure
e08c7bad63 Merge pull request #39549 from frappe/mergify/bp/version-15-hotfix/pr-39547
fix: Item Tax template is not working for e-commerce (backport #39547)
2024-01-25 11:53:30 +05:30
Rohit Waghchaure
2905db19e5 fix: Item Tax template is not working for e-commerce
(cherry picked from commit 7d3240ae3a)
2024-01-25 06:07:23 +00:00
ruthra kumar
bd7e8ed230 Merge pull request #39538 from frappe/mergify/bp/version-15-hotfix/pr-39331
fix: Payment Terms Status for Sales Order report show all payment terms from orders (not only when there is a payment terms template) (backport #39331)
2024-01-24 16:27:29 +05:30
Florian HENRY
b2e0d24954 fix: Payment Terms Status for Sales Order report should show all payment terms from order not only this comming from template
(cherry picked from commit 6c8f52b26f)
2024-01-24 10:43:08 +00:00
rohitwaghchaure
84a94cec6b Merge pull request #39531 from frappe/mergify/bp/version-15-hotfix/pr-39525
fix: email list for auto reorder material request (backport #39525)
2024-01-24 14:49:28 +05:30
Frappe PR Bot
cc195777f4 chore(release): Bumped to Version 15.10.5
## [15.10.5](https://github.com/frappe/erpnext/compare/v15.10.4...v15.10.5) (2024-01-24)

### Bug Fixes

* AttributeError in company transaction deletion ([3549cd3](3549cd39f1))
2024-01-24 07:59:52 +00:00
ruthra kumar
60c10f4457 Merge pull request #39534 from frappe/mergify/bp/version-15/pr-39529
fix: AttributeError in company transaction deletion (backport #39529)
2024-01-24 13:28:34 +05:30
ruthra kumar
871dc6b0da Merge pull request #39533 from frappe/mergify/bp/version-15-hotfix/pr-39529
fix: AttributeError in company transaction deletion (backport #39529)
2024-01-24 13:28:22 +05:30
ruthra kumar
3549cd39f1 fix: AttributeError in company transaction deletion
(cherry picked from commit b127aa308e)
2024-01-24 07:43:02 +00:00
ruthra kumar
222005ca44 fix: AttributeError in company transaction deletion
(cherry picked from commit b127aa308e)
2024-01-24 07:40:59 +00:00
Rohit Waghchaure
98c56535d8 fix: email list for auto reorder material request
(cherry picked from commit 764f3422a0)
2024-01-24 07:07:16 +00:00
rohitwaghchaure
f6a779e1aa Merge pull request #39527 from frappe/mergify/bp/version-15-hotfix/pr-39521
fix: not able to edit address through portal (backport #39521)
2024-01-24 12:17:05 +05:30
Rohit Waghchaure
1f5dbebe68 fix: not able to edit address through portal
(cherry picked from commit b046d980ad)
2024-01-24 06:20:31 +00:00
Gursheen Kaur Anand
4073dfb90b Merge pull request #39522 from frappe/mergify/bp/version-15-hotfix/pr-39493
fix: skip setting liability account for internal transfer (backport #39493)
2024-01-24 11:08:53 +05:30
Gursheen Anand
e2d85c513c fix: skip liability account for internal transfer
(cherry picked from commit 236b73565e)
2024-01-24 05:04:45 +00:00
rohitwaghchaure
880f648846 Merge pull request #39513 from frappe/mergify/bp/version-15-hotfix/pr-39503
fix: Serial No Ledger permission issue (backport #39503)
2024-01-24 10:27:23 +05:30
Raffael Meyer
84d2a80f30 Merge pull request #39516 from frappe/mergify/bp/version-15-hotfix/pr-39512 2024-01-23 19:00:53 +01:00
barredterra
fe41e2a341 refactor(Batch): use const instead of var
(cherry picked from commit 7a7a213285)
2024-01-23 16:55:27 +00:00
barredterra
a97b8fd876 fix(Batch): reload doc after splitting
to show updated qty

(cherry picked from commit 34ec2f8a2b)
2024-01-23 16:55:27 +00:00
barredterra
6ed42e939b refactor: split batch
(cherry picked from commit 3c7e7a76f0)
2024-01-23 16:55:26 +00:00
Rohit Waghchaure
f9d1995954 fix: Serial No Ledger permission issue
(cherry picked from commit 1a670ff266)
2024-01-23 13:37:35 +00:00
Frappe PR Bot
028ae5b34f chore(release): Bumped to Version 15.10.4
## [15.10.4](https://github.com/frappe/erpnext/compare/v15.10.3...v15.10.4) (2024-01-23)

### Bug Fixes

* added button to make serial / batch from Purchase Invoice ([96e1db8](96e1db80ac))
* auto create serial no on scan ([ca93f67](ca93f671df))
* duplicate name error while making variant ([b649c50](b649c50ecc))
* key error during reposting ([b4981f8](b4981f8816))
* linting issue ([86f3f62](86f3f62e00))
* party field in pdf html ([9a08349](9a0834987c))
* set unallocated amount after base tax ([74613c7](74613c7fe8))
* UOM needs to be whole number not being checked in quotations ([c7d5857](c7d5857014))
* use most reliable section reference per report line ([b388adc](b388adcb2e))
* UX improvements for Serial and Batch Bundle ([c761459](c76145985d))
2024-01-23 11:59:22 +00:00
ruthra kumar
2a7f7df3e5 Merge pull request #39505 from frappe/version-15-hotfix
chore: release v15
2024-01-23 17:28:01 +05:30
rohitwaghchaure
1331fb75a3 Merge pull request #39496 from frappe/mergify/bp/version-15-hotfix/pr-39478
fix: UX improvements for Serial and Batch Bundle (backport #39478)
2024-01-23 13:18:16 +05:30
Rohit Waghchaure
ca93f671df fix: auto create serial no on scan
(cherry picked from commit fc0d2aeeff)
2024-01-23 06:27:59 +00:00
Rohit Waghchaure
c76145985d fix: UX improvements for Serial and Batch Bundle
(cherry picked from commit 5d94f0bde5)
2024-01-23 06:27:59 +00:00
rohitwaghchaure
a6b4d5b101 Merge pull request #39492 from frappe/mergify/bp/version-15-hotfix/pr-39488
fix: UOM needs to be whole number not being checked in quotations (backport #39488)
2024-01-23 11:54:54 +05:30
Rohit Waghchaure
c7d5857014 fix: UOM needs to be whole number not being checked in quotations
(cherry picked from commit aaf83da3e9)
2024-01-22 11:55:29 +00:00
Gursheen Kaur Anand
b53e072082 Merge pull request #39483 from frappe/mergify/bp/version-15-hotfix/pr-39462
fix: party field in PDF for AP / AR reports (backport #39462)
2024-01-22 17:05:48 +05:30
ruthra kumar
dc88614f89 Merge pull request #39486 from frappe/mergify/bp/version-15-hotfix/pr-39484
refactor: move 'project' set_query to sales_common.js (backport #39484)
2024-01-22 16:48:52 +05:30
ruthra kumar
0acbbefa8b refactor: move 'project' set_query to sales_common.js
(cherry picked from commit 52814724eb)
2024-01-22 10:21:28 +00:00
Gursheen Anand
9a0834987c fix: party field in pdf html
(cherry picked from commit b2d9380596)
2024-01-22 09:51:29 +00:00
ruthra kumar
3e9449d511 Merge pull request #39480 from frappe/mergify/bp/version-15-hotfix/pr-39457
refactor: delete transactions in background (backport #39457)
2024-01-22 10:44:04 +05:30
ruthra kumar
80e3597338 refactor: delete transactions in background
(cherry picked from commit a50808a077)
2024-01-22 04:28:27 +00:00
rohitwaghchaure
3c84d5ec02 Merge pull request #39479 from frappe/mergify/bp/version-15-hotfix/pr-39476
fix: added button to make serial / batch from Purchase Invoice (backport #39476)
2024-01-22 07:36:55 +05:30
Rohit Waghchaure
b0e872aad4 test: fixed test
(cherry picked from commit 63ffce58cc)
2024-01-21 16:53:46 +00:00
Rohit Waghchaure
96e1db80ac fix: added button to make serial / batch from Purchase Invoice
(cherry picked from commit b4393bc03d)
2024-01-21 16:53:46 +00:00
rohitwaghchaure
35d3edfca4 Merge pull request #39477 from frappe/mergify/bp/version-15-hotfix/pr-39475
fix: key error during reposting (backport #39475)
2024-01-21 22:23:26 +05:30
Rohit Waghchaure
b4981f8816 fix: key error during reposting
(cherry picked from commit ebc8230d45)
2024-01-21 14:22:36 +00:00
Gursheen Kaur Anand
7c666435a2 Merge pull request #39474 from frappe/mergify/bp/version-15-hotfix/pr-39229
fix: use most reliable section reference per report line (backport #39229)
2024-01-21 14:23:12 +05:30
David Arnold
b388adcb2e fix: use most reliable section reference per report line
(cherry picked from commit b5be17c6df)
2024-01-21 08:14:55 +00:00
Gursheen Kaur Anand
3ba413a150 Merge pull request #39471 from frappe/mergify/bp/version-15-hotfix/pr-39424
Revert "fix(minor): financial statements period end date" (backport #39424)
2024-01-20 18:51:34 +05:30
Gursheen Kaur Anand
ddb84d9036 Revert "fix(minor): financial statements period end date"
(cherry picked from commit 73625a2622)
2024-01-20 12:29:27 +00:00
mergify[bot]
00a3ee313b refactor(UX): Accounts workspace cleanup (backport #39232) (#39456)
* refactor(UX): Accounts workspace cleanup (#39232)

* refactor(UX): Accounts workspace cleanup

* chore: move asset workspace outside accounting

* fix: remove redundant links from parent workspace

* chore: change icons for payable & receivable workspaces

* chore: remove redundant links from subworkspaces

(cherry picked from commit 35067282cf)

* chore: fix conflicts

---------

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2024-01-19 12:40:25 +05:30
Gursheen Kaur Anand
f8d7ca515c Merge pull request #39451 from frappe/mergify/bp/version-15-hotfix/pr-39449
fix: unallocated amount after taxes and charges (backport #39449)
2024-01-19 10:57:35 +05:30
Frappe PR Bot
550213b4f4 chore(release): Bumped to Version 15.10.3
## [15.10.3](https://github.com/frappe/erpnext/compare/v15.10.2...v15.10.3) (2024-01-19)

### Bug Fixes

* duplicate name error while making variant ([0c222aa](0c222aa504))
2024-01-19 00:44:51 +00:00
rohitwaghchaure
a962657c7b Merge pull request #39444 from frappe/mergify/bp/version-15/pr-39443
fix: duplicate name error while making variant (backport #39436) (backport #39443)
2024-01-19 06:13:35 +05:30
Gursheen Anand
86f3f62e00 fix: linting issue
(cherry picked from commit 99b94af49f)
2024-01-18 10:45:49 +00:00
Gursheen Anand
74613c7fe8 fix: set unallocated amount after base tax
(cherry picked from commit e9bc63aacf)
2024-01-18 10:45:49 +00:00
Rohit Waghchaure
0c222aa504 fix: duplicate name error while making variant
(cherry picked from commit d7e6b83e64)
(cherry picked from commit b649c50ecc)
2024-01-18 01:24:00 +00:00
rohitwaghchaure
3244ef3a68 Merge pull request #39443 from frappe/mergify/bp/version-15-hotfix/pr-39436
fix: duplicate name error while making variant (backport #39436)
2024-01-18 06:52:17 +05:30
Rohit Waghchaure
b649c50ecc fix: duplicate name error while making variant
(cherry picked from commit d7e6b83e64)
2024-01-18 01:21:52 +00:00
Frappe PR Bot
d5c26efb8c chore(release): Bumped to Version 15.10.2
## [15.10.2](https://github.com/frappe/erpnext/compare/v15.10.1...v15.10.2) (2024-01-17)

### Bug Fixes

* added indexing to improve performance ([50fe419](50fe4191d3))
* added item group in stock reco ([eec6c25](eec6c25f9e))
* Asset module tests ([9e33216](9e33216c24))
* asset WDV depreciation calc according to IT act ([2448ba6](2448ba6bc4))
* batches not coming correctly in the batch selector ([1394a1c](1394a1c5e9))
* broken dimension filters in Sales/Purchase register ([04037b7](04037b7e38))
* Cancel asset capitalisation record on cancellation of asset and vice-versa ([011c5a6](011c5a69f0))
* circular dependency error while deleting QC ([7ca8e49](7ca8e49b38))
* composite asset capitalization using asset components ([8bc8bc1](8bc8bc1822))
* consider all years in holiday list ([21eed78](21eed78fa1))
* consistency in display reserved_stock checkbox on Sales Order Item according global settings and item.is_stock_item (backport [#38322](https://github.com/frappe/erpnext/issues/38322)) ([#39417](https://github.com/frappe/erpnext/issues/39417)) ([53f61f1](53f61f1ad1))
* date in master document for dictionary condition ([9aae439](9aae439b1f))
* fetch name for fy ([53208df](53208dfb3e))
* Ignore default payment terms template for opening invoices ([5dc2e80](5dc2e80987))
* incorrect percentage received in purchase invoice ([758b9b8](758b9b8a81))
* incorrect sql error if account name has '%' ([b43f703](b43f70325c))
* modified date ([cd870ee](cd870ee30c))
* modified date ([f048017](f0480173fb))
* modified date was not set ([2dc8686](2dc8686a81))
* modified date was not updated ([61595c7](61595c7ede))
* performance issue related to stock entry (backport [#39301](https://github.com/frappe/erpnext/issues/39301)) ([#39303](https://github.com/frappe/erpnext/issues/39303)) ([d882305](d882305c72))
* permission issue for the BIN ([8816b27](8816b2740a))
* possible typerror in utils.js ([80956b7](80956b7956))
* project filters on Delivery Note and Sales Order ([a51f956](a51f956f3e))
* project query controller logic ([07e2901](07e2901e4b))
* reset default after test ([e6f3a14](e6f3a14289))
* SBB Total Qty validation for SE ([ca18853](ca18853785))
* test for asset depreciation ([ff1647a](ff1647a1d2))
* **test:** test case for project query ([1b8f572](1b8f572e80))
* unreconcile Bank Transaction on cancel of payment voucher ([16860c2](16860c228d))
* Update subscription period ([e219042](e219042304))
* use child table values instead of global min max ([04c96dd](04c96ddc6c))
* WDV as per IT Act: calculate yearly amount first and then split it based on months ([e3cd35b](e3cd35b959))
2024-01-17 17:06:29 +00:00
Deepesh Garg
e00533ff4e Merge pull request #39405 from frappe/version-15-hotfix
chore: release v15
2024-01-17 22:34:57 +05:30
Nabin Hait
6509548474 Merge pull request #39438 from frappe/mergify/bp/version-15-hotfix/pr-39429
fix: composite asset capitalization using asset components (backport #39429)
2024-01-17 22:13:50 +05:30
mergify[bot]
c8b3478fe1 Merge branch 'version-15-hotfix' into mergify/bp/version-15-hotfix/pr-39429 2024-01-17 16:26:04 +00:00
Nabin Hait
f453aaeab0 Merge pull request #39439 from nabinhait/test-case-fix-asset-depr
fix: test for asset depreciation
2024-01-17 21:54:55 +05:30
Nabin Hait
ff1647a1d2 fix: test for asset depreciation 2024-01-17 21:53:00 +05:30
Nabin Hait
8bc8bc1822 fix: composite asset capitalization using asset components
(cherry picked from commit 5df40661d2)
2024-01-17 15:36:04 +00:00
Nabin Hait
9f86b92eb7 Merge pull request #39431 from frappe/mergify/bp/version-15-hotfix/pr-39427
fix: Asset module tests (backport #39427)
2024-01-17 17:38:46 +05:30
Nabin Hait
04c8e9b355 Merge pull request #39422 from frappe/mergify/bp/version-15-hotfix/pr-39386
fix: Cancel asset capitalisation record on cancellation of asset and vice-versa (backport #39386)
2024-01-17 17:33:21 +05:30
Nabin Hait
fbfd0a6db0 Merge pull request #39420 from frappe/mergify/bp/version-15-hotfix/pr-39385
fix: WDV as per IT Act: calculate yearly amount first and then split it based on months (backport #39385)
2024-01-17 17:29:12 +05:30
Nabin Hait
9e33216c24 fix: Asset module tests
(cherry picked from commit 97f69986ff)
2024-01-17 11:56:41 +00:00
Deepesh Garg
62f7d984be Merge pull request #39425 from frappe/mergify/bp/version-15-hotfix/pr-39423
fix: Update subscription period (#39423)
2024-01-17 15:03:51 +05:30
Deepesh Garg
e219042304 fix: Update subscription period
(cherry picked from commit 7eefedfb11)
2024-01-17 07:28:57 +00:00
Nabin Hait
011c5a69f0 fix: Cancel asset capitalisation record on cancellation of asset and vice-versa
(cherry picked from commit efe9f6656f)
2024-01-17 06:45:39 +00:00
Nabin Hait
e3cd35b959 fix: WDV as per IT Act: calculate yearly amount first and then split it based on months
(cherry picked from commit 22bd6a54b2)
2024-01-17 06:44:26 +00:00
mergify[bot]
53f61f1ad1 fix: consistency in display reserved_stock checkbox on Sales Order Item according global settings and item.is_stock_item (backport #38322) (#39417)
fix: consistency in display reserved_stock checkbox on Sales Order Item according global settings and item.is_stock_item (#38322)

* fix: consistency in display reserved_stock checkbox on Sales Order Item according global settings and item.is_stock_item

* fix: evaluate depends_on for fdata visibility in grid

* fix: evaluate depends_on for fdata visibility in grid

* chore: change after review

* chore: change for review

(cherry picked from commit af80d253db)

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
2024-01-17 10:45:57 +05:30
rohitwaghchaure
c939aa5cf8 Merge pull request #39409 from frappe/mergify/bp/version-15-hotfix/pr-39406
fix: permission issue for the Bin (backport #39406)
2024-01-16 16:55:50 +05:30
ruthra kumar
93a861fac5 Merge pull request #39412 from frappe/mergify/bp/version-15-hotfix/pr-39402
fix: project query controller logic (backport #39402)
2024-01-16 16:49:56 +05:30
ruthra kumar
5a65a10dba refactor: better ordering of query result
(cherry picked from commit bfe42fdccb)
2024-01-16 10:55:36 +00:00
ruthra kumar
1b8f572e80 fix(test): test case for project query
(cherry picked from commit 3349dde5e2)
2024-01-16 10:55:36 +00:00
ruthra kumar
07e2901e4b fix: project query controller logic
(cherry picked from commit 4eefb445a7)
2024-01-16 10:55:35 +00:00
Rohit Waghchaure
8816b2740a fix: permission issue for the BIN
(cherry picked from commit 6e4d4a55cd)
2024-01-16 10:22:22 +00:00
ruthra kumar
bcf8053fd9 Merge pull request #39383 from frappe/mergify/bp/version-15-hotfix/pr-39332
refactor: prevent foreign currency subscription for a party (backport #39332)
2024-01-16 11:19:37 +05:30
ruthra kumar
cd1820f680 refactor(test): set default currency for party 2024-01-16 10:47:51 +05:30
ruthra kumar
235e3893a0 Merge pull request #39393 from frappe/mergify/bp/version-15-hotfix/pr-39391
fix: possible typerror in utils.js (backport #39391)
2024-01-15 20:49:48 +05:30
ruthra kumar
80956b7956 fix: possible typerror in utils.js
and remove unwanted debugging statements

(cherry picked from commit 60b26ad8b2)
2024-01-15 15:16:51 +00:00
Nabin Hait
9897c26ae6 Merge pull request #39285 from frappe/mergify/bp/version-15-hotfix/pr-39052
fix: asset WDV depreciation calc according to IT act [dev] (backport #39052)
2024-01-15 16:58:45 +05:30
ruthra kumar
32afe7de31 refactor(test): supply default currency for subscription plans
(cherry picked from commit 1387b0ba7f)
2024-01-15 09:36:50 +00:00
ruthra kumar
c288db0356 refactor: making currency mandatory for subcscription plans
(cherry picked from commit 19975dcb7b)
2024-01-15 09:36:50 +00:00
ruthra kumar
61f073f8b1 refactor: prevent foreign currency subscription for a party
(cherry picked from commit 6b5fa2c673)
2024-01-15 09:36:49 +00:00
Frappe PR Bot
8a356cbe51 chore(release): Bumped to Version 15.10.1
## [15.10.1](https://github.com/frappe/erpnext/compare/v15.10.0...v15.10.1) (2024-01-15)

### Bug Fixes

* SBB Total Qty validation for SE (backport [#39335](https://github.com/frappe/erpnext/issues/39335)) (backport [#39348](https://github.com/frappe/erpnext/issues/39348)) ([#39353](https://github.com/frappe/erpnext/issues/39353)) ([b8f4c31](b8f4c3193a))
2024-01-15 06:47:45 +00:00
mergify[bot]
1503ba92e3 ci: bump node in release workflow (backport #39377) (backport #39378) (#39380)
ci: bump node in release workflow (backport #39377) (#39378)

* ci: bump node in release workflow

(cherry picked from commit aef87cced7)

# Conflicts:
#	.github/workflows/release.yml

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
(cherry picked from commit e282ba78c1)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-01-15 12:12:35 +05:30
mergify[bot]
e282ba78c1 ci: bump node in release workflow (backport #39377) (#39378)
* ci: bump node in release workflow

(cherry picked from commit aef87cced7)

# Conflicts:
#	.github/workflows/release.yml

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-01-15 12:08:44 +05:30
ruthra kumar
1b8b92b8d7 Merge pull request #39376 from frappe/mergify/bp/version-15-hotfix/pr-39336
refactor: disallow bank transactions on different currencies (backport #39336)
2024-01-15 10:41:26 +05:30
ruthra kumar
f2e19ca6fd Merge pull request #39375 from frappe/mergify/bp/version-15-hotfix/pr-39371
fix: incorrect sql error if account name has '%' (backport #39371)
2024-01-15 10:40:54 +05:30
ruthra kumar
32c6111728 refactor(test): supply default currency to Bank Transaction
(cherry picked from commit a27a4db3de)
2024-01-15 04:32:46 +00:00
ruthra kumar
f609b8ae5d refactor: better error message
(cherry picked from commit b4354cbc8d)
2024-01-15 04:32:46 +00:00
ruthra kumar
dbbba046ab refactor: disallow bank transactions on different currencies
(cherry picked from commit cdd0acc672)
2024-01-15 04:32:45 +00:00
ruthra kumar
b43f70325c fix: incorrect sql error if account name has '%'
(cherry picked from commit 641c3de0ca)
2024-01-15 04:10:40 +00:00
rohitwaghchaure
3f5b1bcd05 Merge pull request #39373 from frappe/mergify/bp/version-15-hotfix/pr-39372
fix: batches not coming correctly in the batch selector (backport #39372)
2024-01-15 06:34:11 +05:30
Rohit Waghchaure
1394a1c5e9 fix: batches not coming correctly in the batch selector
(cherry picked from commit 114f2b4326)
2024-01-14 18:19:30 +00:00
Deepesh Garg
7ca9ffbaa7 Merge pull request #39329 from frappe/mergify/bp/version-15-hotfix/pr-38974
fix: unreconciled Bank Transaction on cancel of payment voucher (#38974)
2024-01-14 17:55:32 +05:30
rohitwaghchaure
137ce76a35 Merge pull request #39369 from frappe/mergify/bp/version-15-hotfix/pr-39224
Update purchase_taxes_and_charges.json label Rate to Tax Rate (backport #39224)
2024-01-14 11:59:41 +05:30
rohitwaghchaure
cd870ee30c fix: modified date
(cherry picked from commit 6827edb2c5)
2024-01-14 05:57:45 +00:00
rohitwaghchaure
2dc8686a81 fix: modified date was not set
(cherry picked from commit 566876ae7a)
2024-01-14 05:57:44 +00:00
mahsem
6bdf944ecf Update purchase_taxes_and_charges.json label Rate to Tax Rate
Change Rate label to existing Tax Rate label so it can be correctly translated in other languages

(cherry picked from commit bd464197c4)
2024-01-14 05:57:44 +00:00
rohitwaghchaure
9842fb5b64 Merge pull request #39361 from frappe/mergify/bp/version-15-hotfix/pr-39225
Update sales_taxes_and_charges.json (backport #39225)
2024-01-14 11:24:20 +05:30
rohitwaghchaure
c548c57207 Merge pull request #39365 from frappe/mergify/bp/version-15-hotfix/pr-39359
fix: added item group in stock reco (backport #39359)
2024-01-14 11:24:00 +05:30
rohitwaghchaure
cb326ac0db Merge pull request #39362 from rohitwaghchaure/fixed-closing-stock-balance-field-issue
chore: removed extra field
2024-01-14 10:44:47 +05:30
rohitwaghchaure
f0480173fb fix: modified date 2024-01-14 10:43:34 +05:30
Rohit Waghchaure
eec6c25f9e fix: added item group in stock reco
(cherry picked from commit 116ff8241c)
2024-01-14 04:58:42 +00:00
Rohit Waghchaure
bf4e514cde chore: removed extra field 2024-01-14 10:21:38 +05:30
rohitwaghchaure
61595c7ede fix: modified date was not updated
(cherry picked from commit f567af49a6)
2024-01-14 04:46:29 +00:00
mahsem
d510b46f13 Update sales_taxes_and_charges.json
Change Rate label to existing Tax Rate label so it can be correctly translated in other languages

(cherry picked from commit 2b93be1139)
2024-01-14 04:46:29 +00:00
rohitwaghchaure
15e116375b Merge pull request #39325 from frappe/mergify/bp/version-15-hotfix/pr-39305
fix: naming series variable parsing for FY (backport #39305)
2024-01-14 09:39:06 +05:30
mergify[bot]
b8f4c3193a fix: SBB Total Qty validation for SE (backport #39335) (backport #39348) (#39353)
fix: SBB Total Qty validation for SE

(cherry picked from commit c20241fcb5)
(cherry picked from commit ca18853785)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-01-13 10:25:53 +05:30
rohitwaghchaure
832aa5f5ab Merge pull request #39348 from frappe/mergify/bp/version-15-hotfix/pr-39335
fix: SBB Total Qty validation for SE (backport #39335)
2024-01-12 21:19:26 +05:30
s-aga-r
ca18853785 fix: SBB Total Qty validation for SE
(cherry picked from commit c20241fcb5)
2024-01-12 15:30:36 +00:00
rohitwaghchaure
049864e7a2 Merge pull request #39342 from frappe/mergify/bp/version-15-hotfix/pr-38970
fix: use local attribute range in multiple item variant dialog (backport #38970)
2024-01-12 20:57:14 +05:30
rohitwaghchaure
62db0d77ca Merge pull request #39345 from frappe/mergify/bp/version-15-hotfix/pr-39333
fix: added indexing to improve performance (backport #39333)
2024-01-12 20:55:57 +05:30
Rohit Waghchaure
50fe4191d3 fix: added indexing to improve performance
(cherry picked from commit ac81323fec)
2024-01-12 13:10:47 +00:00
Gursheen Anand
04c96ddc6c fix: use child table values instead of global min max
(cherry picked from commit 43fed29514)
2024-01-12 13:08:31 +00:00
mergify[bot]
d7840559a0 chore: remove share, print and email permissions from Buying Settings (backport #39337) (#39339)
chore: remove share, print and email permissions from Buying Settings

(cherry picked from commit 3c46abca6c)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-01-12 16:49:00 +05:30
Raffael Meyer
6f06313023 Merge pull request #39327 from frappe/mergify/bp/version-15-hotfix/pr-39117
fix: consider all years in holiday list (backport #39117)
2024-01-11 15:04:29 +01:00
barredterra
6b2e3503d9 chore: resolve merge confilcts 2024-01-11 14:56:20 +01:00
barredterra
b2fc5e4988 test: cancel voucher linked to Bank Transaction
(cherry picked from commit 517bedeb7e)
2024-01-11 13:37:48 +00:00
barredterra
16860c228d fix: unreconcile Bank Transaction on cancel of payment voucher
(cherry picked from commit 0a95b38166)

# Conflicts:
#	erpnext/accounts/doctype/bank_transaction/bank_transaction.py
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.js
2024-01-11 13:37:48 +00:00
barredterra
8a84f8a465 test: improve test for local holidays
(cherry picked from commit 60329ade9e)
2024-01-11 13:29:01 +00:00
barredterra
21eed78fa1 fix: consider all years in holiday list
(cherry picked from commit 300aaa39fe)
2024-01-11 13:29:00 +00:00
Gursheen Anand
e6f3a14289 fix: reset default after test
(cherry picked from commit 813b7a96fb)
2024-01-11 13:27:13 +00:00
Gursheen Anand
2beb3f8718 test: naming series variable parsing
(cherry picked from commit bbdf98a8f0)
2024-01-11 13:27:06 +00:00
Gursheen Anand
9aae439b1f fix: date in master document for dictionary condition
(cherry picked from commit d96a777edd)
2024-01-11 13:27:02 +00:00
Nabin Hait
b748095589 Merge pull request #39220 from frappe/mergify/bp/version-15-hotfix/pr-39202
fix: parse naming series with FY name (backport #39202)
2024-01-11 18:24:34 +05:30
ruthra kumar
7bd2acdef1 Merge pull request #39323 from frappe/mergify/bp/version-15-hotfix/pr-39212
fix: project filters on Delivery Note and Sales Order (backport #39212)
2024-01-11 18:07:12 +05:30
ruthra kumar
a51f956f3e fix: project filters on Delivery Note and Sales Order
(cherry picked from commit 9ba6ff67d5)
2024-01-11 12:34:43 +00:00
ruthra kumar
494c26e48a Merge pull request #39319 from frappe/mergify/bp/version-15-hotfix/pr-39317
fix: broken dimension filters in Sales/Purchase register (backport #39317)
2024-01-11 17:12:35 +05:30
Deepesh Garg
da7b2febe0 Merge pull request #39295 from frappe/mergify/bp/version-15-hotfix/pr-39256
fix: Ignore default payment terms template for opening invoices (#39256)
2024-01-11 17:06:53 +05:30
ruthra kumar
04037b7e38 fix: broken dimension filters in Sales/Purchase register
(cherry picked from commit 7b3f9386d7)
2024-01-11 11:20:43 +00:00
rohitwaghchaure
484db65797 Merge pull request #39315 from frappe/mergify/bp/version-15-hotfix/pr-39215
fix: incorrect percentage received in purchase invoice (backport #39215)
2024-01-11 15:14:44 +05:30
rohitwaghchaure
3f4cf15def Merge pull request #39312 from frappe/mergify/bp/version-15-hotfix/pr-39299
fix: circular dependency error on deletion of QC and Stock Entry (backport #39299)
2024-01-11 15:14:34 +05:30
Rohit Waghchaure
758b9b8a81 fix: incorrect percentage received in purchase invoice
(cherry picked from commit 8d2c78867e)
2024-01-11 09:21:41 +00:00
Rohit Waghchaure
7ca8e49b38 fix: circular dependency error while deleting QC
(cherry picked from commit 7cc324e31e)
2024-01-11 09:20:42 +00:00
mergify[bot]
d882305c72 fix: performance issue related to stock entry (backport #39301) (#39303)
fix: performance issue related to stock entry (#39301)

(cherry picked from commit c67b0a3a64)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-10 22:18:16 +05:30
Deepesh Garg
5dc2e80987 fix: Ignore default payment terms template for opening invoices
(cherry picked from commit 53bf44d2b8)
2024-01-10 10:37:45 +00:00
Frappe PR Bot
1dc85fcaf8 chore(release): Bumped to Version 15.10.0
# [15.10.0](https://github.com/frappe/erpnext/compare/v15.9.1...v15.10.0) (2024-01-10)

### Bug Fixes

* add expected_start_date in sort by ([b064944](b064944753))
* Add name to Hungary - Chart of Accounts for Microenterprises json ([0784488](0784488eec))
* add read permission to Buying Settings ([e62dd0d](e62dd0d7cb))
* bank transction status upon reconciliation ([277aa7b](277aa7bc2b))
* BOM replace tool does not update exploded items of root (backport [#39244](https://github.com/frappe/erpnext/issues/39244)) ([#39250](https://github.com/frappe/erpnext/issues/39250)) ([0898ea5](0898ea5d92))
* Creating Asset Activity while Importing Asset ([#39113](https://github.com/frappe/erpnext/issues/39113)) ([5e46937](5e4693763a))
* don't set rate for non-stock item in Internal Transfer (backport [#39140](https://github.com/frappe/erpnext/issues/39140)) ([#39169](https://github.com/frappe/erpnext/issues/39169)) ([f3882a8](f3882a854f))
* Duplicate Closing Stock Balance (backport [#39262](https://github.com/frappe/erpnext/issues/39262)) ([#39264](https://github.com/frappe/erpnext/issues/39264)) ([78c65f2](78c65f27b0))
* duplicate entry for serial / batch creation (backport [#39188](https://github.com/frappe/erpnext/issues/39188)) ([#39192](https://github.com/frappe/erpnext/issues/39192)) ([672e6d6](672e6d6d06))
* **Employee:** treeview ([#39126](https://github.com/frappe/erpnext/issues/39126)) ([6020c8e](6020c8e8f7))
* FG Item incorrect qty in the work order (backport [#39200](https://github.com/frappe/erpnext/issues/39200)) ([#39211](https://github.com/frappe/erpnext/issues/39211)) ([abc99f8](abc99f84e9))
* flaky demo test case (backport [#39135](https://github.com/frappe/erpnext/issues/39135)) ([#39198](https://github.com/frappe/erpnext/issues/39198)) ([3caf462](3caf462c6b))
* Ignore asset qty and status validation while cancelling LCV ([87d1b0f](87d1b0f476))
* ignore cancelled payments in Sales/Purchase Register ([9e1b443](9e1b443857))
* Ignore UP on "allowed to transact with" ([#39103](https://github.com/frappe/erpnext/issues/39103)) ([aad39cf](aad39cf686))
* improved validation message ([e89dce7](e89dce726b))
* incorrect indicator title for portal sales order (backport [#39247](https://github.com/frappe/erpnext/issues/39247)) ([#39255](https://github.com/frappe/erpnext/issues/39255)) ([9f793b9](9f793b9b28))
* incorrect outstanding amt validation on advance as liability ([51d8a7a](51d8a7a0c1))
* Introduced company field to show amounts in company currency ([1d2e831](1d2e831846))
* inventory dimension negative stock validation (backport [#39149](https://github.com/frappe/erpnext/issues/39149)) ([#39151](https://github.com/frappe/erpnext/issues/39151)) ([82b96d3](82b96d3688))
* possible key error on Financial ratios report ([16269b0](16269b0730))
* possible typeerror on transaction.js ([fec892c](fec892c211))
* projects website list visible for guests and all logged in customers (backport [#39164](https://github.com/frappe/erpnext/issues/39164)) ([#39273](https://github.com/frappe/erpnext/issues/39273)) ([5d6bc96](5d6bc96375)), closes [#39009](https://github.com/frappe/erpnext/issues/39009)
* Purchase date and amount is not mandatory for composite asset creation ([d6d54ed](d6d54ed220))
* Resolved conflict ([afefae0](afefae08af))
* serial / batch barcode scanner (backport [#39114](https://github.com/frappe/erpnext/issues/39114)) ([#39143](https://github.com/frappe/erpnext/issues/39143)) ([2db1e1a](2db1e1a737))
* Set asset purchase amount based on qty and valuation_rate ([f0070b4](f0070b4046))
* set parent doctype on chart (backport [#39286](https://github.com/frappe/erpnext/issues/39286)) ([#39288](https://github.com/frappe/erpnext/issues/39288)) ([fe973a4](fe973a4b53))
* Show maintain-stock and is-fixed-asset checkbox in item quick entry dialog ([50300b9](50300b9be6))
* Show timesheet table after fetching data from timesheet (backport [#39275](https://github.com/frappe/erpnext/issues/39275)) ([#39281](https://github.com/frappe/erpnext/issues/39281)) ([2598f8e](2598f8e7ec))
* skip rate validation for return `DN Items` with `Moving Average` valuation (backport [#39242](https://github.com/frappe/erpnext/issues/39242)) ([#39266](https://github.com/frappe/erpnext/issues/39266)) ([f00a6f6](f00a6f6c59))
* Subscription update patch ([7640fea](7640feaaa7))
* total allocated percentage for sales team issue ([756c062](756c062733))
* TypeError is pricing rules (backport [#39252](https://github.com/frappe/erpnext/issues/39252)) ([#39260](https://github.com/frappe/erpnext/issues/39260)) ([bb6025c](bb6025ca26))
* typerror on multi select dialog ([54a0df5](54a0df5164))
* update Maintenance Schedule status on Maintenance Visit submit (backport [#39167](https://github.com/frappe/erpnext/issues/39167)) ([#39186](https://github.com/frappe/erpnext/issues/39186)) ([926850d](926850d1f6))
* update status on manual allocation ([a147e29](a147e2954f))
* **UX:** dont override framework's permission check messages (backport [#39118](https://github.com/frappe/erpnext/issues/39118)) ([#39120](https://github.com/frappe/erpnext/issues/39120)) ([40ec5ff](40ec5ff90f))

### Features

* provision to close SCO (backport [#39127](https://github.com/frappe/erpnext/issues/39127)) ([#39144](https://github.com/frappe/erpnext/issues/39144)) ([b192ddd](b192ddd13b))
2024-01-10 10:36:08 +00:00
Deepesh Garg
e4e3313a0e Merge pull request #39245 from frappe/version-15-hotfix
chore: release v15
2024-01-10 16:04:56 +05:30
mergify[bot]
2598f8e7ec fix: Show timesheet table after fetching data from timesheet (backport #39275) (#39281)
fix: Show timesheet table after fetching data from timesheet

(cherry picked from commit e1ba5878a3)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-01-10 12:33:24 +05:30
mergify[bot]
fe973a4b53 fix: set parent doctype on chart (backport #39286) (#39288)
fix: set parent doctype on chart (#39286)

(cherry picked from commit 38c5ecf007)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-01-10 12:27:16 +05:30
anandbaburajan
2448ba6bc4 fix: asset WDV depreciation calc according to IT act
(cherry picked from commit 026824880d)
2024-01-10 06:48:06 +00:00
Nabin Hait
f82125144a Merge pull request #39190 from frappe/mergify/bp/version-15-hotfix/pr-39163
fix: Purchase information is not required for creating a composite asset (backport #39163)
2024-01-10 12:15:02 +05:30
Nabin Hait
38c1350018 Merge pull request #39279 from frappe/mergify/bp/version-15-hotfix/pr-39191
fix: Ignore asset qty and status validation while cancelling LCV (backport #39191)
2024-01-10 12:14:45 +05:30
Nabin Hait
24cfcf36e4 Merge pull request #39276 from frappe/mergify/bp/version-15-hotfix/pr-39238
fix: Set asset purchase amount based on qty and valuation_rate (backport #39238)
2024-01-10 12:14:10 +05:30
Nabin Hait
0c0be03e90 Merge pull request #39218 from frappe/mergify/bp/version-15-hotfix/pr-39214
fix: Show maintain-stock and is-fixed-asset checkbox in item quick entry dialog (backport #39214)
2024-01-10 12:12:32 +05:30
ruthra kumar
cd57bbc3d0 Merge pull request #39284 from frappe/mergify/bp/version-15-hotfix/pr-39282
fix: possible typeerror on transaction.js (backport #39282)
2024-01-10 12:00:43 +05:30
Nabin Hait
afefae08af fix: Resolved conflict 2024-01-10 11:59:54 +05:30
ruthra kumar
fec892c211 fix: possible typeerror on transaction.js
(cherry picked from commit 9f27ac142b)
2024-01-10 06:24:46 +00:00
Nabin Hait
87d1b0f476 fix: Ignore asset qty and status validation while cancelling LCV
(cherry picked from commit e9d36242ce)
2024-01-10 06:04:19 +00:00
Nabin Hait
f0070b4046 fix: Set asset purchase amount based on qty and valuation_rate
(cherry picked from commit 135e19d0aa)
2024-01-10 06:03:01 +00:00
mergify[bot]
5d6bc96375 fix: projects website list visible for guests and all logged in customers (backport #39164) (#39273)
fix: projects website list visible for guests and all logged in customers (#39164)

* fix: projects website list visible for guests

fix: projects website list visible for guests and all logged in customers

see the issue for details

fixes issue #39009

* fix: remove user = frappe.session.user

(cherry picked from commit eabf706f37)

Co-authored-by: 0xD0M1M0 <76812428+0xD0M1M0@users.noreply.github.com>
2024-01-10 10:45:45 +05:30
Raffael Meyer
4fa978ef1f test: fix wrong fieldname (#39270) 2024-01-10 10:32:01 +05:30
mergify[bot]
f00a6f6c59 fix: skip rate validation for return DN Items with Moving Average valuation (backport #39242) (#39266)
fix: skip rate validation for return `DN Items` with `Moving Average` valuation

(cherry picked from commit e0ad52b500)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-01-09 22:02:20 +05:30
mergify[bot]
78c65f27b0 fix: Duplicate Closing Stock Balance (backport #39262) (#39264)
fix: Duplicate Closing Stock Balance

(cherry picked from commit b15795392b)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-01-09 20:37:38 +05:30
Raffael Meyer
a326876cc5 Merge pull request #39258 from frappe/mergify/bp/version-15-hotfix/pr-39158
fix: add read permission to Buying Settings (backport #39158)
2024-01-09 13:34:56 +01:00
mergify[bot]
9f793b9b28 fix: incorrect indicator title for portal sales order (backport #39247) (#39255)
fix: incorrect indicator title for portal sales order (#39247)

(cherry picked from commit 2d2ff7cf52)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-09 17:42:27 +05:30
mergify[bot]
bb6025ca26 fix: TypeError is pricing rules (backport #39252) (#39260)
fix: TypeError is pricing rules (#39252)

(cherry picked from commit 274c65c451)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-09 17:41:53 +05:30
ruthra kumar
4ad61fc3a5 Merge pull request #39253 from frappe/mergify/bp/version-15-hotfix/pr-39251
fix: update status on manual allocation (backport #39251)
2024-01-09 16:36:35 +05:30
s-aga-r
e62dd0d7cb fix: add read permission to Buying Settings
(cherry picked from commit e05bf9d32a)
2024-01-09 10:44:21 +00:00
ruthra kumar
a147e2954f fix: update status on manual allocation
(cherry picked from commit d32a407e08)
2024-01-09 10:29:36 +00:00
mergify[bot]
0898ea5d92 fix: BOM replace tool does not update exploded items of root (backport #39244) (#39250)
fix: BOM replace tool does not update exploded items of root (#39244)

(cherry picked from commit 5e0d017497)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-09 15:59:12 +05:30
ruthra kumar
d0688e7a55 Merge pull request #39241 from frappe/mergify/bp/version-15-hotfix/pr-39237
fix: sales team commission overallocation on fetching items from multiple quotations to Sales Order (backport #39237)
2024-01-09 14:40:24 +05:30
ruthra kumar
756c062733 fix: total allocated percentage for sales team issue
(cherry picked from commit b498094a97)
2024-01-09 07:39:28 +00:00
ruthra kumar
ec7a60bd02 Merge pull request #39234 from frappe/mergify/bp/version-15-hotfix/pr-39196
fix: bank transaction status upon reconciliation (backport #39196)
2024-01-09 11:57:50 +05:30
ruthra kumar
53eb6129ea refactor: remove 'Bank Trasaction' logic from status_update
(cherry picked from commit cf988434e9)
2024-01-09 05:51:38 +00:00
ruthra kumar
277aa7bc2b fix: bank transction status upon reconciliation
(cherry picked from commit 6de8c18f98)
2024-01-09 05:51:37 +00:00
Nabin Hait
97a51487c1 Merge pull request #39219 from frappe/mergify/bp/version-15-hotfix/pr-39209
fix: Introduced company field to show amounts in company currency (backport #39209)
2024-01-08 21:53:16 +05:30
Gursheen Anand
53208dfb3e fix: fetch name for fy
(cherry picked from commit d0ea598cdf)
2024-01-08 16:22:58 +00:00
Nabin Hait
1d2e831846 fix: Introduced company field to show amounts in company currency
(cherry picked from commit eab22eb282)
2024-01-08 16:09:42 +00:00
Nabin Hait
50300b9be6 fix: Show maintain-stock and is-fixed-asset checkbox in item quick entry dialog
(cherry picked from commit c14986f9e6)
2024-01-08 16:07:23 +00:00
mergify[bot]
abc99f84e9 fix: FG Item incorrect qty in the work order (backport #39200) (#39211)
fix: FG Item incorrect qty in the work order (#39200)

(cherry picked from commit 466625213b)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-08 18:18:32 +05:30
mergify[bot]
3caf462c6b fix: flaky demo test case (backport #39135) (#39198)
fix: flaky demo test case

(cherry picked from commit 5b1571879c)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-01-08 17:44:24 +05:30
Shariq Ansari
58357f8891 Merge pull request #39206 from frappe/mergify/bp/version-15-hotfix/pr-39204
fix: add expected_start_date in sort by (backport #39204)
2024-01-08 16:37:37 +05:30
Shariq Ansari
8cc9ddaebd chore: linter fix 2024-01-08 16:30:26 +05:30
Shariq Ansari
1f64b8fcd8 chore: linter fix 2024-01-08 16:30:03 +05:30
Shariq Ansari
80a2b79bba chore: linter fix 2024-01-08 16:29:13 +05:30
Shariq Ansari
b064944753 fix: add expected_start_date in sort by
(cherry picked from commit 3d54fd8389)
2024-01-08 10:40:20 +00:00
mergify[bot]
672e6d6d06 fix: duplicate entry for serial / batch creation (backport #39188) (#39192)
fix: duplicate entry for serial / batch creation (#39188)

(cherry picked from commit b96c063c93)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-08 14:21:04 +05:30
mergify[bot]
926850d1f6 fix: update Maintenance Schedule status on Maintenance Visit submit (backport #39167) (#39186)
* fix: make `Sales Person` non-mandatory

(cherry picked from commit 4d56f725fe)

* fix: update Maintenance Schedule status on Maintenance Visit submit

(cherry picked from commit cd293a5173)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-01-08 13:23:12 +05:30
Nabin Hait
d6d54ed220 fix: Purchase date and amount is not mandatory for composite asset creation
(cherry picked from commit c34f09c503)

# Conflicts:
#	erpnext/assets/doctype/asset/asset.py
2024-01-08 06:53:11 +00:00
Nabin Hait
e89dce726b fix: improved validation message
(cherry picked from commit fe43dab4d7)
2024-01-08 06:53:10 +00:00
ruthra kumar
83288fedf1 Merge pull request #39187 from ruthra-kumar/backport_37613
fix: possible key error in Financial Ratio's report
2024-01-08 12:08:13 +05:30
ruthra kumar
16269b0730 fix: possible key error on Financial ratios report 2024-01-08 11:50:13 +05:30
ruthra kumar
f1d25700a8 Merge pull request #39183 from frappe/mergify/bp/version-15-hotfix/pr-39161
refactor: allow sales invoice in Bank Reconciliation tool (backport #39161)
2024-01-08 11:09:42 +05:30
ruthra kumar
00d36d14fb refactor: allow sales invoice in Bank Reconciliation tool
(cherry picked from commit b69cdeb4a6)
2024-01-08 05:02:30 +00:00
ruthra kumar
c912e4c99d Merge pull request #39182 from frappe/mergify/bp/version-15-hotfix/pr-39165
fix: incorrect outstanding amt validation on advance as liability (backport #39165)
2024-01-08 10:31:17 +05:30
ruthra kumar
1eee52c59c Merge pull request #39181 from frappe/mergify/bp/version-15-hotfix/pr-39159
refactor: prevent permission error by always processing bulk transaction in background (backport #39159)
2024-01-08 10:30:48 +05:30
ruthra kumar
51d8a7a0c1 fix: incorrect outstanding amt validation on advance as liability
(cherry picked from commit 4cc3c1b765)
2024-01-08 04:45:03 +00:00
ruthra kumar
f0bc0aa676 refactor: prevent permissions by always processing in background
(cherry picked from commit 15dc5c7e99)
2024-01-08 04:43:11 +00:00
mergify[bot]
f3882a854f fix: don't set rate for non-stock item in Internal Transfer (backport #39140) (#39169)
* fix: don't set rate for non-stock item in Internal Transfer

(cherry picked from commit e1b0fffd0c)

* test: internal transfer for non-stock item

(cherry picked from commit 57b6a98703)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-01-06 11:03:24 +05:30
Aulia Bismar
5e4693763a fix: Creating Asset Activity while Importing Asset (#39113)
* fix: import asset not working on activity

* chore: fix linting issue in asset_activity.py

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2024-01-05 10:46:31 +05:30
mergify[bot]
82b96d3688 fix: inventory dimension negative stock validation (backport #39149) (#39151)
fix: inventory dimension negative stock validation (#39149)

(cherry picked from commit bae7c64964)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-05 05:04:28 +05:30
Raffael Meyer
0454dede92 Merge pull request #39148 from frappe/mergify/bp/version-15-hotfix/pr-39126
fix(Employee): treeview (backport #39126)
2024-01-04 15:24:43 +01:00
Raffael Meyer
6020c8e8f7 fix(Employee): treeview (#39126)
(cherry picked from commit e912e9597d)
2024-01-04 12:34:52 +00:00
mergify[bot]
b192ddd13b feat: provision to close SCO (backport #39127) (#39144)
* feat: provision to close SCO

(cherry picked from commit 5e2669f4b6)

* fix: don't allow to submit/cancel SCR against a closed SCO

(cherry picked from commit 9e973476b2)

* fix: don't allow to submit/cancel SE against a closed SCO

(cherry picked from commit 5bc2035bd0)

* fix(ux): filter closed SCO in `Get Items From` dialog

(cherry picked from commit bb839b2924)

* fix: don't close PO on SCO close

(cherry picked from commit 0d01bd8a5a)

* fix: update qty on SCO status change

(cherry picked from commit 245effcccd)

* fix: don't allow to reopen SCO if PO is closed

(cherry picked from commit 784b6dcfea)

* fix: auto close and reopen SCO based on PO status

(cherry picked from commit 0819675fce)

* fix(text): test_update_status

(cherry picked from commit cdd5441435)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-01-04 17:22:58 +05:30
mergify[bot]
2db1e1a737 fix: serial / batch barcode scanner (backport #39114) (#39143)
fix: serial / batch barcode scanner (#39114)

(cherry picked from commit f09e2130a1)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-04 16:02:29 +05:30
Deepesh Garg
7a5a4be02f Merge pull request #39137 from frappe/mergify/bp/version-15-hotfix/pr-39125
fix: ignore cancelled payments in Sales/Purchase Register (#39125)
2024-01-04 11:25:39 +05:30
Deepesh Garg
b834abbd4f Merge pull request #39139 from frappe/mergify/bp/version-15-hotfix/pr-39138
fix: Subscription update patch (#39138)
2024-01-04 11:25:21 +05:30
Deepesh Garg
7640feaaa7 fix: Subscription update patch
(cherry picked from commit 277dade9f9)
2024-01-04 05:54:51 +00:00
ruthra kumar
9e1b443857 fix: ignore cancelled payments in Sales/Purchase Register
(cherry picked from commit 0f1be03faf)
2024-01-04 05:45:52 +00:00
Deepesh Garg
18575e137c Merge pull request #39129 from monolithonadmin/version-15-hotfix
fix: Add name to Hungary - Chart of Accounts for Microenterprises json
2024-01-04 08:42:03 +05:30
Monolithonadmin
0784488eec fix: Add name to Hungary - Chart of Accounts for Microenterprises json 2024-01-03 20:52:30 +01:00
Frappe PR Bot
290397172e chore(release): Bumped to Version 15.9.1
## [15.9.1](https://github.com/frappe/erpnext/compare/v15.9.0...v15.9.1) (2024-01-03)

### Bug Fixes

* typerror on multi select dialog ([5ee6cc4](5ee6cc4bac))
2024-01-03 15:37:59 +00:00
ruthra kumar
e3c473482b Merge pull request #39124 from frappe/mergify/bp/version-15/pr-39116
fix: typerror on multi select dialog (backport #39116)
2024-01-03 21:06:50 +05:30
ruthra kumar
bc529b51dc Merge pull request #39122 from frappe/mergify/bp/version-15-hotfix/pr-39116
fix: typerror on multi select dialog (backport #39116)
2024-01-03 21:06:06 +05:30
ruthra kumar
5ee6cc4bac fix: typerror on multi select dialog
(cherry picked from commit 7da9ffa3bd)
2024-01-03 15:26:21 +00:00
ruthra kumar
54a0df5164 fix: typerror on multi select dialog
(cherry picked from commit 7da9ffa3bd)
2024-01-03 15:25:24 +00:00
mergify[bot]
40ec5ff90f fix(UX): dont override framework's permission check messages (backport #39118) (#39120)
fix(UX): dont override framework's permission check messages (#39118)

(cherry picked from commit e84c9f7c51)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-01-03 20:32:52 +05:30
Ankush Menat
aad39cf686 fix: Ignore UP on "allowed to transact with" (#39103)
If a customer is allowed to transact with some company it usually
doesn't imply that customer is somehow "linked with" that company.
2024-01-03 13:13:24 +05:30
Frappe PR Bot
3eac0e907e chore(release): Bumped to Version 15.9.0
# [15.9.0](https://github.com/frappe/erpnext/compare/v15.8.3...v15.9.0) (2024-01-03)

### Bug Fixes

* auto fetch not working if bundle exists (backport [#39002](https://github.com/frappe/erpnext/issues/39002)) ([#39004](https://github.com/frappe/erpnext/issues/39004)) ([2e91934](2e919344df))
* **DX:** capture tracebacks with context (backport [#39060](https://github.com/frappe/erpnext/issues/39060)) ([#39063](https://github.com/frappe/erpnext/issues/39063)) ([8ad7faf](8ad7fafe2a))
* enqueue demo data setup on setup complete (backport [#39043](https://github.com/frappe/erpnext/issues/39043)) ([#39044](https://github.com/frappe/erpnext/issues/39044)) ([d8cf994](d8cf994e94))
* incorrect total when Accumulating values ([7c7c3c9](7c7c3c932f))
* Multiple subscription fixes ([#39005](https://github.com/frappe/erpnext/issues/39005)) ([5158884](5158884dc9))
* non stock uom validation for serial and batch (backport [#39018](https://github.com/frappe/erpnext/issues/39018)) ([#39026](https://github.com/frappe/erpnext/issues/39026)) ([89d1069](89d1069472))
* not able to cancel sales invoice (backport [#38979](https://github.com/frappe/erpnext/issues/38979)) ([#38980](https://github.com/frappe/erpnext/issues/38980)) ([f8625f3](f8625f3eb7))
* on cancellation of document cancel the serial and batch bundle (backport [#39076](https://github.com/frappe/erpnext/issues/39076)) ([#39082](https://github.com/frappe/erpnext/issues/39082)) ([2e0abbd](2e0abbd274))
* Opening balance in bank reconciliation tool ([#38977](https://github.com/frappe/erpnext/issues/38977)) ([e0755f9](e0755f9a9a))
* purchase return without item code not working (backport [#39014](https://github.com/frappe/erpnext/issues/39014)) ([#39015](https://github.com/frappe/erpnext/issues/39015)) ([2a390ac](2a390ac2de))
* remove bad defaults (backport [#38986](https://github.com/frappe/erpnext/issues/38986)) ([#38988](https://github.com/frappe/erpnext/issues/38988)) ([46035ed](46035ed9ca))
* select options should dynamically load dimensions ([21f9001](21f90011bc))
* serial and batch bundle company mandatory error (backport [#38994](https://github.com/frappe/erpnext/issues/38994)) ([#38999](https://github.com/frappe/erpnext/issues/38999)) ([d2580be](d2580be4fd))
* take quantity into account when setting asset's gross purchase amt (backport [#39056](https://github.com/frappe/erpnext/issues/39056)) ([#39058](https://github.com/frappe/erpnext/issues/39058)) ([2e93275](2e932754e0))
* Unable to save Sales Invoice ([#39059](https://github.com/frappe/erpnext/issues/39059)) ([73c0f37](73c0f3703c))
* undefined error in Budget Variance and Profitability report ([9fdf5c8](9fdf5c8091))
* undefined error in consolidated financial report ([49f93f9](49f93f9fa1))
* use `Stock Qty` while getting `POS Reserved Qty` (backport [#38962](https://github.com/frappe/erpnext/issues/38962)) ([#38965](https://github.com/frappe/erpnext/issues/38965)) ([76c6b50](76c6b501f9))
* Validate account in Sales/Purchase Taxes and Charges Template ([#39013](https://github.com/frappe/erpnext/issues/39013)) ([f3254c2](f3254c2010))
* work order with multi level, fetch operting cost from sub-assembly (backport [#38992](https://github.com/frappe/erpnext/issues/38992)) ([#39028](https://github.com/frappe/erpnext/issues/39028)) ([3a7506e](3a7506ecbc))

### Features

* Against voucher filter in General Ledger ([#39102](https://github.com/frappe/erpnext/issues/39102)) ([458064f](458064f8a1))
* group by Asset in Asset Depreciations and Balances report (backport [#38923](https://github.com/frappe/erpnext/issues/38923)) ([#39066](https://github.com/frappe/erpnext/issues/39066)) ([d85dad7](d85dad7198))
* Merge taxes from mapped docs ([#38346](https://github.com/frappe/erpnext/issues/38346)) ([4e23048](4e2304818b))
* voucher subtype for general ledger ([#38822](https://github.com/frappe/erpnext/issues/38822)) ([e5d73c7](e5d73c780b))

### Performance Improvements

* index item_code in bom explosion item (backport [#39085](https://github.com/frappe/erpnext/issues/39085)) ([#39088](https://github.com/frappe/erpnext/issues/39088)) ([57bcf9f](57bcf9f568))
2024-01-03 06:01:15 +00:00
Deepesh Garg
d2fdce007e Merge pull request #39090 from frappe/version-15-hotfix
chore: release v15
2024-01-03 11:29:39 +05:30
Deepesh Garg
458064f8a1 feat: Against voucher filter in General Ledger (#39102) 2024-01-03 10:51:34 +05:30
rohitwaghchaure
56d510b878 Merge branch 'version-15' into version-15-hotfix 2024-01-02 17:34:56 +05:30
mergify[bot]
57bcf9f568 perf: index item_code in bom explosion item (backport #39085) (#39088)
perf: index item_code in bom explosion item (#39085)

(cherry picked from commit 739434b727)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-01-02 14:43:10 +05:30
mergify[bot]
2e0abbd274 fix: on cancellation of document cancel the serial and batch bundle (backport #39076) (#39082)
fix: on cancellation of document cancel the serial and batch bundle (#39076)

(cherry picked from commit 6e5484ea03)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-01-02 13:28:43 +05:30
mergify[bot]
73c0f3703c fix: Unable to save Sales Invoice (#39059)
fix: Unable to save Sales Invoice (#39059)

(cherry picked from commit bacf2b7431)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-01-01 19:28:29 +05:30
ruthra kumar
f3088e08bb Merge pull request #39072 from frappe/mergify/bp/version-15-hotfix/pr-39067
fix: undefined error in Budget Variance and Profitability report (backport #39067)
2024-01-01 17:42:45 +05:30
ruthra kumar
21f90011bc fix: select options should dynamically load dimensions
(cherry picked from commit 1a9e091d12)
2024-01-01 12:08:10 +00:00
ruthra kumar
9fdf5c8091 fix: undefined error in Budget Variance and Profitability report
'Budget' and 'Budget Account' doesn't have support for dynamic
dimension. It only supports hard-coded ones -  Project and Cost Center

(cherry picked from commit 92bc962f60)
2024-01-01 12:08:10 +00:00
ruthra kumar
7539623fb9 Merge pull request #39069 from frappe/mergify/bp/version-15-hotfix/pr-39023
refactor(perf): replace account subquery with 'in' condition (backport #39023)
2024-01-01 16:29:25 +05:30
ruthra kumar
cbaa617d20 refactor(perf): replace account subquery with 'in' condition
(cherry picked from commit a517125d64)
2024-01-01 10:13:51 +00:00
mergify[bot]
d85dad7198 feat: group by Asset in Asset Depreciations and Balances report (backport #38923) (#39066)
feat: group by Asset in Asset Depreciations and Balances report (#38923)

feat: group by asset in asset depreciations and balances report
(cherry picked from commit a9576f0cf6)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2024-01-01 15:05:04 +05:30
mergify[bot]
e5d73c780b feat: voucher subtype for general ledger (#38822)
* feat: voucher subtype for general ledger (#38822)

* feat: add voucher subtype column to gle

* feat: add logic to set voucher subtypes

* feat: fetch voucher subtype in ledger report

* fix: order of conditions

(cherry picked from commit 47f7b65058)

# Conflicts:
#	erpnext/accounts/doctype/gl_entry/gl_entry.json

* chore: resolve conflicts

---------

Co-authored-by: Gursheen Kaur Anand <40693548+GursheenK@users.noreply.github.com>
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-01-01 13:30:29 +05:30
mergify[bot]
8ad7fafe2a fix(DX): capture tracebacks with context (backport #39060) (#39063)
fix(DX): capture tracebacks with context (#39060)

(cherry picked from commit 510fdf7bf6)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-01-01 13:12:07 +05:30
mergify[bot]
2e932754e0 fix: take quantity into account when setting asset's gross purchase amt (backport #39056) (#39058)
fix: take quantity into account when setting asset's gross purchase amt (#39056)

fix: take quantity into account when setting asset's gross purchase amount
(cherry picked from commit 0346f47c1d)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2024-01-01 11:27:55 +05:30
mergify[bot]
d8cf994e94 fix: enqueue demo data setup on setup complete (backport #39043) (#39044)
fix: enqueue demo data setup on setup complete (#39043)

(cherry picked from commit 877cc7255d)

Co-authored-by: Smit Vora <smitvora203@gmail.com>
2023-12-31 18:25:15 +05:30
mergify[bot]
89d1069472 fix: non stock uom validation for serial and batch (backport #39018) (#39026)
fix: non stock uom validation for serial and batch (#39018)

* fix: non stock uom validation for serial and batch

* test: delivery note for batch with non stock uom

(cherry picked from commit 0c6de4ecb2)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-29 20:54:49 +05:30
mergify[bot]
3a7506ecbc fix: work order with multi level, fetch operting cost from sub-assembly (backport #38992) (#39028)
fix: work order with multi level, fetch operting cost from sub-assembly (#38992)

(cherry picked from commit 70abedc57a)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-29 20:54:26 +05:30
mergify[bot]
f3254c2010 fix: Validate account in Sales/Purchase Taxes and Charges Template (#39013)
fix: Validate account in Sales/Purchase Taxes and Charges Template (#39013)

(cherry picked from commit cd37fd790b)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-12-29 16:16:02 +05:30
mergify[bot]
2a390ac2de fix: purchase return without item code not working (backport #39014) (#39015)
fix: purchase return without item code not working (#39014)

(cherry picked from commit f983e09f92)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-29 13:07:38 +05:30
mergify[bot]
5158884dc9 fix: Multiple subscription fixes (#39005)
fix: Multiple subscription fixes (#39005)

(cherry picked from commit 3b4b2275de)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-12-29 12:52:41 +05:30
mergify[bot]
2e919344df fix: auto fetch not working if bundle exists (backport #39002) (#39004)
fix: auto fetch not working if bundle exists (#39002)

(cherry picked from commit b5340c5ec0)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-28 18:54:38 +05:30
mergify[bot]
d2580be4fd fix: serial and batch bundle company mandatory error (backport #38994) (#38999)
fix: serial and batch bundle company mandatory error (#38994)

(cherry picked from commit 10074e9980)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-28 18:22:14 +05:30
mergify[bot]
e0755f9a9a fix: Opening balance in bank reconciliation tool (#38977)
fix: Opening balance in bank reconciliation tool (#38977)

(cherry picked from commit bbee9b5637)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-12-28 17:53:44 +05:30
ruthra kumar
1b399e83be Merge pull request #38995 from ruthra-kumar/undefined_error_in_consolidated_report
fix: undefined error in consolidated financial report
2023-12-28 17:42:18 +05:30
ruthra kumar
49f93f9fa1 fix: undefined error in consolidated financial report 2023-12-28 17:36:00 +05:30
ruthra kumar
d2fe221bc7 Merge pull request #38990 from frappe/mergify/bp/version-15-hotfix/pr-38969
fix: incorrect net profit in Profit and Loss Statement (backport #38969)
2023-12-28 17:09:43 +05:30
ruthra kumar
a3cecb892a test: profit and loss report output
(cherry picked from commit 8555617295)
2023-12-28 10:54:27 +00:00
ruthra kumar
7c7c3c932f fix: incorrect total when Accumulating values
(cherry picked from commit d54f8318fb)
2023-12-28 10:54:27 +00:00
mergify[bot]
46035ed9ca fix: remove bad defaults (backport #38986) (#38988)
fix: remove bad defaults (#38986)

Child tables can't have a default.

(cherry picked from commit b71b0d5997)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-12-28 14:22:18 +05:30
mergify[bot]
f8625f3eb7 fix: not able to cancel sales invoice (backport #38979) (#38980)
fix: not able to cancel sales invoice (#38979)

(cherry picked from commit a117ef3cb8)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-28 11:21:51 +05:30
mergify[bot]
4e2304818b feat: Merge taxes from mapped docs (#38346)
feat: Merge taxes from mapped docs (#38346)

* feat: Merge taxes from mapped docs

* chore: ci failures

(cherry picked from commit 9b1c22250f)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-12-28 08:28:02 +05:30
mergify[bot]
3caabf23a5 fix : correct logic for overlap error (backport #38967) (#38968)
fix : correct logic for overlap error (#38967)

fixing overlap error logic with taking care of sequential time job cards in overlap job card list

(cherry picked from commit fe77b9d633)

Co-authored-by: VihangT <151990347+VihangT@users.noreply.github.com>
2023-12-27 20:40:03 +05:30
mergify[bot]
76c6b501f9 fix: use Stock Qty while getting POS Reserved Qty (backport #38962) (#38965)
fix: use `Stock Qty` while getting `POS Reserved Qty`

(cherry picked from commit 7223106417)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-27 15:31:58 +05:30
347 changed files with 12254 additions and 4431 deletions

View File

@@ -17,7 +17,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: 18
node-version: 20
- name: Setup dependencies
run: |

View File

@@ -3,7 +3,7 @@ import inspect
import frappe
__version__ = "15.8.3"
__version__ = "15.16.2"
def get_default_company(user=None):

View File

@@ -118,6 +118,7 @@ class Account(NestedSet):
self.validate_balance_must_be_debit_or_credit()
self.validate_account_currency()
self.validate_root_company_and_sync_account_to_children()
self.validate_receivable_payable_account_type()
def validate_parent_child_account_type(self):
if self.parent_account:
@@ -188,6 +189,24 @@ class Account(NestedSet):
"Balance Sheet" if self.root_type in ("Asset", "Liability", "Equity") else "Profit and Loss"
)
def validate_receivable_payable_account_type(self):
doc_before_save = self.get_doc_before_save()
receivable_payable_types = ["Receivable", "Payable"]
if (
doc_before_save
and doc_before_save.account_type in receivable_payable_types
and doc_before_save.account_type != self.account_type
):
# check for ledger entries
if frappe.db.get_all("GL Entry", filters={"account": self.name, "is_cancelled": 0}, limit=1):
msg = _(
"There are ledger entries against this account. Changing {0} to non-{1} in live system will cause incorrect output in 'Accounts {2}' report"
).format(
frappe.bold("Account Type"), doc_before_save.account_type, doc_before_save.account_type
)
frappe.msgprint(msg)
self.add_comment("Comment", msg)
def validate_root_details(self):
doc_before_save = self.get_doc_before_save()

View File

@@ -56,7 +56,9 @@
"Constru\u00e7\u00f5es em Andamento de Im\u00f3veis Destinados \u00e0 Venda": {},
"Estoques Destinados \u00e0 Doa\u00e7\u00e3o": {},
"Im\u00f3veis Destinados \u00e0 Venda": {},
"Insumos (materiais diretos)": {},
"Insumos (materiais diretos)": {
"account_type": "Stock"
},
"Insumos Agropecu\u00e1rios": {},
"Mercadorias para Revenda": {},
"Outras 11": {},
@@ -146,6 +148,65 @@
"root_type": "Asset"
},
"CUSTOS DE PRODU\u00c7\u00c3O": {
"CUSTO DOS PRODUTOS E SERVI\u00c7OS VENDIDOS": {
"CUSTO DOS PRODUTOS VENDIDOS": {
"CUSTO DOS PRODUTOS VENDIDOS PARA AS DEMAIS ATIVIDADES": {
"Custos dos Produtos Vendidos em Geral": {
"account_type": "Cost of Goods Sold"
},
"Outros Custos 4": {},
"account_type": "Cost of Goods Sold"
},
"CUSTO DOS PRODUTOS VENDIDOS PARA ASSIST\u00caNCIA SOCIAL": {
"Custos dos Produtos para Assist\u00eancia Social - Gratuidades": {},
"Custos dos Produtos para Assist\u00eancia Social - Vendidos": {},
"Outras": {}
},
"CUSTO DOS PRODUTOS VENDIDOS PARA EDUCA\u00c7\u00c3O": {
"Custos dos Produtos para Educa\u00e7\u00e3o - Gratuidades": {},
"Custos dos Produtos para Educa\u00e7\u00e3o - Vendidos": {},
"Outros Custos 6": {}
},
"CUSTO DOS PRODUTOS VENDIDOS PARA SA\u00daDE": {
"Custos dos Produtos para Sa\u00fade - Gratuidades": {},
"Custos dos Produtos para Sa\u00fade \u2013 Vendidos": {},
"Outros Custos 5": {}
},
"account_type": "Cost of Goods Sold"
},
"CUSTO DOS SERVI\u00c7OS PRESTADOS": {
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA AS DEMAIS ATIVIDADES": {
"Custo dos Servi\u00e7os Prestados em Geral": {},
"Outros Custos": {}
},
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA ASSIST\u00caNCIA SOCIAL": {
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es 1": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas 1": {},
"Custo dos Servi\u00e7os Prestados a Gratuidade 1": {},
"Custo dos Servi\u00e7os Prestados a Pacientes Particulares": {},
"Outros Custos 2": {}
},
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA EDUCA\u00c7\u00c3O": {
"Custo dos Servi\u00e7os Prestados a Alunos N\u00e3o Bolsistas": {},
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias (Exceto PROUNI)": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas": {},
"Custo dos Servi\u00e7os Prestados a Gratuidade": {},
"Custo dos Servi\u00e7os Prestados ao PROUNI": {},
"Outros Custos 1": {}
},
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA SA\u00daDE": {
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios SUS": {},
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias 1": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es 2": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas 2": {},
"Custo dos Servi\u00e7os Prestados a Gratuidade 2": {},
"Custo dos Servi\u00e7os Prestados a Pacientes Particulares 1": {},
"Outros Custos 3": {}
}
}
},
"CUSTO DOS BENS E SERVI\u00c7OS PRODUZIDOS": {
"CUSTO DOS PRODUTOS DE FABRICA\u00c7\u00c3O PR\u00d3PRIA PRODUZIDOS": {
"Alimenta\u00e7\u00e3o do Trabalhador": {},
@@ -621,7 +682,9 @@
"Receita das Unidades Imobili\u00e1rias Vendidas": {},
"Receita de Exporta\u00e7\u00e3o Direta de Mercadorias e Produtos": {},
"Receita de Exporta\u00e7\u00e3o de Servi\u00e7os": {},
"Receita de Loca\u00e7\u00e3o de Bens M\u00f3veis e Im\u00f3veis": {},
"Receita de Loca\u00e7\u00e3o de Bens M\u00f3veis e Im\u00f3veis": {
"account_type": "Income Account"
},
"Receita de Vendas de Mercadorias e Produtos a Comercial Exportadora com Fim Espec\u00edfico de Exporta\u00e7\u00e3o": {}
}
}
@@ -645,65 +708,6 @@
}
},
"RESULTADO OPERACIONAL": {
"CUSTO DOS PRODUTOS E SERVI\u00c7OS VENDIDOS": {
"CUSTO DOS PRODUTOS VENDIDOS": {
"CUSTO DOS PRODUTOS VENDIDOS PARA AS DEMAIS ATIVIDADES": {
"Custos dos Produtos Vendidos em Geral": {
"account_type": "Cost of Goods Sold"
},
"Outros Custos 4": {},
"account_type": "Cost of Goods Sold"
},
"CUSTO DOS PRODUTOS VENDIDOS PARA ASSIST\u00caNCIA SOCIAL": {
"Custos dos Produtos para Assist\u00eancia Social - Gratuidades": {},
"Custos dos Produtos para Assist\u00eancia Social - Vendidos": {},
"Outras": {}
},
"CUSTO DOS PRODUTOS VENDIDOS PARA EDUCA\u00c7\u00c3O": {
"Custos dos Produtos para Educa\u00e7\u00e3o - Gratuidades": {},
"Custos dos Produtos para Educa\u00e7\u00e3o - Vendidos": {},
"Outros Custos 6": {}
},
"CUSTO DOS PRODUTOS VENDIDOS PARA SA\u00daDE": {
"Custos dos Produtos para Sa\u00fade - Gratuidades": {},
"Custos dos Produtos para Sa\u00fade \u2013 Vendidos": {},
"Outros Custos 5": {}
},
"account_type": "Cost of Goods Sold"
},
"CUSTO DOS SERVI\u00c7OS PRESTADOS": {
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA AS DEMAIS ATIVIDADES": {
"Custo dos Servi\u00e7os Prestados em Geral": {},
"Outros Custos": {}
},
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA ASSIST\u00caNCIA SOCIAL": {
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es 1": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas 1": {},
"Custo dos Servi\u00e7os Prestados a Gratuidade 1": {},
"Custo dos Servi\u00e7os Prestados a Pacientes Particulares": {},
"Outros Custos 2": {}
},
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA EDUCA\u00c7\u00c3O": {
"Custo dos Servi\u00e7os Prestados a Alunos N\u00e3o Bolsistas": {},
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias (Exceto PROUNI)": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas": {},
"Custo dos Servi\u00e7os Prestados a Gratuidade": {},
"Custo dos Servi\u00e7os Prestados ao PROUNI": {},
"Outros Custos 1": {}
},
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA SA\u00daDE": {
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios SUS": {},
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias 1": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es 2": {},
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas 2": {},
"Custo dos Servi\u00e7os Prestados a Gratuidade 2": {},
"Custo dos Servi\u00e7os Prestados a Pacientes Particulares 1": {},
"Outros Custos 3": {}
}
}
},
"DESPESAS OPERACIONAIS": {
"DESPESAS OPERACIONAIS 1": {
"DESPESAS OPERACIONAIS 2": {

View File

@@ -1,4 +1,6 @@
{
"country_code": "hu",
"name": "Hungary - Chart of Accounts for Microenterprises",
"tree": {
"SZ\u00c1MLAOSZT\u00c1LY BEFEKTETETT ESZK\u00d6Z\u00d6K": {
"account_number": 1,

View File

@@ -6,6 +6,7 @@ import unittest
import frappe
from frappe.test_runner import make_test_records
from frappe.utils import nowdate
from erpnext.accounts.doctype.account.account import (
InvalidAccountMergeError,
@@ -324,6 +325,19 @@ class TestAccount(unittest.TestCase):
acc.account_currency = "USD"
self.assertRaises(frappe.ValidationError, acc.save)
def test_account_balance(self):
from erpnext.accounts.utils import get_balance_on
if not frappe.db.exists("Account", "Test Percent Account %5 - _TC"):
acc = frappe.new_doc("Account")
acc.account_name = "Test Percent Account %5"
acc.parent_account = "Tax Assets - _TC"
acc.company = "_Test Company"
acc.insert()
balance = get_balance_on(account="Test Percent Account %5 - _TC", date=nowdate())
self.assertEqual(balance, 0)
def _make_test_records(verbose=None):
from frappe.test_runner import make_test_objects

View File

@@ -11,6 +11,10 @@ from frappe.model import core_doctypes_list
from frappe.model.document import Document
from frappe.utils import cstr
from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
get_allowed_types_from_settings,
)
class AccountingDimension(Document):
# begin: auto-generated types
@@ -106,6 +110,7 @@ def make_dimension_in_accounting_doctypes(doc, doclist=None):
doc_count = len(get_accounting_dimensions())
count = 0
repostable_doctypes = get_allowed_types_from_settings()
for doctype in doclist:
@@ -121,6 +126,7 @@ def make_dimension_in_accounting_doctypes(doc, doclist=None):
"options": doc.document_type,
"insert_after": insert_after_field,
"owner": "Administrator",
"allow_on_submit": 1 if doctype in repostable_doctypes else 0,
}
meta = frappe.get_meta(doctype, cached=False)

View File

@@ -1,7 +1,6 @@
{
"actions": [],
"creation": "2013-06-24 15:49:57",
"description": "Settings for Accounts",
"doctype": "DocType",
"document_type": "Other",
"editable_grid": 1,
@@ -462,7 +461,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-11-20 09:37:47.650347",
"modified": "2024-01-30 14:04:26.553554",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -11,6 +11,7 @@
{
"fieldname": "company",
"fieldtype": "Link",
"ignore_user_permissions": 1,
"in_list_view": 1,
"label": "Company",
"options": "Company",
@@ -19,7 +20,7 @@
],
"istable": 1,
"links": [],
"modified": "2020-05-01 12:32:34.044911",
"modified": "2024-01-03 11:13:02.669632",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Allowed To Transact With",
@@ -28,5 +29,6 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -9,6 +9,7 @@ from frappe.contacts.address_and_contact import (
load_address_and_contact,
)
from frappe.model.document import Document
from frappe.utils import comma_and, get_link_to_form
class BankAccount(Document):
@@ -52,6 +53,19 @@ class BankAccount(Document):
def validate(self):
self.validate_company()
self.validate_iban()
self.validate_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_company(self):
if self.is_company_account and not self.company:

View File

@@ -5,7 +5,9 @@
import frappe
from frappe import _, msgprint
from frappe.model.document import Document
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt, fmt_money, getdate
from pypika import Order
import erpnext
@@ -179,39 +181,62 @@ def get_payment_entries_for_bank_clearance(
pos_sales_invoices, pos_purchase_invoices = [], []
if include_pos_transactions:
pos_sales_invoices = frappe.db.sql(
"""
select
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
si.posting_date, si.customer as against_account, sip.clearance_date,
account.account_currency, 0 as credit
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
where
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name
and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s
order by
si.posting_date ASC, si.name DESC
""",
{"account": account, "from": from_date, "to": to_date},
as_dict=1,
)
si_payment = frappe.qb.DocType("Sales Invoice Payment")
si = frappe.qb.DocType("Sales Invoice")
acc = frappe.qb.DocType("Account")
pos_purchase_invoices = frappe.db.sql(
"""
select
"Purchase Invoice" as payment_document, pi.name as payment_entry, pi.paid_amount as credit,
pi.posting_date, pi.supplier as against_account, pi.clearance_date,
account.account_currency, 0 as debit
from `tabPurchase Invoice` pi, `tabAccount` account
where
pi.cash_bank_account=%(account)s and pi.docstatus=1 and account.name = pi.cash_bank_account
and pi.posting_date >= %(from)s and pi.posting_date <= %(to)s
order by
pi.posting_date ASC, pi.name DESC
""",
{"account": account, "from": from_date, "to": to_date},
as_dict=1,
)
pos_sales_invoices = (
frappe.qb.from_(si_payment)
.inner_join(si)
.on(si_payment.parent == si.name)
.inner_join(acc)
.on(si_payment.account == acc.name)
.select(
ConstantColumn("Sales Invoice").as_("payment_document"),
si.name.as_("payment_entry"),
si_payment.reference_no.as_("cheque_number"),
si_payment.amount.as_("debit"),
si.posting_date,
si.customer.as_("against_account"),
si_payment.clearance_date,
acc.account_currency,
ConstantColumn(0).as_("credit"),
)
.where(
(si.docstatus == 1)
& (si_payment.account == account)
& (si.posting_date >= from_date)
& (si.posting_date <= to_date)
)
.orderby(si.posting_date)
.orderby(si.name, order=Order.desc)
).run(as_dict=True)
pi = frappe.qb.DocType("Purchase Invoice")
pos_purchase_invoices = (
frappe.qb.from_(pi)
.inner_join(acc)
.on(pi.cash_bank_account == acc.name)
.select(
ConstantColumn("Purchase Invoice").as_("payment_document"),
pi.name.as_("payment_entry"),
pi.paid_amount.as_("credit"),
pi.posting_date,
pi.supplier.as_("against_account"),
pi.clearance_date,
acc.account_currency,
ConstantColumn(0).as_("debit"),
)
.where(
(pi.docstatus == 1)
& (pi.cash_bank_account == account)
& (pi.posting_date >= from_date)
& (pi.posting_date <= to_date)
)
.orderby(pi.posting_date)
.orderby(pi.name, order=Order.desc)
).run(as_dict=True)
entries = (
list(payment_entries)

View File

@@ -137,7 +137,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
args: {
bank_account: frm.doc.bank_account,
till_date: frm.doc.bank_statement_from_date,
till_date: frappe.datetime.add_days(frm.doc.bank_statement_from_date, -1)
},
callback: (response) => {
frm.set_value("account_opening_balance", response.message);

View File

@@ -444,6 +444,10 @@ def reconcile_vouchers(bank_transaction_name, vouchers):
vouchers = json.loads(vouchers)
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
transaction.add_payment_entries(vouchers)
transaction.validate_duplicate_references()
transaction.allocate_payment_entries()
transaction.update_allocated_amount()
transaction.set_status()
transaction.save()
return transaction

View File

@@ -76,6 +76,7 @@ class TestBankReconciliationTool(AccountsTestMixin, FrappeTestCase):
"deposit": 100,
"bank_account": self.bank_account,
"reference_number": "123",
"currency": "INR",
}
)
.save()

View File

@@ -3,12 +3,12 @@
import frappe
from frappe import _
from frappe.model.docstatus import DocStatus
from frappe.model.document import Document
from frappe.utils import flt
from erpnext.controllers.status_updater import StatusUpdater
class BankTransaction(StatusUpdater):
class BankTransaction(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.
@@ -49,6 +49,33 @@ class BankTransaction(StatusUpdater):
def validate(self):
self.validate_duplicate_references()
self.validate_currency()
def validate_currency(self):
"""
Bank Transaction should be on the same currency as the Bank Account.
"""
if self.currency and self.bank_account:
account = frappe.get_cached_value("Bank Account", self.bank_account, "account")
account_currency = frappe.get_cached_value("Account", account, "account_currency")
if self.currency != account_currency:
frappe.throw(
_(
"Transaction currency: {0} cannot be different from Bank Account({1}) currency: {2}"
).format(
frappe.bold(self.currency), frappe.bold(self.bank_account), frappe.bold(account_currency)
)
)
def set_status(self):
if self.docstatus == 2:
self.db_set("status", "Cancelled")
elif self.docstatus == 1:
if self.unallocated_amount > 0:
self.db_set("status", "Unreconciled")
elif self.unallocated_amount <= 0:
self.db_set("status", "Reconciled")
def validate_duplicate_references(self):
"""Make sure the same voucher is not allocated twice within the same Bank Transaction"""
@@ -67,10 +94,13 @@ class BankTransaction(StatusUpdater):
pe.append(reference)
def update_allocated_amount(self):
self.allocated_amount = (
allocated_amount = (
sum(p.allocated_amount for p in self.payment_entries) if self.payment_entries else 0.0
)
self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - self.allocated_amount
unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - allocated_amount
self.allocated_amount = flt(allocated_amount, self.precision("allocated_amount"))
self.unallocated_amount = flt(unallocated_amount, self.precision("unallocated_amount"))
def before_submit(self):
self.allocate_payment_entries()
@@ -83,12 +113,13 @@ class BankTransaction(StatusUpdater):
self.validate_duplicate_references()
self.allocate_payment_entries()
self.update_allocated_amount()
self.set_status()
def on_cancel(self):
for payment_entry in self.payment_entries:
self.clear_linked_payment_entry(payment_entry, for_cancel=True)
self.set_status(update=True)
self.set_status()
def add_payment_entries(self, vouchers):
"Add the vouchers with zero allocation. Save() will perform the allocations and clearance"
@@ -366,15 +397,17 @@ def set_voucher_clearance(doctype, docname, clearance_date, self):
and len(get_reconciled_bank_transactions(doctype, docname)) < 2
):
return
frappe.db.set_value(doctype, docname, "clearance_date", clearance_date)
elif doctype == "Sales Invoice":
frappe.db.set_value(
"Sales Invoice Payment",
dict(parenttype=doctype, parent=docname),
"clearance_date",
clearance_date,
)
if doctype == "Sales Invoice":
frappe.db.set_value(
"Sales Invoice Payment",
dict(parenttype=doctype, parent=docname),
"clearance_date",
clearance_date,
)
return
frappe.db.set_value(doctype, docname, "clearance_date", clearance_date)
elif doctype == "Bank Transaction":
# For when a second bank transaction has fixed another, e.g. refund
@@ -404,3 +437,21 @@ def unclear_reference_payment(doctype, docname, bt_name):
bt = frappe.get_doc("Bank Transaction", bt_name)
set_voucher_clearance(doctype, docname, None, bt)
return docname
def remove_from_bank_transaction(doctype, docname):
"""Remove a (cancelled) voucher from all Bank Transactions."""
for bt_name in get_reconciled_bank_transactions(doctype, docname):
bt = frappe.get_doc("Bank Transaction", bt_name)
if bt.docstatus == DocStatus.cancelled():
continue
modified = False
for pe in bt.payment_entries:
if pe.payment_document == doctype and pe.payment_entry == docname:
bt.remove(pe)
modified = True
if modified:
bt.save()

View File

@@ -2,10 +2,10 @@
# See license.txt
import json
import unittest
import frappe
from frappe import utils
from frappe.model.docstatus import DocStatus
from frappe.tests.utils import FrappeTestCase
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
@@ -32,8 +32,16 @@ class TestBankTransaction(FrappeTestCase):
frappe.db.delete(dt)
clear_loan_transactions()
make_pos_profile()
add_transactions()
add_vouchers()
# generate and use a uniq hash identifier for 'Bank Account' and it's linked GL 'Account' to avoid validation error
uniq_identifier = frappe.generate_hash(length=10)
gl_account = create_gl_account("_Test Bank " + uniq_identifier)
bank_account = create_bank_account(
gl_account=gl_account, bank_account_name="Checking Account " + uniq_identifier
)
add_transactions(bank_account=bank_account)
add_vouchers(gl_account=gl_account)
# This test checks if ERPNext is able to provide a linked payment for a bank transaction based on the amount of the bank transaction.
def test_linked_payments(self):
@@ -81,6 +89,29 @@ class TestBankTransaction(FrappeTestCase):
clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date")
self.assertFalse(clearance_date)
def test_cancel_voucher(self):
bank_transaction = frappe.get_doc(
"Bank Transaction",
dict(description="1512567 BG/000003025 OPSKATTUZWXXX AT776000000098709849 Herr G"),
)
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1700))
vouchers = json.dumps(
[
{
"payment_doctype": "Payment Entry",
"payment_name": payment.name,
"amount": bank_transaction.unallocated_amount,
}
]
)
reconcile_vouchers(bank_transaction.name, vouchers)
payment.reload()
payment.cancel()
bank_transaction.reload()
self.assertEqual(bank_transaction.docstatus, DocStatus.submitted())
self.assertEqual(bank_transaction.unallocated_amount, 1700)
self.assertEqual(bank_transaction.payment_entries, [])
# Check if ERPNext can correctly filter a linked payments based on the debit/credit amount
def test_debit_credit_output(self):
bank_transaction = frappe.get_doc(
@@ -196,7 +227,9 @@ def clear_loan_transactions():
frappe.db.delete("Loan Repayment")
def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
def create_bank_account(
bank_name="Citi Bank", gl_account="_Test Bank - _TC", bank_account_name="Checking Account"
):
try:
frappe.get_doc(
{
@@ -208,21 +241,35 @@ def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
pass
try:
frappe.get_doc(
bank_account = frappe.get_doc(
{
"doctype": "Bank Account",
"account_name": "Checking Account",
"account_name": bank_account_name,
"bank": bank_name,
"account": account_name,
"account": gl_account,
}
).insert(ignore_if_duplicate=True)
except frappe.DuplicateEntryError:
pass
return bank_account.name
def add_transactions():
create_bank_account()
def create_gl_account(gl_account_name="_Test Bank - _TC"):
gl_account = frappe.get_doc(
{
"doctype": "Account",
"company": "_Test Company",
"parent_account": "Current Assets - _TC",
"account_type": "Bank",
"is_group": 0,
"account_name": gl_account_name,
}
).insert()
return gl_account.name
def add_transactions(bank_account="_Test Bank - _TC"):
doc = frappe.get_doc(
{
"doctype": "Bank Transaction",
@@ -230,7 +277,7 @@ def add_transactions():
"date": "2018-10-23",
"deposit": 1200,
"currency": "INR",
"bank_account": "Checking Account - Citi Bank",
"bank_account": bank_account,
}
).insert()
doc.submit()
@@ -242,7 +289,7 @@ def add_transactions():
"date": "2018-10-23",
"deposit": 1700,
"currency": "INR",
"bank_account": "Checking Account - Citi Bank",
"bank_account": bank_account,
}
).insert()
doc.submit()
@@ -254,7 +301,7 @@ def add_transactions():
"date": "2018-10-26",
"withdrawal": 690,
"currency": "INR",
"bank_account": "Checking Account - Citi Bank",
"bank_account": bank_account,
}
).insert()
doc.submit()
@@ -266,7 +313,7 @@ def add_transactions():
"date": "2018-10-27",
"deposit": 3900,
"currency": "INR",
"bank_account": "Checking Account - Citi Bank",
"bank_account": bank_account,
}
).insert()
doc.submit()
@@ -278,13 +325,13 @@ def add_transactions():
"date": "2018-10-27",
"withdrawal": 109080,
"currency": "INR",
"bank_account": "Checking Account - Citi Bank",
"bank_account": bank_account,
}
).insert()
doc.submit()
def add_vouchers():
def add_vouchers(gl_account="_Test Bank - _TC"):
try:
frappe.get_doc(
{
@@ -300,7 +347,7 @@ def add_vouchers():
pi = make_purchase_invoice(supplier="Conrad Electronic", qty=1, rate=690)
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
pe.reference_no = "Conrad Oct 18"
pe.reference_date = "2018-10-24"
pe.insert()
@@ -319,14 +366,14 @@ def add_vouchers():
pass
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1200)
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
pe.reference_no = "Herr G Oct 18"
pe.reference_date = "2018-10-24"
pe.insert()
pe.submit()
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1700)
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
pe.reference_no = "Herr G Nov 18"
pe.reference_date = "2018-11-01"
pe.insert()
@@ -357,10 +404,10 @@ def add_vouchers():
pass
pi = make_purchase_invoice(supplier="Poore Simon's", qty=1, rate=3900, is_paid=1, do_not_save=1)
pi.cash_bank_account = "_Test Bank - _TC"
pi.cash_bank_account = gl_account
pi.insert()
pi.submit()
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
pe.reference_no = "Poore Simon's Oct 18"
pe.reference_date = "2018-10-28"
pe.paid_amount = 690
@@ -369,7 +416,7 @@ def add_vouchers():
pe.submit()
si = create_sales_invoice(customer="Poore Simon's", qty=1, rate=3900)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
pe = get_payment_entry("Sales Invoice", si.name, bank_account=gl_account)
pe.reference_no = "Poore Simon's Oct 18"
pe.reference_date = "2018-10-28"
pe.insert()
@@ -392,16 +439,12 @@ def add_vouchers():
if not frappe.db.get_value(
"Mode of Payment Account", {"company": "_Test Company", "parent": "Cash"}
):
mode_of_payment.append(
"accounts", {"company": "_Test Company", "default_account": "_Test Bank - _TC"}
)
mode_of_payment.append("accounts", {"company": "_Test Company", "default_account": gl_account})
mode_of_payment.save()
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080, do_not_save=1)
si.is_pos = 1
si.append(
"payments", {"mode_of_payment": "Cash", "account": "_Test Bank - _TC", "amount": 109080}
)
si.append("payments", {"mode_of_payment": "Cash", "account": gl_account, "amount": 109080})
si.insert()
si.submit()

View File

@@ -1,457 +1,152 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"actions": [],
"autoname": "naming_series:",
"beta": 0,
"creation": "2018-06-18 16:51:49.994750",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"naming_series",
"user",
"date",
"from_time",
"time",
"expense",
"custody",
"returns",
"outstanding_amount",
"payments",
"net_amount",
"amended_from"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "POS-CLO-",
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Series",
"length": 0,
"no_copy": 0,
"options": "POS-CLO-",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "user",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "User",
"length": 0,
"no_copy": 0,
"options": "User",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
"fieldname": "date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "from_time",
"fieldtype": "Time",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "From Time",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "time",
"fieldtype": "Time",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "To Time",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.00",
"fieldname": "expense",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Expense",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"label": "Expense"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.00",
"fieldname": "custody",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Custody",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"label": "Custody"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.00",
"fieldname": "returns",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Returns",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "2",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"precision": "2"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.00",
"fieldname": "outstanding_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Outstanding Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.0",
"fieldname": "payments",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payments",
"length": 0,
"no_copy": 0,
"options": "Cashier Closing Payments",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"options": "Cashier Closing Payments"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "net_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Net Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
"length": 0,
"no_copy": 1,
"options": "Cashier Closing",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-02-19 08:35:24.157327",
"links": [],
"modified": "2023-12-28 13:15:46.858427",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cashier Closing",
"name_case": "",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
}
"states": [],
"track_changes": 1
}

View File

@@ -3,16 +3,21 @@
frappe.ui.form.on('Cost Center Allocation', {
setup: function(frm) {
let filters = {"is_group": 0};
if (frm.doc.company) {
$.extend(filters, {
"company": frm.doc.company
});
}
frm.set_query('main_cost_center', function() {
return {
filters: filters
filters: {
company: frm.doc.company,
is_group: 0
}
};
});
frm.set_query('cost_center', 'allocation_percentages', function() {
return {
filters: {
company: frm.doc.company,
is_group: 0
}
};
});
}

View File

@@ -3,7 +3,7 @@
"allow_import": 1,
"autoname": "field:year",
"creation": "2013-01-22 16:50:25",
"description": "**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.",
"description": "Represents a Financial Year. All accounting entries and other major transactions are tracked against the Fiscal Year.",
"doctype": "DocType",
"document_type": "Setup",
"engine": "InnoDB",
@@ -82,10 +82,11 @@
"icon": "fa fa-calendar",
"idx": 1,
"links": [],
"modified": "2020-11-05 12:16:53.081573",
"modified": "2024-01-30 12:35:38.645968",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Fiscal Year",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
@@ -122,5 +123,6 @@
],
"show_name_in_global_search": 1,
"sort_field": "name",
"sort_order": "DESC"
"sort_order": "DESC",
"states": []
}

View File

@@ -39,7 +39,7 @@ def test_record_generator():
]
start = 2012
end = now_datetime().year + 5
end = now_datetime().year + 25
for year in range(start, end):
test_records.append(
{

View File

@@ -21,6 +21,7 @@
"against_voucher_type",
"against_voucher",
"voucher_type",
"voucher_subtype",
"voucher_no",
"voucher_detail_no",
"project",
@@ -278,13 +279,18 @@
"fieldtype": "Currency",
"label": "Credit Amount in Transaction Currency",
"options": "transaction_currency"
},
{
"fieldname": "voucher_subtype",
"fieldtype": "Small Text",
"label": "Voucher Subtype"
}
],
"icon": "fa fa-list",
"idx": 1,
"in_create": 1,
"links": [],
"modified": "2023-08-16 21:38:44.072267",
"modified": "2023-12-18 15:38:14.006208",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GL Entry",

View File

@@ -13,16 +13,9 @@ import erpnext
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_checks_for_pl_and_bs_accounts,
)
from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import (
get_dimension_filter_map,
)
from erpnext.accounts.party import validate_party_frozen_disabled, validate_party_gle_currency
from erpnext.accounts.utils import get_account_currency, get_fiscal_year
from erpnext.exceptions import (
InvalidAccountCurrency,
InvalidAccountDimensionError,
MandatoryAccountDimensionError,
)
from erpnext.exceptions import InvalidAccountCurrency
exclude_from_linked_with = True
@@ -39,6 +32,8 @@ class GLEntry(Document):
account: DF.Link | None
account_currency: DF.Link | None
against: DF.Text | None
against_link: DF.DynamicLink | None
against_type: DF.Link | None
against_voucher: DF.DynamicLink | None
against_voucher_type: DF.Link | None
company: DF.Link | None
@@ -66,6 +61,7 @@ class GLEntry(Document):
transaction_exchange_rate: DF.Float
voucher_detail_no: DF.Data | None
voucher_no: DF.DynamicLink | None
voucher_subtype: DF.SmallText | None
voucher_type: DF.Link | None
# end: auto-generated types
@@ -95,7 +91,6 @@ class GLEntry(Document):
if not self.flags.from_repost and self.voucher_type != "Period Closing Voucher":
self.validate_account_details(adv_adj)
self.validate_dimensions_for_pl_and_bs()
self.validate_allowed_dimensions()
validate_balance_type(self.account, adv_adj)
validate_frozen_account(self.account, adv_adj)
@@ -205,42 +200,6 @@ class GLEntry(Document):
)
)
def validate_allowed_dimensions(self):
dimension_filter_map = get_dimension_filter_map()
for key, value in dimension_filter_map.items():
dimension = key[0]
account = key[1]
if self.account == account:
if value["is_mandatory"] and not self.get(dimension):
frappe.throw(
_("{0} is mandatory for account {1}").format(
frappe.bold(frappe.unscrub(dimension)), frappe.bold(self.account)
),
MandatoryAccountDimensionError,
)
if value["allow_or_restrict"] == "Allow":
if self.get(dimension) and self.get(dimension) not in value["allowed_dimensions"]:
frappe.throw(
_("Invalid value {0} for {1} against account {2}").format(
frappe.bold(self.get(dimension)),
frappe.bold(frappe.unscrub(dimension)),
frappe.bold(self.account),
),
InvalidAccountDimensionError,
)
else:
if self.get(dimension) and self.get(dimension) in value["allowed_dimensions"]:
frappe.throw(
_("Invalid value {0} for {1} against account {2}").format(
frappe.bold(self.get(dimension)),
frappe.bold(frappe.unscrub(dimension)),
frappe.bold(self.account),
),
InvalidAccountDimensionError,
)
def check_pl_account(self):
if (
self.is_opening == "Yes"

View File

@@ -8,12 +8,31 @@ frappe.provide("erpnext.journal_entry");
frappe.ui.form.on("Journal Entry", {
setup: function(frm) {
frm.add_fetch("bank_account", "account", "account");
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset', 'Asset Movement', 'Asset Depreciation Schedule', "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries"];
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset', 'Asset Movement', 'Asset Depreciation Schedule', "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Bank Transaction"];
},
refresh: function(frm) {
erpnext.toggle_naming_series();
if (frm.doc.repost_required && frm.doc.docstatus===1) {
frm.set_intro(__("Accounting entries for this Journal Entry need to be reposted. Please click on 'Repost' button to update."));
frm.add_custom_button(__('Repost Accounting Entries'),
() => {
frm.call({
doc: frm.doc,
method: 'repost_accounting_entries',
freeze: true,
freeze_message: __('Reposting...'),
callback: (r) => {
if (!r.exc) {
frappe.msgprint(__('Accounting Entries are reposted.'));
frm.refresh();
}
}
});
}).removeClass('btn-default').addClass('btn-warning');
}
if(frm.doc.docstatus > 0) {
frm.add_custom_button(__('Ledger'), function() {
frappe.route_options = {
@@ -184,7 +203,6 @@ var update_jv_details = function(doc, r) {
$.each(r, function(i, d) {
var row = frappe.model.add_child(doc, "Journal Entry Account", "accounts");
frappe.model.set_value(row.doctype, row.name, "account", d.account)
frappe.model.set_value(row.doctype, row.name, "balance", d.balance)
});
refresh_field("accounts");
}
@@ -193,7 +211,6 @@ erpnext.accounts.JournalEntry = class JournalEntry extends frappe.ui.form.Contro
onload() {
this.load_defaults();
this.setup_queries();
this.setup_balance_formatter();
erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype);
}
@@ -292,19 +309,6 @@ erpnext.accounts.JournalEntry = class JournalEntry extends frappe.ui.form.Contro
}
setup_balance_formatter() {
const formatter = function(value, df, options, doc) {
var currency = frappe.meta.get_field_currency(df, doc);
var dr_or_cr = value ? ('<label>' + (value > 0.0 ? __("Dr") : __("Cr")) + '</label>') : "";
return "<div style='text-align: right'>"
+ ((value==null || value==="") ? "" : format_currency(Math.abs(value), currency))
+ " " + dr_or_cr
+ "</div>";
};
this.frm.fields_dict.accounts.grid.update_docfield_property('balance', 'formatter', formatter);
this.frm.fields_dict.accounts.grid.update_docfield_property('party_balance', 'formatter', formatter);
}
reference_name(doc, cdt, cdn) {
var d = frappe.get_doc(cdt, cdn);
@@ -400,23 +404,22 @@ frappe.ui.form.on("Journal Entry Account", {
if(!d.account && d.party_type && d.party) {
if(!frm.doc.company) frappe.throw(__("Please select Company"));
return frm.call({
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_party_account_and_balance",
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_party_account_and_currency",
child: d,
args: {
company: frm.doc.company,
party_type: d.party_type,
party: d.party,
cost_center: d.cost_center
}
});
}
},
cost_center: function(frm, dt, dn) {
erpnext.journal_entry.set_account_balance(frm, dt, dn);
erpnext.journal_entry.set_account_details(frm, dt, dn);
},
account: function(frm, dt, dn) {
erpnext.journal_entry.set_account_balance(frm, dt, dn);
erpnext.journal_entry.set_account_details(frm, dt, dn);
},
debit_in_account_currency: function(frm, cdt, cdn) {
@@ -600,14 +603,14 @@ $.extend(erpnext.journal_entry, {
});
$.extend(erpnext.journal_entry, {
set_account_balance: function(frm, dt, dn) {
set_account_details: function(frm, dt, dn) {
var d = locals[dt][dn];
if(d.account) {
if(!frm.doc.company) frappe.throw(__("Please select Company first"));
if(!frm.doc.posting_date) frappe.throw(__("Please select Posting Date first"));
return frappe.call({
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_account_balance_and_party_type",
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_account_details_and_party_type",
args: {
account: d.account,
date: frm.doc.posting_date,
@@ -615,7 +618,6 @@ $.extend(erpnext.journal_entry, {
debit: flt(d.debit_in_account_currency),
credit: flt(d.credit_in_account_currency),
exchange_rate: d.exchange_rate,
cost_center: d.cost_center
},
callback: function(r) {
if(r.message) {

View File

@@ -64,7 +64,8 @@
"stock_entry",
"subscription_section",
"auto_repeat",
"amended_from"
"amended_from",
"repost_required"
],
"fields": [
{
@@ -543,6 +544,15 @@
"label": "Is System Generated",
"no_copy": 1,
"read_only": 1
},
{
"default": "0",
"fieldname": "repost_required",
"fieldtype": "Check",
"hidden": 1,
"label": "Repost Required",
"print_hide": 1,
"read_only": 1
}
],
"icon": "fa fa-file-text",

View File

@@ -13,6 +13,10 @@ from erpnext.accounts.deferred_revenue import get_deferred_booking_accounts
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import (
get_party_account_based_on_invoice_discounting,
)
from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
validate_docs_for_deferred_accounting,
validate_docs_for_voucher_types,
)
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
get_party_tax_withholding_details,
)
@@ -140,7 +144,6 @@ class JournalEntry(AccountsController):
self.set_print_format_fields()
self.validate_credit_debit_note()
self.validate_empty_accounts_table()
self.set_account_and_party_balance()
self.validate_inter_company_accounts()
self.validate_depr_entry_voucher_type()
@@ -150,6 +153,24 @@ class JournalEntry(AccountsController):
if not self.title:
self.title = self.get_title()
def validate_for_repost(self):
validate_docs_for_voucher_types(["Journal Entry"])
validate_docs_for_deferred_accounting([self.name], [])
def submit(self):
if len(self.accounts) > 100:
msgprint(_("The task has been enqueued as a background job."), alert=True)
self.queue_action("submit", timeout=4600)
else:
return self._submit()
def cancel(self):
if len(self.accounts) > 100:
msgprint(_("The task has been enqueued as a background job."), alert=True)
self.queue_action("cancel", timeout=4600)
else:
return self._cancel()
def on_submit(self):
self.validate_cheque_info()
self.check_credit_limit()
@@ -159,6 +180,15 @@ class JournalEntry(AccountsController):
self.update_inter_company_jv()
self.update_invoice_discounting()
def on_update_after_submit(self):
if hasattr(self, "repost_required"):
self.needs_repost = self.check_if_fields_updated(
fields_to_check=[], child_tables={"accounts": []}
)
if self.needs_repost:
self.validate_for_repost()
self.db_set("repost_required", self.needs_repost)
def on_cancel(self):
# References for this Journal are removed on the `on_cancel` event in accounts_controller
super(JournalEntry, self).on_cancel()
@@ -545,17 +575,28 @@ class JournalEntry(AccountsController):
elif d.party_type == "Supplier" and flt(d.credit) > 0:
frappe.throw(_("Row {0}: Advance against Supplier must be debit").format(d.idx))
def system_generated_gain_loss(self):
return (
self.voucher_type == "Exchange Gain Or Loss"
and self.multi_currency
and self.is_system_generated
)
def validate_against_jv(self):
for d in self.get("accounts"):
if d.reference_type == "Journal Entry":
account_root_type = frappe.get_cached_value("Account", d.account, "root_type")
if account_root_type == "Asset" and flt(d.debit) > 0:
if account_root_type == "Asset" and flt(d.debit) > 0 and not self.system_generated_gain_loss():
frappe.throw(
_(
"Row #{0}: For {1}, you can select reference document only if account gets credited"
).format(d.idx, d.account)
)
elif account_root_type == "Liability" and flt(d.credit) > 0:
elif (
account_root_type == "Liability"
and flt(d.credit) > 0
and not self.system_generated_gain_loss()
):
frappe.throw(
_(
"Row #{0}: For {1}, you can select reference document only if account gets debited"
@@ -587,7 +628,7 @@ class JournalEntry(AccountsController):
for jvd in against_entries:
if flt(jvd[dr_or_cr]) > 0:
valid = True
if not valid:
if not valid and not self.system_generated_gain_loss():
frappe.throw(
_("Against Journal Entry {0} does not have any unmatched {1} entry").format(
d.reference_name, dr_or_cr
@@ -1135,21 +1176,6 @@ class JournalEntry(AccountsController):
if not self.get("accounts"):
frappe.throw(_("Accounts table cannot be blank."))
def set_account_and_party_balance(self):
account_balance = {}
party_balance = {}
for d in self.get("accounts"):
if d.account not in account_balance:
account_balance[d.account] = get_balance_on(account=d.account, date=self.posting_date)
if (d.party_type, d.party) not in party_balance:
party_balance[(d.party_type, d.party)] = get_balance_on(
party_type=d.party_type, party=d.party, date=self.posting_date, company=self.company
)
d.account_balance = account_balance[d.account]
d.party_balance = party_balance[(d.party_type, d.party)]
@frappe.whitelist()
def get_default_bank_cash_account(company, account_type=None, mode_of_payment=None, account=None):
@@ -1315,8 +1341,6 @@ def get_payment_entry(ref_doc, args):
"account_type": frappe.get_cached_value("Account", args.get("party_account"), "account_type"),
"account_currency": args.get("party_account_currency")
or get_account_currency(args.get("party_account")),
"balance": get_balance_on(args.get("party_account")),
"party_balance": get_balance_on(party=args.get("party"), party_type=args.get("party_type")),
"exchange_rate": exchange_rate,
args.get("amount_field_party"): args.get("amount"),
"is_advance": args.get("is_advance"),
@@ -1464,30 +1488,23 @@ def get_outstanding(args):
@frappe.whitelist()
def get_party_account_and_balance(company, party_type, party, cost_center=None):
def get_party_account_and_currency(company, party_type, party):
if not frappe.has_permission("Account"):
frappe.msgprint(_("No Permission"), raise_exception=1)
account = get_party_account(party_type, party, company)
account_balance = get_balance_on(account=account, cost_center=cost_center)
party_balance = get_balance_on(
party_type=party_type, party=party, company=company, cost_center=cost_center
)
return {
"account": account,
"balance": account_balance,
"party_balance": party_balance,
"account_currency": frappe.get_cached_value("Account", account, "account_currency"),
}
@frappe.whitelist()
def get_account_balance_and_party_type(
account, date, company, debit=None, credit=None, exchange_rate=None, cost_center=None
def get_account_details_and_party_type(
account, date, company, debit=None, credit=None, exchange_rate=None
):
"""Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
"""Returns dict of account details and party type to be set in Journal Entry on selection of account."""
if not frappe.has_permission("Account"):
frappe.msgprint(_("No Permission"), raise_exception=1)
@@ -1507,7 +1524,6 @@ def get_account_balance_and_party_type(
party_type = ""
grid_values = {
"balance": get_balance_on(account, date, cost_center=cost_center),
"party_type": party_type,
"account_type": account_details.account_type,
"account_currency": account_details.account_currency or company_currency,

View File

@@ -166,43 +166,37 @@ class TestJournalEntry(unittest.TestCase):
jv.get("accounts")[1].credit_in_account_currency = 5000
jv.submit()
gl_entries = frappe.db.sql(
"""select account, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
order by account asc""",
jv.name,
as_dict=1,
)
self.voucher_no = jv.name
self.assertTrue(gl_entries)
self.fields = [
"account",
"account_currency",
"debit",
"debit_in_account_currency",
"credit",
"credit_in_account_currency",
]
expected_values = {
"_Test Bank USD - _TC": {
"account_currency": "USD",
"debit": 5000,
"debit_in_account_currency": 100,
"credit": 0,
"credit_in_account_currency": 0,
},
"_Test Bank - _TC": {
self.expected_gle = [
{
"account": "_Test Bank - _TC",
"account_currency": "INR",
"debit": 0,
"debit_in_account_currency": 0,
"credit": 5000,
"credit_in_account_currency": 5000,
},
}
{
"account": "_Test Bank USD - _TC",
"account_currency": "USD",
"debit": 5000,
"debit_in_account_currency": 100,
"credit": 0,
"credit_in_account_currency": 0,
},
]
for field in (
"account_currency",
"debit",
"debit_in_account_currency",
"credit",
"credit_in_account_currency",
):
for i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account][field], gle[field])
self.check_gl_entries()
# cancel
jv.cancel()
@@ -228,43 +222,37 @@ class TestJournalEntry(unittest.TestCase):
rjv.posting_date = nowdate()
rjv.submit()
gl_entries = frappe.db.sql(
"""select account, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
order by account asc""",
rjv.name,
as_dict=1,
)
self.voucher_no = rjv.name
self.assertTrue(gl_entries)
self.fields = [
"account",
"account_currency",
"debit",
"credit",
"debit_in_account_currency",
"credit_in_account_currency",
]
expected_values = {
"_Test Bank USD - _TC": {
self.expected_gle = [
{
"account": "_Test Bank USD - _TC",
"account_currency": "USD",
"debit": 0,
"debit_in_account_currency": 0,
"credit": 5000,
"credit_in_account_currency": 100,
},
"Sales - _TC": {
{
"account": "Sales - _TC",
"account_currency": "INR",
"debit": 5000,
"debit_in_account_currency": 5000,
"credit": 0,
"credit_in_account_currency": 0,
},
}
]
for field in (
"account_currency",
"debit",
"debit_in_account_currency",
"credit",
"credit_in_account_currency",
):
for i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account][field], gle[field])
self.check_gl_entries()
def test_disallow_change_in_account_currency_for_a_party(self):
# create jv in USD
@@ -344,23 +332,25 @@ class TestJournalEntry(unittest.TestCase):
jv.insert()
jv.submit()
expected_values = {
"_Test Cash - _TC": {"cost_center": cost_center},
"_Test Bank - _TC": {"cost_center": cost_center},
}
self.voucher_no = jv.name
gl_entries = frappe.db.sql(
"""select account, cost_center, debit, credit
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
order by account asc""",
jv.name,
as_dict=1,
)
self.fields = [
"account",
"cost_center",
]
self.assertTrue(gl_entries)
self.expected_gle = [
{
"account": "_Test Bank - _TC",
"cost_center": cost_center,
},
{
"account": "_Test Cash - _TC",
"cost_center": cost_center,
},
]
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
self.check_gl_entries()
def test_jv_with_project(self):
from erpnext.projects.doctype.project.test_project import make_project
@@ -387,23 +377,22 @@ class TestJournalEntry(unittest.TestCase):
jv.insert()
jv.submit()
expected_values = {
"_Test Cash - _TC": {"project": project_name},
"_Test Bank - _TC": {"project": project_name},
}
self.voucher_no = jv.name
gl_entries = frappe.db.sql(
"""select account, project, debit, credit
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
order by account asc""",
jv.name,
as_dict=1,
)
self.fields = ["account", "project"]
self.assertTrue(gl_entries)
self.expected_gle = [
{
"account": "_Test Bank - _TC",
"project": project_name,
},
{
"account": "_Test Cash - _TC",
"project": project_name,
},
]
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["project"], gle.project)
self.check_gl_entries()
def test_jv_account_and_party_balance_with_cost_centre(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
@@ -426,6 +415,79 @@ class TestJournalEntry(unittest.TestCase):
account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=cost_center)
self.assertEqual(expected_account_balance, account_balance)
def test_repost_accounting_entries(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
# Configure Repost Accounting Ledger for JVs
settings = frappe.get_doc("Repost Accounting Ledger Settings")
if not [x for x in settings.allowed_types if x.document_type == "Journal Entry"]:
settings.append("allowed_types", {"document_type": "Journal Entry", "allowed": True})
settings.save()
# Create JV with defaut cost center - _Test Cost Center
jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, save=False)
jv.multi_currency = 0
jv.submit()
# Check GL entries before reposting
self.voucher_no = jv.name
self.fields = [
"account",
"debit_in_account_currency",
"credit_in_account_currency",
"cost_center",
]
self.expected_gle = [
{
"account": "_Test Bank - _TC",
"debit_in_account_currency": 0,
"credit_in_account_currency": 100,
"cost_center": "_Test Cost Center - _TC",
},
{
"account": "_Test Cash - _TC",
"debit_in_account_currency": 100,
"credit_in_account_currency": 0,
"cost_center": "_Test Cost Center - _TC",
},
]
self.check_gl_entries()
# Change cost center for bank account - _Test Cost Center for BS Account
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
jv.accounts[1].cost_center = "_Test Cost Center for BS Account - _TC"
jv.save()
# Check if repost flag gets set on update after submit
self.assertTrue(jv.repost_required)
jv.repost_accounting_entries()
# Check GL entries after reposting
jv.load_from_db()
self.expected_gle[0]["cost_center"] = "_Test Cost Center for BS Account - _TC"
self.check_gl_entries()
def check_gl_entries(self):
gl = frappe.qb.DocType("GL Entry")
query = frappe.qb.from_(gl)
for field in self.fields:
query = query.select(gl[field])
query = query.where(
(gl.voucher_type == "Journal Entry")
& (gl.voucher_no == self.voucher_no)
& (gl.is_cancelled == 0)
).orderby(gl.account)
gl_entries = query.run(as_dict=True)
for i in range(len(self.expected_gle)):
for field in self.fields:
self.assertEqual(self.expected_gle[i][field], gl_entries[i][field])
def make_journal_entry(
account1,

View File

@@ -9,12 +9,10 @@
"field_order": [
"account",
"account_type",
"balance",
"col_break1",
"bank_account",
"party_type",
"party",
"party_balance",
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
@@ -64,17 +62,7 @@
"print_hide": 1
},
{
"fieldname": "balance",
"fieldtype": "Currency",
"label": "Account Balance",
"no_copy": 1,
"oldfieldname": "balance",
"oldfieldtype": "Data",
"options": "account_currency",
"print_hide": 1,
"read_only": 1
},
{
"allow_on_submit": 1,
"default": ":Company",
"description": "If Income or Expense",
"fieldname": "cost_center",
@@ -107,14 +95,6 @@
"label": "Party",
"options": "party_type"
},
{
"fieldname": "party_balance",
"fieldtype": "Currency",
"label": "Party Balance",
"options": "account_currency",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "currency_section",
"fieldtype": "Section Break",
@@ -223,6 +203,7 @@
"no_copy": 1
},
{
"allow_on_submit": 1,
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
@@ -287,7 +268,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2023-11-23 11:44:25.841187",
"modified": "2024-02-05 01:10:50.224840",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry Account",

View File

@@ -1,173 +1,77 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:distribution_id",
"beta": 0,
"creation": "2013-01-10 16:34:05",
"custom": 0,
"description": "**Monthly Distribution** helps you distribute the Budget/Target across months if you have seasonality in your business.",
"docstatus": 0,
"doctype": "DocType",
"editable_grid": 0,
"engine": "InnoDB",
"actions": [],
"autoname": "field:distribution_id",
"creation": "2013-01-10 16:34:05",
"description": "Helps you distribute the Budget/Target across months if you have seasonality in your business.",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"distribution_id",
"fiscal_year",
"percentages"
],
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Name of the Monthly Distribution",
"fieldname": "distribution_id",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Distribution Name",
"length": 0,
"no_copy": 0,
"oldfieldname": "distribution_id",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"description": "Name of the Monthly Distribution",
"fieldname": "distribution_id",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Distribution Name",
"oldfieldname": "distribution_id",
"oldfieldtype": "Data",
"reqd": 1,
"unique": 1
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "fiscal_year",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Fiscal Year",
"length": 0,
"no_copy": 0,
"oldfieldname": "fiscal_year",
"oldfieldtype": "Select",
"options": "Fiscal Year",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
"fieldname": "fiscal_year",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Fiscal Year",
"oldfieldname": "fiscal_year",
"oldfieldtype": "Select",
"options": "Fiscal Year",
"search_index": 1
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "percentages",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Monthly Distribution Percentages",
"length": 0,
"no_copy": 0,
"oldfieldname": "budget_distribution_details",
"oldfieldtype": "Table",
"options": "Monthly Distribution Percentage",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldname": "percentages",
"fieldtype": "Table",
"label": "Monthly Distribution Percentages",
"oldfieldname": "budget_distribution_details",
"oldfieldtype": "Table",
"options": "Monthly Distribution Percentage"
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-bar-chart",
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-11-21 14:54:35.998761",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Monthly Distribution",
"name_case": "Title Case",
"owner": "Administrator",
],
"icon": "fa fa-bar-chart",
"idx": 1,
"links": [],
"modified": "2024-01-30 13:57:55.802744",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Monthly Distribution",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
},
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 2,
"print": 0,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
"permlevel": 2,
"read": 1,
"report": 1,
"role": "Accounts Manager"
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_seen": 0
],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

View File

@@ -9,7 +9,7 @@ erpnext.accounts.taxes.setup_tax_filters("Advance Taxes and Charges");
frappe.ui.form.on('Payment Entry', {
onload: function(frm) {
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payment', 'Unreconcile Payment Entries'];
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payment', 'Unreconcile Payment Entries', "Bank Transaction"];
if(frm.doc.__islocal) {
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
@@ -149,7 +149,7 @@ frappe.ui.form.on('Payment Entry', {
},
refresh: function(frm) {
erpnext.hide_company();
erpnext.hide_company(frm);
frm.events.hide_unhide_fields(frm);
frm.events.set_dynamic_labels(frm);
frm.events.show_general_ledger(frm);
@@ -640,7 +640,7 @@ frappe.ui.form.on('Payment Entry', {
get_outstanding_invoices_or_orders: function(frm, get_outstanding_invoices, get_orders_to_be_billed) {
const today = frappe.datetime.get_today();
const fields = [
let fields = [
{fieldtype:"Section Break", label: __("Posting Date")},
{fieldtype:"Date", label: __("From Date"),
fieldname:"from_posting_date", default:frappe.datetime.add_days(today, -30)},
@@ -655,18 +655,29 @@ frappe.ui.form.on('Payment Entry', {
fieldname:"outstanding_amt_greater_than", default: 0},
{fieldtype:"Column Break"},
{fieldtype:"Float", label: __("Less Than Amount"), fieldname:"outstanding_amt_less_than"},
{fieldtype:"Section Break"},
{fieldtype:"Link", label:__("Cost Center"), fieldname:"cost_center", options:"Cost Center",
"get_query": function() {
return {
"filters": {"company": frm.doc.company}
}
];
if (frm.dimension_filters) {
let column_break_insertion_point = Math.ceil((frm.dimension_filters.length)/2);
fields.push({fieldtype:"Section Break"});
frm.dimension_filters.map((elem, idx)=>{
fields.push({
fieldtype: "Link",
label: elem.document_type == "Cost Center" ? "Cost Center" : elem.label,
options: elem.document_type,
fieldname: elem.fieldname || elem.document_type
});
if(idx+1 == column_break_insertion_point) {
fields.push({fieldtype:"Column Break"});
}
},
{fieldtype:"Column Break"},
});
}
fields = fields.concat([
{fieldtype:"Section Break"},
{fieldtype:"Check", label: __("Allocate Payment Amount"), fieldname:"allocate_payment_amount", default:1},
];
]);
let btn_text = "";
@@ -747,6 +758,10 @@ frappe.ui.form.on('Payment Entry', {
args["get_orders_to_be_billed"] = true;
}
if (frm.doc.book_advance_payments_in_separate_party_account) {
args["book_advance_payments_in_separate_party_account"] = true;
}
frappe.flags.allocate_payment_amount = filters['allocate_payment_amount'];
return frappe.call({
@@ -929,7 +944,7 @@ frappe.ui.form.on('Payment Entry', {
if(frm.doc.payment_type == "Receive"
&& frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions
&& frm.doc.total_allocated_amount < frm.doc.paid_amount + (total_deductions / frm.doc.source_exchange_rate)) {
unallocated_amount = (frm.doc.base_received_amount + total_deductions + flt(frm.doc.base_total_taxes_and_charges)
unallocated_amount = (frm.doc.base_received_amount + total_deductions - flt(frm.doc.base_total_taxes_and_charges)
- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
} else if (frm.doc.payment_type == "Pay"
&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions

View File

@@ -87,12 +87,14 @@
"status",
"custom_remarks",
"remarks",
"base_in_words",
"column_break_16",
"letter_head",
"print_heading",
"bank",
"bank_account_no",
"payment_order",
"in_words",
"subscription_section",
"auto_repeat",
"amended_from",
@@ -746,6 +748,20 @@
"hidden": 1,
"label": "Book Advance Payments in Separate Party Account",
"read_only": 1
},
{
"fieldname": "base_in_words",
"fieldtype": "Small Text",
"label": "In Words (Company Currency)",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "in_words",
"fieldtype": "Small Text",
"label": "In Words",
"print_hide": 1,
"read_only": 1
}
],
"index_web_pages_for_search": 1,
@@ -759,7 +775,7 @@
"table_fieldname": "payment_entries"
}
],
"modified": "2023-11-23 12:07:20.887885",
"modified": "2024-01-03 12:46:41.759121",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@@ -13,6 +13,7 @@ from pypika import Case
from pypika.functions import Coalesce, Sum
import erpnext
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_dimensions
from erpnext.accounts.doctype.bank_account.bank_account import (
get_bank_account_details,
get_party_bank_account,
@@ -95,6 +96,7 @@ class PaymentEntry(AccountsController):
self.validate_paid_invoices()
self.ensure_supplier_is_not_blocked()
self.set_status()
self.set_total_in_words()
def on_submit(self):
if self.difference_amount:
@@ -107,7 +109,7 @@ class PaymentEntry(AccountsController):
def set_liability_account(self):
# Auto setting liability account should only be done during 'draft' status
if self.docstatus > 0:
if self.docstatus > 0 or self.payment_type == "Internal Transfer":
return
if not frappe.db.get_value(
@@ -256,6 +258,7 @@ class PaymentEntry(AccountsController):
"get_outstanding_invoices": True,
"get_orders_to_be_billed": True,
"vouchers": vouchers,
"book_advance_payments_in_separate_party_account": self.book_advance_payments_in_separate_party_account,
},
validate=True,
)
@@ -386,7 +389,10 @@ class PaymentEntry(AccountsController):
)
def set_missing_ref_details(
self, force: bool = False, update_ref_details_only_for: list | None = None
self,
force: bool = False,
update_ref_details_only_for: list | None = None,
ref_exchange_rate: float | None = None,
) -> None:
for d in self.get("references"):
if d.allocated_amount:
@@ -398,6 +404,8 @@ class PaymentEntry(AccountsController):
ref_details = get_reference_details(
d.reference_doctype, d.reference_name, self.party_account_currency
)
if ref_exchange_rate:
ref_details.update({"exchange_rate": ref_exchange_rate})
for field, value in ref_details.items():
if d.exchange_gain_loss:
@@ -701,6 +709,21 @@ class PaymentEntry(AccountsController):
self.db_set("status", self.status, update_modified=True)
def set_total_in_words(self):
from frappe.utils import money_in_words
if self.payment_type in ("Pay", "Internal Transfer"):
base_amount = abs(self.base_paid_amount)
amount = abs(self.paid_amount)
currency = self.paid_from_account_currency
elif self.payment_type == "Receive":
base_amount = abs(self.base_received_amount)
amount = abs(self.received_amount)
currency = self.paid_to_account_currency
self.base_in_words = money_in_words(base_amount, self.company_currency)
self.in_words = money_in_words(amount, currency)
def set_tax_withholding(self):
if not self.party_type == "Supplier":
return
@@ -928,19 +951,19 @@ class PaymentEntry(AccountsController):
)
base_party_amount = flt(self.base_total_allocated_amount) + flt(base_unallocated_amount)
if self.payment_type == "Receive":
self.difference_amount = base_party_amount - self.base_received_amount
elif self.payment_type == "Pay":
self.difference_amount = self.base_paid_amount - base_party_amount
else:
self.difference_amount = self.base_paid_amount - flt(self.base_received_amount)
total_deductions = sum(flt(d.amount) for d in self.get("deductions"))
included_taxes = self.get_included_taxes()
if self.payment_type == "Receive":
self.difference_amount = base_party_amount - self.base_received_amount + included_taxes
elif self.payment_type == "Pay":
self.difference_amount = self.base_paid_amount - base_party_amount - included_taxes
else:
self.difference_amount = self.base_paid_amount - flt(self.base_received_amount) - included_taxes
total_deductions = sum(flt(d.amount) for d in self.get("deductions"))
self.difference_amount = flt(
self.difference_amount - total_deductions - included_taxes, self.precision("difference_amount")
self.difference_amount - total_deductions, self.precision("difference_amount")
)
def get_included_taxes(self):
@@ -1587,6 +1610,13 @@ def get_outstanding_reference_documents(args, validate=False):
condition += " and cost_center='%s'" % args.get("cost_center")
accounting_dimensions_filter.append(ple.cost_center == args.get("cost_center"))
# dynamic dimension filters
active_dimensions = get_dimensions()[0]
for dim in active_dimensions:
if args.get(dim.fieldname):
condition += " and {0}='{1}'".format(dim.fieldname, args.get(dim.fieldname))
accounting_dimensions_filter.append(ple[dim.fieldname] == args.get(dim.fieldname))
date_fields_dict = {
"posting_date": ["from_posting_date", "to_posting_date"],
"due_date": ["from_due_date", "to_due_date"],
@@ -1614,11 +1644,16 @@ def get_outstanding_reference_documents(args, validate=False):
outstanding_invoices = []
negative_outstanding_invoices = []
if args.get("book_advance_payments_in_separate_party_account"):
party_account = get_party_account(args.get("party_type"), args.get("party"), args.get("company"))
else:
party_account = args.get("party_account")
if args.get("get_outstanding_invoices"):
outstanding_invoices = get_outstanding_invoices(
args.get("party_type"),
args.get("party"),
get_party_account(args.get("party_type"), args.get("party"), args.get("company")),
party_account,
common_filter=common_filter,
posting_date=posting_and_due_date,
min_outstanding=args.get("outstanding_amt_greater_than"),
@@ -1815,6 +1850,12 @@ def get_orders_to_be_billed(
if doc and hasattr(doc, "cost_center") and doc.cost_center:
condition = " and cost_center='%s'" % cost_center
# dynamic dimension filters
active_dimensions = get_dimensions()[0]
for dim in active_dimensions:
if filters.get(dim.fieldname):
condition += " and {0}='{1}'".format(dim.fieldname, filters.get(dim.fieldname))
if party_account_currency == company_currency:
grand_total_field = "base_grand_total"
rounded_total_field = "base_rounded_total"

View File

@@ -4,9 +4,13 @@
import unittest
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import getdate
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import create_bank_account
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import (
create_bank_account,
create_gl_account,
)
from erpnext.accounts.doctype.payment_entry.payment_entry import (
get_payment_entry,
make_payment_order,
@@ -14,28 +18,32 @@ from erpnext.accounts.doctype.payment_entry.payment_entry import (
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
class TestPaymentOrder(unittest.TestCase):
class TestPaymentOrder(FrappeTestCase):
def setUp(self):
create_bank_account()
# generate and use a uniq hash identifier for 'Bank Account' and it's linked GL 'Account' to avoid validation error
uniq_identifier = frappe.generate_hash(length=10)
self.gl_account = create_gl_account("_Test Bank " + uniq_identifier)
self.bank_account = create_bank_account(
gl_account=self.gl_account, bank_account_name="Checking Account " + uniq_identifier
)
def tearDown(self):
for bt in frappe.get_all("Payment Order"):
doc = frappe.get_doc("Payment Order", bt.name)
doc.cancel()
doc.delete()
frappe.db.rollback()
def test_payment_order_creation_against_payment_entry(self):
purchase_invoice = make_purchase_invoice()
payment_entry = get_payment_entry(
"Purchase Invoice", purchase_invoice.name, bank_account="_Test Bank - _TC"
"Purchase Invoice", purchase_invoice.name, bank_account=self.gl_account
)
payment_entry.reference_no = "_Test_Payment_Order"
payment_entry.reference_date = getdate()
payment_entry.party_bank_account = "Checking Account - Citi Bank"
payment_entry.party_bank_account = self.bank_account
payment_entry.insert()
payment_entry.submit()
doc = create_payment_order_against_payment_entry(payment_entry, "Payment Entry")
doc = create_payment_order_against_payment_entry(
payment_entry, "Payment Entry", self.bank_account
)
reference_doc = doc.get("references")[0]
self.assertEqual(reference_doc.reference_name, payment_entry.name)
self.assertEqual(reference_doc.reference_doctype, "Payment Entry")
@@ -43,13 +51,13 @@ class TestPaymentOrder(unittest.TestCase):
self.assertEqual(reference_doc.amount, 250)
def create_payment_order_against_payment_entry(ref_doc, order_type):
def create_payment_order_against_payment_entry(ref_doc, order_type, bank_account):
payment_order = frappe.get_doc(
dict(
doctype="Payment Order",
company="_Test Company",
payment_order_type=order_type,
company_bank_account="Checking Account - Citi Bank",
company_bank_account=bank_account,
)
)
doc = make_payment_order(ref_doc.name, payment_order)

View File

@@ -95,6 +95,8 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
this.frm.change_custom_button_type(__('Allocate'), null, 'default');
}
this.frm.trigger("set_query_for_dimension_filters");
// check for any running reconciliation jobs
if (this.frm.doc.receivable_payable_account) {
this.frm.call({
@@ -125,6 +127,25 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
}
}
set_query_for_dimension_filters() {
frappe.call({
method: "erpnext.accounts.doctype.payment_reconciliation.payment_reconciliation.get_queries_for_dimension_filters",
args: {
company: this.frm.doc.company,
},
callback: (r) => {
if (!r.exc && r.message) {
r.message.forEach(x => {
this.frm.set_query(x.fieldname, () => {
return {
'filters': x.filters
};
});
});
}
}
});
}
company() {
this.frm.set_value('party', '');

View File

@@ -25,7 +25,9 @@
"invoice_limit",
"payment_limit",
"bank_cash_account",
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
"sec_break1",
"invoice_name",
"invoices",
@@ -208,6 +210,18 @@
"fieldname": "payment_name",
"fieldtype": "Data",
"label": "Filter on Payment"
},
{
"collapsible": 1,
"collapsible_depends_on": "eval: doc.invoices.length == 0",
"depends_on": "eval:doc.receivable_payable_account",
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions Filter"
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
}
],
"hide_toolbar": 1,
@@ -215,7 +229,7 @@
"is_virtual": 1,
"issingle": 1,
"links": [],
"modified": "2023-11-17 17:33:55.701726",
"modified": "2023-12-14 13:38:16.264013",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation",

View File

@@ -10,6 +10,7 @@ from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt, fmt_money, get_link_to_form, getdate, nowdate, today
import erpnext
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_dimensions
from erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation import (
is_any_doc_running,
)
@@ -70,6 +71,7 @@ class PaymentReconciliation(Document):
self.common_filter_conditions = []
self.accounting_dimension_filter_conditions = []
self.ple_posting_date_filter = []
self.dimensions = get_dimensions()[0]
def load_from_db(self):
# 'modified' attribute is required for `run_doc_method` to work properly.
@@ -172,6 +174,14 @@ class PaymentReconciliation(Document):
if self.payment_name:
condition.update({"name": self.payment_name})
# pass dynamic dimension filter values to query builder
dimensions = {}
for x in self.dimensions:
dimension = x.fieldname
if self.get(dimension):
dimensions.update({dimension: self.get(dimension)})
condition.update({"accounting_dimensions": dimensions})
payment_entries = get_advance_payment_entries_for_regional(
self.party_type,
self.party,
@@ -185,66 +195,67 @@ class PaymentReconciliation(Document):
return payment_entries
def get_jv_entries(self):
condition = self.get_conditions()
je = qb.DocType("Journal Entry")
jea = qb.DocType("Journal Entry Account")
conditions = self.get_journal_filter_conditions()
# Dimension filters
for x in self.dimensions:
dimension = x.fieldname
if self.get(dimension):
conditions.append(jea[dimension] == self.get(dimension))
if self.payment_name:
condition += f" and t1.name like '%%{self.payment_name}%%'"
conditions.append(je.name.like(f"%%{self.payment_name}%%"))
if self.get("cost_center"):
condition += f" and t2.cost_center = '{self.cost_center}' "
conditions.append(jea.cost_center == self.cost_center)
dr_or_cr = (
"credit_in_account_currency"
if erpnext.get_party_account_type(self.party_type) == "Receivable"
else "debit_in_account_currency"
)
conditions.append(jea[dr_or_cr].gt(0))
bank_account_condition = (
"t2.against_account like %(bank_cash_account)s" if self.bank_cash_account else "1=1"
if self.bank_cash_account:
conditions.append(jea.against_account.like(f"%%{self.bank_cash_account}%%"))
journal_query = (
qb.from_(je)
.inner_join(jea)
.on(jea.parent == je.name)
.select(
ConstantColumn("Journal Entry").as_("reference_type"),
je.name.as_("reference_name"),
je.posting_date,
je.remark.as_("remarks"),
jea.name.as_("reference_row"),
jea[dr_or_cr].as_("amount"),
jea.is_advance,
jea.exchange_rate,
jea.account_currency.as_("currency"),
jea.cost_center.as_("cost_center"),
)
.where(
(je.docstatus == 1)
& (jea.party_type == self.party_type)
& (jea.party == self.party)
& (jea.account == self.receivable_payable_account)
& (
(jea.reference_type == "")
| (jea.reference_type.isnull())
| (jea.reference_type.isin(("Sales Order", "Purchase Order")))
)
)
.where(Criterion.all(conditions))
.orderby(je.posting_date)
)
limit = f"limit {self.payment_limit}" if self.payment_limit else " "
if self.payment_limit:
journal_query = journal_query.limit(self.payment_limit)
# nosemgrep
journal_entries = frappe.db.sql(
"""
select
"Journal Entry" as reference_type, t1.name as reference_name,
t1.posting_date, t1.remark as remarks, t2.name as reference_row,
{dr_or_cr} as amount, t2.is_advance, t2.exchange_rate,
t2.account_currency as currency, t2.cost_center as cost_center
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
t1.name = t2.parent and t1.docstatus = 1 and t2.docstatus = 1
and t2.party_type = %(party_type)s and t2.party = %(party)s
and t2.account = %(account)s and {dr_or_cr} > 0 {condition}
and (t2.reference_type is null or t2.reference_type = '' or
(t2.reference_type in ('Sales Order', 'Purchase Order')
and t2.reference_name is not null and t2.reference_name != ''))
and (CASE
WHEN t1.voucher_type in ('Debit Note', 'Credit Note')
THEN 1=1
ELSE {bank_account_condition}
END)
order by t1.posting_date
{limit}
""".format(
**{
"dr_or_cr": dr_or_cr,
"bank_account_condition": bank_account_condition,
"condition": condition,
"limit": limit,
}
),
{
"party_type": self.party_type,
"party": self.party,
"account": self.receivable_payable_account,
"bank_cash_account": "%%%s%%" % self.bank_cash_account,
},
as_dict=1,
)
journal_entries = journal_query.run(as_dict=True)
return list(journal_entries)
@@ -298,6 +309,7 @@ class PaymentReconciliation(Document):
min_outstanding=-(self.minimum_payment_amount) if self.minimum_payment_amount else None,
max_outstanding=-(self.maximum_payment_amount) if self.maximum_payment_amount else None,
get_payments=True,
accounting_dimensions=self.accounting_dimension_filter_conditions,
)
for inv in return_outstanding:
@@ -446,8 +458,15 @@ class PaymentReconciliation(Document):
row = self.append("allocation", {})
row.update(entry)
def update_dimension_values_in_allocated_entries(self, res):
for x in self.dimensions:
dimension = x.fieldname
if self.get(dimension):
res[dimension] = self.get(dimension)
return res
def get_allocated_entry(self, pay, inv, allocated_amount):
return frappe._dict(
res = frappe._dict(
{
"reference_type": pay.get("reference_type"),
"reference_name": pay.get("reference_name"),
@@ -463,6 +482,9 @@ class PaymentReconciliation(Document):
}
)
res = self.update_dimension_values_in_allocated_entries(res)
return res
def reconcile_allocations(self, skip_ref_details_update_for_pe=False):
adjust_allocations_for_taxes(self)
dr_or_cr = (
@@ -485,10 +507,10 @@ class PaymentReconciliation(Document):
reconciled_entry.append(payment_details)
if entry_list:
reconcile_against_document(entry_list, skip_ref_details_update_for_pe)
reconcile_against_document(entry_list, skip_ref_details_update_for_pe, self.dimensions)
if dr_or_cr_notes:
reconcile_dr_cr_note(dr_or_cr_notes, self.company)
reconcile_dr_cr_note(dr_or_cr_notes, self.company, self.dimensions)
@frappe.whitelist()
def reconcile(self):
@@ -517,7 +539,7 @@ class PaymentReconciliation(Document):
self.get_unreconciled_entries()
def get_payment_details(self, row, dr_or_cr):
return frappe._dict(
payment_details = frappe._dict(
{
"voucher_type": row.get("reference_type"),
"voucher_no": row.get("reference_name"),
@@ -539,6 +561,12 @@ class PaymentReconciliation(Document):
}
)
for x in self.dimensions:
if row.get(x.fieldname):
payment_details[x.fieldname] = row.get(x.fieldname)
return payment_details
def check_mandatory_to_fetch(self):
for fieldname in ["company", "party_type", "party", "receivable_payable_account"]:
if not self.get(fieldname):
@@ -603,7 +631,12 @@ class PaymentReconciliation(Document):
journals_map = frappe._dict(
frappe.db.get_all(
"Journal Entry Account",
filters={"parent": ("in", journals), "account": ("in", [self.receivable_payable_account])},
filters={
"parent": ("in", journals),
"account": ("in", [self.receivable_payable_account]),
"party_type": self.party_type,
"party": self.party,
},
fields=[
"parent as `name`",
"exchange_rate",
@@ -646,6 +679,13 @@ class PaymentReconciliation(Document):
if not invoices_to_reconcile:
frappe.throw(_("No records found in Allocation table"))
def build_dimensions_filter_conditions(self):
ple = qb.DocType("Payment Ledger Entry")
for x in self.dimensions:
dimension = x.fieldname
if self.get(dimension):
self.accounting_dimension_filter_conditions.append(ple[dimension] == self.get(dimension))
def build_qb_filter_conditions(self, get_invoices=False, get_return_invoices=False):
self.common_filter_conditions.clear()
self.accounting_dimension_filter_conditions.clear()
@@ -669,40 +709,30 @@ class PaymentReconciliation(Document):
if self.to_payment_date:
self.ple_posting_date_filter.append(ple.posting_date.lte(self.to_payment_date))
def get_conditions(self, get_payments=False):
condition = " and company = '{0}' ".format(self.company)
self.build_dimensions_filter_conditions()
if self.get("cost_center") and get_payments:
condition = " and cost_center = '{0}' ".format(self.cost_center)
def get_journal_filter_conditions(self):
conditions = []
je = qb.DocType("Journal Entry")
jea = qb.DocType("Journal Entry Account")
conditions.append(je.company == self.company)
condition += (
" and posting_date >= {0}".format(frappe.db.escape(self.from_payment_date))
if self.from_payment_date
else ""
)
condition += (
" and posting_date <= {0}".format(frappe.db.escape(self.to_payment_date))
if self.to_payment_date
else ""
)
if self.from_payment_date:
conditions.append(je.posting_date.gte(self.from_payment_date))
if self.to_payment_date:
conditions.append(je.posting_date.lte(self.to_payment_date))
if self.minimum_payment_amount:
condition += (
" and unallocated_amount >= {0}".format(flt(self.minimum_payment_amount))
if get_payments
else " and total_debit >= {0}".format(flt(self.minimum_payment_amount))
)
conditions.append(je.total_debit.gte(self.minimum_payment_amount))
if self.maximum_payment_amount:
condition += (
" and unallocated_amount <= {0}".format(flt(self.maximum_payment_amount))
if get_payments
else " and total_debit <= {0}".format(flt(self.maximum_payment_amount))
)
conditions.append(je.total_debit.lte(self.maximum_payment_amount))
return condition
return conditions
def reconcile_dr_cr_note(dr_cr_notes, company):
def reconcile_dr_cr_note(dr_cr_notes, company, active_dimensions=None):
for inv in dr_cr_notes:
voucher_type = "Credit Note" if inv.voucher_type == "Sales Invoice" else "Debit Note"
@@ -752,6 +782,15 @@ def reconcile_dr_cr_note(dr_cr_notes, company):
}
)
# Credit Note(JE) will inherit the same dimension values as payment
dimensions_dict = frappe._dict()
if active_dimensions:
for dim in active_dimensions:
dimensions_dict[dim.fieldname] = inv.get(dim.fieldname)
jv.accounts[0].update(dimensions_dict)
jv.accounts[1].update(dimensions_dict)
jv.flags.ignore_mandatory = True
jv.flags.ignore_exchange_rate = True
jv.remark = None
@@ -785,9 +824,27 @@ def reconcile_dr_cr_note(dr_cr_notes, company):
inv.against_voucher,
None,
inv.cost_center,
dimensions_dict,
)
@erpnext.allow_regional
def adjust_allocations_for_taxes(doc):
pass
@frappe.whitelist()
def get_queries_for_dimension_filters(company: str = None):
dimensions_with_filters = []
for d in get_dimensions()[0]:
filters = {}
meta = frappe.get_meta(d.document_type)
if meta.has_field("company") and company:
filters.update({"company": company})
if meta.is_tree:
filters.update({"is_group": 0})
dimensions_with_filters.append({"fieldname": d.fieldname, "filters": filters})
return dimensions_with_filters

View File

@@ -56,6 +56,7 @@ class TestPaymentReconciliation(FrappeTestCase):
self.expense_account = "Cost of Goods Sold - _PR"
self.debit_to = "Debtors - _PR"
self.creditors = "Creditors - _PR"
self.cash = "Cash - _PR"
# create bank account
if frappe.db.exists("Account", "HDFC - _PR"):
@@ -486,6 +487,91 @@ class TestPaymentReconciliation(FrappeTestCase):
self.assertEqual(len(pr.get("invoices")), 0)
self.assertEqual(len(pr.get("payments")), 0)
def test_payment_against_foreign_currency_journal(self):
transaction_date = nowdate()
self.supplier = "_Test Supplier USD"
self.supplier2 = make_supplier("_Test Supplier2 USD", "USD")
amount = 100
exc_rate1 = 80
exc_rate2 = 83
je = frappe.new_doc("Journal Entry")
je.posting_date = transaction_date
je.company = self.company
je.user_remark = "test"
je.multi_currency = 1
je.set(
"accounts",
[
{
"account": self.creditors_usd,
"party_type": "Supplier",
"party": self.supplier,
"exchange_rate": exc_rate1,
"cost_center": self.cost_center,
"credit": amount * exc_rate1,
"credit_in_account_currency": amount,
},
{
"account": self.creditors_usd,
"party_type": "Supplier",
"party": self.supplier2,
"exchange_rate": exc_rate2,
"cost_center": self.cost_center,
"credit": amount * exc_rate2,
"credit_in_account_currency": amount,
},
{
"account": self.expense_account,
"cost_center": self.cost_center,
"debit": (amount * exc_rate1) + (amount * exc_rate2),
"debit_in_account_currency": (amount * exc_rate1) + (amount * exc_rate2),
},
],
)
je.save().submit()
pe = self.create_payment_entry(amount=amount, posting_date=transaction_date)
pe.payment_type = "Pay"
pe.party_type = "Supplier"
pe.party = self.supplier
pe.paid_to = self.creditors_usd
pe.paid_from = self.cash
pe.paid_amount = 8000
pe.received_amount = 100
pe.target_exchange_rate = exc_rate1
pe.paid_to_account_currency = "USD"
pe.save().submit()
pr = self.create_payment_reconciliation(party_is_customer=False)
pr.receivable_payable_account = self.creditors_usd
pr.minimum_invoice_amount = pr.maximum_invoice_amount = amount
pr.from_invoice_date = pr.to_invoice_date = transaction_date
pr.from_payment_date = pr.to_payment_date = transaction_date
pr.get_unreconciled_entries()
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}))
# There should no difference_amount as the Journal and Payment have same exchange rate - 'exc_rate1'
for row in pr.allocation:
self.assertEqual(flt(row.get("difference_amount")), 0.0)
pr.reconcile()
# check PR tool output
self.assertEqual(len(pr.get("invoices")), 0)
self.assertEqual(len(pr.get("payments")), 0)
journals = frappe.db.get_all(
"Journal Entry Account",
filters={"reference_type": je.doctype, "reference_name": je.name, "docstatus": 1},
fields=["parent"],
)
self.assertEqual([], journals)
def test_journal_against_invoice(self):
transaction_date = nowdate()
amount = 100
@@ -591,6 +677,70 @@ class TestPaymentReconciliation(FrappeTestCase):
self.assertEqual(si.status, "Paid")
self.assertEqual(si.outstanding_amount, 0)
def test_invoice_status_after_cr_note_cancellation(self):
# This test case is made after the 'always standalone Credit/Debit notes' feature is introduced
transaction_date = nowdate()
amount = 100
si = self.create_sales_invoice(qty=1, rate=amount, posting_date=transaction_date)
cr_note = self.create_sales_invoice(
qty=-1, rate=amount, posting_date=transaction_date, do_not_save=True, do_not_submit=True
)
cr_note.is_return = 1
cr_note.return_against = si.name
cr_note = cr_note.save().submit()
pr = self.create_payment_reconciliation()
pr.get_unreconciled_entries()
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()
pr.get_unreconciled_entries()
self.assertEqual(pr.get("invoices"), [])
self.assertEqual(pr.get("payments"), [])
journals = frappe.db.get_all(
"Journal Entry",
filters={
"is_system_generated": 1,
"docstatus": 1,
"voucher_type": "Credit Note",
"reference_type": si.doctype,
"reference_name": si.name,
},
pluck="name",
)
self.assertEqual(len(journals), 1)
# assert status and outstanding
si.reload()
self.assertEqual(si.status, "Credit Note Issued")
self.assertEqual(si.outstanding_amount, 0)
cr_note.reload()
cr_note.cancel()
# 'Credit Note' Journal should be auto cancelled
journals = frappe.db.get_all(
"Journal Entry",
filters={
"is_system_generated": 1,
"docstatus": 1,
"voucher_type": "Credit Note",
"reference_type": si.doctype,
"reference_name": si.name,
},
pluck="name",
)
self.assertEqual(len(journals), 0)
# assert status and outstanding
si.reload()
self.assertEqual(si.status, "Unpaid")
self.assertEqual(si.outstanding_amount, 100)
def test_cr_note_partial_against_invoice(self):
transaction_date = nowdate()
amount = 100
@@ -1184,3 +1334,17 @@ def make_customer(customer_name, currency=None):
return customer.name
else:
return customer_name
def make_supplier(supplier_name, currency=None):
if not frappe.db.exists("Supplier", supplier_name):
supplier = frappe.new_doc("Supplier")
supplier.supplier_name = supplier_name
supplier.type = "Individual"
if currency:
supplier.default_currency = currency
supplier.save()
return supplier.name
else:
return supplier_name

View File

@@ -23,7 +23,9 @@
"difference_account",
"exchange_rate",
"currency",
"cost_center"
"accounting_dimensions_section",
"cost_center",
"dimension_col_break"
],
"fields": [
{
@@ -151,12 +153,26 @@
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
},
{
"fieldname": "gain_loss_posting_date",
"fieldtype": "Date",
"label": "Difference Posting Date"
},
{
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
}
],
"is_virtual": 1,
"istable": 1,
"links": [],
"modified": "2023-11-17 17:33:38.612615",
"modified": "2023-12-14 13:38:26.104150",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Allocation",

View File

@@ -11,7 +11,6 @@ from erpnext.accounts.doctype.loyalty_program.loyalty_program import validate_lo
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
SalesInvoice,
get_bank_cash_account,
get_mode_of_payment_info,
update_multi_mode_option,
)
@@ -208,7 +207,6 @@ class POSInvoice(SalesInvoice):
self.validate_stock_availablility()
self.validate_return_items_qty()
self.set_status()
self.set_account_for_mode_of_payment()
self.validate_pos()
self.validate_payment_amount()
self.validate_loyalty_transaction()
@@ -643,11 +641,6 @@ class POSInvoice(SalesInvoice):
update_multi_mode_option(self, pos_profile)
self.paid_amount = 0
def set_account_for_mode_of_payment(self):
for pay in self.payments:
if not pay.account:
pay.account = get_bank_cash_account(pay.mode_of_payment, self.company).get("account")
@frappe.whitelist()
def create_payment_request(self):
for pay in self.payments:
@@ -765,7 +758,7 @@ def get_pos_reserved_qty(item_code, warehouse):
reserved_qty = (
frappe.qb.from_(p_inv)
.from_(p_item)
.select(Sum(p_item.qty).as_("qty"))
.select(Sum(p_item.stock_qty).as_("stock_qty"))
.where(
(p_inv.name == p_item.parent)
& (IfNull(p_inv.consolidated_invoice, "") == "")
@@ -775,7 +768,7 @@ def get_pos_reserved_qty(item_code, warehouse):
)
).run(as_dict=True)
return reserved_qty[0].qty or 0 if reserved_qty else 0
return flt(reserved_qty[0].stock_qty) if reserved_qty else 0
@frappe.whitelist()

View File

@@ -80,13 +80,16 @@
"target_warehouse",
"quality_inspection",
"serial_and_batch_bundle",
"batch_no",
"use_serial_batch_fields",
"col_break5",
"allow_zero_valuation_rate",
"serial_no",
"item_tax_rate",
"actual_batch_qty",
"actual_qty",
"section_break_tlhi",
"serial_no",
"column_break_ciit",
"batch_no",
"edit_references",
"sales_order",
"so_detail",
@@ -628,13 +631,13 @@
"options": "Quality Inspection"
},
{
"depends_on": "eval:doc.use_serial_batch_fields === 1",
"fieldname": "batch_no",
"fieldtype": "Link",
"hidden": 1,
"label": "Batch No",
"options": "Batch",
"print_hide": 1,
"read_only": 1
"print_hide": 1
},
{
"fieldname": "col_break5",
@@ -649,14 +652,14 @@
"print_hide": 1
},
{
"depends_on": "eval:doc.use_serial_batch_fields === 1",
"fieldname": "serial_no",
"fieldtype": "Small Text",
"fieldtype": "Text",
"hidden": 1,
"in_list_view": 1,
"label": "Serial No",
"oldfieldname": "serial_no",
"oldfieldtype": "Small Text",
"read_only": 1
"oldfieldtype": "Small Text"
},
{
"fieldname": "item_tax_rate",
@@ -824,17 +827,33 @@
"read_only": 1
},
{
"depends_on": "eval:doc.use_serial_batch_fields === 1",
"fieldname": "serial_and_batch_bundle",
"fieldtype": "Link",
"label": "Serial and Batch Bundle",
"no_copy": 1,
"options": "Serial and Batch Bundle",
"print_hide": 1
},
{
"default": "0",
"fieldname": "use_serial_batch_fields",
"fieldtype": "Check",
"label": "Use Serial No / Batch Fields"
},
{
"depends_on": "eval:doc.use_serial_batch_fields === 1",
"fieldname": "section_break_tlhi",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_ciit",
"fieldtype": "Column Break"
}
],
"istable": 1,
"links": [],
"modified": "2023-11-14 18:33:22.585715",
"modified": "2024-02-25 15:50:17.140269",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice Item",

View File

@@ -72,7 +72,7 @@ class POSInvoiceItem(Document):
rate_with_margin: DF.Currency
sales_order: DF.Link | None
serial_and_batch_bundle: DF.Link | None
serial_no: DF.SmallText | None
serial_no: DF.Text | None
service_end_date: DF.Date | None
service_start_date: DF.Date | None
service_stop_date: DF.Date | None
@@ -82,6 +82,7 @@ class POSInvoiceItem(Document):
target_warehouse: DF.Link | None
total_weight: DF.Float
uom: DF.Link
use_serial_batch_fields: DF.Check
warehouse: DF.Link | None
weight_per_unit: DF.Float
weight_uom: DF.Link | None

View File

@@ -579,12 +579,17 @@ def apply_price_discount_rule(pricing_rule, item_details, args):
item_details[field] += pricing_rule.get(field, 0) if pricing_rule else args.get(field, 0)
@frappe.whitelist()
def remove_pricing_rule_for_item(pricing_rules, item_details, item_code=None, rate=None):
from erpnext.accounts.doctype.pricing_rule.utils import (
get_applied_pricing_rules,
get_pricing_rule_items,
)
if isinstance(item_details, str):
item_details = json.loads(item_details)
item_details = frappe._dict(item_details)
for d in get_applied_pricing_rules(pricing_rules):
if not d or not frappe.db.exists("Pricing Rule", d):
continue

View File

@@ -527,7 +527,7 @@ def get_qty_amount_data_for_cumulative(pr_doc, doc, items=None):
values.extend(warehouses)
if items:
condition = " and `tab{child_doc}`.{apply_on} in ({items})".format(
condition += " and `tab{child_doc}`.{apply_on} in ({items})".format(
child_doc=child_doctype, apply_on=apply_on, items=",".join(["%s"] * len(items))
)

View File

@@ -440,7 +440,7 @@ def reconcile(doc: None | str = None) -> None:
# Update the parent doc about the exception
frappe.db.rollback()
traceback = frappe.get_traceback()
traceback = frappe.get_traceback(with_context=True)
if traceback:
message = "Traceback: <br>" + traceback
frappe.db.set_value("Process Payment Reconciliation Log", log, "error_log", message)

View File

@@ -120,18 +120,6 @@ def get_statement_dict(doc, get_statement_dict=False):
statement_dict = {}
ageing = ""
err_journals = None
if doc.report == "General Ledger" and doc.ignore_exchange_rate_revaluation_journals:
err_journals = frappe.db.get_all(
"Journal Entry",
filters={
"company": doc.company,
"docstatus": 1,
"voucher_type": ("in", ["Exchange Rate Revaluation", "Exchange Gain Or Loss"]),
},
as_list=True,
)
for entry in doc.customers:
if doc.include_ageing:
ageing = set_ageing(doc, entry)
@@ -144,8 +132,8 @@ def get_statement_dict(doc, get_statement_dict=False):
)
filters = get_common_filters(doc)
if err_journals:
filters.update({"voucher_no_not_in": [x[0] for x in err_journals]})
if doc.ignore_exchange_rate_revaluation_journals:
filters.update({"ignore_err": True})
if doc.report == "General Ledger":
filters.update(get_gl_filters(doc, entry, tax_id, presentation_currency))

View File

@@ -35,7 +35,17 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
super.onload();
// Ignore linked advances
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Serial and Batch Bundle"];
this.frm.ignore_doctypes_on_cancel_all = [
"Journal Entry",
"Payment Entry",
"Purchase Invoice",
"Repost Payment Ledger",
"Repost Accounting Ledger",
"Unreconcile Payment",
"Unreconcile Payment Entries",
"Serial and Batch Bundle",
"Bank Transaction",
];
if(!this.frm.doc.__islocal) {
// show credit_to in print format

View File

@@ -22,6 +22,8 @@
"is_paid",
"is_return",
"return_against",
"update_billed_amount_in_purchase_order",
"update_billed_amount_in_purchase_receipt",
"apply_tds",
"tax_withholding_category",
"amended_from",
@@ -412,6 +414,20 @@
"read_only": 1,
"search_index": 1
},
{
"default": "0",
"depends_on": "eval: doc.is_return",
"fieldname": "update_billed_amount_in_purchase_order",
"fieldtype": "Check",
"label": "Update Billed Amount in Purchase Order"
},
{
"default": "1",
"depends_on": "eval: doc.is_return",
"fieldname": "update_billed_amount_in_purchase_receipt",
"fieldtype": "Check",
"label": "Update Billed Amount in Purchase Receipt"
},
{
"fieldname": "section_addresses",
"fieldtype": "Section Break",
@@ -1612,7 +1628,7 @@
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2023-11-29 15:35:44.697496",
"modified": "2024-02-25 11:20:28.366808",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
@@ -1675,4 +1691,4 @@
"timeline_field": "supplier",
"title_field": "title",
"track_changes": 1
}
}

View File

@@ -214,6 +214,8 @@ class PurchaseInvoice(BuyingController):
total_qty: DF.Float
total_taxes_and_charges: DF.Currency
unrealized_profit_loss_account: DF.Link | None
update_billed_amount_in_purchase_order: DF.Check
update_billed_amount_in_purchase_receipt: DF.Check
update_stock: DF.Check
use_company_roundoff_cost_center: DF.Check
use_transaction_date_exchange_rate: DF.Check
@@ -296,6 +298,18 @@ class PurchaseInvoice(BuyingController):
self.reset_default_field_value("set_warehouse", "items", "warehouse")
self.reset_default_field_value("rejected_warehouse", "items", "rejected_warehouse")
self.reset_default_field_value("set_from_warehouse", "items", "from_warehouse")
self.set_percentage_received()
def set_percentage_received(self):
total_billed_qty = 0.0
total_received_qty = 0.0
for row in self.items:
if row.purchase_receipt and row.pr_detail and row.received_qty:
total_billed_qty += row.qty
total_received_qty += row.received_qty
if total_billed_qty and total_received_qty:
self.per_received = total_received_qty / total_billed_qty * 100
def validate_release_date(self):
if self.release_date and getdate(nowdate()) >= getdate(self.release_date):
@@ -667,6 +681,11 @@ class PurchaseInvoice(BuyingController):
super(PurchaseInvoice, self).on_submit()
self.check_prev_docstatus()
if self.is_return and not self.update_billed_amount_in_purchase_order:
# NOTE status updating bypassed for is_return
self.status_updater = []
self.update_status_updater_args()
self.update_prevdoc_status()
@@ -684,6 +703,7 @@ class PurchaseInvoice(BuyingController):
# Updating stock ledger should always be called after updating prevdoc status,
# because updating ordered qty in bin depends upon updated ordered qty in PO
if self.update_stock == 1:
self.make_bundle_using_old_serial_batch_fields()
self.update_stock_ledger()
if self.is_old_subcontracting_flow:
@@ -711,6 +731,7 @@ class PurchaseInvoice(BuyingController):
"cash_bank_account",
"write_off_account",
"unrealized_profit_loss_account",
"is_opening",
]
child_tables = {"items": ("expense_account",), "taxes": ("account_head",)}
self.needs_repost = self.check_if_fields_updated(fields_to_check, child_tables)
@@ -1003,9 +1024,14 @@ class PurchaseInvoice(BuyingController):
if provisional_accounting_for_non_stock_items:
if item.purchase_receipt:
provisional_account = frappe.db.get_value(
"Purchase Receipt Item", item.pr_detail, "provisional_expense_account"
) or self.get_company_default("default_provisional_account")
provisional_account, pr_qty, pr_base_rate = frappe.get_cached_value(
"Purchase Receipt Item",
item.pr_detail,
["provisional_expense_account", "qty", "base_rate"],
)
provisional_account = provisional_account or self.get_company_default(
"default_provisional_account"
)
purchase_receipt_doc = purchase_receipt_doc_map.get(item.purchase_receipt)
if not purchase_receipt_doc:
@@ -1022,13 +1048,18 @@ class PurchaseInvoice(BuyingController):
"voucher_detail_no": item.pr_detail,
"account": provisional_account,
},
["name"],
"name",
)
if expense_booked_in_pr:
# Intentionally passing purchase invoice item to handle partial billing
purchase_receipt_doc.add_provisional_gl_entry(
item, gl_entries, self.posting_date, provisional_account, reverse=1
item,
gl_entries,
self.posting_date,
provisional_account,
reverse=1,
item_amount=(min(item.qty, pr_qty) * pr_base_rate),
)
if not self.is_internal_transfer():
@@ -1084,17 +1115,6 @@ class PurchaseInvoice(BuyingController):
item=item,
)
)
# update gross amount of asset bought through this document
assets = frappe.db.get_all(
"Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code}
)
for asset in assets:
frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate))
frappe.db.set_value(
"Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate)
)
if (
self.auto_accounting_for_stock
and self.is_opening == "No"
@@ -1134,12 +1154,25 @@ class PurchaseInvoice(BuyingController):
item.item_tax_amount, item.precision("item_tax_amount")
)
if item.is_fixed_asset and item.landed_cost_voucher_amount:
self.update_gross_purchase_amount_for_linked_assets(item)
def update_gross_purchase_amount_for_linked_assets(self, item):
assets = frappe.db.get_all(
"Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code}
"Asset",
filters={"purchase_invoice": self.name, "item_code": item.item_code},
fields=["name", "asset_quantity"],
)
for asset in assets:
frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate))
frappe.db.set_value("Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate))
purchase_amount = flt(item.valuation_rate) * asset.asset_quantity
frappe.db.set_value(
"Asset",
asset.name,
{
"gross_purchase_amount": purchase_amount,
"purchase_receipt_amount": purchase_amount,
},
)
def make_stock_adjustment_entry(
self, gl_entries, item, voucher_wise_stock_value, account_currency
@@ -1411,6 +1444,10 @@ class PurchaseInvoice(BuyingController):
self.check_on_hold_or_closed_status()
if self.is_return and not self.update_billed_amount_in_purchase_order:
# NOTE status updating bypassed for is_return
self.status_updater = []
self.update_status_updater_args()
self.update_prevdoc_status()
@@ -1505,6 +1542,9 @@ class PurchaseInvoice(BuyingController):
frappe.throw(_("Supplier Invoice No exists in Purchase Invoice {0}").format(pi))
def update_billing_status_in_pr(self, update_modified=True):
if self.is_return and not self.update_billed_amount_in_purchase_receipt:
return
updated_pr = []
po_details = []

View File

@@ -1227,11 +1227,11 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
@change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
def test_gain_loss_with_advance_entry(self):
unlink_enabled = frappe.db.get_value(
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice"
unlink_enabled = frappe.db.get_single_value(
"Accounts Settings", "unlink_payment_on_cancellation_of_invoice"
)
frappe.db.set_single_value("Accounts Settings", "unlink_payment_on_cancel_of_invoice", 1)
frappe.db.set_single_value("Accounts Settings", "unlink_payment_on_cancellation_of_invoice", 1)
original_account = frappe.db.get_value("Company", "_Test Company", "exchange_gain_loss_account")
frappe.db.set_value(
@@ -1422,7 +1422,7 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
pay.cancel()
frappe.db.set_single_value(
"Accounts Settings", "unlink_payment_on_cancel_of_invoice", unlink_enabled
"Accounts Settings", "unlink_payment_on_cancellation_of_invoice", unlink_enabled
)
frappe.db.set_value("Company", "_Test Company", "exchange_gain_loss_account", original_account)
@@ -1529,18 +1529,7 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
self.assertEqual(payment_entry.taxes[0].allocated_amount, 0)
def test_provisional_accounting_entry(self):
create_item("_Test Non Stock Item", is_stock_item=0)
provisional_account = create_account(
account_name="Provision Account",
parent_account="Current Liabilities - _TC",
company="_Test Company",
)
company = frappe.get_doc("Company", "_Test Company")
company.enable_provisional_accounting_for_non_stock_items = 1
company.default_provisional_account = provisional_account
company.save()
setup_provisional_accounting()
pr = make_purchase_receipt(
item_code="_Test Non Stock Item", posting_date=add_days(nowdate(), -2)
@@ -1584,8 +1573,97 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
self, pr.name, expected_gle_for_purchase_receipt_post_pi_cancel, pr.posting_date
)
company.enable_provisional_accounting_for_non_stock_items = 0
company.save()
toggle_provisional_accounting_setting()
def test_provisional_accounting_entry_for_over_billing(self):
setup_provisional_accounting()
# Configure Buying Settings to allow rate change
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 0)
# Create PR: rate = 1000, qty = 5
pr = make_purchase_receipt(
item_code="_Test Non Stock Item", rate=1000, posting_date=add_days(nowdate(), -2)
)
# Overbill PR: rate = 2000, qty = 10
pi = create_purchase_invoice_from_receipt(pr.name)
pi.set_posting_time = 1
pi.posting_date = add_days(pr.posting_date, -1)
pi.items[0].qty = 10
pi.items[0].rate = 2000
pi.items[0].expense_account = "Cost of Goods Sold - _TC"
pi.save()
pi.submit()
expected_gle = [
["Cost of Goods Sold - _TC", 20000, 0, add_days(pr.posting_date, -1)],
["Creditors - _TC", 0, 20000, add_days(pr.posting_date, -1)],
]
check_gl_entries(self, pi.name, expected_gle, pi.posting_date)
expected_gle_for_purchase_receipt = [
["Provision Account - _TC", 5000, 0, pr.posting_date],
["_Test Account Cost for Goods Sold - _TC", 0, 5000, pr.posting_date],
["Provision Account - _TC", 0, 5000, pi.posting_date],
["_Test Account Cost for Goods Sold - _TC", 5000, 0, pi.posting_date],
]
check_gl_entries(self, pr.name, expected_gle_for_purchase_receipt, pr.posting_date)
# Cancel purchase invoice to check reverse provisional entry cancellation
pi.cancel()
expected_gle_for_purchase_receipt_post_pi_cancel = [
["Provision Account - _TC", 0, 5000, pi.posting_date],
["_Test Account Cost for Goods Sold - _TC", 5000, 0, pi.posting_date],
]
check_gl_entries(
self, pr.name, expected_gle_for_purchase_receipt_post_pi_cancel, pr.posting_date
)
toggle_provisional_accounting_setting()
def test_provisional_accounting_entry_for_partial_billing(self):
setup_provisional_accounting()
# Configure Buying Settings to allow rate change
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 0)
# Create PR: rate = 1000, qty = 5
pr = make_purchase_receipt(
item_code="_Test Non Stock Item", rate=1000, posting_date=add_days(nowdate(), -2)
)
# Partially bill PR: rate = 500, qty = 2
pi = create_purchase_invoice_from_receipt(pr.name)
pi.set_posting_time = 1
pi.posting_date = add_days(pr.posting_date, -1)
pi.items[0].qty = 2
pi.items[0].rate = 500
pi.items[0].expense_account = "Cost of Goods Sold - _TC"
pi.save()
pi.submit()
expected_gle = [
["Cost of Goods Sold - _TC", 1000, 0, add_days(pr.posting_date, -1)],
["Creditors - _TC", 0, 1000, add_days(pr.posting_date, -1)],
]
check_gl_entries(self, pi.name, expected_gle, pi.posting_date)
expected_gle_for_purchase_receipt = [
["Provision Account - _TC", 5000, 0, pr.posting_date],
["_Test Account Cost for Goods Sold - _TC", 0, 5000, pr.posting_date],
["Provision Account - _TC", 0, 1000, pi.posting_date],
["_Test Account Cost for Goods Sold - _TC", 1000, 0, pi.posting_date],
]
check_gl_entries(self, pr.name, expected_gle_for_purchase_receipt, pr.posting_date)
toggle_provisional_accounting_setting()
def test_adjust_incoming_rate(self):
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 0)
@@ -1985,6 +2063,127 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
self.assertEqual(pi.items[0].cost_center, "_Test Cost Center Buying - _TC")
def test_debit_note_with_account_mismatch(self):
new_creditors = create_account(
parent_account="Accounts Payable - _TC",
account_name="Creditors 2",
company="_Test Company",
account_type="Payable",
)
pi = make_purchase_invoice(qty=1, rate=1000)
dr_note = make_purchase_invoice(
qty=-1, rate=1000, is_return=1, return_against=pi.name, do_not_save=True
)
dr_note.credit_to = new_creditors
self.assertRaises(frappe.ValidationError, dr_note.save)
def test_debit_note_without_item(self):
pi = make_purchase_invoice(item_name="_Test Item", qty=10, do_not_submit=True)
pi.items[0].item_code = ""
pi.save()
self.assertFalse(pi.items[0].item_code)
pi.submit()
return_pi = make_purchase_invoice(
item_name="_Test Item",
is_return=1,
return_against=pi.name,
qty=-10,
do_not_save=True,
)
return_pi.items[0].item_code = ""
return_pi.save()
return_pi.submit()
self.assertEqual(return_pi.docstatus, 1)
def test_purchase_invoice_with_use_serial_batch_field_for_rejected_qty(self):
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
batch_item = make_item(
"_Test Purchase Invoice Batch Item For Rejected Qty",
properties={"has_batch_no": 1, "create_new_batch": 1, "is_stock_item": 1},
).name
serial_item = make_item(
"_Test Purchase Invoice Serial Item for Rejected Qty",
properties={"has_serial_no": 1, "is_stock_item": 1},
).name
rej_warehouse = create_warehouse("_Test Purchase INV Warehouse For Rejected Qty")
batch_no = "BATCH-PI-BNU-TPRBI-0001"
serial_nos = ["SNU-PI-TPRSI-0001", "SNU-PI-TPRSI-0002", "SNU-PI-TPRSI-0003"]
if not frappe.db.exists("Batch", batch_no):
frappe.get_doc(
{
"doctype": "Batch",
"batch_id": batch_no,
"item": batch_item,
}
).insert()
for serial_no in serial_nos:
if not frappe.db.exists("Serial No", serial_no):
frappe.get_doc(
{
"doctype": "Serial No",
"item_code": serial_item,
"serial_no": serial_no,
}
).insert()
pi = make_purchase_invoice(
item_code=batch_item,
received_qty=10,
qty=8,
rejected_qty=2,
update_stock=1,
rejected_warehouse=rej_warehouse,
use_serial_batch_fields=1,
batch_no=batch_no,
rate=100,
do_not_submit=1,
)
pi.append(
"items",
{
"item_code": serial_item,
"qty": 2,
"rate": 100,
"base_rate": 100,
"item_name": serial_item,
"uom": "Nos",
"stock_uom": "Nos",
"conversion_factor": 1,
"rejected_qty": 1,
"warehouse": pi.items[0].warehouse,
"rejected_warehouse": rej_warehouse,
"use_serial_batch_fields": 1,
"serial_no": "\n".join(serial_nos[:2]),
"rejected_serial_no": serial_nos[2],
},
)
pi.save()
pi.submit()
pi.reload()
for row in pi.items:
self.assertTrue(row.serial_and_batch_bundle)
self.assertTrue(row.rejected_serial_and_batch_bundle)
if row.item_code == batch_item:
self.assertEqual(row.batch_no, batch_no)
else:
self.assertEqual(row.serial_no, "\n".join(serial_nos[:2]))
self.assertEqual(row.rejected_serial_no, serial_nos[2])
def set_advance_flag(company, flag, default_account):
frappe.db.set_value(
@@ -2092,7 +2291,7 @@ def make_purchase_invoice(**args):
pi.cost_center = args.parent_cost_center
bundle_id = None
if args.get("batch_no") or args.get("serial_no"):
if not args.use_serial_batch_fields and ((args.get("batch_no") or args.get("serial_no"))):
batches = {}
qty = args.qty or 5
item_code = args.item or args.item_code or "_Test Item"
@@ -2121,6 +2320,7 @@ def make_purchase_invoice(**args):
"items",
{
"item_code": args.item or args.item_code or "_Test Item",
"item_name": args.item_name,
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": args.qty or 5,
"received_qty": args.received_qty or 0,
@@ -2138,6 +2338,9 @@ def make_purchase_invoice(**args):
"rejected_warehouse": args.rejected_warehouse or "",
"asset_location": args.location or "",
"allow_zero_valuation_rate": args.get("allow_zero_valuation_rate") or 0,
"use_serial_batch_fields": args.get("use_serial_batch_fields") or 0,
"batch_no": args.get("batch_no") if args.get("use_serial_batch_fields") else "",
"serial_no": args.get("serial_no") if args.get("use_serial_batch_fields") else "",
},
)
@@ -2228,4 +2431,26 @@ def make_purchase_invoice_against_cost_center(**args):
return pi
def setup_provisional_accounting(**args):
args = frappe._dict(args)
create_item("_Test Non Stock Item", is_stock_item=0)
company = args.company or "_Test Company"
provisional_account = create_account(
account_name=args.account_name or "Provision Account",
parent_account=args.parent_account or "Current Liabilities - _TC",
company=company,
)
toggle_provisional_accounting_setting(
enable=1, company=company, provisional_account=provisional_account
)
def toggle_provisional_accounting_setting(**args):
args = frappe._dict(args)
company = frappe.get_doc("Company", args.company or "_Test Company")
company.enable_provisional_accounting_for_non_stock_items = args.enable or 0
company.default_provisional_account = args.provisional_account
company.save()
test_records = frappe.get_test_records("Purchase Invoice")

View File

@@ -62,15 +62,19 @@
"rm_supp_cost",
"warehouse_section",
"warehouse",
"add_serial_batch_bundle",
"serial_and_batch_bundle",
"use_serial_batch_fields",
"col_br_wh",
"from_warehouse",
"quality_inspection",
"serial_and_batch_bundle",
"serial_no",
"col_br_wh",
"rejected_warehouse",
"rejected_serial_and_batch_bundle",
"batch_no",
"section_break_rqbe",
"serial_no",
"rejected_serial_no",
"column_break_vbbb",
"batch_no",
"manufacture_details",
"manufacturer",
"column_break_13",
@@ -439,13 +443,11 @@
"print_hide": 1
},
{
"depends_on": "eval:!doc.is_fixed_asset",
"depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "batch_no",
"fieldtype": "Link",
"hidden": 1,
"label": "Batch No",
"options": "Batch",
"read_only": 1,
"search_index": 1
},
{
@@ -453,21 +455,18 @@
"fieldtype": "Column Break"
},
{
"depends_on": "eval:!doc.is_fixed_asset",
"depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "serial_no",
"fieldtype": "Text",
"hidden": 1,
"label": "Serial No",
"read_only": 1
"label": "Serial No"
},
{
"depends_on": "eval:!doc.is_fixed_asset",
"depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "rejected_serial_no",
"fieldtype": "Text",
"label": "Rejected Serial No",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
"print_hide": 1
},
{
"fieldname": "accounting",
@@ -890,7 +889,7 @@
"label": "Apply TDS"
},
{
"depends_on": "eval:parent.update_stock == 1",
"depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
"fieldname": "serial_and_batch_bundle",
"fieldtype": "Link",
"label": "Serial and Batch Bundle",
@@ -900,7 +899,7 @@
"search_index": 1
},
{
"depends_on": "eval:parent.update_stock == 1",
"depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
"fieldname": "rejected_serial_and_batch_bundle",
"fieldtype": "Link",
"label": "Rejected Serial and Batch Bundle",
@@ -913,12 +912,33 @@
"fieldtype": "Link",
"label": "WIP Composite Asset",
"options": "Asset"
},
{
"depends_on": "eval:parent.update_stock === 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
"fieldname": "add_serial_batch_bundle",
"fieldtype": "Button",
"label": "Add Serial / Batch No"
},
{
"default": "0",
"fieldname": "use_serial_batch_fields",
"fieldtype": "Check",
"label": "Use Serial No / Batch Fields"
},
{
"depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "section_break_rqbe",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_vbbb",
"fieldtype": "Column Break"
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2023-12-25 22:00:28.043555",
"modified": "2024-02-04 14:11:52.742228",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@@ -88,6 +88,7 @@ class PurchaseInvoiceItem(Document):
stock_uom_rate: DF.Currency
total_weight: DF.Float
uom: DF.Link
use_serial_batch_fields: DF.Check
valuation_rate: DF.Currency
warehouse: DF.Link | None
weight_per_unit: DF.Float

View File

@@ -126,7 +126,7 @@
"fieldname": "rate",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Rate",
"label": "Tax Rate",
"oldfieldname": "rate",
"oldfieldtype": "Currency"
},
@@ -230,7 +230,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2021-08-05 20:04:36.618240",
"modified": "2024-01-14 10:04:36.618240",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Taxes and Charges",
@@ -239,4 +239,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}
}

View File

@@ -3,7 +3,7 @@
"allow_import": 1,
"allow_rename": 1,
"creation": "2013-01-10 16:34:08",
"description": "Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.\n10. Add or Deduct: Whether you want to add or deduct the tax.",
"description": "Standard tax template that can be applied to all Purchase Transactions. This template can contain a list of tax heads and also other expense heads like \"Shipping\", \"Insurance\", \"Handling\", etc.",
"doctype": "DocType",
"document_type": "Setup",
"engine": "InnoDB",
@@ -77,7 +77,7 @@
"icon": "fa fa-money",
"idx": 1,
"links": [],
"modified": "2022-05-16 16:15:29.059370",
"modified": "2024-01-30 13:08:09.537242",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Taxes and Charges Template",

View File

@@ -88,6 +88,7 @@ class RepostAccountingLedger(Document):
).append(gle.update({"old": True}))
def generate_preview_data(self):
frappe.flags.through_repost_accounting_ledger = True
self.gl_entries = []
self.get_existing_ledger_entries()
for x in self.vouchers:
@@ -141,6 +142,7 @@ class RepostAccountingLedger(Document):
@frappe.whitelist()
def start_repost(account_repost_doc=str) -> None:
frappe.flags.through_repost_accounting_ledger = True
if account_repost_doc:
repost_doc = frappe.get_doc("Repost Accounting Ledger", account_repost_doc)

View File

@@ -43,7 +43,7 @@ def start_payment_ledger_repost(docname=None):
except Exception as e:
frappe.db.rollback()
traceback = frappe.get_traceback()
traceback = frappe.get_traceback(with_context=True)
if traceback:
message = "Traceback: <br>" + traceback
frappe.db.set_value(repost_doc.doctype, repost_doc.name, "repost_error_log", message)

View File

@@ -14,31 +14,26 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
super.setup(doc);
}
company() {
super.company();
erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype);
let me = this;
if (this.frm.doc.company) {
frappe.call({
method:
"erpnext.accounts.party.get_party_account",
args: {
party_type: 'Customer',
party: this.frm.doc.customer,
company: this.frm.doc.company
},
callback: (response) => {
if (response) me.frm.set_value("debit_to", response.message);
},
});
}
}
onload() {
var me = this;
super.onload();
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log',
'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries",
'Serial and Batch Bundle'
this.frm.ignore_doctypes_on_cancel_all = [
"POS Invoice",
"Timesheet",
"POS Invoice Merge Log",
"POS Closing Entry",
"Journal Entry",
"Payment Entry",
"Repost Payment Ledger",
"Repost Accounting Ledger",
"Unreconcile Payment",
"Unreconcile Payment Entries",
"Serial and Batch Bundle",
"Bank Transaction",
];
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
@@ -898,8 +893,8 @@ frappe.ui.form.on('Sales Invoice', {
frm.events.append_time_log(frm, timesheet, 1.0);
}
});
frm.refresh_field("timesheets");
frm.trigger("calculate_timesheet_totals");
frm.refresh();
},
async get_exchange_rate(frm, from_currency, to_currency) {

View File

@@ -269,7 +269,7 @@ class SalesInvoice(SellingController):
super(SalesInvoice, self).validate()
self.validate_auto_set_posting_time()
if not self.is_pos:
if not (self.is_pos or self.is_debit_note):
self.so_dn_required()
self.set_tax_withholding()
@@ -420,7 +420,8 @@ class SalesInvoice(SellingController):
self.calculate_taxes_and_totals()
def before_save(self):
set_account_for_mode_of_payment(self)
self.set_account_for_mode_of_payment()
self.set_paid_amount()
def on_submit(self):
self.validate_pos_paid_amount()
@@ -445,6 +446,11 @@ class SalesInvoice(SellingController):
# Updating stock ledger should always be called after updating prevdoc status,
# because updating reserved qty in bin depends upon updated delivered qty in SO
if self.update_stock == 1:
for table_name in ["items", "packed_items"]:
if not self.get(table_name):
continue
self.make_bundle_using_old_serial_batch_fields(table_name)
self.update_stock_ledger()
# this sequence because outstanding may get -ve
@@ -586,6 +592,8 @@ class SalesInvoice(SellingController):
"Serial and Batch Bundle",
)
self.delete_auto_created_batches()
def update_status_updater_args(self):
if cint(self.update_stock):
self.status_updater.append(
@@ -704,9 +712,6 @@ class SalesInvoice(SellingController):
):
data.sales_invoice = sales_invoice
def on_update(self):
self.set_paid_amount()
def on_update_after_submit(self):
if hasattr(self, "repost_required"):
fields_to_check = [
@@ -716,6 +721,7 @@ class SalesInvoice(SellingController):
"write_off_account",
"loyalty_redemption_account",
"unrealized_profit_loss_account",
"is_opening",
]
child_tables = {
"items": ("income_account", "expense_account", "discount_account"),
@@ -737,6 +743,11 @@ class SalesInvoice(SellingController):
self.paid_amount = paid_amount
self.base_paid_amount = base_paid_amount
def set_account_for_mode_of_payment(self):
for payment in self.payments:
if not payment.account:
payment.account = get_bank_cash_account(payment.mode_of_payment, self.company).get("account")
def validate_time_sheets_are_submitted(self):
for data in self.timesheets:
if data.time_sheet:
@@ -1466,9 +1477,7 @@ class SalesInvoice(SellingController):
"credit_in_account_currency": payment_mode.base_amount
if self.party_account_currency == self.company_currency
else payment_mode.amount,
"against_voucher": self.return_against
if cint(self.is_return) and self.return_against
else self.name,
"against_voucher": self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center,
},
@@ -2105,12 +2114,6 @@ def make_sales_return(source_name, target_doc=None):
return make_return_doc("Sales Invoice", source_name, target_doc)
def set_account_for_mode_of_payment(self):
for data in self.payments:
if not data.account:
data.account = get_bank_cash_account(data.mode_of_payment, self.company).get("account")
def get_inter_company_details(doc, doctype):
if doctype in ["Sales Invoice", "Sales Order", "Delivery Note"]:
parties = frappe.db.get_all(

View File

@@ -1088,6 +1088,44 @@ class TestSalesInvoice(FrappeTestCase):
self.assertEqual(pos.grand_total, 100.0)
self.assertEqual(pos.write_off_amount, 10)
def test_ledger_entries_of_return_pos_invoice(self):
make_pos_profile()
pos = create_sales_invoice(do_not_save=True)
pos.is_pos = 1
pos.append("payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 100})
pos.save().submit()
self.assertEqual(pos.outstanding_amount, 0.0)
self.assertEqual(pos.status, "Paid")
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_sales_return
pos_return = make_sales_return(pos.name)
pos_return.save().submit()
pos_return.reload()
pos.reload()
self.assertEqual(pos_return.is_return, 1)
self.assertEqual(pos_return.return_against, pos.name)
self.assertEqual(pos_return.outstanding_amount, 0.0)
self.assertEqual(pos_return.status, "Return")
self.assertEqual(pos.outstanding_amount, 0.0)
self.assertEqual(pos.status, "Credit Note Issued")
expected = (
("Cash - _TC", 0.0, 100.0, pos_return.name, None),
("Debtors - _TC", 0.0, 100.0, pos_return.name, pos_return.name),
("Debtors - _TC", 100.0, 0.0, pos_return.name, pos_return.name),
("Sales - _TC", 100.0, 0.0, pos_return.name, None),
)
res = frappe.db.get_all(
"GL Entry",
filters={"voucher_no": pos_return.name, "is_cancelled": 0},
fields=["account", "debit", "credit", "voucher_no", "against_voucher"],
order_by="account, debit, credit",
as_list=1,
)
self.assertEqual(expected, res)
def test_pos_with_no_gl_entry_for_change_amount(self):
frappe.db.set_single_value("Accounts Settings", "post_change_gl_entries", 0)
@@ -1414,10 +1452,11 @@ class TestSalesInvoice(FrappeTestCase):
def test_serialized_cancel(self):
si = self.test_serialized()
si.cancel()
si.reload()
serial_nos = get_serial_nos_from_bundle(si.get("items")[0].serial_and_batch_bundle)
si.cancel()
self.assertEqual(
frappe.db.get_value("Serial No", serial_nos[0], "warehouse"), "_Test Warehouse - _TC"
)
@@ -1532,6 +1571,19 @@ class TestSalesInvoice(FrappeTestCase):
self.assertEqual(frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount"), -1000)
self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 2500)
def test_return_invoice_with_account_mismatch(self):
debtors2 = create_account(
parent_account="Accounts Receivable - _TC",
account_name="Debtors 2",
company="_Test Company",
account_type="Receivable",
)
si = create_sales_invoice(qty=1, rate=1000)
cr_note = create_sales_invoice(
qty=-1, rate=1000, is_return=1, return_against=si.name, debit_to=debtors2, do_not_save=True
)
self.assertRaises(frappe.ValidationError, cr_note.save)
def test_gle_made_when_asset_is_returned(self):
create_asset_data()
asset = create_asset(item_code="Macbook Pro")
@@ -3550,6 +3602,33 @@ class TestSalesInvoice(FrappeTestCase):
check_gl_entries(self, pe.name, expected_gle, nowdate(), voucher_type="Payment Entry")
set_advance_flag(company="_Test Company", flag=0, default_account="")
def test_pulling_advance_based_on_debit_to(self):
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
debtors2 = create_account(
parent_account="Accounts Receivable - _TC",
account_name="Debtors 2",
company="_Test Company",
account_type="Receivable",
)
si = create_sales_invoice(do_not_submit=True)
si.debit_to = debtors2
si.save()
pe = create_payment_entry(
company=si.company,
payment_type="Receive",
party_type="Customer",
party=si.customer,
paid_from=debtors2,
paid_to="Cash - _TC",
paid_amount=1000,
)
pe.submit()
advances = si.get_advance_entries()
self.assertEqual(1, len(advances))
self.assertEqual(advances[0].reference_name, pe.name)
def set_advance_flag(company, flag, default_account):
frappe.db.set_value(

View File

@@ -81,15 +81,19 @@
"warehouse",
"target_warehouse",
"quality_inspection",
"pick_serial_and_batch",
"serial_and_batch_bundle",
"batch_no",
"incoming_rate",
"use_serial_batch_fields",
"col_break5",
"allow_zero_valuation_rate",
"serial_no",
"incoming_rate",
"item_tax_rate",
"actual_batch_qty",
"actual_qty",
"section_break_eoec",
"serial_no",
"column_break_ytgd",
"batch_no",
"edit_references",
"sales_order",
"so_detail",
@@ -599,12 +603,11 @@
"options": "Quality Inspection"
},
{
"depends_on": "eval: doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "batch_no",
"fieldtype": "Link",
"hidden": 1,
"label": "Batch No",
"options": "Batch",
"read_only": 1,
"search_index": 1
},
{
@@ -620,13 +623,12 @@
"print_hide": 1
},
{
"depends_on": "eval: doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "serial_no",
"fieldtype": "Small Text",
"hidden": 1,
"fieldtype": "Text",
"label": "Serial No",
"oldfieldname": "serial_no",
"oldfieldtype": "Small Text",
"read_only": 1
"oldfieldtype": "Small Text"
},
{
"fieldname": "item_group",
@@ -890,6 +892,7 @@
"read_only": 1
},
{
"depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
"fieldname": "serial_and_batch_bundle",
"fieldtype": "Link",
"label": "Serial and Batch Bundle",
@@ -897,12 +900,33 @@
"options": "Serial and Batch Bundle",
"print_hide": 1,
"search_index": 1
},
{
"depends_on": "eval:parent.update_stock === 1",
"fieldname": "pick_serial_and_batch",
"fieldtype": "Button",
"label": "Pick Serial / Batch No"
},
{
"default": "0",
"fieldname": "use_serial_batch_fields",
"fieldtype": "Check",
"label": "Use Serial No / Batch Fields"
},
{
"depends_on": "eval:doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "section_break_eoec",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_ytgd",
"fieldtype": "Column Break"
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2023-11-14 18:34:10.479329",
"modified": "2024-02-25 15:56:44.828634",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",

View File

@@ -75,7 +75,7 @@ class SalesInvoiceItem(Document):
sales_invoice_item: DF.Data | None
sales_order: DF.Link | None
serial_and_batch_bundle: DF.Link | None
serial_no: DF.SmallText | None
serial_no: DF.Text | None
service_end_date: DF.Date | None
service_start_date: DF.Date | None
service_stop_date: DF.Date | None
@@ -86,6 +86,7 @@ class SalesInvoiceItem(Document):
target_warehouse: DF.Link | None
total_weight: DF.Float
uom: DF.Link
use_serial_batch_fields: DF.Check
warehouse: DF.Link | None
weight_per_unit: DF.Float
weight_uom: DF.Link | None

View File

@@ -8,6 +8,7 @@
"default",
"mode_of_payment",
"amount",
"reference_no",
"column_break_3",
"account",
"type",
@@ -75,11 +76,16 @@
"hidden": 1,
"label": "Default",
"read_only": 1
},
{
"fieldname": "reference_no",
"fieldtype": "Data",
"label": "Reference No"
}
],
"istable": 1,
"links": [],
"modified": "2020-08-03 12:45:39.986598",
"modified": "2024-01-23 16:20:06.436979",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Payment",
@@ -87,5 +93,6 @@
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC"
"sort_order": "DESC",
"states": []
}

View File

@@ -23,6 +23,7 @@ class SalesInvoicePayment(Document):
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
reference_no: DF.Data | None
type: DF.ReadOnly | None
# end: auto-generated types

View File

@@ -108,7 +108,7 @@
"fieldname": "rate",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Rate",
"label": "Tax Rate",
"oldfieldname": "rate",
"oldfieldtype": "Currency"
},
@@ -218,7 +218,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2022-10-17 13:08:17.776528",
"modified": "2024-01-14 10:08:17.776528",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Taxes and Charges",
@@ -227,4 +227,4 @@
"sort_field": "modified",
"sort_order": "ASC",
"states": []
}
}

View File

@@ -3,7 +3,7 @@
"allow_import": 1,
"allow_rename": 1,
"creation": "2013-01-10 16:34:09",
"description": "Standard tax template that can be applied to all Sales Transactions. This template can contain list of tax heads and also other expense / income heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.",
"description": "Standard tax template that can be applied to all Sales Transactions. This template can contain a list of tax heads and also other expense/income heads like \"Shipping\", \"Insurance\", \"Handling\" etc.",
"doctype": "DocType",
"document_type": "Setup",
"engine": "InnoDB",
@@ -79,7 +79,7 @@
"icon": "fa fa-money",
"idx": 1,
"links": [],
"modified": "2022-05-16 16:14:52.061672",
"modified": "2024-01-30 13:07:28.801104",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Taxes and Charges Template",

View File

@@ -148,13 +148,13 @@
{
"fieldname": "additional_discount_percentage",
"fieldtype": "Percent",
"label": "Additional DIscount Percentage"
"label": "Additional Discount Percentage"
},
{
"collapsible": 1,
"fieldname": "additional_discount_amount",
"fieldtype": "Currency",
"label": "Additional DIscount Amount"
"label": "Additional Discount Amount"
},
{
"collapsible": 1,
@@ -267,7 +267,7 @@
"link_fieldname": "subscription"
}
],
"modified": "2023-09-18 17:48:21.900252",
"modified": "2023-12-28 17:20:42.687789",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Subscription",

View File

@@ -16,6 +16,7 @@ from frappe.utils.data import (
date_diff,
flt,
get_last_day,
get_link_to_form,
getdate,
nowdate,
)
@@ -317,6 +318,37 @@ class Subscription(Document):
if self.is_new():
self.set_subscription_status()
self.validate_party_billing_currency()
def validate_party_billing_currency(self):
"""
Subscription should be of the same currency as the Party's default billing currency or company default.
"""
if self.party:
party_billing_currency = frappe.get_cached_value(
self.party_type, self.party, "default_currency"
) or frappe.get_cached_value("Company", self.company, "default_currency")
plans = [x.plan for x in self.plans]
subscription_plan_currencies = frappe.db.get_all(
"Subscription Plan", filters={"name": ("in", plans)}, fields=["name", "currency"]
)
unsupported_plans = []
for x in subscription_plan_currencies:
if x.currency != party_billing_currency:
unsupported_plans.append("{0}".format(get_link_to_form("Subscription Plan", x.name)))
if unsupported_plans:
unsupported_plans = [
_(
"Below Subscription Plans are of different currency to the party default billing currency/Company currency: {0}"
).format(frappe.bold(party_billing_currency))
] + unsupported_plans
frappe.throw(
unsupported_plans, frappe.ValidationError, "Unsupported Subscription Plans", as_list=True
)
def validate_trial_period(self) -> None:
"""
Runs sanity checks on trial period dates for the `Subscription`
@@ -356,18 +388,20 @@ class Subscription(Document):
self,
from_date: Optional[Union[str, datetime.date]] = None,
to_date: Optional[Union[str, datetime.date]] = None,
posting_date: Optional[Union[str, datetime.date]] = None,
) -> Document:
"""
Creates a `Invoice` for the `Subscription`, updates `self.invoices` and
saves the `Subscription`.
Backwards compatibility
"""
return self.create_invoice(from_date=from_date, to_date=to_date)
return self.create_invoice(from_date=from_date, to_date=to_date, posting_date=posting_date)
def create_invoice(
self,
from_date: Optional[Union[str, datetime.date]] = None,
to_date: Optional[Union[str, datetime.date]] = None,
posting_date: Optional[Union[str, datetime.date]] = None,
) -> Document:
"""
Creates a `Invoice`, submits it and returns it
@@ -385,11 +419,13 @@ class Subscription(Document):
invoice = frappe.new_doc(self.invoice_document_type)
invoice.company = company
invoice.set_posting_time = 1
invoice.posting_date = (
self.current_invoice_start
if self.generate_invoice_at == "Beginning of the current subscription period"
else self.current_invoice_end
)
if self.generate_invoice_at == "Beginning of the current subscription period":
invoice.posting_date = self.current_invoice_start
elif self.generate_invoice_at == "Days before the current subscription period":
invoice.posting_date = posting_date or self.current_invoice_start
else:
invoice.posting_date = self.current_invoice_end
invoice.cost_center = self.cost_center
@@ -413,6 +449,7 @@ class Subscription(Document):
# Subscription is better suited for service items. I won't update `update_stock`
# for that reason
items_list = self.get_items_from_plans(self.plans, is_prorate())
for item in items_list:
item["cost_center"] = self.cost_center
invoice.append("items", item)
@@ -556,8 +593,10 @@ class Subscription(Document):
if not self.is_current_invoice_generated(
self.current_invoice_start, self.current_invoice_end
) and self.can_generate_new_invoice(posting_date):
self.generate_invoice()
self.generate_invoice(posting_date=posting_date)
self.update_subscription_period(add_days(self.current_invoice_end, 1))
elif posting_date and getdate(posting_date) > getdate(self.current_invoice_end):
self.update_subscription_period()
if self.cancel_at_period_end and (
getdate(posting_date) >= getdate(self.current_invoice_end)

View File

@@ -460,11 +460,13 @@ class TestSubscription(FrappeTestCase):
self.assertEqual(len(subscription.invoices), 1)
def test_multi_currency_subscription(self):
party = "_Test Subscription Customer"
frappe.db.set_value("Customer", party, "default_currency", "USD")
subscription = create_subscription(
start_date="2018-01-01",
generate_invoice_at="Beginning of the current subscription period",
plans=[{"plan": "_Test Plan Multicurrency", "qty": 1}],
party="_Test Subscription Customer",
plans=[{"plan": "_Test Plan Multicurrency", "qty": 1, "currency": "USD"}],
party=party,
)
subscription.process()
@@ -528,13 +530,21 @@ class TestSubscription(FrappeTestCase):
def make_plans():
create_plan(plan_name="_Test Plan Name", cost=900)
create_plan(plan_name="_Test Plan Name 2", cost=1999)
create_plan(plan_name="_Test Plan Name", cost=900, currency="INR")
create_plan(plan_name="_Test Plan Name 2", cost=1999, currency="INR")
create_plan(
plan_name="_Test Plan Name 3", cost=1999, billing_interval="Day", billing_interval_count=14
plan_name="_Test Plan Name 3",
cost=1999,
billing_interval="Day",
billing_interval_count=14,
currency="INR",
)
create_plan(
plan_name="_Test Plan Name 4", cost=20000, billing_interval="Month", billing_interval_count=3
plan_name="_Test Plan Name 4",
cost=20000,
billing_interval="Month",
billing_interval_count=3,
currency="INR",
)
create_plan(
plan_name="_Test Plan Multicurrency", cost=50, billing_interval="Month", currency="USD"

View File

@@ -41,7 +41,8 @@
"fieldname": "currency",
"fieldtype": "Link",
"label": "Currency",
"options": "Currency"
"options": "Currency",
"reqd": 1
},
{
"fieldname": "column_break_3",
@@ -148,10 +149,11 @@
}
],
"links": [],
"modified": "2021-12-10 15:24:15.794477",
"modified": "2024-01-14 17:59:34.687977",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Subscription Plan",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
@@ -193,5 +195,6 @@
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -24,7 +24,7 @@ class SubscriptionPlan(Document):
billing_interval_count: DF.Int
cost: DF.Currency
cost_center: DF.Link | None
currency: DF.Link | None
currency: DF.Link
item: DF.Link
payment_gateway: DF.Link | None
plan_name: DF.Data

View File

@@ -546,6 +546,7 @@ def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers):
"GL Entry",
{
"is_cancelled": 0,
"party_type": "Customer",
"party": ["in", parties],
"company": inv.company,
"voucher_no": ["in", vouchers],
@@ -560,6 +561,7 @@ def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers):
conditions = []
conditions.append(ple.amount.lt(0))
conditions.append(ple.delinked == 0)
conditions.append(ple.party_type == "Customer")
conditions.append(ple.party.isin(parties))
conditions.append(ple.voucher_no == ple.against_voucher_no)
conditions.append(ple.company == inv.company)
@@ -579,6 +581,7 @@ def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers):
{
"is_cancelled": 0,
"credit": [">", 0],
"party_type": "Customer",
"party": ["in", parties],
"posting_date": ["between", (tax_details.from_date, tax_details.to_date)],
"company": inv.company,

View File

@@ -8,6 +8,7 @@ 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.test.accounts_mixin import AccountsTestMixin
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
class TestUnreconcilePayment(AccountsTestMixin, FrappeTestCase):
@@ -49,6 +50,16 @@ class TestUnreconcilePayment(AccountsTestMixin, FrappeTestCase):
)
return pe
def create_sales_order(self):
so = make_sales_order(
company=self.company,
customer=self.customer,
item=self.item,
rate=100,
transaction_date=today(),
)
return so
def test_01_unreconcile_invoice(self):
si1 = self.create_sales_invoice()
si2 = self.create_sales_invoice()
@@ -314,3 +325,41 @@ class TestUnreconcilePayment(AccountsTestMixin, FrappeTestCase):
),
1,
)
def test_05_unreconcile_order(self):
so = self.create_sales_order()
pe = self.create_payment_entry()
# Allocation payment against Sales Order
pe.paid_amount = 100
pe.append(
"references",
{"reference_doctype": so.doctype, "reference_name": so.name, "allocated_amount": 100},
)
pe.save().submit()
# Assert 'Advance Paid'
so.reload()
self.assertEqual(so.advance_paid, 100)
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), 1)
allocations = [x.reference_name for x in unreconcile.allocations]
self.assertEquals([so.name], allocations)
# unreconcile so
unreconcile.save().submit()
# Assert 'Advance Paid'
so.reload()
pe.reload()
self.assertEqual(so.advance_paid, 0)
self.assertEqual(len(pe.references), 0)
self.assertEqual(pe.unallocated_amount, 100)

View File

@@ -82,6 +82,9 @@ class UnreconcilePayment(Document):
update_voucher_outstanding(
alloc.reference_doctype, alloc.reference_name, alloc.account, alloc.party_type, alloc.party
)
if doc.doctype in frappe.get_hooks("advance_payment_doctypes"):
doc.set_total_advance_paid()
frappe.db.set_value("Unreconcile Payment Entries", alloc.name, "unlinked", True)

View File

@@ -13,9 +13,13 @@ import erpnext
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
)
from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import (
get_dimension_filter_map,
)
from erpnext.accounts.doctype.accounting_period.accounting_period import ClosedAccountingPeriod
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
from erpnext.accounts.utils import create_payment_ledger_entry
from erpnext.exceptions import InvalidAccountDimensionError, MandatoryAccountDimensionError
def make_gl_entries(
@@ -355,6 +359,7 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
process_debit_credit_difference(gl_map)
dimension_filter_map = get_dimension_filter_map()
if gl_map:
check_freezing_date(gl_map[0]["posting_date"], adv_adj)
is_opening = any(d.get("is_opening") == "Yes" for d in gl_map)
@@ -362,6 +367,7 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
validate_against_pcv(is_opening, gl_map[0]["posting_date"], gl_map[0]["company"])
for entry in gl_map:
validate_allowed_dimensions(entry, dimension_filter_map)
make_entry(entry, adv_adj, update_outstanding, from_repost)
@@ -700,3 +706,39 @@ def set_as_cancel(voucher_type, voucher_no):
where voucher_type=%s and voucher_no=%s and is_cancelled = 0""",
(now(), frappe.session.user, voucher_type, voucher_no),
)
def validate_allowed_dimensions(gl_entry, dimension_filter_map):
for key, value in dimension_filter_map.items():
dimension = key[0]
account = key[1]
if gl_entry.account == account:
if value["is_mandatory"] and not gl_entry.get(dimension):
frappe.throw(
_("{0} is mandatory for account {1}").format(
frappe.bold(frappe.unscrub(dimension)), frappe.bold(gl_entry.account)
),
MandatoryAccountDimensionError,
)
if value["allow_or_restrict"] == "Allow":
if gl_entry.get(dimension) and gl_entry.get(dimension) not in value["allowed_dimensions"]:
frappe.throw(
_("Invalid value {0} for {1} against account {2}").format(
frappe.bold(gl_entry.get(dimension)),
frappe.bold(frappe.unscrub(dimension)),
frappe.bold(gl_entry.account),
),
InvalidAccountDimensionError,
)
else:
if gl_entry.get(dimension) and gl_entry.get(dimension) in value["allowed_dimensions"]:
frappe.throw(
_("Invalid value {0} for {1} against account {2}").format(
frappe.bold(gl_entry.get(dimension)),
frappe.bold(frappe.unscrub(dimension)),
frappe.bold(gl_entry.account),
),
InvalidAccountDimensionError,
)

View File

@@ -9,7 +9,7 @@ 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, Date, Sum
from frappe.query_builder.functions import Abs, Count, Date, Sum
from frappe.utils import (
add_days,
add_months,
@@ -114,14 +114,12 @@ def _get_party_details(
set_account_and_due_date(party, account, party_type, company, posting_date, bill_date, doctype)
)
party = party_details[party_type.lower()]
if not ignore_permissions and not (
frappe.has_permission(party_type, "read", party)
or frappe.has_permission(party_type, "select", party)
):
frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError)
party = frappe.get_doc(party_type, party)
if not ignore_permissions:
ptype = "select" if frappe.only_has_select_perm(party_type) else "read"
frappe.has_permission(party_type, ptype, party, throw=True)
currency = party.get("default_currency") or currency or get_company_currency(company)
party_address, shipping_address = set_address_details(
@@ -637,9 +635,7 @@ def get_due_date_from_template(template_name, posting_date, bill_date):
return due_date
def validate_due_date(
posting_date, due_date, party_type, party, company=None, bill_date=None, template_name=None
):
def validate_due_date(posting_date, due_date, bill_date=None, template_name=None):
if getdate(due_date) < getdate(posting_date):
frappe.throw(_("Due Date cannot be before Posting / Supplier Invoice Date"))
else:
@@ -788,34 +784,37 @@ def get_timeline_data(doctype, name):
from frappe.desk.form.load import get_communication_data
out = {}
fields = "creation, count(*)"
after = add_years(None, -1).strftime("%Y-%m-%d")
group_by = "group by Date(creation)"
data = get_communication_data(
doctype,
name,
after=after,
group_by="group by creation",
fields="C.creation as creation, count(C.name)",
group_by="group by communication_date",
fields="C.communication_date as communication_date, count(C.name)",
as_dict=False,
)
# fetch and append data from Activity Log
data += frappe.db.sql(
"""select {fields}
from `tabActivity Log`
where (reference_doctype=%(doctype)s and reference_name=%(name)s)
or (timeline_doctype in (%(doctype)s) and timeline_name=%(name)s)
or (reference_doctype in ("Quotation", "Opportunity") and timeline_name=%(name)s)
and status!='Success' and creation > {after}
{group_by} order by creation desc
""".format(
fields=fields, group_by=group_by, after=after
),
{"doctype": doctype, "name": name},
as_dict=False,
)
activity_log = frappe.qb.DocType("Activity Log")
data += (
frappe.qb.from_(activity_log)
.select(activity_log.communication_date, Count(activity_log.name))
.where(
(
((activity_log.reference_doctype == doctype) & (activity_log.reference_name == name))
| ((activity_log.timeline_doctype == doctype) & (activity_log.timeline_name == name))
| (
(activity_log.reference_doctype.isin(["Quotation", "Opportunity"]))
& (activity_log.timeline_name == name)
)
)
& (activity_log.status != "Success")
& (activity_log.creation > after)
)
.groupby(activity_log.communication_date)
.orderby(activity_log.communication_date, order=frappe.qb.desc)
).run()
timeline_items = dict(data)

View File

@@ -10,10 +10,8 @@
<h2 class="text-center" style="margin-top:0">{%= __(report.report_name) %}</h2>
<h4 class="text-center">
{% if (filters.customer_name) { %}
{%= filters.customer_name %}
{% } else { %}
{%= filters.customer || filters.supplier %}
{% if (filters.party) { %}
{%= __(filters.party) %}
{% } %}
</h4>
<h6 class="text-center">
@@ -141,7 +139,7 @@
<th style="width: 24%">{%= __("Reference") %}</th>
{% } %}
{% if(!filters.show_future_payments) { %}
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
<th style="width: 20%">{%= (filters.party) ? __("Remarks"): __("Party") %}</th>
{% } %}
<th style="width: 10%; text-align: right">{%= __("Invoiced Amount") %}</th>
{% if(!filters.show_future_payments) { %}
@@ -158,7 +156,7 @@
<th style="width: 10%">{%= __("Remaining Balance") %}</th>
{% } %}
{% } else { %}
<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
<th style="width: 40%">{%= (filters.party) ? __("Remarks"): __("Party") %}</th>
<th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
<th style="width: 15%">{%= __("Total Paid Amount") %}</th>
<th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
@@ -187,7 +185,7 @@
{% if(!filters.show_future_payments) { %}
<td>
{% if(!(filters.customer || filters.supplier)) { %}
{% if(!(filters.party)) { %}
{%= data[i]["party"] %}
{% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
<br> {%= data[i]["customer_name"] %}
@@ -260,7 +258,7 @@
{% if(data[i]["party"]|| "&nbsp;") { %}
{% if(!data[i]["is_total_row"]) { %}
<td>
{% if(!(filters.customer || filters.supplier)) { %}
{% if(!(filters.party)) { %}
{%= data[i]["party"] %}
{% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
<br> {%= data[i]["customer_name"] %}

View File

@@ -5,7 +5,7 @@
from collections import OrderedDict
import frappe
from frappe import _, qb, scrub
from frappe import _, qb, query_builder, scrub
from frappe.query_builder import Criterion
from frappe.query_builder.functions import Date, Substring, Sum
from frappe.utils import cint, cstr, flt, getdate, nowdate
@@ -83,7 +83,10 @@ class ReceivablePayableReport(object):
self.skip_total_row = 1
if self.filters.get("in_party_currency"):
self.skip_total_row = 1
if self.filters.get("party") and len(self.filters.get("party")) == 1:
self.skip_total_row = 0
else:
self.skip_total_row = 1
def get_data(self):
self.get_ple_entries()
@@ -576,6 +579,8 @@ class ReceivablePayableReport(object):
def get_future_payments_from_payment_entry(self):
pe = frappe.qb.DocType("Payment Entry")
pe_ref = frappe.qb.DocType("Payment Entry Reference")
ifelse = query_builder.CustomFunction("IF", ["condition", "then", "else"])
return (
frappe.qb.from_(pe)
.inner_join(pe_ref)
@@ -587,6 +592,11 @@ class ReceivablePayableReport(object):
(pe.posting_date).as_("future_date"),
(pe_ref.allocated_amount).as_("future_amount"),
(pe.reference_no).as_("future_ref"),
ifelse(
pe.payment_type == "Receive",
pe.source_exchange_rate * pe_ref.allocated_amount,
pe.target_exchange_rate * pe_ref.allocated_amount,
).as_("future_amount_in_base_currency"),
)
.where(
(pe.docstatus < 2)
@@ -623,13 +633,24 @@ class ReceivablePayableReport(object):
query = query.select(
Sum(jea.debit_in_account_currency - jea.credit_in_account_currency).as_("future_amount")
)
query = query.select(Sum(jea.debit - jea.credit).as_("future_amount_in_base_currency"))
else:
query = query.select(
Sum(jea.credit_in_account_currency - jea.debit_in_account_currency).as_("future_amount")
)
query = query.select(Sum(jea.credit - jea.debit).as_("future_amount_in_base_currency"))
else:
query = query.select(
Sum(jea.debit if self.account_type == "Payable" else jea.credit).as_("future_amount")
Sum(jea.debit if self.account_type == "Payable" else jea.credit).as_(
"future_amount_in_base_currency"
)
)
query = query.select(
Sum(
jea.debit_in_account_currency
if self.account_type == "Payable"
else jea.credit_in_account_currency
).as_("future_amount")
)
query = query.having(qb.Field("future_amount") > 0)
@@ -645,14 +666,19 @@ class ReceivablePayableReport(object):
row.remaining_balance = row.outstanding
row.future_amount = 0.0
for future in self.future_payments.get((row.voucher_no, row.party), []):
if row.remaining_balance > 0 and future.future_amount:
if future.future_amount > row.outstanding:
if self.filters.in_party_currency:
future_amount_field = "future_amount"
else:
future_amount_field = "future_amount_in_base_currency"
if row.remaining_balance > 0 and future.get(future_amount_field):
if future.get(future_amount_field) > row.outstanding:
row.future_amount = row.outstanding
future.future_amount = future.future_amount - row.outstanding
future[future_amount_field] = future.get(future_amount_field) - row.outstanding
row.remaining_balance = 0
else:
row.future_amount += future.future_amount
future.future_amount = 0
row.future_amount += future.get(future_amount_field)
future[future_amount_field] = 0
row.remaining_balance = row.outstanding - row.future_amount
row.setdefault("future_ref", []).append(

View File

@@ -772,3 +772,92 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
# post sorting output should be [[Additional Debtors, ...], [Debtors, ...]]
report_output = sorted(report_output, key=lambda x: x[0])
self.assertEqual(expected_data, report_output)
def test_future_payments_on_foreign_currency(self):
self.customer2 = (
frappe.get_doc(
{
"doctype": "Customer",
"customer_name": "Jane Doe",
"type": "Individual",
"default_currency": "USD",
}
)
.insert()
.submit()
)
si = self.create_sales_invoice(do_not_submit=True)
si.posting_date = add_days(today(), -1)
si.customer = self.customer2
si.currency = "USD"
si.conversion_rate = 80
si.debit_to = self.debtors_usd
si.save().submit()
# full payment in USD
pe = get_payment_entry(si.doctype, si.name)
pe.posting_date = add_days(today(), 1)
pe.base_received_amount = 7500
pe.received_amount = 7500
pe.source_exchange_rate = 75
pe.save().submit()
filters = frappe._dict(
{
"company": self.company,
"report_date": today(),
"range1": 30,
"range2": 60,
"range3": 90,
"range4": 120,
"show_future_payments": True,
"in_party_currency": False,
}
)
report = execute(filters)[1]
self.assertEqual(len(report), 1)
expected_data = [8000.0, 8000.0, 500.0, 7500.0]
row = report[0]
self.assertEqual(
expected_data, [row.invoiced, row.outstanding, row.remaining_balance, row.future_amount]
)
filters.in_party_currency = True
report = execute(filters)[1]
self.assertEqual(len(report), 1)
expected_data = [100.0, 100.0, 0.0, 100.0]
row = report[0]
self.assertEqual(
expected_data, [row.invoiced, row.outstanding, row.remaining_balance, row.future_amount]
)
pe.cancel()
# partial payment in USD on a future date
pe = get_payment_entry(si.doctype, si.name)
pe.posting_date = add_days(today(), 1)
pe.base_received_amount = 6750
pe.received_amount = 6750
pe.source_exchange_rate = 75
pe.paid_amount = 90 # in USD
pe.references[0].allocated_amount = 90
pe.save().submit()
filters.in_party_currency = False
report = execute(filters)[1]
self.assertEqual(len(report), 1)
expected_data = [8000.0, 8000.0, 1250.0, 6750.0]
row = report[0]
self.assertEqual(
expected_data, [row.invoiced, row.outstanding, row.remaining_balance, row.future_amount]
)
filters.in_party_currency = True
report = execute(filters)[1]
self.assertEqual(len(report), 1)
expected_data = [100.0, 100.0, 10.0, 90.0]
row = report[0]
self.assertEqual(
expected_data, [row.invoiced, row.outstanding, row.remaining_balance, row.future_amount]
)

View File

@@ -25,11 +25,26 @@ frappe.query_reports["Asset Depreciations and Balances"] = {
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
"reqd": 1
},
{
"fieldname":"group_by",
"label": __("Group By"),
"fieldtype": "Select",
"options": ["Asset Category", "Asset"],
"default": "Asset Category",
},
{
"fieldname":"asset_category",
"label": __("Asset Category"),
"fieldtype": "Link",
"options": "Asset Category"
}
"options": "Asset Category",
"depends_on": "eval: doc.group_by == 'Asset Category'",
},
{
"fieldname":"asset",
"label": __("Asset"),
"fieldtype": "Link",
"options": "Asset",
"depends_on": "eval: doc.group_by == 'Asset'",
},
]
}

View File

@@ -14,10 +14,17 @@ def execute(filters=None):
def get_data(filters):
if filters.get("group_by") == "Asset Category":
return get_group_by_asset_category_data(filters)
elif filters.get("group_by") == "Asset":
return get_group_by_asset_data(filters)
def get_group_by_asset_category_data(filters):
data = []
asset_categories = get_asset_categories(filters)
assets = get_assets(filters)
asset_categories = get_asset_categories_for_grouped_by_category(filters)
assets = get_assets_for_grouped_by_category(filters)
for asset_category in asset_categories:
row = frappe._dict()
@@ -38,6 +45,7 @@ def get_data(filters):
if asset["asset_category"] == asset_category.get("asset_category", "")
)
)
row.accumulated_depreciation_as_on_to_date = (
flt(row.accumulated_depreciation_as_on_from_date)
+ flt(row.depreciation_amount_during_the_period)
@@ -57,7 +65,7 @@ def get_data(filters):
return data
def get_asset_categories(filters):
def get_asset_categories_for_grouped_by_category(filters):
condition = ""
if filters.get("asset_category"):
condition += " and asset_category = %(asset_category)s"
@@ -116,7 +124,105 @@ def get_asset_categories(filters):
)
def get_assets(filters):
def get_asset_details_for_grouped_by_category(filters):
condition = ""
if filters.get("asset"):
condition += " and name = %(asset)s"
return frappe.db.sql(
"""
SELECT name,
ifnull(sum(case when purchase_date < %(from_date)s then
case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_as_on_from_date,
ifnull(sum(case when purchase_date >= %(from_date)s then
gross_purchase_amount
else
0
end), 0) as cost_of_new_purchase,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Sold" then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_sold_asset,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Scrapped" then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_scrapped_asset
from `tabAsset`
where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s {}
group by name
""".format(
condition
),
{
"to_date": filters.to_date,
"from_date": filters.from_date,
"company": filters.company,
"asset": filters.get("asset"),
},
as_dict=1,
)
def get_group_by_asset_data(filters):
data = []
asset_details = get_asset_details_for_grouped_by_category(filters)
assets = get_assets_for_grouped_by_asset(filters)
for asset_detail in asset_details:
row = frappe._dict()
# row.asset_category = asset_category
row.update(asset_detail)
row.cost_as_on_to_date = (
flt(row.cost_as_on_from_date)
+ flt(row.cost_of_new_purchase)
- flt(row.cost_of_sold_asset)
- flt(row.cost_of_scrapped_asset)
)
row.update(next(asset for asset in assets if asset["asset"] == asset_detail.get("name", "")))
row.accumulated_depreciation_as_on_to_date = (
flt(row.accumulated_depreciation_as_on_from_date)
+ flt(row.depreciation_amount_during_the_period)
- flt(row.depreciation_eliminated_during_the_period)
)
row.net_asset_value_as_on_from_date = flt(row.cost_as_on_from_date) - flt(
row.accumulated_depreciation_as_on_from_date
)
row.net_asset_value_as_on_to_date = flt(row.cost_as_on_to_date) - flt(
row.accumulated_depreciation_as_on_to_date
)
data.append(row)
return data
def get_assets_for_grouped_by_category(filters):
condition = ""
if filters.get("asset_category"):
condition = " and a.asset_category = '{}'".format(filters.get("asset_category"))
@@ -178,15 +284,93 @@ def get_assets(filters):
)
def get_assets_for_grouped_by_asset(filters):
condition = ""
if filters.get("asset"):
condition = " and a.name = '{}'".format(filters.get("asset"))
return frappe.db.sql(
"""
SELECT results.name as asset,
sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date,
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
from (SELECT a.name as name,
ifnull(sum(case when gle.posting_date < %(from_date)s and (ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
gle.debit
else
0
end), 0) as accumulated_depreciation_as_on_from_date,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s and gle.posting_date <= a.disposal_date then
gle.debit
else
0
end), 0) as depreciation_eliminated_during_the_period,
ifnull(sum(case when gle.posting_date >= %(from_date)s and gle.posting_date <= %(to_date)s
and (ifnull(a.disposal_date, 0) = 0 or gle.posting_date <= a.disposal_date) then
gle.debit
else
0
end), 0) as depreciation_amount_during_the_period
from `tabGL Entry` gle
join `tabAsset` a on
gle.against_voucher = a.name
join `tabAsset Category Account` aca on
aca.parent = a.asset_category and aca.company_name = %(company)s
join `tabCompany` company on
company.name = %(company)s
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and gle.debit != 0 and gle.is_cancelled = 0 and gle.account = ifnull(aca.depreciation_expense_account, company.depreciation_expense_account) {0}
group by a.name
union
SELECT a.name as name,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
0
else
a.opening_accumulated_depreciation
end), 0) as accumulated_depreciation_as_on_from_date,
ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then
a.opening_accumulated_depreciation
else
0
end), 0) as depreciation_eliminated_during_the_period,
0 as depreciation_amount_during_the_period
from `tabAsset` a
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {0}
group by a.name) as results
group by results.name
""".format(
condition
),
{"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company},
as_dict=1,
)
def get_columns(filters):
return [
{
"label": _("Asset Category"),
"fieldname": "asset_category",
"fieldtype": "Link",
"options": "Asset Category",
"width": 120,
},
columns = []
if filters.get("group_by") == "Asset Category":
columns.append(
{
"label": _("Asset Category"),
"fieldname": "asset_category",
"fieldtype": "Link",
"options": "Asset Category",
"width": 120,
}
)
elif filters.get("group_by") == "Asset":
columns.append(
{
"label": _("Asset"),
"fieldname": "asset",
"fieldtype": "Link",
"options": "Asset",
"width": 120,
}
)
columns += [
{
"label": _("Cost as on") + " " + formatdate(filters.day_before_from_date),
"fieldname": "cost_as_on_from_date",
@@ -254,3 +438,5 @@ def get_columns(filters):
"width": 200,
},
]
return columns

View File

@@ -8,6 +8,20 @@ frappe.query_reports["Balance Sheet"] = $.extend(
erpnext.utils.add_dimensions("Balance Sheet", 10);
frappe.query_reports["Balance Sheet"]["filters"].push(
{
"fieldname": "selected_view",
"label": __("Select View"),
"fieldtype": "Select",
"options": [
{ "value": "Report", "label": __("Report View") },
{ "value": "Growth", "label": __("Growth View") }
],
"default": "Report",
"reqd": 1
},
);
frappe.query_reports["Balance Sheet"]["filters"].push({
fieldname: "accumulated_values",
label: __("Accumulated Values"),

View File

@@ -2,7 +2,44 @@
// License: GNU General Public License v3. See license.txt
frappe.query_reports["Budget Variance Report"] = {
"filters": [
"filters": get_filters(),
"formatter": function (value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (column.fieldname.includes(__("variance"))) {
if (data[column.fieldname] < 0) {
value = "<span style='color:red'>" + value + "</span>";
}
else if (data[column.fieldname] > 0) {
value = "<span style='color:green'>" + value + "</span>";
}
}
return value;
}
}
function get_filters() {
function get_dimensions() {
let result = [];
frappe.call({
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimensions",
args: {
'with_cost_center_and_project': true
},
async: false,
callback: function(r) {
if(!r.exc) {
result = r.message[0].map(elem => elem.document_type);
}
}
});
return result;
}
let budget_against_options = get_dimensions();
let filters = [
{
fieldname: "from_fiscal_year",
label: __("From Fiscal Year"),
@@ -44,7 +81,7 @@ frappe.query_reports["Budget Variance Report"] = {
fieldname: "budget_against",
label: __("Budget Against"),
fieldtype: "Select",
options: ["Cost Center", "Project"],
options: budget_against_options,
default: "Cost Center",
reqd: 1,
on_change: function() {
@@ -71,24 +108,8 @@ frappe.query_reports["Budget Variance Report"] = {
fieldtype: "Check",
default: 0,
},
],
"formatter": function (value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
]
if (column.fieldname.includes(__("variance"))) {
if (data[column.fieldname] < 0) {
value = "<span style='color:red'>" + value + "</span>";
}
else if (data[column.fieldname] > 0) {
value = "<span style='color:green'>" + value + "</span>";
}
}
return value;
}
return filters;
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Budget Variance Report"].filters[4].options.push(dimension["document_type"]);
});

View File

@@ -3,7 +3,7 @@
import frappe
from frappe import _, scrub
from frappe import _, qb, scrub
from frappe.utils import getdate, nowdate
@@ -38,7 +38,6 @@ class PartyLedgerSummaryReport(object):
"""
Additional Columns for 'User Permission' based access control
"""
from frappe import qb
if self.filters.party_type == "Customer":
self.territories = frappe._dict({})
@@ -365,13 +364,33 @@ class PartyLedgerSummaryReport(object):
def get_party_adjustment_amounts(self):
conditions = self.prepare_conditions()
income_or_expense = (
"Expense Account" if self.filters.party_type == "Customer" else "Income Account"
account_type = "Expense Account" if self.filters.party_type == "Customer" else "Income Account"
income_or_expense_accounts = frappe.db.get_all(
"Account", filters={"account_type": account_type, "company": self.filters.company}, pluck="name"
)
invoice_dr_or_cr = "debit" if self.filters.party_type == "Customer" else "credit"
reverse_dr_or_cr = "credit" if self.filters.party_type == "Customer" else "debit"
round_off_account = frappe.get_cached_value("Company", self.filters.company, "round_off_account")
gl = qb.DocType("GL Entry")
if not income_or_expense_accounts:
# prevent empty 'in' condition
income_or_expense_accounts.append("")
else:
# escape '%' in account name
# ignoring frappe.db.escape as it replaces single quotes with double quotes
income_or_expense_accounts = [x.replace("%", "%%") for x in income_or_expense_accounts]
accounts_query = (
qb.from_(gl)
.select(gl.voucher_type, gl.voucher_no)
.where(
(gl.account.isin(income_or_expense_accounts))
& (gl.posting_date.gte(self.filters.from_date))
& (gl.posting_date.lte(self.filters.to_date))
)
)
gl_entries = frappe.db.sql(
"""
select
@@ -381,16 +400,15 @@ class PartyLedgerSummaryReport(object):
where
docstatus < 2 and is_cancelled = 0
and (voucher_type, voucher_no) in (
select voucher_type, voucher_no from `tabGL Entry` gle, `tabAccount` acc
where acc.name = gle.account and acc.account_type = '{income_or_expense}'
and gle.posting_date between %(from_date)s and %(to_date)s and gle.docstatus < 2
{accounts_query}
) and (voucher_type, voucher_no) in (
select voucher_type, voucher_no from `tabGL Entry` gle
where gle.party_type=%(party_type)s and ifnull(party, '') != ''
and gle.posting_date between %(from_date)s and %(to_date)s and gle.docstatus < 2 {conditions}
)
""".format(
conditions=conditions, income_or_expense=income_or_expense
""".format(
accounts_query=accounts_query,
conditions=conditions,
),
self.filters,
as_dict=True,
@@ -414,7 +432,7 @@ class PartyLedgerSummaryReport(object):
elif gle.party:
parties.setdefault(gle.party, 0)
parties[gle.party] += gle.get(reverse_dr_or_cr) - gle.get(invoice_dr_or_cr)
elif frappe.get_cached_value("Account", gle.account, "account_type") == income_or_expense:
elif frappe.get_cached_value("Account", gle.account, "account_type") == account_type:
accounts.setdefault(gle.account, 0)
accounts[gle.account] += gle.get(invoice_dr_or_cr) - gle.get(reverse_dr_or_cr)
else:

View File

@@ -177,8 +177,8 @@ def add_solvency_ratios(
return_on_equity_ratio = {"ratio": "Return on Equity Ratio"}
for year in years:
profit_after_tax = total_income[year] + total_expense[year]
share_holder_fund = total_asset[year] - total_liability[year]
profit_after_tax = flt(total_income.get(year)) + flt(total_expense.get(year))
share_holder_fund = flt(total_asset.get(year)) - flt(total_liability.get(year))
debt_equity_ratio[year] = calculate_ratio(
total_liability.get(year), share_holder_fund, precision

View File

@@ -8,17 +8,7 @@ import re
import frappe
from frappe import _
from frappe.utils import (
add_days,
add_months,
cint,
cstr,
flt,
formatdate,
get_first_day,
getdate,
today,
)
from frappe.utils import add_days, add_months, cint, cstr, flt, formatdate, get_first_day, getdate
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
@@ -53,8 +43,6 @@ def get_period_list(
year_start_date = getdate(period_start_date)
year_end_date = getdate(period_end_date)
year_end_date = getdate(today()) if year_end_date > getdate(today()) else year_end_date
months_to_add = {"Yearly": 12, "Half-Yearly": 6, "Quarterly": 3, "Monthly": 1}[periodicity]
period_list = []
@@ -211,7 +199,13 @@ def get_data(
ignore_accumulated_values_for_fy,
)
accumulate_values_into_parents(accounts, accounts_by_name, period_list)
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
out = prepare_data(
accounts,
balance_must_be,
period_list,
company_currency,
accumulated_values=filters.accumulated_values,
)
out = filter_out_zero_value_rows(out, parent_children_map)
if out and total:
@@ -270,7 +264,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name, period_list):
) + d.get("opening_balance", 0.0)
def prepare_data(accounts, balance_must_be, period_list, company_currency):
def prepare_data(accounts, balance_must_be, period_list, company_currency, accumulated_values):
data = []
year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d")
year_end_date = period_list[-1]["year_end_date"].strftime("%Y-%m-%d")
@@ -310,8 +304,14 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
has_value = True
total += flt(row[period.key])
row["has_value"] = has_value
row["total"] = total
if accumulated_values:
# when 'accumulated_values' is enabled, periods have running balance.
# so, last period will have the net amount.
row["has_value"] = has_value
row["total"] = flt(d.get(period_list[-1].key, 0.0), 3)
else:
row["has_value"] = has_value
row["total"] = total
data.append(row)
return data

View File

@@ -52,6 +52,11 @@ frappe.query_reports["General Ledger"] = {
frappe.query_report.set_filter_value('group_by', "Group by Voucher (Consolidated)");
}
},
{
"fieldname":"against_voucher_no",
"label": __("Against Voucher No"),
"fieldtype": "Data",
},
{
"fieldtype": "Break",
},
@@ -198,8 +203,14 @@ frappe.query_reports["General Ledger"] = {
"fieldname": "show_remarks",
"label": __("Show Remarks"),
"fieldtype": "Check"
},
{
"fieldname": "ignore_err",
"label": __("Ignore Exchange Rate Revaluation Journals"),
"fieldtype": "Check"
}
]
}

View File

@@ -200,7 +200,7 @@ def get_gl_entries(filters, accounting_dimensions):
"""
select
name as gl_entry, posting_date, account, party_type, party,
voucher_type, voucher_no, {dimension_fields}
voucher_type, voucher_subtype, voucher_no, {dimension_fields}
cost_center, project, {transaction_currency_fields}
against_voucher_type, against_voucher, account_currency,
against, is_opening, creation {select_fields}
@@ -238,6 +238,22 @@ def get_conditions(filters):
if filters.get("voucher_no"):
conditions.append("voucher_no=%(voucher_no)s")
if filters.get("against_voucher_no"):
conditions.append("against_voucher=%(against_voucher_no)s")
if filters.get("ignore_err"):
err_journals = frappe.db.get_all(
"Journal Entry",
filters={
"company": filters.get("company"),
"docstatus": 1,
"voucher_type": ("in", ["Exchange Rate Revaluation", "Exchange Gain Or Loss"]),
},
as_list=True,
)
if err_journals:
filters.update({"voucher_no_not_in": [x[0] for x in err_journals]})
if filters.get("voucher_no_not_in"):
conditions.append("voucher_no not in %(voucher_no_not_in)s")
@@ -608,6 +624,12 @@ def get_columns(filters):
columns += [
{"label": _("Voucher Type"), "fieldname": "voucher_type", "width": 120},
{
"label": _("Voucher Subtype"),
"fieldname": "voucher_subtype",
"fieldtype": "Data",
"width": 180,
},
{
"label": _("Voucher No"),
"fieldname": "voucher_no",

View File

@@ -3,7 +3,7 @@
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import today
from frappe.utils import flt, today
from erpnext.accounts.report.general_ledger.general_ledger import execute
@@ -148,3 +148,105 @@ class TestGeneralLedger(FrappeTestCase):
self.assertEqual(data[2]["credit"], 900)
self.assertEqual(data[3]["debit"], 100)
self.assertEqual(data[3]["credit"], 100)
def test_ignore_exchange_rate_journals_filter(self):
# create a new account with USD currency
account_name = "Test Debtors USD"
company = "_Test Company"
account = frappe.get_doc(
{
"account_name": account_name,
"is_group": 0,
"company": company,
"root_type": "Asset",
"report_type": "Balance Sheet",
"account_currency": "USD",
"parent_account": "Accounts Receivable - _TC",
"account_type": "Receivable",
"doctype": "Account",
}
)
account.insert(ignore_if_duplicate=True)
# create a JV to debit 1000 USD at 75 exchange rate
jv = frappe.new_doc("Journal Entry")
jv.posting_date = today()
jv.company = company
jv.multi_currency = 1
jv.cost_center = "_Test Cost Center - _TC"
jv.set(
"accounts",
[
{
"account": account.name,
"party_type": "Customer",
"party": "_Test Customer USD",
"debit_in_account_currency": 1000,
"credit_in_account_currency": 0,
"exchange_rate": 75,
"cost_center": "_Test Cost Center - _TC",
},
{
"account": "Cash - _TC",
"debit_in_account_currency": 0,
"credit_in_account_currency": 75000,
"cost_center": "_Test Cost Center - _TC",
},
],
)
jv.save()
jv.submit()
revaluation = frappe.new_doc("Exchange Rate Revaluation")
revaluation.posting_date = today()
revaluation.company = company
accounts = revaluation.get_accounts_data()
revaluation.extend("accounts", accounts)
row = revaluation.accounts[0]
row.new_exchange_rate = 83
row.new_balance_in_base_currency = flt(
row.new_exchange_rate * flt(row.balance_in_account_currency)
)
row.gain_loss = row.new_balance_in_base_currency - flt(row.balance_in_base_currency)
revaluation.set_total_gain_loss()
revaluation = revaluation.save().submit()
# post journal entry for Revaluation doc
frappe.db.set_value(
"Company", company, "unrealized_exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC"
)
revaluation_jv = revaluation.make_jv_for_revaluation()
revaluation_jv.cost_center = "_Test Cost Center - _TC"
for acc in revaluation_jv.get("accounts"):
acc.cost_center = "_Test Cost Center - _TC"
revaluation_jv.save()
revaluation_jv.submit()
# With ignore_err enabled
columns, data = execute(
frappe._dict(
{
"company": company,
"from_date": today(),
"to_date": today(),
"account": [account.name],
"group_by": "Group by Voucher (Consolidated)",
"ignore_err": True,
}
)
)
self.assertNotIn(revaluation_jv.name, set([x.voucher_no for x in data]))
# Without ignore_err enabled
columns, data = execute(
frappe._dict(
{
"company": company,
"from_date": today(),
"to_date": today(),
"account": [account.name],
"group_by": "Group by Voucher (Consolidated)",
"ignore_err": False,
}
)
)
self.assertIn(revaluation_jv.name, set([x.voucher_no for x in data]))

View File

@@ -134,7 +134,7 @@ def get_revenue(data, period_list, include_in_gross=1):
def remove_parent_with_no_child(data):
data_to_be_removed = False
for parent in data:
for parent in list(data):
if "is_group" in parent and parent.get("is_group") == 1:
have_child = False
for child in data:

View File

@@ -975,7 +975,7 @@ class GrossProfitGenerator(object):
& (sle.is_cancelled == 0)
)
.orderby(sle.item_code)
.orderby(sle.warehouse, sle.posting_date, sle.posting_time, sle.creation, order=Order.desc)
.orderby(sle.warehouse, sle.posting_datetime, sle.creation, order=Order.desc)
.run(as_dict=True)
)

View File

@@ -350,7 +350,13 @@ def get_conditions(filters, additional_conditions=None):
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
if filters.get("warehouse"):
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
if frappe.db.get_value("Warehouse", filters.get("warehouse"), "is_group"):
lft, rgt = frappe.db.get_all(
"Warehouse", filters={"name": filters.get("warehouse")}, fields=["lft", "rgt"], as_list=True
)[0]
conditions += f"and ifnull(`tabSales Invoice Item`.warehouse, '') in (select name from `tabWarehouse` where lft > {lft} and rgt < {rgt}) "
else:
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
if filters.get("brand"):
conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s"""

View File

@@ -163,7 +163,7 @@ def get_entries(filters):
"""select
voucher_type, voucher_no, party_type, party, posting_date, debit, credit, remarks, against_voucher
from `tabGL Entry`
where company=%(company)s and voucher_type in ('Journal Entry', 'Payment Entry') {0}
where company=%(company)s and voucher_type in ('Journal Entry', 'Payment Entry') and is_cancelled = 0 {0}
""".format(
get_conditions(filters)
),

View File

@@ -8,6 +8,21 @@ frappe.query_reports["Profit and Loss Statement"] = $.extend(
erpnext.utils.add_dimensions("Profit and Loss Statement", 10);
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
{
"fieldname": "selected_view",
"label": __("Select View"),
"fieldtype": "Select",
"options": [
{ "value": "Report", "label": __("Report View") },
{ "value": "Growth", "label": __("Growth View") },
{ "value": "Margin", "label": __("Margin View") },
],
"default": "Report",
"reqd": 1
},
);
frappe.query_reports["Profit and Loss Statement"]["filters"].push({
fieldname: "accumulated_values",
label: __("Accumulated Values"),

View File

@@ -82,14 +82,25 @@ def get_report_summary(
if filters.get("accumulated_in_group_company"):
period_list = get_filtered_list_for_consolidated_report(filters, period_list)
for period in period_list:
key = period if consolidated else period.key
if filters.accumulated_values:
# when 'accumulated_values' is enabled, periods have running balance.
# so, last period will have the net amount.
key = period_list[-1].key
if income:
net_income += income[-2].get(key)
net_income = income[-2].get(key)
if expense:
net_expense += expense[-2].get(key)
net_expense = expense[-2].get(key)
if net_profit_loss:
net_profit += net_profit_loss.get(key)
net_profit = net_profit_loss.get(key)
else:
for period in period_list:
key = period if consolidated else period.key
if income:
net_income += income[-2].get(key)
if expense:
net_expense += expense[-2].get(key)
if net_profit_loss:
net_profit += net_profit_loss.get(key)
if len(period_list) == 1 and periodicity == "Yearly":
profit_label = _("Profit This Year")

View File

@@ -0,0 +1,94 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, getdate, today
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.accounts.report.financial_statements import get_period_list
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import execute
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
class TestProfitAndLossStatement(AccountsTestMixin, FrappeTestCase):
def setUp(self):
self.create_company()
self.create_customer()
self.create_item()
def tearDown(self):
frappe.db.rollback()
def create_sales_invoice(self, qty=1, rate=150, no_payment_schedule=False, do_not_submit=False):
frappe.set_user("Administrator")
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=rate,
price_list_rate=rate,
qty=qty,
do_not_save=1,
)
si = si.save()
if not do_not_submit:
si = si.submit()
return si
def get_fiscal_year(self):
active_fy = frappe.db.get_all(
"Fiscal Year",
filters={"disabled": 0, "year_start_date": ("<=", today()), "year_end_date": (">=", today())},
)[0]
return frappe.get_doc("Fiscal Year", active_fy.name)
def get_report_filters(self):
fy = self.get_fiscal_year()
return frappe._dict(
company=self.company,
from_fiscal_year=fy.name,
to_fiscal_year=fy.name,
period_start_date=fy.year_start_date,
period_end_date=fy.year_end_date,
filter_based_on="Fiscal Year",
periodicity="Monthly",
accumulated_vallues=True,
)
def test_profit_and_loss_output_and_summary(self):
si = self.create_sales_invoice(qty=1, rate=150)
filters = self.get_report_filters()
period_list = get_period_list(
filters.from_fiscal_year,
filters.to_fiscal_year,
filters.period_start_date,
filters.period_end_date,
filters.filter_based_on,
filters.periodicity,
company=filters.company,
)
result = execute(filters)[1]
current_period = [x for x in period_list if x.from_date <= getdate() and x.to_date >= getdate()][
0
]
current_period_key = current_period.key
without_current_period = [x for x in period_list if x.key != current_period.key]
# all period except current period(whence invoice was posted), should be '0'
for acc in result:
if acc:
with self.subTest(acc=acc):
for period in without_current_period:
self.assertEqual(acc[period.key], 0)
for acc in result:
if acc:
with self.subTest(current_period_key=current_period_key):
self.assertEqual(acc[current_period_key], 150)
self.assertEqual(acc["total"], 150)

View File

@@ -117,8 +117,3 @@ frappe.query_reports["Profitability Analysis"] = {
"parent_field": "parent_account",
"initial_depth": 3
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Profitability Analysis"].filters[1].options.push(dimension["document_type"]);
});

View File

@@ -46,12 +46,10 @@ def get_result(
out = []
for name, details in gle_map.items():
tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
bill_no, bill_date = "", ""
tax_withholding_category = tax_category_map.get(name)
rate = tax_rate_map.get(tax_withholding_category)
for entry in details:
tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
tax_withholding_category, rate = None, None
bill_no, bill_date = "", ""
party = entry.party or entry.against
posting_date = entry.posting_date
voucher_type = entry.voucher_type
@@ -61,13 +59,18 @@ def get_result(
if party_list:
party = party_list[0]
if not tax_withholding_category:
tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category")
rate = tax_rate_map.get(tax_withholding_category)
if entry.account in tds_accounts:
if entry.account in tds_accounts.keys():
tax_amount += entry.credit - entry.debit
# infer tax withholding category from the account if it's the single account for this category
tax_withholding_category = tds_accounts.get(entry.account)
# or else the consolidated value from the voucher document
if not tax_withholding_category:
tax_withholding_category = tax_category_map.get(name)
# or else from the party default
if not tax_withholding_category:
tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category")
rate = tax_rate_map.get(tax_withholding_category)
if net_total_map.get(name):
if voucher_type == "Journal Entry":
# back calcalute total amount from rate and tax_amount
@@ -80,41 +83,41 @@ def get_result(
else:
total_amount += entry.credit
if tax_amount:
if party_map.get(party, {}).get("party_type") == "Supplier":
party_name = "supplier_name"
party_type = "supplier_type"
else:
party_name = "customer_name"
party_type = "customer_type"
if tax_amount:
if party_map.get(party, {}).get("party_type") == "Supplier":
party_name = "supplier_name"
party_type = "supplier_type"
else:
party_name = "customer_name"
party_type = "customer_type"
row = {
"pan"
if frappe.db.has_column(filters.party_type, "pan")
else "tax_id": party_map.get(party, {}).get("pan"),
"party": party_map.get(party, {}).get("name"),
}
if filters.naming_series == "Naming Series":
row.update({"party_name": party_map.get(party, {}).get(party_name)})
row.update(
{
"section_code": tax_withholding_category or "",
"entity_type": party_map.get(party, {}).get(party_type),
"rate": rate,
"total_amount": total_amount,
"grand_total": grand_total,
"base_total": base_total,
"tax_amount": tax_amount,
"transaction_date": posting_date,
"transaction_type": voucher_type,
"ref_no": name,
"supplier_invoice_no": bill_no,
"supplier_invoice_date": bill_date,
row = {
"pan"
if frappe.db.has_column(filters.party_type, "pan")
else "tax_id": party_map.get(party, {}).get("pan"),
"party": party_map.get(party, {}).get("name"),
}
)
out.append(row)
if filters.naming_series == "Naming Series":
row.update({"party_name": party_map.get(party, {}).get(party_name)})
row.update(
{
"section_code": tax_withholding_category or "",
"entity_type": party_map.get(party, {}).get(party_type),
"rate": rate,
"total_amount": total_amount,
"grand_total": grand_total,
"base_total": base_total,
"tax_amount": tax_amount,
"transaction_date": posting_date,
"transaction_type": voucher_type,
"ref_no": name,
"supplier_invoice_no": bill_no,
"supplier_invoice_date": bill_date,
}
)
out.append(row)
out.sort(key=lambda x: x["section_code"])
@@ -239,7 +242,7 @@ def get_columns(filters):
"width": 120,
},
{
"label": _("Tax Amount"),
"label": _("TDS Amount") if filters.get("party_type") == "Supplier" else _("TCS Amount"),
"fieldname": "tax_amount",
"fieldtype": "Float",
"width": 120,
@@ -282,11 +285,20 @@ def get_tds_docs(filters):
journal_entry_party_map = frappe._dict()
bank_accounts = frappe.get_all("Account", {"is_group": 0, "account_type": "Bank"}, pluck="name")
tds_accounts = frappe.get_all(
"Tax Withholding Account", {"company": filters.get("company")}, pluck="account"
_tds_accounts = frappe.get_all(
"Tax Withholding Account",
{"company": filters.get("company")},
["account", "parent"],
)
tds_accounts = {}
for tds_acc in _tds_accounts:
# if it turns out not to be the only tax withholding category, then don't include in the map
if tds_acc["account"] in tds_accounts:
tds_accounts[tds_acc["account"]] = None
else:
tds_accounts[tds_acc["account"]] = tds_acc["parent"]
tds_docs = get_tds_docs_query(filters, bank_accounts, tds_accounts).run(as_dict=True)
tds_docs = get_tds_docs_query(filters, bank_accounts, list(tds_accounts.keys())).run(as_dict=True)
for d in tds_docs:
if d.voucher_type == "Purchase Invoice":
@@ -394,7 +406,7 @@ def get_doc_info(vouchers, doctype, tax_category_map, net_total_map=None):
"paid_amount_after_tax",
"base_paid_amount",
],
"Journal Entry": ["tax_withholding_category", "total_amount"],
"Journal Entry": ["total_amount"],
}
entries = frappe.get_all(

View File

@@ -5,7 +5,6 @@ import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import today
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
@@ -17,36 +16,63 @@ from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
from erpnext.accounts.utils import get_fiscal_year
class TestTdsPayableMonthly(AccountsTestMixin, FrappeTestCase):
class TestTaxWithholdingDetails(AccountsTestMixin, FrappeTestCase):
def setUp(self):
self.create_company()
self.clear_old_entries()
create_tax_accounts()
create_tcs_category()
def test_tax_withholding_for_customers(self):
create_tax_category(cumulative_threshold=300)
frappe.db.set_value("Customer", "_Test Customer", "tax_withholding_category", "TCS")
si = create_sales_invoice(rate=1000)
pe = create_tcs_payment_entry()
jv = create_tcs_journal_entry()
filters = frappe._dict(
company="_Test Company", party_type="Customer", from_date=today(), to_date=today()
)
result = execute(filters)[1]
expected_values = [
# Check for JV totals using back calculation logic
[jv.name, "TCS", 0.075, -10000.0, -7.5, -10000.0],
[pe.name, "TCS", 0.075, 2550, 0.53, 2550.53],
[si.name, "TCS", 0.075, 1000, 0.52, 1000.52],
]
self.check_expected_values(result, expected_values)
def test_single_account_for_multiple_categories(self):
create_tax_category("TDS - 1", rate=10, account="TDS - _TC")
inv_1 = make_purchase_invoice(rate=1000, do_not_submit=True)
inv_1.tax_withholding_category = "TDS - 1"
inv_1.submit()
create_tax_category("TDS - 2", rate=20, account="TDS - _TC")
inv_2 = make_purchase_invoice(rate=1000, do_not_submit=True)
inv_2.tax_withholding_category = "TDS - 2"
inv_2.submit()
result = execute(
frappe._dict(company="_Test Company", party_type="Supplier", from_date=today(), to_date=today())
)[1]
expected_values = [
[inv_1.name, "TDS - 1", 10, 5000, 500, 5500],
[inv_2.name, "TDS - 2", 20, 5000, 1000, 6000],
]
self.check_expected_values(result, expected_values)
def check_expected_values(self, result, expected_values):
for i in range(len(result)):
voucher = frappe._dict(result[i])
voucher_expected_values = expected_values[i]
self.assertEqual(voucher.ref_no, voucher_expected_values[0])
self.assertEqual(voucher.section_code, voucher_expected_values[1])
self.assertEqual(voucher.rate, voucher_expected_values[2])
self.assertEqual(voucher.base_total, voucher_expected_values[3])
self.assertAlmostEqual(voucher.tax_amount, voucher_expected_values[4])
self.assertAlmostEqual(voucher.grand_total, voucher_expected_values[5])
voucher_actual_values = (
voucher.ref_no,
voucher.section_code,
voucher.rate,
voucher.base_total,
voucher.tax_amount,
voucher.grand_total,
)
self.assertSequenceEqual(voucher_actual_values, voucher_expected_values)
def tearDown(self):
self.clear_old_entries()
@@ -67,24 +93,20 @@ def create_tax_accounts():
).insert(ignore_if_duplicate=True)
def create_tcs_category():
def create_tax_category(category="TCS", rate=0.075, account="TCS - _TC", cumulative_threshold=0):
fiscal_year = get_fiscal_year(today(), company="_Test Company")
from_date = fiscal_year[1]
to_date = fiscal_year[2]
tax_category = create_tax_withholding_category(
category_name="TCS",
rate=0.075,
create_tax_withholding_category(
category_name=category,
rate=rate,
from_date=from_date,
to_date=to_date,
account="TCS - _TC",
cumulative_threshold=300,
account=account,
cumulative_threshold=cumulative_threshold,
)
customer = frappe.get_doc("Customer", "_Test Customer")
customer.tax_withholding_category = "TCS"
customer.save()
def create_tcs_payment_entry():
payment_entry = create_payment_entry(
@@ -109,3 +131,32 @@ def create_tcs_payment_entry():
)
payment_entry.submit()
return payment_entry
def create_tcs_journal_entry():
jv = frappe.new_doc("Journal Entry")
jv.posting_date = today()
jv.company = "_Test Company"
jv.set(
"accounts",
[
{
"account": "Debtors - _TC",
"party_type": "Customer",
"party": "_Test Customer",
"credit_in_account_currency": 10000,
},
{
"account": "Debtors - _TC",
"party_type": "Customer",
"party": "_Test Customer",
"debit_in_account_currency": 9992.5,
},
{
"account": "TCS - _TC",
"debit_in_account_currency": 7.5,
},
],
)
jv.insert()
return jv.submit()

View File

@@ -78,8 +78,14 @@ frappe.query_reports["Trial Balance"] = {
"options": erpnext.get_presentation_currency_list()
},
{
"fieldname": "with_period_closing_entry",
"label": __("Period Closing Entry"),
"fieldname": "with_period_closing_entry_for_opening",
"label": __("With Period Closing Entry For Opening Balances"),
"fieldtype": "Check",
"default": 1
},
{
"fieldname": "with_period_closing_entry_for_current_period",
"label": __("Period Closing Entry For Current Period"),
"fieldtype": "Check",
"default": 1
},

View File

@@ -116,7 +116,7 @@ def get_data(filters):
max_rgt,
filters,
gl_entries_by_account,
ignore_closing_entries=not flt(filters.with_period_closing_entry),
ignore_closing_entries=not flt(filters.with_period_closing_entry_for_current_period),
ignore_opening_entries=True,
)
@@ -249,7 +249,7 @@ def get_opening_balance(
):
opening_balance = opening_balance.where(closing_balance.posting_date >= filters.year_start_date)
if not flt(filters.with_period_closing_entry):
if not flt(filters.with_period_closing_entry_for_opening):
if doctype == "Account Closing Balance":
opening_balance = opening_balance.where(closing_balance.is_period_closing_voucher_entry == 0)
else:

View File

@@ -251,6 +251,7 @@ def get_journal_entries(filters, args):
)
.where(
(je.voucher_type == "Journal Entry")
& (je.docstatus == 1)
& (journal_account.party == filters.get(args.party))
& (journal_account.account.isin(args.party_account))
)
@@ -281,7 +282,9 @@ def get_payment_entries(filters, args):
pe.cost_center,
)
.where(
(pe.party == filters.get(args.party)) & (pe[args.account_fieldname].isin(args.party_account))
(pe.docstatus == 1)
& (pe.party == filters.get(args.party))
& (pe[args.account_fieldname].isin(args.party_account))
)
.orderby(pe.posting_date, pe.name, order=Order.desc)
)
@@ -365,7 +368,7 @@ def filter_invoices_based_on_dimensions(filters, query, parent_doc):
dimension.document_type, filters.get(dimension.fieldname)
)
fieldname = dimension.fieldname
query = query.where(parent_doc[fieldname] == filters.fieldname)
query = query.where(parent_doc[fieldname].isin(filters[fieldname]))
return query

View File

@@ -23,6 +23,10 @@ class TestUtils(unittest.TestCase):
super(TestUtils, cls).setUpClass()
make_test_objects("Address", ADDRESS_RECORDS)
@classmethod
def tearDownClass(cls):
frappe.db.rollback()
def test_get_party_shipping_address(self):
address = get_party_shipping_address("Customer", "_Test Customer 1")
self.assertEqual(address, "_Test Billing Address 2 Title-Billing")
@@ -126,6 +130,38 @@ class TestUtils(unittest.TestCase):
self.assertEqual(len(payment_entry.references), 1)
self.assertEqual(payment_entry.difference_amount, 0)
def test_naming_series_variable_parsing(self):
"""
Tests parsing utility used by Naming Series Variable hook for FY
"""
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from frappe.utils import nowdate
from erpnext.accounts.utils import get_fiscal_year
from erpnext.buying.doctype.supplier.test_supplier import create_supplier
# Configure Supplier Naming in Buying Settings
frappe.db.set_default("supp_master_name", "Auto Name")
# Configure Autoname in Supplier DocType
make_property_setter(
"Supplier", None, "naming_rule", "Expression", "Data", for_doctype="Doctype"
)
make_property_setter(
"Supplier", None, "autoname", "SUP-.FY.-.#####", "Data", for_doctype="Doctype"
)
fiscal_year = get_fiscal_year(nowdate())[0]
# Create Supplier
supplier = create_supplier()
# Check Naming Series in generated Supplier ID
doc_name = supplier.name.split("-")
self.assertEqual(len(doc_name), 3)
self.assertSequenceEqual(doc_name[0:2], ("SUP", fiscal_year))
frappe.db.set_default("supp_master_name", "Supplier Name")
ADDRESS_RECORDS = [
{

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